package financewithdrawal import ( "errors" "strconv" "strings" "hyapp-admin-server/internal/integration/activityclient" "hyapp-admin-server/internal/integration/walletclient" "hyapp-admin-server/internal/middleware" "hyapp-admin-server/internal/modules/shared" "hyapp-admin-server/internal/repository" "hyapp-admin-server/internal/response" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type Handler struct { service *Service audit shared.OperationLogger } func New(store *repository.Store, wallet walletclient.Client, activity activityclient.Client, audit shared.OperationLogger) *Handler { return &Handler{service: NewService(store, wallet, activity), audit: audit} } func (h *Handler) ListApplications(c *gin.Context) { options := shared.ListOptions(c) items, total, err := h.service.ListApplications(repository.WithdrawalApplicationListOptions{ Page: options.Page, PageSize: options.PageSize, AppCode: firstQuery(c, "app_code", "appCode"), Keyword: options.Keyword, }) if err != nil { response.ServerError(c, "获取用户提现申请列表失败") return } response.OK(c, response.Page{Items: items, Page: options.Page, PageSize: options.PageSize, Total: total}) } func (h *Handler) ApproveApplication(c *gin.Context) { h.auditApplication(c, "approved") } func (h *Handler) RejectApplication(c *gin.Context) { h.auditApplication(c, "rejected") } func (h *Handler) auditApplication(c *gin.Context, decision string) { id, ok := shared.ParseID(c, "application_id") if !ok { return } var req struct { AuditRemark string `json:"auditRemark"` AuditImageURL string `json:"auditImageUrl"` AuditImageURLSnake string `json:"audit_image_url"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "审核参数不正确") return } var ( item *withdrawalApplicationDTO err error ) if decision == "approved" { item, err = h.service.ApproveApplication(c.Request.Context(), shared.ActorFromContext(c), id, req.AuditRemark, firstNonEmpty(req.AuditImageURL, req.AuditImageURLSnake), middleware.CurrentRequestID(c)) } else { item, err = h.service.RejectApplication(c.Request.Context(), shared.ActorFromContext(c), id, req.AuditRemark, middleware.CurrentRequestID(c)) } if err != nil { writeWithdrawalServiceError(c, err) return } shared.OperationLogWithResourceID(c, h.audit, "audit-user-withdrawal-application", "admin_user_withdrawal_applications", strconv.FormatUint(uint64(item.ID), 10), "success", decision) response.OK(c, item) } func writeWithdrawalServiceError(c *gin.Context, err error) { if errors.Is(err, gorm.ErrRecordNotFound) { response.NotFound(c, "用户提现申请不存在") return } if errors.Is(err, repository.ErrWithdrawalApplicationAlreadyAudited) { response.BadRequest(c, "提现申请已审核") return } switch strings.TrimSpace(err.Error()) { case "没有操作权限": response.Forbidden(c, err.Error()) case "admin finance withdrawal service is not configured": response.ServerError(c, "审核用户提现申请失败") default: response.BadRequest(c, err.Error()) } } func firstQuery(c *gin.Context, keys ...string) string { for _, key := range keys { if value := strings.TrimSpace(c.Query(key)); value != "" { return value } } return "" } func firstNonEmpty(values ...string) string { for _, value := range values { if trimmed := strings.TrimSpace(value); trimmed != "" { return trimmed } } return "" }