## CI 修复 (P0/P1) P0 — 编译阻塞: - interfaces.go: postUseCase ISP 接口移除不用的 Create/Update/Delete P1 — 必须修复: - ST1000: 为 13 个包添加包注释 (common/config/model/service/...) - ST1005: redis_store.go 全部错误消息改为小写开头 - errcheck (19处): defer Close()→闭包忽略, notifier.Create→_=, r.Run→检查error - errorlint (9处): switch-on-error→errors.Is 链, ==→errors.Is - ST1020/ST1022: 导出符号注释以符号名开头 P2 — 安全评审: - gosec (12处): G203/G301/G304/G306 添加 nolint 注释并附理由 P3 — 清理: - unused: 移除 hasUnicode/energyStore/current/energyAdminUseCase - gofumpt + goimports 全量格式化 (35+ 文件)
141 lines
3.7 KiB
Go
141 lines
3.7 KiB
Go
package admin
|
||
|
||
import (
|
||
"errors"
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"metazone.cc/mce/internal/common"
|
||
"metazone.cc/mce/internal/model"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// AuditController 审核管理控制器
|
||
type AuditController struct {
|
||
auditService auditUseCase
|
||
userRepo auditStatusProvider
|
||
}
|
||
|
||
// NewAuditController 构造函数
|
||
func NewAuditController(auditService auditUseCase, userRepo auditStatusProvider) *AuditController {
|
||
return &AuditController{auditService: auditService, userRepo: userRepo}
|
||
}
|
||
|
||
// AuditPage 审核管理页面
|
||
func (ac *AuditController) AuditPage(c *gin.Context) {
|
||
c.HTML(http.StatusOK, "admin/audit/index.html", common.BuildAdminPageData(c, gin.H{
|
||
"Title": "审核管理",
|
||
"ExtraCSS": "/admin/static/css/audit.css",
|
||
"ExtraJS": "/admin/static/js/audit.js",
|
||
"AuditTypes": model.AuditTypeNames,
|
||
"AuditStatus": model.AuditStatusNames,
|
||
}))
|
||
}
|
||
|
||
// ListAudits 审核列表 API(分页 + 类型筛选)
|
||
func (ac *AuditController) ListAudits(c *gin.Context) {
|
||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||
auditType := c.Query("type")
|
||
status := c.Query("status")
|
||
|
||
// 默认查 pending
|
||
if status == "" {
|
||
status = model.AuditStatusPending
|
||
}
|
||
|
||
result, err := ac.auditService.List(auditType, status, page, pageSize)
|
||
if err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "查询失败")
|
||
return
|
||
}
|
||
|
||
// 为每个审核记录附加提交者的当前用户名
|
||
type auditItem struct {
|
||
model.AuditSubmission
|
||
CurrentUsername string `json:"current_username"`
|
||
}
|
||
|
||
items := make([]auditItem, 0, len(result.Items))
|
||
for _, a := range result.Items {
|
||
item := auditItem{AuditSubmission: a}
|
||
if user, err := ac.userRepo.FindByID(a.UserID); err == nil {
|
||
item.CurrentUsername = user.Username
|
||
}
|
||
items = append(items, item)
|
||
}
|
||
|
||
common.Ok(c, gin.H{
|
||
"items": items,
|
||
"total": result.Total,
|
||
"page": result.Page,
|
||
})
|
||
}
|
||
|
||
// Approve 通过审核
|
||
func (ac *AuditController) Approve(c *gin.Context) {
|
||
submissionID, err := parseIDParam(c.Param("id"))
|
||
if err != nil {
|
||
common.Error(c, http.StatusBadRequest, "无效的审核 ID")
|
||
return
|
||
}
|
||
|
||
reviewerID := c.GetUint("uid")
|
||
if err := ac.auditService.Approve(reviewerID, submissionID); err != nil {
|
||
handleAuditError(c, err)
|
||
return
|
||
}
|
||
|
||
common.OkMessage(c, "审核通过")
|
||
}
|
||
|
||
// Reject 拒绝审核
|
||
func (ac *AuditController) Reject(c *gin.Context) {
|
||
submissionID, err := parseIDParam(c.Param("id"))
|
||
if err != nil {
|
||
common.Error(c, http.StatusBadRequest, "无效的审核 ID")
|
||
return
|
||
}
|
||
|
||
var req struct {
|
||
Reason string `json:"reason"`
|
||
}
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
common.Error(c, http.StatusBadRequest, "参数错误")
|
||
return
|
||
}
|
||
|
||
reviewerID := c.GetUint("uid")
|
||
if err := ac.auditService.Reject(reviewerID, submissionID, req.Reason); err != nil {
|
||
handleAuditError(c, err)
|
||
return
|
||
}
|
||
|
||
common.OkMessage(c, "已拒绝")
|
||
}
|
||
|
||
// parseIDParam 从 URL 路径参数解析 uint ID
|
||
func parseIDParam(s string) (uint, error) {
|
||
id, err := strconv.ParseUint(s, 10, 64)
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
return uint(id), nil
|
||
}
|
||
|
||
// handleAuditError 统一处理审核接口的 service 层错误
|
||
func handleAuditError(c *gin.Context, err error) {
|
||
if errors.Is(err, common.ErrAuditNotFound) {
|
||
common.Error(c, http.StatusNotFound, "审核记录不存在")
|
||
} else if errors.Is(err, common.ErrAuditNotPending) {
|
||
common.Error(c, http.StatusBadRequest, "该审核记录已处理")
|
||
} else if errors.Is(err, common.ErrUserNotFound) {
|
||
common.Error(c, http.StatusNotFound, "用户不存在")
|
||
} else if errors.Is(err, common.ErrUsernameTaken) {
|
||
common.Error(c, http.StatusConflict, "该用户名已被其他用户占用,审批失败")
|
||
} else {
|
||
common.Error(c, http.StatusInternalServerError, "操作失败")
|
||
}
|
||
}
|