Files
zt-closet-backend/.codebuddy/plans/修复中高等级代码问题_7e510a15.md
2026-09-11 01:41:52 +08:00

148 lines
8.5 KiB
Markdown
Raw Permalink 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.
---
name: 修复中高等级代码问题
overview: 修复三次代码审查报告中「中等及以上」问题(排除限流 M11、虚拟订单垃圾堆积 M15):广告激励加配置开关+服务端定价、退款改为管理员操作、XPay 退款反查、vip_type 推导、iOS 退款问询、platform 校验、pay_time 兜底、上传请求体限制。
todos:
- id: adreward-config
content: 新增 AdReward 配置段与错误码,改造广告激励为开关加服务端定价
status: completed
- id: xpay-refund-verify
content: 新增微信侧退款查询并接入 XPay 退款推送反查
status: completed
- id: refund-manual-review
content: 重写自动退款为待审核退款单并兼容已取消订单退款流转
status: completed
- id: vip-type-derive
content: 改造 VIPGrantIdempotent 按最终到期时长推导会员类型
status: completed
- id: virtualpay-fixes
content: 修复 iOS 退款问询、平台真实性校验与支付时间兜底
status: completed
- id: upload-body-limit
content: 上传 handler 入口增加请求体大小限制
status: completed
- id: update-report-verify
content: 更新审查报告修复状态并执行编译与静态检查验证
status: completed
dependencies:
- adreward-config
- xpay-refund-verify
- refund-manual-review
- vip-type-derive
- virtualpay-fixes
- upload-body-limit
---
## 用户需求
针对三次代码审查报告,修复中等及以上问题(排除公开接口限流、虚拟支付订单禁取消带来的垃圾订单堆积两项),并落实两项产品调整:
1. **广告激励配置化与防刷**:广告激励额度在 config 中配置「是否开启」;每种 reward_type 的发放金额改为服务端配置固定值,前端不再传金额,从根源杜绝刷额度。
2. **退款管理员操作**:取消订单自动调微信退款的行为改为生成待审核退款单,由管理员在后台手动退款,所有退款均由管理员操作。
3. **修复范围**:严重问题 S1-new(XPay 退款推送无反查)、S2-new(广告激励刷额度);中等问题 M1-new(自动退款卡死)、M2-new(会员类型覆盖)、M3(iOS 退款问询无条件建议退款)、M4(platform 可伪造)、M9(并发支付时间无兜底)、M12(上传请求体无大小限制)。
## 核心功能
- 广告激励开关关闭时接口返回明确的「未开启」错误;开启后按服务端配置金额发放,前端仅传奖励类型与广告记录 ID。
- XPay 退款推送在处理前反查微信侧退款真实性,未通过拒绝发放并触发微信重试。
- 取消后已付款订单生成待审核退款单,退款回调兼容「已取消」订单的退款流转,且不误回收从未发放的权益。
- 会员续费时会员类型按最终到期时长自动推导,年度会员续月包不再被降级。
- iOS 退款问询按权益消耗情况细化同意/拒绝。
- 虚拟支付发货时校验微信侧真实平台,支付时间统一兜底。
- 上传接口在解析 multipart 前限制请求体大小。
## 视觉/交互
本任务为后端逻辑修复,不涉及界面视觉与交互变更。
## 技术栈
- 语言:Go 1.27
- 框架:Gin v1.12、GORM + MySQL(含 soft_delete)、go-redis v9、viper(仅读 YAML)
- 微信:微信支付 V3 官方 SDK、小程序虚拟支付(XPay)自研 HMAC-SHA256 签名客户端
- 复用项目既有模式:`errcode` 语义化错误、事务幂等、best-effort 告警、`*int64` 配置指针区分「未配置/显式 0」
## 实现方式
按 8 个修复点分 6 组独立实施,均沿既有分层(handler → service → dao / pkg 客户端)推进,不改动架构:
1. **广告激励(S2)**:新增 `AdReward` 配置段与错误码,DTO 移除金额字段,`Grant` 校验开关并从配置取金额。
2. **XPay 退款反查(S1)**:`wechat` 层补退款状态查询,`handleRefundNotify` 在权益回退前反查微信侧真实性。
3. **退款管理员操作(M1)**:`autoRefundCancelledOrder` 重写为待审核退款单,`settleRefundSuccess` 兼容「已取消」订单。
4. **会员类型推导(M2)**:`VIPGrantIdempotent` 原生 SQL 按最终到期时长推导会员类型。
5. **虚拟支付细节(M3/M4/M9)**:iOS 退款问询细化、平台真实性校验、支付时间兜底。
6. **上传限制(M12)**:handler 入口加 `http.MaxBytesReader`。
## 架构设计
```mermaid
flowchart LR
A[config AdReward] --> B[adreward.Grant]
B --> C[QuotaGrant]
D[XPay 退款推送] --> E[handleRefundNotify]
E --> F[QueryOrder 反查]
F --> G[settleRefundSuccess]
H[PayNotify Cancelled] --> I[autoRefundCancelledOrder]
I --> J[待审核 RefundFlowLog]
K[grantVIP] --> L[VIPGrantIdempotent SQL 推导类型]
M[Upload handler] --> N[MaxBytesReader] --> O[service.Upload]
```
## 目录结构
以下为本次修改/新增的文件:
```
zt-closet-backend/
├── configs/
│ └── config.example.yaml # [MODIFY] 新增 AdReward 配置段(Enable + 各类型金额,含注释)
├── global/
│ └── setting.go # [MODIFY] 注册 AdRewardSetting 全局指针
├── main.go # [MODIFY] setupSetting() 读取 AdReward 段并做默认值兜底
├── pkg/
│ ├── setting/
│ │ └── section.go # [MODIFY] 新增 AdRewardSettingS 结构体
│ ├── errcode/
│ │ └── quota_code.go # [MODIFY] 新增 AdRewardDisabled 错误码
│ └── wechat/
│ └── virtualpay.go # [MODIFY] XPayOrderInfo 补退款状态字段 + 退款状态判断
└── internal/
├── dto/
│ └── adreward.go # [MODIFY] 移除 Amount 字段
├── mysqldao/
│ └── user.go # [MODIFY] VIPGrantIdempotent 按最终到期时长推导 vip_type
├── routers/api/v1/
│ └── clothes.go # [MODIFY] Upload handler 入口加 MaxBytesReader
└── service/
├── adreward.go # [MODIFY] Grant 校验开关 + 服务端定价
├── virtualpay.go # [MODIFY] 退款反查、iOS 问询细化、platform 校验、pay_time 兜底
└── order.go # [MODIFY] autoRefundCancelledOrder 改待审核、settleRefundSuccess 兼容 Cancelled、grantVIP 调整
```
## 实现注意事项
- **S1 字段待确认**:XPay 官方退款查询/平台字段未联调确认,新增字段与状态枚举处必须保留「待确认」注释,不臆造字段名;未通过反查一律 `OrderRealityCheckFailed(70009)` + `ErrCode:1` 触发微信重试。
- **M1 防误回收**:「已取消但已付款」的订单权益从未发放,`settleRefundSuccess` 对该场景只做 `Cancelled->Refunded` 流转与退款信息记录,**跳过 `revokeOrderBenefits`**,避免误扣用户其他来源的会员天数/额度凭证。
- **M2 保持 Trial**:`ensureTrialVIP` 复用 `VIPGrantIdempotent` 传 `Trial(4)`,SQL 推导时须保留 Trial 不参与年度/月度推导。
- **M2 SQL 求值顺序**:依赖 MySQL 单表 UPDATE SET 从左到右求值,先计算 `vip_expire` 再推导 `vip_type`,与现有「显式控制 SET 顺序」注释保持一致。
- **M4 不信任前端**:platform 的资损判断改为以微信侧反查结果为准,保留 env 校验。
- **M12 余量**:`MaxBytesReader` 上限按 `MaxSizeMB*1024*1024 + 1MB`(multipart 边界开销),超限返回上传超限语义错误,避免误伤合法请求。
- **安全**:广告激励金额服务端定价后,不再接收客户端金额;退款反查沿 HMAC 签名服务端 API,无法被伪造。
- **验证**:全部改动完成后 `go build ./...` 与 `go vet ./...` 通过,并核对 linter。
## 推荐扩展
### Skill
- **lsp-code-analysis**
- 用途:追踪 `settleRefundSuccess`、`VIPGrantIdempotent`、`QuotaGrant`、`verifyXPayOrderPaid` 等关键符号的定义与全部调用点,确认改动影响面,避免遗漏调用链或误改 Trial 场景。
- 预期结果:明确各修复点的完整调用链,验证「Cancelled 订单跳过权益回退」「Trial 保持」等分支覆盖所有相关调用方。
### SubAgent
- **code-explorer**
- 用途:跨目录核对涉及文件与调用点,补充确认 `errcode` 分段、`QuotaGrantDao` 查询能力、`RefundFlowLog` 字段等实现细节。
- 预期结果:产出修复所需的精确文件与函数清单,支撑分组实施。