package routes import ( "github.com/gofiber/fiber/v2" "github.com/break/junhong_cmp_fiber/internal/handler/admin" "github.com/break/junhong_cmp_fiber/internal/model/dto" "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/openapi" ) func registerShopRoutes(router fiber.Router, handler *admin.ShopHandler, doc *openapi.Generator, basePath string) { shops := router.Group("/shops") groupPath := basePath + "/shops" Register(shops, doc, groupPath, "GET", "", coreShopManagement(handler.List), RouteSpec{ Summary: "店铺列表", Description: constants.ShopManagementAccessDescription + constants.ShopListPaginationDescription, Tags: []string{"店铺管理"}, Input: new(dto.ShopListRequest), Output: new(dto.ShopPageResult), Auth: true, }) Register(shops, doc, groupPath, "POST", "", coreShopManagement(handler.Create), RouteSpec{ Summary: "创建店铺", Description: constants.ShopManagementAccessDescription, Tags: []string{"店铺管理"}, Input: new(dto.CreateShopRequest), Output: new(dto.ShopResponse), Auth: true, }) Register(shops, doc, groupPath, "GET", "/business-owner-candidates", coreShopManagement(handler.BusinessOwnerCandidates), RouteSpec{ Summary: "查询店铺业务员候选", Description: "仅超级管理员和平台账号可查询;只返回当前启用、未删除的平台账号最小摘要。", Tags: []string{"店铺管理"}, Input: new(dto.ShopBusinessOwnerCandidateRequest), Output: new(dto.ShopBusinessOwnerCandidatePageResult), Auth: true, }) Register(shops, doc, groupPath, "PUT", "/:id", coreShopManagement(handler.Update), RouteSpec{ Summary: "更新店铺", Description: constants.ShopManagementAccessDescription, Tags: []string{"店铺管理"}, Input: new(dto.UpdateShopParams), Output: new(dto.ShopResponse), Auth: true, }) Register(shops, doc, groupPath, "PUT", "/:id/credit-limit", handler.UpdateCreditLimit, RouteSpec{ Summary: "调整既有店铺实际信用额度", Description: "后端不校验按钮权限;shop:credit-limit:manage 仅供前端控制按钮显示。", Tags: []string{"代理商资金管理"}, Input: new(dto.UpdateShopCreditLimitParams), Output: new(dto.ShopCreditLimitResponse), Auth: true, }) Register(shops, doc, groupPath, "DELETE", "/:id", coreShopManagement(handler.Delete), RouteSpec{ Summary: "删除店铺", Description: constants.ShopManagementAccessDescription, Tags: []string{"店铺管理"}, Input: new(dto.IDReq), Output: nil, Auth: true, }) Register(shops, doc, groupPath, "GET", "/cascade", coreShopManagement(handler.Cascade), RouteSpec{ Summary: "店铺联级查询", Description: constants.ShopManagementAccessDescription, Tags: []string{"店铺管理"}, Input: new(dto.ShopCascadeRequest), Output: new([]dto.ShopCascadeItem), Auth: true, }) } func registerShopDetailRoute(router fiber.Router, handler *admin.ShopHandler, doc *openapi.Generator, basePath string) { shops := router.Group("/shops") groupPath := basePath + "/shops" Register(shops, doc, groupPath, "GET", "/:id", coreShopManagement(handler.Detail), RouteSpec{ Summary: "查询店铺详情", Description: constants.ShopManagementAccessDescription + " 返回与店铺列表一致的业务员归属摘要。", Tags: []string{"店铺管理"}, Input: new(dto.IDReq), Output: new(dto.ShopResponse), Auth: true, }) } func coreShopManagement(handler fiber.Handler) fiber.Handler { return func(c *fiber.Ctx) error { if middleware.GetUserTypeFromContext(c.UserContext()) == constants.UserTypeEnterprise { return errors.New(errors.CodeForbidden, constants.ShopManagementForbiddenMessage) } return handler(c) } } func registerShopRoleRoutes(router fiber.Router, handler *admin.ShopRoleHandler, doc *openapi.Generator, basePath string) { shops := router.Group("/shops") groupPath := basePath + "/shops" Register(shops, doc, groupPath, "POST", "/:shop_id/roles", handler.AssignShopRoles, RouteSpec{ Summary: "分配店铺默认角色", Tags: []string{"店铺管理"}, Input: new(dto.AssignShopRolesRequest), Output: new(dto.ShopRolesResponse), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/roles", handler.GetShopRoles, RouteSpec{ Summary: "查询店铺默认角色", Tags: []string{"店铺管理"}, Input: new(dto.GetShopRolesRequest), Output: new(dto.ShopRolesResponse), Auth: true, }) Register(shops, doc, groupPath, "DELETE", "/:shop_id/roles/:role_id", handler.DeleteShopRole, RouteSpec{ Summary: "删除店铺默认角色", Tags: []string{"店铺管理"}, Input: new(dto.DeleteShopRoleRequest), Output: nil, Auth: true, }) } func registerShopCommissionRoutes(router fiber.Router, handler *admin.ShopCommissionHandler, doc *openapi.Generator, basePath string) { shops := router.Group("/shops") groupPath := basePath + "/shops" Register(shops, doc, groupPath, "GET", "/fund-summary", agentFundManagement(handler.ListFundSummary), RouteSpec{ Summary: "代理商资金概况", Description: "按当前店铺数据范围分页返回主钱包、佣金及信用资金事实;现金可用、总可用和欠款均由服务端计算,读取不代表具有调额权限。", Tags: []string{"代理商资金管理"}, Input: new(dto.ShopFundSummaryListReq), Output: new(dto.ShopFundSummaryPageResult), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/withdrawal-requests", handler.ListWithdrawalRequests, RouteSpec{ Summary: "代理商提现记录", Tags: []string{"代理商资金管理"}, Input: new(dto.ShopWithdrawalRequestListReq), Output: new(dto.ShopWithdrawalRequestPageResult), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/commission-records", handler.ListCommissionRecords, RouteSpec{ Summary: "代理商佣金明细", Tags: []string{"代理商资金管理"}, Input: new(dto.ShopCommissionRecordListReq), Output: new(dto.ShopCommissionRecordPageResult), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/commission-records/:id", handler.GetCommissionRecord, RouteSpec{ Summary: "佣金明细详情", Description: "返回单条佣金明细;source=clawback 时返回回溯明细并附带其原佣金,默认返回原佣金并附带全部回溯明细。仅限有数据范围的后台账号,越权与不存在返回同一结果。", Tags: []string{"代理商资金管理"}, Input: new(dto.ShopCommissionRecordDetailReq), Output: new(dto.ShopCommissionRecordDetailResp), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/main-wallet/transactions", handler.ListMainWalletTransactions, RouteSpec{ Summary: "代理商预充值钱包流水", Tags: []string{"代理商资金管理"}, Input: new(dto.MainWalletTransactionListRequest), Output: new(dto.MainWalletTransactionListResponse), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/commission-stats", handler.GetCommissionStats, RouteSpec{ Summary: "代理商佣金统计", Tags: []string{"代理商资金管理"}, Input: new(dto.CommissionStatsRequest), Output: new(dto.CommissionStatsResponse), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/commission-daily-stats", handler.GetCommissionDailyStats, RouteSpec{ Summary: "代理商每日佣金统计", Tags: []string{"代理商资金管理"}, Input: new(dto.DailyCommissionStatsRequest), Output: []dto.DailyCommissionStatsResponse{}, Auth: true, }) Register(shops, doc, groupPath, "POST", "/:shop_id/withdrawal-requests", handler.CreateWithdrawal, RouteSpec{ Summary: "发起提现申请", Tags: []string{"代理商资金管理"}, Input: new(dto.CreateMyWithdrawalReq), Output: new(dto.CreateMyWithdrawalResp), Auth: true, }) Register(shops, doc, groupPath, "PUT", "/:shop_id/withdrawal-requests/:id", handler.ResubmitWithdrawal, RouteSpec{ Summary: "重提被驳回的提现申请", Description: "仅本人代理店铺,且仅已被企业微信驳回的申请可重提。事务内先释放旧未结算冻结再按新金额冻结,新增审批尝试记录与新的审批实例,历史尝试与审批结果不被覆盖。", Tags: []string{"代理商资金管理"}, Input: new(dto.ResubmitWithdrawalReq), Output: new(dto.CreateMyWithdrawalResp), Auth: true, }) Register(shops, doc, groupPath, "GET", "/:shop_id/withdrawal-requests/:id", handler.WithdrawalDetail, RouteSpec{ Summary: "提现申请详情", Description: "返回指定提现申请及其全部审批尝试记录与正交异常标记,用于详情展示;仅限有数据范围的后台账号。", Tags: []string{"代理商资金管理"}, Input: new(dto.ShopWithdrawalRequestDetailReq), Output: new(dto.ShopWithdrawalRequestDetailResp), Auth: true, }) commissionRecords := router.Group("/commission-records") crPath := basePath + "/commission-records" Register(commissionRecords, doc, crPath, "POST", "/:id/resolve", handler.ResolveCommissionRecord, RouteSpec{ Summary: "修正待审佣金记录", Tags: []string{"代理商资金管理"}, Input: new(dto.CommissionRecordResolveRequest), Auth: true, }) } func agentFundManagement(handler fiber.Handler) fiber.Handler { return func(c *fiber.Ctx) error { if middleware.GetUserTypeFromContext(c.UserContext()) == constants.UserTypeEnterprise { return errors.New(errors.CodeForbidden, constants.AgentFundManagementForbiddenMessage) } return handler(c) } } // registerWithdrawalQualificationRoutes 注册提现资料资格路由。 // 资格提交与查询沿用既有认证与数据范围校验,绝不公开。 func registerWithdrawalQualificationRoutes(router fiber.Router, handler *admin.WithdrawalQualificationHandler, doc *openapi.Generator, basePath string) { shops := router.Group("/shops") shopsPath := basePath + "/shops" qualifications := router.Group("/withdrawal-qualifications") qualificationPath := basePath + "/withdrawal-qualifications" Register(shops, doc, shopsPath, "POST", "/:shop_id/withdrawal-qualifications", agentFundManagement(handler.SubmitWithdrawalQualification), RouteSpec{ Summary: "提交提现资料资格", Description: "仅本人代理店铺。合同与法人身份证正反面必填;企业必填统一社会信用代码,个人填写法人身份证号。替换合同或法人身份证时同一事务新增资料版本并使旧有效版本失效,需重新审批通过后才可提现。", Tags: []string{"代理商提现资格"}, Input: new(dto.SubmitWithdrawalQualificationReq), Output: new(dto.SubmitWithdrawalQualificationResp), Auth: true, }) Register(shops, doc, shopsPath, "GET", "/:shop_id/withdrawal-qualifications", agentFundManagement(handler.ListWithdrawalQualifications), RouteSpec{ Summary: "查询提现资料资格版本", Description: "仅返回当前账号数据范围内店铺的资料版本,按版本从新到旧;证件号脱敏,附件只返回对象存储 Key 引用。", Tags: []string{"代理商提现资格"}, Input: new(dto.WithdrawalQualificationListReq), Output: new(dto.WithdrawalQualificationPageResult), Auth: true, }) Register(qualifications, doc, qualificationPath, "POST", "/:id/void", agentFundManagement(handler.VoidWithdrawalQualification), RouteSpec{ Summary: "作废提现资料资格", Description: "仅超级管理员;reason 必填。作废后该资格失效且原因可查询,代理提现被拒绝直至重新审批通过。", Tags: []string{"代理商提现资格"}, Input: new(dto.VoidWithdrawalQualificationParams), Output: nil, Auth: true, }) }