feat: 代理商资金可见性重构(agent-fund-visibility)
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m10s

- 将 GET /shops/commission-summary 重命名为 GET /shops/fund-summary,
  响应新增 main_balance、main_frozen_balance 两个预充值钱包字段
- 新增 GET /shops/:id/main-wallet/transactions 预充值钱包流水接口
- 将佣金统计、每日统计、发起提现从 /my/ 路径迁移至 /shops/:id/ 路径:
  GET /shops/:id/commission-stats
  GET /shops/:id/commission-daily-stats
  POST /shops/:id/withdrawal-requests
- 删除 MyCommissionService、MyCommissionHandler 及全部 /my/ 路由
- 补齐 ListShopWithdrawalRequests、ListShopCommissionRecords 的
  CanManageShop 越权校验(安全修复)
- 提现接口增加严格权限:仅代理账号本人可为自己店铺发起提现

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 14:40:39 +08:00
parent 1d6535b81b
commit 0627ffec42
25 changed files with 1806 additions and 1426 deletions

View File

@@ -60,14 +60,14 @@ type DailyCommissionStatsResponse struct {
// CommissionStatsRequest 佣金统计请求
type CommissionStatsRequest struct {
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"店铺ID"`
ShopID uint `json:"-" path:"shop_id" description:"店铺ID" required:"true"`
StartTime *string `json:"start_time" query:"start_time" validate:"omitempty" description:"开始时间"`
EndTime *string `json:"end_time" query:"end_time" validate:"omitempty" description:"结束时间"`
}
// DailyCommissionStatsRequest 每日佣金统计请求
type DailyCommissionStatsRequest struct {
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"店铺ID"`
ShopID uint `json:"-" path:"shop_id" description:"店铺ID" required:"true"`
StartDate *string `json:"start_date" query:"start_date" validate:"omitempty" description:"开始日期YYYY-MM-DD"`
EndDate *string `json:"end_date" query:"end_date" validate:"omitempty" description:"结束日期YYYY-MM-DD"`
Days *int `json:"days" query:"days" validate:"omitempty,min=1,max=365" minimum:"1" maximum:"365" description:"查询天数默认30天"`

View File

@@ -1,23 +1,15 @@
package dto
type MyCommissionSummaryResp struct {
ShopID uint `json:"shop_id" description:"店铺ID"`
ShopName string `json:"shop_name" description:"店铺名称"`
TotalCommission int64 `json:"total_commission" description:"累计佣金(分)"`
WithdrawnCommission int64 `json:"withdrawn_commission" description:"已提现佣金(分)"`
UnwithdrawCommission int64 `json:"unwithdraw_commission" description:"未提现佣金(分)"`
FrozenCommission int64 `json:"frozen_commission" description:"冻结佣金(分)"`
WithdrawingCommission int64 `json:"withdrawing_commission" description:"提现中佣金(分)"`
AvailableCommission int64 `json:"available_commission" description:"可提现佣金(分)"`
}
// CreateMyWithdrawalReq 发起提现申请请求(由 POST /shops/:id/withdrawal-requests 复用)
type CreateMyWithdrawalReq struct {
ShopID uint `json:"-" path:"shop_id" description:"店铺ID" required:"true"`
Amount int64 `json:"amount" validate:"required,min=1" required:"true" minimum:"1" description:"提现金额(分)"`
WithdrawalMethod string `json:"withdrawal_method" validate:"required,oneof=alipay" required:"true" enum:"alipay" description:"收款类型"`
AccountName string `json:"account_name" validate:"required,max=50" required:"true" maximum:"50" description:"收款人姓名"`
AccountNumber string `json:"account_number" validate:"required,max=100" required:"true" maximum:"100" description:"收款账号"`
}
// CreateMyWithdrawalResp 发起提现申请响应(由 POST /shops/:id/withdrawal-requests 复用)
type CreateMyWithdrawalResp struct {
ID uint `json:"id" description:"提现申请ID"`
WithdrawalNo string `json:"withdrawal_no" description:"提现单号"`
@@ -29,38 +21,3 @@ type CreateMyWithdrawalResp struct {
StatusName string `json:"status_name" description:"状态名称"`
CreatedAt string `json:"created_at" description:"申请时间"`
}
type MyWithdrawalListReq struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
Status *int `json:"status" query:"status" description:"状态1=待审批, 2=已通过, 3=已拒绝)"`
StartTime string `json:"start_time" query:"start_time" description:"申请开始时间"`
EndTime string `json:"end_time" query:"end_time" description:"申请结束时间"`
}
type MyCommissionRecordListReq struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
CommissionSource *string `json:"commission_source" query:"commission_source" validate:"omitempty,oneof=cost_diff one_time tier_bonus" description:"佣金来源 (cost_diff:成本价差, one_time:一次性佣金, tier_bonus(已废弃):梯度奖励)"`
ICCID string `json:"iccid" query:"iccid" description:"ICCID模糊查询"`
VirtualNo string `json:"virtual_no" query:"virtual_no" description:"设备虚拟号(模糊查询)"`
OrderNo string `json:"order_no" query:"order_no" description:"订单号(模糊查询)"`
}
type MyCommissionRecordItem struct {
ID uint `json:"id" description:"佣金记录ID"`
ShopID uint `json:"shop_id" description:"店铺ID"`
OrderID uint `json:"order_id" description:"订单ID"`
CommissionSource string `json:"commission_source" description:"佣金来源 (cost_diff:成本价差, one_time:一次性佣金, tier_bonus(已废弃):梯度奖励)"`
Amount int64 `json:"amount" description:"佣金金额(分)"`
Status int `json:"status" description:"状态 (1:已入账, 2:已失效)"`
StatusName string `json:"status_name" description:"状态名称"`
CreatedAt string `json:"created_at" description:"创建时间"`
}
type MyCommissionRecordPageResult struct {
Items []MyCommissionRecordItem `json:"items" description:"佣金记录列表"`
Total int64 `json:"total" description:"总记录数"`
Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"`
}

View File

@@ -1,25 +1,27 @@
package dto
// ========================================
// 代理商佣金查询 DTO
// 代理商资金概况查询 DTO
// ========================================
// ShopCommissionSummaryListReq 代理商佣金列表查询请求
type ShopCommissionSummaryListReq struct {
// ShopFundSummaryListReq 代理商资金概况列表查询请求
type ShopFundSummaryListReq struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"`
ShopName string `json:"shop_name" query:"shop_name" validate:"omitempty,max=100" maxLength:"100" description:"店铺名称(模糊查询)"`
Username string `json:"username" query:"username" validate:"omitempty,max=50" maxLength:"50" description:"主账号用户名(模糊查询)"`
}
// ShopCommissionSummaryItem 代理商佣金汇总项
type ShopCommissionSummaryItem struct {
// ShopFundSummaryItem 代理商资金概况项(含预充值钱包和佣金钱包)
type ShopFundSummaryItem struct {
ShopID uint `json:"shop_id" description:"店铺ID"`
ShopName string `json:"shop_name" description:"店铺名称"`
ShopCode string `json:"shop_code" description:"店铺编码"`
Username string `json:"username" description:"主账号用户名"`
Phone string `json:"phone" description:"主账号手机号"`
TotalCommission int64 `json:"total_commission" description:"总佣金(分)"`
MainBalance int64 `json:"main_balance" description:"预充值钱包余额(分)"`
MainFrozenBalance int64 `json:"main_frozen_balance" description:"预充值钱包冻结余额(分,预留字段)"`
TotalCommission int64 `json:"total_commission" description:"累计佣金总额(分)"`
WithdrawnCommission int64 `json:"withdrawn_commission" description:"已提现佣金(分)"`
UnwithdrawCommission int64 `json:"unwithdraw_commission" description:"未提现佣金(分)"`
FrozenCommission int64 `json:"frozen_commission" description:"冻结中佣金(分)"`
@@ -28,9 +30,43 @@ type ShopCommissionSummaryItem struct {
CreatedAt string `json:"created_at" description:"店铺创建时间"`
}
// ShopCommissionSummaryPageResult 代理商佣金列表分页响应
type ShopCommissionSummaryPageResult struct {
Items []ShopCommissionSummaryItem `json:"items" description:"代理商佣金列表"`
// ShopFundSummaryPageResult 代理商资金概况列表分页响应
type ShopFundSummaryPageResult struct {
Items []ShopFundSummaryItem `json:"items" description:"代理商资金概况列表"`
Total int64 `json:"total" description:"总记录数"`
Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"`
}
// ========================================
// 主钱包流水查询 DTO
// ========================================
// MainWalletTransactionListRequest 主钱包流水查询请求
type MainWalletTransactionListRequest struct {
ShopID uint `json:"-" path:"shop_id" description:"店铺ID" required:"true"`
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"`
TransactionType string `json:"transaction_type" query:"transaction_type" validate:"omitempty,max=50" maxLength:"50" description:"交易类型过滤recharge:充值入账, deduct:套餐扣款, refund:退款)"`
StartDate string `json:"start_date" query:"start_date" validate:"omitempty" description:"开始日期YYYY-MM-DD"`
EndDate string `json:"end_date" query:"end_date" validate:"omitempty" description:"结束日期YYYY-MM-DD"`
}
// MainWalletTransactionItem 主钱包流水记录项
type MainWalletTransactionItem struct {
ID uint `json:"id" description:"流水记录ID"`
TransactionType string `json:"transaction_type" description:"交易类型recharge:充值入账, deduct:套餐扣款, refund:退款)"`
TransactionSubtype string `json:"transaction_subtype" description:"交易子类型(可为空)"`
Amount int64 `json:"amount" description:"变动金额(分,正数为入账,负数为扣款)"`
BalanceBefore int64 `json:"balance_before" description:"变动前余额(分)"`
BalanceAfter int64 `json:"balance_after" description:"变动后余额(分)"`
Remark string `json:"remark" description:"备注(可为空)"`
CreatedAt string `json:"created_at" description:"流水时间"`
}
// MainWalletTransactionListResponse 主钱包流水列表响应
type MainWalletTransactionListResponse struct {
Items []MainWalletTransactionItem `json:"items" description:"流水记录列表"`
Total int64 `json:"total" description:"总记录数"`
Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"`