Files
junhong_cmp_fiber/openspec/changes/agent-fund-visibility/proposal.md
huang 0627ffec42
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m10s
feat: 代理商资金可见性重构(agent-fund-visibility)
- 将 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>
2026-04-09 14:40:39 +08:00

157 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Why
目前平台人员和代理账号均无法看到代理的预充值钱包(主钱包)余额与流水,佣金相关接口散落在 `/my/` 前缀下且与 `/shops/:id/` 路径存在职责重叠,亟需统一入口、补全预充值钱包可见性。
## What Changes
- **BREAKING** `GET /shops/commission-summary` 重命名为 `GET /shops/fund-summary`,响应 DTO 由 `ShopCommissionSummaryItem` 改为 `ShopFundSummaryItem`,新增 `main_balance``main_frozen_balance` 两个字段
- **新增** `GET /shops/:id/main-wallet/transactions` — 预充值钱包流水列表(全新功能)
- **新增** `GET /shops/:id/commission-stats` — 佣金统计,迁移自 `/my/commission-stats`
- **新增** `GET /shops/:id/commission-daily-stats` — 每日佣金统计,迁移自 `/my/commission-daily-stats`
- **新增** `POST /shops/:id/withdrawal-requests` — 发起提现申请,迁移自 `POST /my/withdrawal-requests`
- **BREAKING 废弃** `/my/` 全部 6 个路由(详见废弃对照表)
### 废弃路由对照表
| 废弃路由 | 作用 | 替代路由 | 状态 |
|---------|------|---------|------|
| `GET /my/commission-summary` | 代理看自己的佣金钱包余额概览 | `GET /shops/fund-summary` | 本次改造 |
| `GET /my/withdrawal-requests` | 代理看自己的提现申请记录 | `GET /shops/:id/withdrawal-requests` | 已有,直接复用 |
| `GET /my/commission-records` | 代理看自己的每笔佣金入账明细(订单维度) | `GET /shops/:id/commission-records` | 已有,直接复用 |
| `GET /my/commission-stats` | 代理看自己的佣金汇总统计(按时间段) | `GET /shops/:id/commission-stats` | 本次新增 |
| `GET /my/commission-daily-stats` | 代理看自己的每日佣金金额趋势 | `GET /shops/:id/commission-daily-stats` | 本次新增 |
| `POST /my/withdrawal-requests` | 代理发起提现申请 | `POST /shops/:id/withdrawal-requests` | 本次新增 |
### API 全景(变更前 vs 变更后)
```
变更前 变更后
─────────────────────────────────────────────────────────────────────────
GET /shops/commission-summary → GET /shops/fund-summary ★ 改造+扩展
GET /shops/:id/withdrawal-requests GET /shops/:id/withdrawal-requests
GET /shops/:id/commission-records GET /shops/:id/commission-records
→ GET /shops/:id/commission-stats ★ 新增
→ GET /shops/:id/commission-daily-stats ★ 新增
→ POST /shops/:id/withdrawal-requests ★ 新增
→ GET /shops/:id/main-wallet/transactions ★ 新增
GET /my/commission-summary × 废弃
GET /my/withdrawal-requests × 废弃
GET /my/commission-records × 废弃
GET /my/commission-stats × 废弃
GET /my/commission-daily-stats × 废弃
POST /my/withdrawal-requests × 废弃
GET /agent-recharges GET /agent-recharges 不变
GET /agent-recharges/:id GET /agent-recharges/:id 不变
POST /agent-recharges POST /agent-recharges 不变
POST /agent-recharges/:id/offline-pay POST /agent-recharges/:id/offline-pay 不变
```
### 两个视角的完整操作流
```
┌──────────────────────────────────────────────────────────────────┐
│ 平台人员 │
├──────────────────────────────────────────────────────────────────┤
│ [代理商资金概况列表] │
│ GET /shops/fund-summary │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 店铺名 │ 预充值余额 │ 可提现佣金 │ 冻结佣金 │ 提现中 │ │
│ │ 代理A │ ¥2,000 │ ¥500 │ ¥100 │ ¥200 │ │
│ │ 代理B │ ¥500 │ ¥200 │ ¥0 │ ¥0 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ 进入某代理详情 │
│ ▼ │
│ [代理详情 — 分 tab 查看] │
│ ├─ 预充值流水 GET /shops/:id/main-wallet/transactions │
│ ├─ 佣金明细 GET /shops/:id/commission-records │
│ ├─ 佣金统计 GET /shops/:id/commission-stats │
│ ├─ 每日统计 GET /shops/:id/commission-daily-stats │
│ └─ 提现记录 GET /shops/:id/withdrawal-requests │
│ │
│ [充值管理] │
│ GET /agent-recharges 查看所有充值订单(含状态) │
│ POST /agent-recharges/:id/offline-pay 确认线下到账 │
│ │
│ [提现审批] │
│ GET /commission/withdrawal-requests 审批提现申请 │
└──────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────┐
│ 代理账号(同接口,按数据权限过滤) │
├──────────────────────────────────────────────────────────────────┤
│ [我的资金概况(返回自己 + 所有下级代理店铺)] │
│ GET /shops/fund-summary │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 预充值余额: ¥2,000 │ 可提现佣金: ¥500 │ │
│ │ 冻结余额: ¥100 │ 提现中: ¥200 │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ [预充值钱包流水] │
│ GET /shops/自己ID/main-wallet/transactions │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 时间 │ 类型 │ 金额 │ 变动后余额 │ │
│ │ 04-08 10:00 │ 充值入账 │ +¥500 │ ¥2,000 │ │
│ │ 04-07 15:30 │ 套餐扣款 │ -¥100 │ ¥1,500 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ [佣金相关] │
│ GET /shops/自己ID/commission-records 佣金明细 │
│ GET /shops/自己ID/commission-stats 佣金统计 │
│ GET /shops/自己ID/withdrawal-requests 提现记录 │
│ POST /shops/自己ID/withdrawal-requests 发起提现 │
│ │
│ [充值订单GORM 自动过滤,只见自己的)] │
│ GET /agent-recharges │
└──────────────────────────────────────────────────────────────────┘
```
### 数据流向
```
【充值流】
平台操作 POST /agent-recharges
tb_agent_recharge_record充值订单含状态待支付/已完成/已取消)
↓ 线下确认 / 微信回调
tb_agent_wallet (wallet_type=main) balance +
tb_agent_wallet_transaction (transaction_type=recharge)
↓ 代理购买套餐
tb_agent_wallet (wallet_type=main) balance -
tb_agent_wallet_transaction (transaction_type=deduct)
【佣金流】
用户下单 → 佣金计算 → tb_commission_record订单维度明细
↓ 佣金入账
tb_agent_wallet (wallet_type=commission) balance +
tb_agent_wallet_transaction (transaction_type=commission)
↓ 代理发起提现 POST /shops/:id/withdrawal-requests
tb_commission_withdrawal_request提现申请
↓ 平台审批通过
tb_agent_wallet (wallet_type=commission) balance -
tb_agent_wallet_transaction (transaction_type=withdrawal)
```
## Capabilities
### New Capabilities
- `agent-fund-summary`: 代理商资金概况接口,同一接口支持平台(全量)和代理(仅自己)两种视角,包含预充值余额与佣金钱包字段
- `main-wallet-transactions`: 代理预充值钱包(主钱包)流水查询,按 shop_id 分页检索 tb_agent_wallet_transactionwallet_type=main
### Modified Capabilities
- `commission-record-query`: 佣金统计和每日统计从 `/my/` 路径迁移至 `/shops/:id/` 路径,同时新增 POST 提现发起路由;原 `/my/` 路径全部废弃
- `agent-wallet`: 资金概况接口现在对外暴露主钱包余额,`AgentWalletStore.GetShopCommissionSummaryBatch` 需扩展以批量拉取主钱包余额
## Impact
- **Handler 层**: 扩展 `ShopCommissionHandler`,新增 `ListFundSummary``ListMainWalletTransactions``GetCommissionStats``GetCommissionDailyStats``CreateWithdrawal` 五个方法;`MyCommissionHandler` 整体删除
- **Service 层**: `ShopCommissionService` 构造函数补两个依赖(`commissionWithdrawalSettingStore``agentWalletTransactionStore``ListShopCommissionSummary` 改造为 `ListShopFundSummary`,新增 `ListMainWalletTransactions`,并从 `MyCommissionService` 迁移 `GetStats / GetDailyStats / CreateWithdrawalRequest` 三个方法(签名改为显式 `shopID`,入口强制调用 `middleware.CanManageShop` 校验);`MyCommissionService` 整体删除
- **Store 层**: `AgentWalletStore` 新增 `GetShopMainWalletBatch``AgentWalletTransactionStore` 新增 `ListByWalletIDWithFilters` / `CountByWalletID`,并删除原 `ListByShopID` / `CountByShopID`(全局无其他调用者,且会跨钱包类型返回数据,留着易被误用)
- **DTO 层**: `ShopCommissionSummaryItem``ShopFundSummaryItem`(新增 `main_balance``main_frozen_balance`);新增主钱包流水 DTO删除 `/my/` 系列 DTO
- **路由层**: 删除 `registerMyCommissionRoutes`,在 `registerShopCommissionRoutes` 内将 `/commission-summary` 改为 `/fund-summary`,并追加 4 条 `/:shop_id/...` 路由
- **权限层**: 所有迁移过来的 `/shops/:shop_id/...` 入口必须在 Service 层显式调用 `middleware.CanManageShop(ctx, shopID)`,同时覆盖本次新增接口和已有的 `ListShopWithdrawalRequests``ListShopCommissionRecords`(当前只做了店铺存在性检查,未做越权校验,迁移后代理只要猜到其他 shopID 就能读取,必须补齐)
- **文档生成器**: `cmd/api/docs.go``cmd/gendocs/main.go` 同步更新