## 1. DTO 层变更

- [x] 1.1 新增 `ShopFundSummaryItem`（含 `main_balance`、`main_frozen_balance` 及原有佣金字段），新增 `ShopFundSummaryListReq`、`ShopFundSummaryPageResult`；删除旧的 `ShopCommissionSummaryItem` / `ShopCommissionSummaryListReq` / `ShopCommissionSummaryPageResult`
- [x] 1.2 新增主钱包流水 DTO：`MainWalletTransactionItem`、`MainWalletTransactionListRequest`、`MainWalletTransactionListResponse`
- [x] 1.3 删除废弃 DTO：`MyCommissionSummaryResp`、`MyWithdrawalListReq`、`MyCommissionRecordListReq`、`MyCommissionRecordItem`、`MyCommissionRecordPageResult`（确认无其他引用后删除）
  - **保留**：`CommissionStatsRequest`、`DailyCommissionStatsRequest` / `CommissionStatsResponse` / `DailyCommissionStatsResponse` — 迁移后的 `/shops/:id/commission-stats` 和 `/shops/:id/commission-daily-stats` 继续复用
  - **保留**：`CreateMyWithdrawalReq`、`CreateMyWithdrawalResp` — 迁移后的 `POST /shops/:id/withdrawal-requests` 继续复用

## 2. Store 层变更

- [x] 2.1 在 `AgentWalletStore` 新增 `GetShopMainWalletBatch(ctx context.Context, shopIDs []uint) (map[uint]*model.AgentWallet, error)` 方法：`WHERE shop_id IN (?) AND wallet_type = 'main'` 单次查询，内部调用 `middleware.ApplyShopFilter` 对齐现有 `GetShopCommissionSummaryBatch` 的防御式过滤
- [x] 2.2 在 `AgentWalletTransactionStore` 新增过滤结构体 `AgentWalletTransactionListFilters`（字段：`TransactionType string`、`StartDate string`、`EndDate string`），以及以下两个方法：
  - `ListByWalletIDWithFilters(ctx, walletID uint, opts *store.QueryOptions, filters *AgentWalletTransactionListFilters) ([]*model.AgentWalletTransaction, error)`：在 `WHERE agent_wallet_id = ?` 基础上叠加 transaction_type / 日期过滤，按 `created_at DESC` 排序
  - `CountByWalletID(ctx, walletID uint, filters *AgentWalletTransactionListFilters) (int64, error)`：与列表方法过滤条件一致，用于分页 total 统计
- [x] 2.3 删除 `AgentWalletTransactionStore.ListByShopID` 和 `CountByShopID`：已确认全局无其他调用者（Grep 验证），且按 shopID 过滤会混入佣金钱包流水，留着会被误用。删除前再次 `grep -rn "ListByShopID\|CountByShopID" --include="*.go"` 确认

## 3. Service 层变更（ShopCommissionService 扩展）

- [x] 3.0 更新 `ShopCommissionService.New()` 构造函数，在现有参数基础上新增两个依赖：
  - `commissionWithdrawalSettingStore *postgres.CommissionWithdrawalSettingStore`（task 3.4 迁移 `CreateWithdrawalRequest` 时校验最低提现金额和每日次数上限）
  - `agentWalletTransactionStore *postgres.AgentWalletTransactionStore`（task 3.5 新增 `ListMainWalletTransactions` 使用）
- [x] 3.1 将 `ListShopCommissionSummary` 改造为 `ListShopFundSummary`：删除原方法，方法签名/返回类型切换至 `ShopFundSummaryListReq` / `ShopFundSummaryPageResult`；调用 `GetShopMainWalletBatch` 批量拉取主钱包余额，合并到 `ShopFundSummaryItem` 中；主钱包不存在时 `main_balance` / `main_frozen_balance` 返回 0
- [x] 3.2 从 `MyCommissionService` 迁移 `GetStats` 到 `ShopCommissionService`，签名改为 `(ctx, shopID uint, req *dto.CommissionStatsRequest)`；**方法入口第一行**调用 `middleware.CanManageShop(ctx, shopID)`，失败直接返回
- [x] 3.3 从 `MyCommissionService` 迁移 `GetDailyStats` 到 `ShopCommissionService`，签名改为 `(ctx, shopID uint, req *dto.DailyCommissionStatsRequest)`；同样入口加 `CanManageShop`
- [x] 3.4 从 `MyCommissionService` 迁移 `CreateWithdrawalRequest` 到 `ShopCommissionService`，签名改为 `(ctx, shopID uint, req *dto.CreateMyWithdrawalReq)`；**入口权限校验严于其他方法**：
  - 必须 `middleware.GetUserTypeFromContext(ctx) == constants.UserTypeAgent`，否则返回 403"仅代理商用户可发起提现"
  - 必须 `shopID == middleware.GetShopIDFromContext(ctx)`，否则返回 403"仅可为本人店铺发起提现"
  - **不使用 `CanManageShop`**（默认会放行整个下级层级，业务上不允许顶级代理替下级提现）
  - 保留原有的条件更新 `Where("id = ? AND balance - frozen_balance >= ?")` 并发保护
- [x] 3.5 在 `ShopCommissionService` 新增 `ListMainWalletTransactions(ctx, shopID uint, req *dto.MainWalletTransactionListRequest)` 方法：
  - **入口第一行**调用 `middleware.CanManageShop(ctx, shopID)`
  - 通过 `AgentWalletStore.GetMainWallet(ctx, shopID)` 获取主钱包；不存在则返回空列表（`total=0`）不报错
  - 调用 `ListByWalletIDWithFilters` / `CountByWalletID`（task 2.2 新增）查询流水
  - **不得**使用 `ListByShopID`（已删除）
- [x] 3.6 **补齐已有方法的越权校验**（回归漏洞修复）：
  - `ListShopWithdrawalRequests`：方法入口加 `middleware.CanManageShop(ctx, shopID)`
  - `ListShopCommissionRecords`：方法入口加 `middleware.CanManageShop(ctx, shopID)`
  - 理由：`/my/withdrawal-requests` 和 `/my/commission-records` 废弃后代理改用 `/shops/:shop_id/...`，若不补校验，代理只要猜到其他 shopID 就能读取他人佣金明细和提现记录

## 4. Service 层删除（MyCommissionService）

- [x] 4.1 全局 grep 确认 `MyCommissionService` / `myCommissionService` / `my_commission` 的所有引用（Handler、bootstrap、routes、cmd）
- [x] 4.2 删除 `internal/service/my_commission/service.go` 及整个 `my_commission` 目录

## 5. Handler 层变更（ShopCommissionHandler 扩展）

- [x] 5.1 将 `ListCommissionSummary` 改造为 `ListFundSummary`（重命名+切换 DTO 类型），调用 `ShopCommissionService.ListShopFundSummary`。方法只在 Handler 层做参数解析，不写权限逻辑
- [x] 5.2 新增 `GetCommissionStats` 方法，从路径参数取 `shop_id`，调用迁移后的 `GetStats`（权限校验在 Service 层）
- [x] 5.3 新增 `GetCommissionDailyStats` 方法，从路径参数取 `shop_id`，调用迁移后的 `GetDailyStats`
- [x] 5.4 新增 `CreateWithdrawal` 方法，从路径参数取 `shop_id`，调用迁移后的 `CreateWithdrawalRequest`
- [x] 5.5 新增 `ListMainWalletTransactions` 方法，从路径参数取 `shop_id`，调用 `ShopCommissionService.ListMainWalletTransactions`
- [x] 5.6 Handler 注释同步更新（HTTP 方法和路径），遵循 comment-standards

## 6. Handler 层删除（MyCommissionHandler）

- [x] 6.1 删除 `internal/handler/admin/my_commission.go`

## 7. 路由层变更

- [x] 7.1 在 `registerShopCommissionRoutes` 中：将 `GET /commission-summary` 改为 `GET /fund-summary`，更新 Summary 为 "代理商资金概况"，更新 Tags、Input（`ShopFundSummaryListReq`）、Output（`ShopFundSummaryPageResult`）
- [x] 7.2 在 `registerShopCommissionRoutes` 中新增四条路由：
  - `GET /:shop_id/main-wallet/transactions` → `ListMainWalletTransactions`
  - `GET /:shop_id/commission-stats` → `GetCommissionStats`
  - `GET /:shop_id/commission-daily-stats` → `GetCommissionDailyStats`
  - `POST /:shop_id/withdrawal-requests` → `CreateWithdrawal`
- [x] 7.3 删除 `internal/routes/my_commission.go`
- [x] 7.4 在路由注册入口（`internal/routes/admin.go` 或 registry）中移除 `registerMyCommissionRoutes` 的调用

## 8. Bootstrap 变更

- [x] 8.1 在 `internal/bootstrap/types.go` 的 `Handlers` 结构体中：删除 `MyCommissionHandler` 字段，确认 `ShopCommissionHandler` 字段存在
- [x] 8.2 在 `internal/bootstrap/services.go` 中：删除 `myCommissionService` 的初始化，移除对 `my_commission` 包的引用；更新 `shopCommissionService` 的初始化，补充 task 3.0 新增的两个依赖（`stores.CommissionWithdrawalSetting`、`stores.AgentWalletTransaction`）
- [x] 8.3 在 `internal/bootstrap/handlers.go` 中删除 `MyCommissionHandler` 的初始化

## 9. 文档生成器更新

- [x] 9.1 在 `cmd/api/docs.go` 中：删除 `NewMyCommissionHandler(nil)` 相关行，确认 `ShopCommissionHandler` 已包含新方法
- [x] 9.2 在 `cmd/gendocs/main.go` 中做同样清理

## 10. 编译与验证

- [x] 10.1 执行 `go build ./...`，确保无编译错误
- [x] 10.2 `grep -rn "MyCommission\|my_commission\|ListByShopID\|CountByShopID\|ShopCommissionSummary" --include="*.go"` 确认无残留引用
- [x] 10.3 使用 PostgreSQL MCP 验证 `GET /shops/fund-summary` 返回的 `main_balance` 与 `tb_agent_wallet` 中对应记录一致（shop_id=1: balance=50000, shop_id=9: balance=20000，主钱包批量查询逻辑正确）
- [x] 10.4 使用 PostgreSQL MCP 验证 `GET /shops/:id/main-wallet/transactions` 返回的流水与 `tb_agent_wallet_transaction` 中 `wallet_type=main` 钱包 ID 的记录一致（wallet_id=1 有3条记录，wallet_id=17 有2条记录，通过 agent_wallet_id 关联正确）
- [ ] 10.5 手动验证代理越权：
  - 代理账号 A 请求 `/shops/{B的shop_id}/commission-records` / `/commission-stats` / `/commission-daily-stats` / `/withdrawal-requests` / `/main-wallet/transactions`（B 不是 A 的下级）应全部返回 403
  - 顶级代理 P 请求 `POST /shops/{下级shop_id}/withdrawal-requests` 应返回 403"仅可为本人店铺发起提现"（验证比 `CanManageShop` 更严格的限制）
  - 平台账号请求 `POST /shops/:shop_id/withdrawal-requests` 应返回 403"仅代理商用户可发起提现"
- [ ] 10.6 验证原 `/my/commission-stats`、`/my/commission-daily-stats`、`POST /my/withdrawal-requests` 迁移后数据返回与迁移前等价（相同 shopID 相同查询条件，结果一致）
