Files
junhong_cmp_fiber/openspec/changes/archive/2026-03-28-fix-business-completion/design.md
huang f339fb1987
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
fix: 资产钱包自动创建机制 — 修复C端购买时钱包不存在报错
- client_order: 新增 getOrCreateWallet 兜底,钱包不存在时自动创建
- device_import: 设备导入事务内同步创建设备钱包
- iot_card_import: IoT卡批量导入后批量创建卡钱包
- queue/handler: 传递 AssetWalletStore 给两个导入 handler
- migration 000098: 为存量IoT卡和设备补建资产钱包
2026-03-30 11:37:41 +08:00

3.4 KiB
Raw Blame History

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 迁移范围

决策:仅迁移 ListOrdersGetOrderDetail 两个查询方法到 Service 层。不重构其他正常工作的 Handler 方法。

原因:最小改动原则。其他 Handler 方法如果没有绕层问题则不动。

迁移后 Handler 中删除 h.db 字段引用和 SkipPermissionCtx 用法。

3. J-1 富友客户端构造方式

决策:每次调用时从 wechatConfigStore.GetActive() 读配置并构造 fuiou.Client,不做全局单例缓存。

原因配置可以在管理端切换activate/deactivate缓存可能导致读到旧配置。构造成本很低纯内存操作无需优化。

替代方案:全局单例 + 配置变更时刷新 → 增加复杂度,收益不大,拒绝。

4. J-2 平台代购的身份伪装

决策:平台代购时,orderBuyerType 设为 agentorderBuyerID 设为 *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 避免覆盖