package admin import ( "strconv" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" distributionapp "github.com/break/junhong_cmp_fiber/internal/application/distributionwithdrawal" distributiondomain "github.com/break/junhong_cmp_fiber/internal/domain/distribution" "github.com/break/junhong_cmp_fiber/internal/model/dto" distributionquery "github.com/break/junhong_cmp_fiber/internal/query/distributionwithdrawal" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/middleware" "github.com/break/junhong_cmp_fiber/pkg/response" ) // WithdrawalQualificationHandler 提现资料资格后台 Handler。 type WithdrawalQualificationHandler struct { service *distributionapp.QualificationService query *distributionquery.Query validator *validator.Validate } // NewWithdrawalQualificationHandler 创建提现资料资格后台 Handler。 func NewWithdrawalQualificationHandler( service *distributionapp.QualificationService, query *distributionquery.Query, validate *validator.Validate, ) *WithdrawalQualificationHandler { return &WithdrawalQualificationHandler{service: service, query: query, validator: validate} } // SubmitWithdrawalQualification 提交或替换提现资料资格 // POST /api/admin/shops/:shop_id/withdrawal-qualifications // 仅本人代理店铺;替换合同或法人身份证时同一事务新增版本并使旧有效版本失效。 func (h *WithdrawalQualificationHandler) SubmitWithdrawalQualification(c *fiber.Ctx) error { if h.service == nil { return errors.New(errors.CodeServiceUnavailable, "提现资料资格能力尚未配置") } var req dto.SubmitWithdrawalQualificationReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } if h.validator == nil { return errors.New(errors.CodeInternalError, "提现资料资格校验器未配置") } if err := h.validator.Struct(&req); err != nil { return errors.New(errors.CodeInvalidParam, "提现资料资格参数不合法") } shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil || shopID == 0 { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } result, err := h.service.Submit(c.UserContext(), uint(shopID), distributiondomain.QualificationInput{ SubjectType: req.SubjectType, SubjectCode: req.SubjectCode, LegalPersonIDCard: req.LegalPersonIDCard, ContractFileKey: req.ContractFileKey, IDCardFrontFileKey: req.IDCardFrontFileKey, IDCardBackFileKey: req.IDCardBackFileKey, BusinessLicenseFileKey: req.BusinessLicenseFileKey, ShopFrontFileKey: req.ShopFrontFileKey, InvoiceFileKey: req.InvoiceFileKey, InvoiceTitle: req.InvoiceTitle, InvoiceSubjectCode: req.InvoiceSubjectCode, }) if err != nil { return err } return response.Success(c, &dto.SubmitWithdrawalQualificationResp{ ID: result.QualificationID, Status: result.Status, StatusName: constants.GetWithdrawalQualificationStatusName(result.Status), }) } // VoidWithdrawalQualification 超级管理员作废有效提现资料资格 // POST /api/admin/withdrawal-qualifications/:id/void func (h *WithdrawalQualificationHandler) VoidWithdrawalQualification(c *fiber.Ctx) error { if h.service == nil { return errors.New(errors.CodeServiceUnavailable, "提现资料资格能力尚未配置") } id, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil || id == 0 { return errors.New(errors.CodeInvalidParam, "无效的资格 ID") } var req dto.VoidWithdrawalQualificationReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } if h.validator == nil { return errors.New(errors.CodeInternalError, "提现资料资格校验器未配置") } if err := h.validator.Struct(&req); err != nil { return errors.New(errors.CodeInvalidParam, "作废提现资料资格必须填写原因") } if err := h.service.Void(c.UserContext(), uint(id), req.Reason); err != nil { return err } return response.Success(c, nil) } // ListWithdrawalQualifications 查询提现资料资格版本 // GET /api/admin/shops/:shop_id/withdrawal-qualifications // 仅返回当前账号数据范围内的资料版本;证件号脱敏,附件只返回对象存储 Key。 func (h *WithdrawalQualificationHandler) ListWithdrawalQualifications(c *fiber.Ctx) error { if h.query == nil { return errors.New(errors.CodeInternalError, "提现资料资格查询能力未配置") } var req dto.WithdrawalQualificationListReq if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } // 路由路径必带 shop_id;数据范围由 CanManageShop 在业务边界强制。 shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil || shopID == 0 { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } if err := middleware.CanManageShop(c.UserContext(), uint(shopID)); err != nil { return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在") } result, err := h.query.ListQualifications(c.UserContext(), []uint{uint(shopID)}, &req) if err != nil { return err } return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size) }