package admin import ( "strconv" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" "github.com/break/junhong_cmp_fiber/internal/model/dto" distributionquery "github.com/break/junhong_cmp_fiber/internal/query/distributionwithdrawal" shopQuery "github.com/break/junhong_cmp_fiber/internal/query/shop" shopCommissionService "github.com/break/junhong_cmp_fiber/internal/service/shop_commission" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/middleware" "github.com/break/junhong_cmp_fiber/pkg/response" ) // ShopCommissionHandler 代理商资金管理 Handler type ShopCommissionHandler struct { service *shopCommissionService.Service fundSummaryQuery *shopQuery.FundSummaryQuery withdrawalQuery *distributionquery.Query validator *validator.Validate } // NewShopCommissionHandler 创建代理商资金管理 Handler func NewShopCommissionHandler( service *shopCommissionService.Service, validate *validator.Validate, ) *ShopCommissionHandler { return &ShopCommissionHandler{service: service, validator: validate} } // SetWithdrawalQuery 注入提现申请详情查询。 func (h *ShopCommissionHandler) SetWithdrawalQuery(query *distributionquery.Query) { h.withdrawalQuery = query } // SetFundSummaryQuery 注入代理商资金概况 Query。 func (h *ShopCommissionHandler) SetFundSummaryQuery(query *shopQuery.FundSummaryQuery) { h.fundSummaryQuery = query } // ListFundSummary 代理商资金概况列表 // GET /api/admin/shops/fund-summary func (h *ShopCommissionHandler) ListFundSummary(c *fiber.Ctx) error { var req dto.ShopFundSummaryListReq if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } if c.Context().QueryArgs().Has("shop_id") && (req.ShopID == nil || *req.ShopID == 0) { return errors.New(errors.CodeInvalidParam) } if h.fundSummaryQuery == nil { return errors.New(errors.CodeInternalError, "代理商资金概况查询能力未配置") } result, err := h.fundSummaryQuery.List(c.UserContext(), req) if err != nil { return err } return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size) } // ListWithdrawalRequests 代理商提现记录列表 // GET /api/admin/shops/:shop_id/withdrawal-requests func (h *ShopCommissionHandler) ListWithdrawalRequests(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } var req dto.ShopWithdrawalRequestListReq if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } result, err := h.service.ListShopWithdrawalRequests(c.UserContext(), uint(shopID), &req) if err != nil { return err } return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size) } // ListCommissionRecords 代理商佣金明细列表 // GET /api/admin/shops/:shop_id/commission-records func (h *ShopCommissionHandler) ListCommissionRecords(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } var req dto.ShopCommissionRecordListReq if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } result, err := h.service.ListShopCommissionRecords(c.UserContext(), uint(shopID), &req) if err != nil { return err } return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size) } // GetCommissionRecord 佣金明细详情 // GET /api/admin/shops/:shop_id/commission-records/:id // source 区分原佣金与回溯明细;越权与不存在返回同一结果。 func (h *ShopCommissionHandler) GetCommissionRecord(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil || shopID == 0 { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } recordID, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil || recordID == 0 { return errors.New(errors.CodeInvalidParam, "无效的佣金明细ID") } var req dto.ShopCommissionRecordDetailReq if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } req.ShopID = uint(shopID) req.ID = uint(recordID) result, err := h.service.GetShopCommissionRecord(c.UserContext(), &req) if err != nil { return err } return response.Success(c, result) } // ResolveCommissionRecord 修正待审佣金记录 // POST /api/admin/commission-records/:id/resolve func (h *ShopCommissionHandler) ResolveCommissionRecord(c *fiber.Ctx) error { recordID, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil || recordID == 0 { return errors.New(errors.CodeInvalidParam, "无效的佣金记录ID") } var req dto.CommissionRecordResolveRequest if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } if err := h.service.ResolveCommissionRecord(c.UserContext(), uint(recordID), &req); err != nil { return err } return response.Success(c, nil) } // GetCommissionStats 代理商佣金统计 // GET /api/admin/shops/:shop_id/commission-stats func (h *ShopCommissionHandler) GetCommissionStats(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } var req dto.CommissionStatsRequest if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } result, err := h.service.GetStats(c.UserContext(), uint(shopID), &req) if err != nil { return err } return response.Success(c, result) } // GetCommissionDailyStats 代理商每日佣金统计 // GET /api/admin/shops/:shop_id/commission-daily-stats func (h *ShopCommissionHandler) GetCommissionDailyStats(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } var req dto.DailyCommissionStatsRequest if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } result, err := h.service.GetDailyStats(c.UserContext(), uint(shopID), &req) if err != nil { return err } return response.Success(c, result) } // CreateWithdrawal 发起提现申请 // POST /api/admin/shops/:shop_id/withdrawal-requests func (h *ShopCommissionHandler) CreateWithdrawal(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } var req dto.CreateMyWithdrawalReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } result, err := h.service.CreateWithdrawalRequest(c.UserContext(), uint(shopID), &req) if err != nil { return err } return response.Success(c, result) } // ResubmitWithdrawal 重提被驳回的提现申请 // PUT /api/admin/shops/:shop_id/withdrawal-requests/:id func (h *ShopCommissionHandler) ResubmitWithdrawal(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil || shopID == 0 { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } requestID, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil || requestID == 0 { return errors.New(errors.CodeInvalidParam, "无效的提现申请 ID") } var req dto.ResubmitWithdrawalReq 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, "提现重提参数不合法") } result, err := h.service.ResubmitWithdrawalRequest(c.UserContext(), uint(shopID), uint(requestID), &req) if err != nil { return err } return response.Success(c, result) } // WithdrawalDetail 提现申请详情 // GET /api/admin/shops/:shop_id/withdrawal-requests/:id // 仅返回当前账号数据范围内的申请;超出范围与不存在返回同一结果。 func (h *ShopCommissionHandler) WithdrawalDetail(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil || shopID == 0 { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } requestID, err := strconv.ParseUint(c.Params("id"), 10, 64) if err != nil || requestID == 0 { return errors.New(errors.CodeInvalidParam, "无效的提现申请 ID") } if h.withdrawalQuery == nil { return errors.New(errors.CodeInternalError, "提现详情查询能力未配置") } if err := middleware.CanManageShop(c.UserContext(), uint(shopID)); err != nil { return errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在") } detail, err := h.withdrawalQuery.WithdrawalDetail(c.UserContext(), uint(requestID)) if err != nil { return err } if detail.ShopID != uint(shopID) { return errors.New(errors.CodeNotFound, "提现申请不存在") } return response.Success(c, detail) } // ListMainWalletTransactions 预充值钱包流水列表 // GET /api/admin/shops/:shop_id/main-wallet/transactions func (h *ShopCommissionHandler) ListMainWalletTransactions(c *fiber.Ctx) error { shopID, err := strconv.ParseUint(c.Params("shop_id"), 10, 64) if err != nil { return errors.New(errors.CodeInvalidParam, "无效的店铺 ID") } var req dto.MainWalletTransactionListRequest if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } result, err := h.service.ListMainWalletTransactions(c.UserContext(), uint(shopID), &req) if err != nil { return err } return response.SuccessWithPagination(c, result.Items, result.Total, result.Page, result.Size) }