All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
- client_order: 新增 getOrCreateWallet 兜底,钱包不存在时自动创建 - device_import: 设备导入事务内同步创建设备钱包 - iot_card_import: IoT卡批量导入后批量创建卡钱包 - queue/handler: 传递 AssetWalletStore 给两个导入 handler - migration 000098: 为存量IoT卡和设备补建资产钱包
66 lines
3.4 KiB
Markdown
66 lines
3.4 KiB
Markdown
## Context
|
||
|
||
修正业务方案 v5 中 5 项业务逻辑补全,涉及佣金计算、订单查询、支付对接、订单创建、资产状态管理共 5 个模块。各项之间无强依赖,但 J-2(平台钱包代购)与 J-1(富友支付)涉及同一个文件 `order/service.go`,建议 J-2 先做避免合并冲突。
|
||
|
||
## Goals / Non-Goals
|
||
|
||
**Goals:**
|
||
- 佣金链断裂可被平台发现(F-1)
|
||
- C端订单查询符合 Handler → Service 分层(F-4)
|
||
- 富友支付 JSAPI/MiniApp 可正常预下单(J-1)
|
||
- 平台可代用代理钱包购包(J-2)
|
||
- 卡/设备状态反映真实使用情况(J-3)
|
||
|
||
**Non-Goals:**
|
||
- 不修改佣金计算核心算法
|
||
- 不新增自动化测试
|
||
- 不改动回调链路(已存在且正常工作)
|
||
- 不新建 DB 表(仅插入配置数据)
|
||
|
||
## Decisions
|
||
|
||
### 1. F-1 零额待审记录的触发点
|
||
|
||
**决策**:在 `calculateChainOneTimeCommission` 和类似链式计算函数中,当 `getCostPrice` 返回零/无配置时,`break` 之前创建记录。
|
||
|
||
**原因**:这是佣金链唯一的断裂点——上游代理缺少套餐系列授权。在此处插入最精准。
|
||
|
||
记录写入失败不阻断主流程(`_ = store.Create()`),仅记 Error 日志。
|
||
|
||
### 2. F-4 迁移范围
|
||
|
||
**决策**:仅迁移 `ListOrders` 和 `GetOrderDetail` 两个查询方法到 Service 层。不重构其他正常工作的 Handler 方法。
|
||
|
||
**原因**:最小改动原则。其他 Handler 方法如果没有绕层问题则不动。
|
||
|
||
迁移后 Handler 中删除 `h.db` 字段引用和 `SkipPermissionCtx` 用法。
|
||
|
||
### 3. J-1 富友客户端构造方式
|
||
|
||
**决策**:每次调用时从 `wechatConfigStore.GetActive()` 读配置并构造 `fuiou.Client`,不做全局单例缓存。
|
||
|
||
**原因**:配置可以在管理端切换(activate/deactivate),缓存可能导致读到旧配置。构造成本很低(纯内存操作),无需优化。
|
||
|
||
**替代方案**:全局单例 + 配置变更时刷新 → 增加复杂度,收益不大,拒绝。
|
||
|
||
### 4. J-2 平台代购的身份伪装
|
||
|
||
**决策**:平台代购时,`orderBuyerType` 设为 `agent`,`orderBuyerID` 设为 `*resourceShopID`。成本价和钱包都使用资产所属代理的。
|
||
|
||
**原因**:从订单归属和佣金计算角度,这笔订单等效于"该代理用自己钱包买的",只是操作人是平台。
|
||
|
||
### 5. J-3 状态更新时机
|
||
|
||
**决策**:
|
||
- `status → 3`:在 `PackageActivationHandler` / `ActivateByRealname` 激活套餐成功后,检查 `card.Status < 3` 则更新为 3
|
||
- `status → 4`:在套餐到期处理逻辑中(`OrderExpireHandler` 或类似),当卡的最后一个 active 套餐过期时更新为 4
|
||
|
||
**原因**:与套餐生命周期绑定最自然——有活跃套餐就是"已激活",无活跃套餐就是"已停用"。
|
||
|
||
## Risks / Trade-offs
|
||
|
||
- **[F-1 零额记录堆积]** 如果某代理长期缺配置,会产生大量 status=99 记录 → 平台应定期处理待审记录(这本身就是 F-1 的目的)
|
||
- **[F-4 SkipPermissionCtx 移除]** 迁移后 Service 层查询会经过数据权限过滤 → 需确保 C端用户的数据权限配置正确,否则可能查不到数据
|
||
- **[J-1 凭证安全]** 富友私钥存在 DB → 当前 `wechat_config` 表已有类似敏感数据(微信支付密钥),风险等级一致
|
||
- **[J-3 并发更新]** 多个套餐同时激活可能并发更新 status → 使用条件更新 `WHERE status < 3` 避免覆盖
|