2026-07-02 10:53:44 +08:00

118 lines
3.4 KiB
Go

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 ""
}