- 深度优化商品审核工作台:指标概览卡片、风险边条队列、标价管道联动、核心资产高密度展示、底部决策浮动 Dock、全套键盘快捷键 - 重构截图大图查看体验:移除旧版底部溢出的全局画廊,封装全屏居中弹窗 AdminListingReviewPreviewDialog,支持「按住速览(松手即关闭)」与「常驻弹窗(缩放/翻页/打码/原图)」双模交互 - 新增在线截图编辑器 ImageEditorDialog:支持平滑马赛克打码、自由裁剪与旋转保存 - 弹窗组件解耦:抽离审核拒绝、调价、全量核验、快捷键速查等子组件,严格控制单文件行数 - 后端支持:新增商品审核调整价格接口与配套单元测试
209 lines
4.4 KiB
Go
209 lines
4.4 KiB
Go
package listing
|
|
|
|
import (
|
|
"context"
|
|
|
|
"hfb_sys/backend/internal/middleware"
|
|
"hfb_sys/backend/pkg/response"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func (h *Handler) ListPendingReview(c *gin.Context) {
|
|
items, err := h.service.ListPendingReview(c.Request.Context())
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, gin.H{"items": items})
|
|
}
|
|
|
|
func (h *Handler) ListAdmin(c *gin.Context) {
|
|
query, ok := parseAdminListQuery(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
result, err := h.service.ListAdmin(c.Request.Context(), query)
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, result)
|
|
}
|
|
|
|
func (h *Handler) FindAdmin(c *gin.Context) {
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
item, err := h.service.FindAdmin(c.Request.Context(), id)
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) AdminOffline(c *gin.Context) {
|
|
h.adminAction(c, h.service.AdminOffline)
|
|
}
|
|
|
|
func (h *Handler) AdminMarkAbnormal(c *gin.Context) {
|
|
h.adminAction(c, h.service.AdminMarkAbnormal)
|
|
}
|
|
|
|
func (h *Handler) TransferOwner(c *gin.Context) {
|
|
adminID, ok := currentAdminID(c)
|
|
if !ok {
|
|
response.Unauthorized(c, "缺少管理员上下文")
|
|
return
|
|
}
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req TransferOwnerRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "转移参数不正确")
|
|
return
|
|
}
|
|
item, err := h.service.TransferOwner(c.Request.Context(), adminID, id, req, auditMeta(c))
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) adminAction(c *gin.Context, fn func(context.Context, uint64, uint64, AdminActionRequest, AuditMeta) (*ListingDTO, error)) {
|
|
adminID, ok := currentAdminID(c)
|
|
if !ok {
|
|
response.Unauthorized(c, "缺少管理员上下文")
|
|
return
|
|
}
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req AdminActionRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "操作原因不能为空")
|
|
return
|
|
}
|
|
item, err := fn(c.Request.Context(), adminID, id, req, auditMeta(c))
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func auditMeta(c *gin.Context) AuditMeta {
|
|
return AuditMeta{
|
|
IP: c.ClientIP(),
|
|
UserAgent: c.GetHeader("User-Agent"),
|
|
RequestID: middleware.GetRequestID(c),
|
|
}
|
|
}
|
|
|
|
func (h *Handler) Approve(c *gin.Context) {
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
item, err := h.service.Approve(c.Request.Context(), id)
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) AdjustReviewPrice(c *gin.Context) {
|
|
adminID, ok := currentAdminID(c)
|
|
if !ok {
|
|
response.Unauthorized(c, "缺少管理员上下文")
|
|
return
|
|
}
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req AdminPriceAdjustRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "调价参数不正确")
|
|
return
|
|
}
|
|
item, err := h.service.AdjustReviewPrice(c.Request.Context(), adminID, id, req, auditMeta(c))
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) AdjustExternalListing(c *gin.Context) {
|
|
adminID, ok := currentAdminID(c)
|
|
if !ok {
|
|
response.Unauthorized(c, "缺少管理员上下文")
|
|
return
|
|
}
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req AdminExternalListingAdjustRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "外部商品调整参数不正确")
|
|
return
|
|
}
|
|
item, err := h.service.AdjustExternalListing(c.Request.Context(), adminID, id, req, auditMeta(c))
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) Reject(c *gin.Context) {
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req ReviewRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "审核拒绝原因不能为空")
|
|
return
|
|
}
|
|
item, err := h.service.Reject(c.Request.Context(), id, req)
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|
|
func (h *Handler) UpdateScreenshots(c *gin.Context) {
|
|
adminID, ok := currentAdminID(c)
|
|
if !ok {
|
|
response.Unauthorized(c, "缺少管理员上下文")
|
|
return
|
|
}
|
|
id, ok := parseID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req AdminUpdateScreenshotsRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "截图参数不正确")
|
|
return
|
|
}
|
|
item, err := h.service.UpdateScreenshots(c.Request.Context(), adminID, id, req, auditMeta(c))
|
|
if err != nil {
|
|
writeListingError(c, err)
|
|
return
|
|
}
|
|
response.OK(c, item)
|
|
}
|
|
|