This commit is contained in:
2026-08-16 09:02:39 +08:00
parent c554152f4f
commit f7f6db8695
105 changed files with 2535 additions and 948 deletions
+128 -37
View File
@@ -2,6 +2,7 @@ package handler
import (
"errors"
"io"
"strconv"
"time"
@@ -28,6 +29,15 @@ func page(c *gin.Context) (int, int) {
size, _ := strconv.Atoi(c.Query("pageSize"))
return value, size
}
func queryUintValue(c *gin.Context, key string) (uint, bool, error) {
raw, ok := c.GetQuery(key)
if !ok || raw == "" {
return 0, false, nil
}
value, err := strconv.ParseUint(raw, 10, 0)
return uint(value), true, err
}
func IDsFromQuery(c *gin.Context) []uint {
values := c.QueryArray("IDs[]")
if len(values) == 0 {
@@ -43,19 +53,57 @@ func IDsFromQuery(c *gin.Context) []uint {
return ids
}
// auditID accepts both forms used by the GVA web client over time: DELETE
// requests may carry the identifier in the query string or in a JSON body.
func auditID(c *gin.Context) (uint, error) {
if raw := c.Query("ID"); raw != "" {
value, err := strconv.ParseUint(raw, 10, 64)
return uint(value), err
}
var request dto.IDRequest
if err := c.ShouldBindJSON(&request); err != nil && !errors.Is(err, io.EOF) {
return 0, err
}
return request.ID, nil
}
// auditIDs mirrors auditID for bulk deletes and supports both query-array and
// JSON-body encodings used by compatible GVA pages.
func auditIDs(c *gin.Context) ([]uint, error) {
if ids := IDsFromQuery(c); len(ids) > 0 {
return ids, nil
}
var request dto.IDsRequest
if err := c.ShouldBindJSON(&request); err != nil && !errors.Is(err, io.EOF) {
return nil, err
}
return request.IDs, nil
}
func (h *Audit) Operations(c *gin.Context) {
p, size := page(c)
status, _ := strconv.Atoi(c.Query("status"))
items, total, err := h.service.OperationsFilter(c.Request.Context(), p, size, c.Query("path"), c.Query("method"), status)
var req dto.OperationRecordSearchRequest
if err := c.ShouldBindQuery(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
items, total, err := h.service.OperationsFilter(c.Request.Context(), req.Page, req.PageSize, req.Path, req.Method, req.Status)
if err != nil {
httpx.Fail(c, "获取失败")
return
}
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: req.Page, PageSize: req.PageSize}, "获取成功")
}
func (h *Audit) Operation(c *gin.Context) {
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
item, err := h.service.Operation(c.Request.Context(), uint(id))
var req dto.AuditIDQuery
if err := c.ShouldBindQuery(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
if req.ID == 0 {
httpx.Fail(c, "ID值不能为空")
return
}
item, err := h.service.Operation(c.Request.Context(), req.ID)
if err != nil {
httpx.Fail(c, "查询失败")
return
@@ -63,24 +111,28 @@ func (h *Audit) Operation(c *gin.Context) {
httpx.Write(c, httpx.CodeSuccess, gin.H{"reSysOperationRecord": item}, "查询成功")
}
func (h *Audit) DeleteOperation(c *gin.Context) {
var req dto.IDRequest
if err := c.ShouldBindJSON(&req); err != nil {
id, err := auditID(c)
if err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteOperations(c.Request.Context(), []uint{req.ID}); err != nil {
if id == 0 {
httpx.Fail(c, "删除失败")
return
}
if err := h.service.DeleteOperations(c.Request.Context(), []uint{id}); err != nil {
httpx.Fail(c, "删除失败")
return
}
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
}
func (h *Audit) DeleteOperations(c *gin.Context) {
var req dto.IDsRequest
if err := c.ShouldBindJSON(&req); err != nil {
ids, err := auditIDs(c)
if err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteOperations(c.Request.Context(), req.IDs); err != nil {
if err := h.service.DeleteOperations(c.Request.Context(), ids); err != nil {
httpx.Fail(c, "批量删除失败")
return
}
@@ -88,18 +140,25 @@ func (h *Audit) DeleteOperations(c *gin.Context) {
}
func (h *Audit) Logins(c *gin.Context) {
p, size := page(c)
status, _ := strconv.ParseBool(c.Query("status"))
items, total, err := h.service.LoginsFilter(c.Request.Context(), p, size, c.Query("username"), status)
var req dto.LoginLogSearchRequest
if err := c.ShouldBindQuery(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
items, total, err := h.service.LoginsFilter(c.Request.Context(), req.Page, req.PageSize, req.Username, req.Status)
if err != nil {
httpx.Fail(c, "获取失败")
return
}
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: p, PageSize: size}, "获取成功")
httpx.Write(c, httpx.CodeSuccess, httpx.PageResult{List: items, Total: total, Page: req.Page, PageSize: req.PageSize}, "获取成功")
}
func (h *Audit) Login(c *gin.Context) {
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
item, err := h.service.Login(c.Request.Context(), uint(id))
var req dto.AuditIDQuery
if err := c.ShouldBindQuery(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
item, err := h.service.Login(c.Request.Context(), req.ID)
if err != nil {
httpx.Fail(c, "查询失败")
return
@@ -107,24 +166,28 @@ func (h *Audit) Login(c *gin.Context) {
httpx.Write(c, httpx.CodeSuccess, item, "查询成功")
}
func (h *Audit) DeleteLogin(c *gin.Context) {
var req dto.IDRequest
if err := c.ShouldBindJSON(&req); err != nil {
id, err := auditID(c)
if err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteLogins(c.Request.Context(), []uint{req.ID}); err != nil {
if id == 0 {
httpx.Fail(c, "删除失败")
return
}
if err := h.service.DeleteLogins(c.Request.Context(), []uint{id}); err != nil {
httpx.Fail(c, "删除失败")
return
}
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
}
func (h *Audit) DeleteLogins(c *gin.Context) {
var req dto.IDsRequest
if err := c.ShouldBindJSON(&req); err != nil {
ids, err := auditIDs(c)
if err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteLogins(c.Request.Context(), req.IDs); err != nil {
if err := h.service.DeleteLogins(c.Request.Context(), ids); err != nil {
httpx.Fail(c, "批量删除失败")
return
}
@@ -133,8 +196,8 @@ func (h *Audit) DeleteLogins(c *gin.Context) {
func (h *Audit) DataAccess(c *gin.Context) {
var req dto.DataAccessListRequest
if c.ShouldBindJSON(&req) != nil {
httpx.Fail(c, "参数错误")
if err := c.ShouldBindJSON(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
items, total, err := h.service.DataAccessRequest(c.Request.Context(), &req)
@@ -146,8 +209,8 @@ func (h *Audit) DataAccess(c *gin.Context) {
}
func (h *Audit) DeleteDataAccess(c *gin.Context) {
var req dto.IDsRequest
if c.ShouldBindJSON(&req) != nil {
httpx.Fail(c, "参数错误")
if err := c.ShouldBindJSON(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteDataAccess(c.Request.Context(), req.IDs); err != nil {
@@ -158,7 +221,14 @@ func (h *Audit) DeleteDataAccess(c *gin.Context) {
}
func (h *Audit) LogDates(c *gin.Context) {
data, err := h.logs.LogDates(c.Request.Context(), c.Query("month"))
month := c.Query("month")
// Month uses `binding:"required"`; an omitted or empty query is a
// generic parameter error, not the service's format-specific error.
if month == "" {
httpx.Fail(c, "参数错误")
return
}
data, err := h.logs.LogDates(c.Request.Context(), month)
if err != nil {
failLogViewer(c, err)
return
@@ -166,7 +236,12 @@ func (h *Audit) LogDates(c *gin.Context) {
httpx.Write(c, httpx.CodeSuccess, data, "获取成功")
}
func (h *Audit) LogFiles(c *gin.Context) {
data, err := h.logs.LogFiles(c.Request.Context(), c.Query("date"))
date := c.Query("date")
if date == "" {
httpx.Fail(c, "参数错误")
return
}
data, err := h.logs.LogFiles(c.Request.Context(), date)
if err != nil {
failLogViewer(c, err)
return
@@ -174,16 +249,23 @@ func (h *Audit) LogFiles(c *gin.Context) {
httpx.Write(c, httpx.CodeSuccess, data, "获取成功")
}
func (h *Audit) LogContent(c *gin.Context) {
date, path := c.Query("date"), c.Query("path")
if date == "" || path == "" {
httpx.Fail(c, "参数错误")
return
}
var cursor *int64
if raw := c.Query("cursor"); raw != "" {
value, err := strconv.ParseInt(raw, 10, 64)
if err != nil || value < 0 {
if err != nil {
httpx.Fail(c, "参数错误")
return
}
cursor = &value
}
data, err := h.logs.LogContent(c.Request.Context(), c.Query("date"), c.Query("path"), cursor)
// Preserve negative cursors for the usecase to classify with the compatible
// "日志文件路径不合法" error rather than rejecting them as binding errors.
data, err := h.logs.LogContent(c.Request.Context(), date, path, cursor)
if err != nil {
failLogViewer(c, err)
return
@@ -211,15 +293,24 @@ func failLogViewer(c *gin.Context, err error) {
}
func (h *Audit) DeleteError(c *gin.Context) {
id, _ := strconv.ParseUint(c.Query("ID"), 10, 64)
if err := h.service.DeleteErrors(c.Request.Context(), []uint{uint(id)}); err != nil {
id, err := auditID(c)
if err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteErrors(c.Request.Context(), []uint{id}); err != nil {
httpx.Fail(c, "删除失败:"+err.Error())
return
}
httpx.Write(c, httpx.CodeSuccess, gin.H{}, "删除成功")
}
func (h *Audit) DeleteErrors(c *gin.Context) {
if err := h.service.DeleteErrors(c.Request.Context(), IDsFromQuery(c)); err != nil {
ids, err := auditIDs(c)
if err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.DeleteErrors(c.Request.Context(), ids); err != nil {
httpx.Fail(c, "批量删除失败:"+err.Error())
return
}
@@ -227,8 +318,8 @@ func (h *Audit) DeleteErrors(c *gin.Context) {
}
func (h *Audit) UpdateError(c *gin.Context) {
var req dto.ErrorRecordRequest
if c.ShouldBindJSON(&req) != nil {
httpx.Fail(c, "参数错误")
if err := c.ShouldBindJSON(&req); err != nil {
httpx.Fail(c, err.Error())
return
}
if err := h.service.UpdateErrorRequest(c.Request.Context(), &req); err != nil {