# 钱包系统分离提案 ## Why 当前所有钱包类型(代理钱包、卡钱包)混在同一张表 `tb_wallet` 中,通过 `resource_type` 和 `wallet_type` 字段区分。业务方担心未来某个钱包业务的代码问题会影响其他钱包类型,特别是代理钱包作为核心资产需要最高等级的稳定性保障。在系统复杂度增长前,需要提前做预防性架构优化,将代理钱包和卡钱包在数据层和代码层完全隔离。 ## What Changes ### 数据库层变更 **新增表**: - `tb_agent_wallet` - 代理钱包主表(店铺级别) - `tb_agent_wallet_transaction` - 代理钱包交易记录表 - `tb_agent_recharge_record` - 代理充值记录表 - `tb_card_wallet` - 卡钱包主表(物联网卡和设备) - `tb_card_wallet_transaction` - 卡钱包交易记录表 - `tb_card_recharge_record` - 卡充值记录表 **删除表** - **BREAKING**: - `tb_wallet` - 统一钱包表(由新的两张表替代) - `tb_wallet_transaction` - 统一交易记录表(由新的两张表替代) - `tb_recharge_record` - 统一充值记录表(由新的两张表替代) ### 代码层变更 **新增 Model**: - `internal/model/agent_wallet.go` - 代理钱包相关 Model(AgentWallet、AgentWalletTransaction、AgentRechargeRecord) - `internal/model/card_wallet.go` - 卡钱包相关 Model(CardWallet、CardWalletTransaction、CardRechargeRecord) **删除 Model** - **BREAKING**: - `internal/model/wallet.go` - 统一钱包 Model(由新的两个文件替代) **新增 Store**: - `internal/store/postgres/agent_wallet_store.go` - 代理钱包数据访问层 - `internal/store/postgres/agent_wallet_transaction_store.go` - 代理钱包交易记录访问层 - `internal/store/postgres/agent_recharge_store.go` - 代理充值记录访问层 - `internal/store/postgres/card_wallet_store.go` - 卡钱包数据访问层 - `internal/store/postgres/card_wallet_transaction_store.go` - 卡钱包交易记录访问层 - `internal/store/postgres/card_recharge_store.go` - 卡充值记录访问层 **删除 Store** - **BREAKING**: - `internal/store/postgres/wallet_store.go` - 统一钱包 Store(由新的 Store 替代) - `internal/store/postgres/wallet_transaction_store.go` - 统一交易记录 Store(由新的 Store 替代) **重构 Service**: - `internal/service/commission_*` - 佣金相关服务改用 `AgentWalletStore` - `internal/service/order` - 订单服务改用 `CardWalletStore` - `internal/service/recharge` - 充值服务拆分为代理充值和卡充值两个独立服务 **更新常量定义**: - `pkg/constants/wallet.go` - 按钱包类型隔离常量定义和 Redis Key 生成函数 **更新依赖注入**: - `internal/bootstrap/stores.go` - 注册新的 Store 实例 - `internal/bootstrap/services.go` - 更新 Service 依赖注入 ### 监控和运维 **新增监控指标**(建议): - `agent_wallet_transaction_count` - 代理钱包交易量 - `agent_wallet_error_rate` - 代理钱包错误率 - `card_wallet_transaction_count` - 卡钱包交易量 - `card_wallet_error_rate` - 卡钱包错误率 **告警策略差异化**: - 代理钱包错误率阈值更严格(建议 P0 级别告警) - 卡钱包错误率阈值相对宽松(建议 P1 级别告警) ## Capabilities ### New Capabilities - `agent-wallet`: 代理钱包系统,提供店铺级别的主钱包和分佣钱包管理,支持充值、扣款、冻结、提现等操作 - `card-wallet`: 卡钱包系统,提供物联网卡和设备级别的钱包管理,支持充值、套餐扣费、余额查询等操作 ### Modified Capabilities - `wallet`: 需求变更 - 废弃统一钱包设计,拆分为 `agent-wallet` 和 `card-wallet` 两个完全独立的系统,要求在数据表、Model、Store、部分 Service 层面完全隔离 ## Impact ### 受影响的模块 | 模块类型 | 受影响组件 | 变更类型 | |---------|-----------|---------| | **数据库** | `tb_wallet`、`tb_wallet_transaction`、`tb_recharge_record` | 删除并替换为 6 张新表 | | **Model** | `internal/model/wallet.go` | 删除并替换为 2 个新文件 | | **Store** | `internal/store/postgres/wallet_*.go` | 删除并替换为 6 个新 Store | | **Service** | `internal/service/commission_*` | 依赖注入改为 `AgentWalletStore` | | **Service** | `internal/service/order` | 依赖注入改为 `CardWalletStore` | | **Service** | `internal/service/recharge` | 拆分为两个独立服务 | | **Bootstrap** | `internal/bootstrap/stores.go`、`services.go` | 更新依赖注入配置 | | **常量** | `pkg/constants/wallet.go` | 按钱包类型重构常量定义 | | **Redis Key** | 钱包相关缓存 Key | 按钱包类型隔离(`agent_wallet:*`、`card_wallet:*`) | ### API 影响 **无 API 破坏性变更** - 所有对外 API 接口保持不变,仅内部实现重构 ### 性能影响 **预期正向影响**: - 代理钱包和卡钱包数据量独立,查询性能提升 - 索引优化可针对不同钱包类型的查询模式独立调优 - 减少单表数据量,降低锁竞争概率 ### 部署影响 **当前处于开发阶段**: - 无需数据迁移 - 删除旧表,创建新表 - 一次性部署代码变更 **如果未来生产环境部署**(预留方案): - 需要制定数据迁移脚本 - 需要停机窗口或在线双写迁移方案 ### 风险评估 | 风险项 | 风险等级 | 缓解措施 | |-------|---------|---------| | 代码重构引入 Bug | 中 | 充分的手动测试,验证核心流程 | | 遗漏依赖点导致编译失败 | 低 | 编译检查,逐步重构 | | 数据表设计遗漏字段 | 低 | 参考现有 Model 设计,保持字段完整性 | | 性能回退 | 低 | 索引设计参考现有表,预期性能持平或提升 | ### 测试策略 **手动测试覆盖**: - 代理钱包:佣金发放、提现、余额查询 - 卡钱包:订单支付、充值、余额查询 - 边界场景:余额不足、并发扣款、冻结/解冻 **数据一致性验证**: - 验证代理钱包交易记录的 `balance_before` 和 `balance_after` 准确性 - 验证卡钱包交易记录的余额变动准确性 - 验证乐观锁(version 字段)在并发场景下的有效性 ### 时间估算 **预估工作量**: - 数据库迁移文件编写:0.5 天 - Model 和 Store 重构:2 天 - Service 层重构:2 天 - Bootstrap 和常量更新:0.5 天 - 手动测试和验证:1 天 - **总计:6 天** ### 依赖和前置条件 - ✅ 项目处于开发阶段,可直接重构 - ✅ 无生产数据,无需迁移方案 - ✅ 技术栈符合项目规范(GORM、PostgreSQL、Redis)