## Context

### 当前系统状态

**钱包系统现状**：
- 已有 Wallet、WalletTransaction 模型和 Store 层实现
- 已有 RechargeRecord 模型定义，但完全未使用（表已创建，无 Store/Service/Handler）
- 个人客户只能通过购买套餐间接充值钱包，无法直接充值
- 订单支付采用"强充"机制：用户必须通过购买套餐来充值，不支持纯钱包充值

**订单系统现状**：
- Order 模型已支持单卡购买和设备购买两种类型
- 支持 wallet、wechat、alipay 三种支付方式
- 订单创建 → 支付 → 激活套餐 → 触发佣金计算的完整流程已实现
- 支付回调处理支持微信和支付宝

**佣金计算现状**：
- 支持成本价差佣金和一次性佣金两种类型
- 一次性佣金支持首次充值和累计充值两种触发方式
- 订单支付成功后自动更新 `AccumulatedRecharge`
- **存在问题**：所有订单（包括代购订单）都会更新累计充值，都会触发一次性佣金

**系列分配配置现状**：
- ShopSeriesAllocation 已支持一次性佣金配置（类型、触发方式、阈值、模式、值）
- 支持梯度佣金配置（独立表 ShopSeriesOneTimeCommissionTier）
- **缺失**：没有强充金额配置字段

### 业务需求背景

1. **线下收款场景**：平台/代理线下已收款，需要为代理代购套餐，但系统无法支持
2. **个人客户充值体验**：用户想充值钱包但不想立即购买套餐，当前系统无法满足
3. **强充机制完善**：
   - 首次充值需强制充值阈值金额（如100元）
   - 累计充值可选启用强充，每次充值固定金额（如100元），避免"买39元套餐却要充1000元"的不合理情况
4. **佣金计算准确性**：代购订单不应触发一次性佣金，因为不是客户真实充值

### 约束条件

- **技术栈**：必须使用 Fiber + GORM + Viper + Zap + Asynq，禁止外键和 GORM 关联
- **架构分层**：Handler → Service → Store → Model，严格分层
- **性能要求**：预检接口 < 100ms，充值创建 < 200ms，支付回调 < 500ms
- **测试要求**：核心业务逻辑覆盖率 ≥ 90%
- **向后兼容**：新增字段必须有默认值，不能破坏现有订单和佣金计算逻辑

---

## Goals / Non-Goals

### Goals

1. **实现钱包充值系统**
   - 个人客户可以直接给卡/设备钱包充值（不购买套餐）
   - 充值支持微信支付和支付宝支付
   - 充值成功自动更新钱包余额和累计充值金额
   - 充值达到阈值触发一次性佣金

2. **实现强充预检机制**
   - 提供充值预检接口，告知用户强充要求
   - 提供套餐购买预检接口，计算实际支付金额
   - 创建订单/充值订单时后端强制验证，防止前端绕过

3. **实现代购订单功能**
   - 平台/代理可为其他代理代购套餐
   - 支持线下支付方式（offline）
   - 代购订单不触发一次性佣金，不更新累计充值
   - 代购订单仍计算差价佣金

4. **扩展强充配置**
   - ShopSeriesAllocation 增加强充配置字段
   - 首次充值：强充金额 = 阈值（不可配置）
   - 累计充值：可选启用强充，配置固定充值金额

5. **修复佣金计算逻辑**
   - 代购订单不累加 AccumulatedRecharge
   - 代购订单不触发一次性佣金
   - 充值订单正常触发佣金

### Non-Goals

1. **不支持钱包转账**：用户钱包间转账不在本次范围
2. **不支持退款流程**：充值退款、订单退款流程留待后续实现
3. **不修改梯度佣金逻辑**：梯度佣金计算保持不变
4. **不修改差价佣金逻辑**：成本价差计算保持不变
5. **不支持企业客户钱包**：企业客户无钱包，本次不涉及
6. **不实现充值优惠**：充值满减、赠送等营销功能不在范围

---

## Decisions

### Decision 1: 数据库模型设计

**选择**：使用现有 RechargeRecord 表，新增必要字段到 Order 和 ShopSeriesAllocation 表。

**理由**：
- RechargeRecord 表已存在，结构合理，只需激活使用
- Order 表新增 `is_purchase_on_behalf BOOLEAN DEFAULT false`
- ShopSeriesAllocation 表新增 `enable_force_recharge BOOLEAN DEFAULT false` 和 `force_recharge_amount BIGINT DEFAULT 0`

**备选方案及拒绝原因**：
- ~~创建新表 PurchaseOnBehalfOrder~~：增加复杂度，Order 表扩展一个字段即可
- ~~使用订单备注字段标识代购~~：不利于查询和统计，需要独立字段

**实现细节**：
```sql
-- 迁移文件 1: 订单表增加代购标识
ALTER TABLE tb_order 
  ADD COLUMN is_purchase_on_behalf BOOLEAN DEFAULT false 
  COMMENT '是否为代购订单(平台/代理代购)';

-- 迁移文件 2: 系列分配表增加强充配置
ALTER TABLE tb_shop_series_allocation
  ADD COLUMN enable_force_recharge BOOLEAN DEFAULT false 
    COMMENT '是否启用强充(累计充值时可选)',
  ADD COLUMN force_recharge_amount BIGINT DEFAULT 0 
    COMMENT '强充金额(分,0表示使用阈值金额)';
```

---

### Decision 2: 强充验证策略

**选择**：前端预检 + 后端强制验证的双重保障策略。

**架构**：
```
前端调用预检接口 → 获取强充要求 → 显示给用户
    ↓
用户提交订单/充值 → 后端验证金额是否符合强充要求
    ↓
验证不通过 → 拒绝创建订单，返回错误
验证通过 → 创建订单/充值订单
```

**预检接口设计**：

1. **钱包充值预检**：`GET /api/h5/wallets/recharge-check?resource_type=iot_card&resource_id=123`
   ```go
   type RechargeCheckResponse struct {
       NeedForceRecharge   bool   `json:"need_force_recharge"`
       ForceRechargeAmount int64  `json:"force_recharge_amount"`
       TriggerType         string `json:"trigger_type"` // single_recharge/accumulated_recharge
       MinAmount           int64  `json:"min_amount"`
       MaxAmount           *int64 `json:"max_amount"`
       CurrentAccumulated  int64  `json:"current_accumulated"`
       Threshold           int64  `json:"threshold"`
       Message             string `json:"message"`
   }
   ```

2. **套餐购买预检**：`POST /api/h5/orders/purchase-check`
   ```go
   type PurchaseCheckRequest struct {
       OrderType  string  `json:"order_type"`
       ResourceID uint    `json:"resource_id"` // iot_card_id/device_id
       PackageIDs []uint  `json:"package_ids"`
   }
   
   type PurchaseCheckResponse struct {
       TotalPackageAmount  int64  `json:"total_package_amount"`
       NeedForceRecharge   bool   `json:"need_force_recharge"`
       ForceRechargeAmount int64  `json:"force_recharge_amount"`
       ActualPayment       int64  `json:"actual_payment"`
       WalletCredit        int64  `json:"wallet_credit"`
       Message             string `json:"message"`
   }
   ```

**验证逻辑**：
```go
func (s *RechargeService) checkForceRechargeRequirement(ctx, resourceType, resourceID) (*ForceRechargeRequirement, error) {
    // 1. 查询资源（卡/设备）
    resource := queryResource(resourceType, resourceID)
    
    // 2. 查询系列分配
    allocation := s.allocationStore.GetByID(ctx, resource.SeriesAllocationID)
    
    // 3. 判断是否需要强充
    if !allocation.EnableOneTimeCommission {
        return &ForceRechargeRequirement{NeedForceRecharge: false}, nil
    }
    
    if resource.FirstCommissionPaid {
        return &ForceRechargeRequirement{NeedForceRecharge: false}, nil
    }
    
    // 4. 根据触发类型判断
    if allocation.OneTimeCommissionTrigger == "single_recharge" {
        // 首次充值：强充金额 = 阈值
        return &ForceRechargeRequirement{
            NeedForceRecharge:   true,
            ForceRechargeAmount: allocation.OneTimeCommissionThreshold,
            TriggerType:         "single_recharge",
        }, nil
    } else {
        // 累计充值：检查是否启用强充
        if allocation.EnableForceRecharge {
            return &ForceRechargeRequirement{
                NeedForceRecharge:   true,
                ForceRechargeAmount: allocation.ForceRechargeAmount,
                TriggerType:         "accumulated_recharge",
            }, nil
        }
        return &ForceRechargeRequirement{NeedForceRecharge: false}, nil
    }
}
```

**备选方案及拒绝原因**：
- ~~仅前端验证~~：不安全，用户可以绕过前端直接调用 API
- ~~仅后端验证~~：用户体验差，提交后才知道金额不对

---

### Decision 3: 充值订单与套餐订单的关系

**选择**：充值订单和套餐订单完全独立，使用不同的表和流程。

**理由**：
- **关注点分离**：充值订单关注钱包余额变动，套餐订单关注套餐激活
- **业务语义清晰**：RechargeRecord 表示纯充值，Order 表示购买套餐
- **支付回调区分**：通过订单号前缀区分（RCH 开头是充值，ORD 开头是订单）
- **佣金计算独立**：充值和购买的佣金触发逻辑不同

**处理流程对比**：

| 流程步骤 | 充值订单（RechargeRecord） | 套餐订单（Order） |
|---------|---------------------------|------------------|
| 创建订单 | 创建 RechargeRecord | 创建 Order + OrderItem |
| 验证强充 | ✅ 验证充值金额 | ✅ 验证支付金额 |
| 生成订单号 | RCH + 时间戳 + 随机数 | ORD + 时间戳 + 随机数 |
| 支付 | 微信/支付宝 | 钱包/微信/支付宝/线下 |
| 支付成功 | 增加钱包余额 | 激活套餐，可能返还余额 |
| 更新累计充值 | ✅ 更新 AccumulatedRecharge | ✅ 更新（代购除外）|
| 触发佣金 | ✅ 触发一次性佣金判断 | ✅ 触发差价+一次性佣金（代购除外）|

**支付回调路由**：
```go
func (h *PaymentHandler) WechatPayCallback(c *fiber.Ctx) error {
    result := parseWechatCallback(c.Body())
    
    // 根据订单号前缀判断类型
    if strings.HasPrefix(result.OutTradeNo, "RCH") {
        // 充值订单回调
        return h.rechargeService.HandlePaymentCallback(ctx, result.OutTradeNo, "wechat")
    } else if strings.HasPrefix(result.OutTradeNo, "ORD") {
        // 套餐订单回调
        return h.orderService.HandlePaymentCallback(ctx, result.OutTradeNo, "wechat")
    }
    
    return errors.New(errors.CodeInvalidParam, "无效的订单号")
}
```

**备选方案及拒绝原因**：
- ~~使用同一个 Order 表，通过 order_type 区分~~：语义混乱，充值不是"订单"
- ~~充值也创建 Order，但 order_items 为空~~：违反业务语义，items 为空表示什么？

---

### Decision 4: 代购订单处理

**选择**：代购订单使用 `is_purchase_on_behalf` 字段标识，创建时直接标记为已支付，跳过支付流程。

**创建流程**：
```
平台/代理创建代购订单
    ↓
查询卡/设备归属的代理店铺
    ↓
计算买家的成本价（不是卖价）
    ↓
创建订单：
  - buyer_id = 代理店铺ID
  - is_purchase_on_behalf = true
  - payment_method = "offline"
  - payment_status = 2 (已支付)
  - total_amount = 买家成本价
    ↓
立即激活套餐（创建 PackageUsage）
    ↓
触发佣金计算（仅差价佣金，不触发一次性佣金）
```

**权限控制**：
```go
func (h *OrderHandler) Create(c *fiber.Ctx) error {
    req := parseRequest(c)
    userType := middleware.GetUserTypeFromContext(ctx)
    
    // 检查线下支付权限
    if req.PaymentMethod == model.PaymentMethodOffline {
        if userType != constants.UserTypePlatform {
            return errors.New(errors.CodeForbidden, "只有平台账号可以使用线下支付")
        }
    }
    
    // 平台代购 vs 普通订单
    if userType == constants.UserTypePlatform && req.PaymentMethod == "offline" {
        // 平台代购逻辑
        buyerShopID := queryResourceOwner(req.OrderType, req.ResourceID)
        return h.service.CreatePurchaseOnBehalf(ctx, req, buyerShopID)
    } else {
        // 普通订单逻辑
        shopID := middleware.GetShopIDFromContext(ctx)
        return h.service.Create(ctx, req, buyerType, shopID)
    }
}
```

**备选方案及拒绝原因**：
- ~~使用独立的 purchase_on_behalf_orders 表~~：增加复杂度，查询和统计不便
- ~~使用订单状态区分（如 payment_status = 5 表示代购）~~：滥用状态字段，语义不清

---

### Decision 5: 佣金计算修复

**选择**：在佣金计算Service中增加 `is_purchase_on_behalf` 判断，代购订单跳过一次性佣金和累计充值更新。

**修改逻辑**：
```go
func (s *CommissionCalculationService) CalculateCommission(ctx, orderID) error {
    order := s.orderStore.GetByID(ctx, orderID)
    
    // 1. 差价佣金：所有订单都计算（包括代购）
    costDiffRecords := s.CalculateCostDiffCommission(ctx, order)
    
    // 2. 累计充值：仅非代购订单更新
    if !order.IsPurchaseOnBehalf {
        s.updateAccumulatedRecharge(ctx, order)
    }
    
    // 3. 一次性佣金：仅非代购订单触发
    if !order.IsPurchaseOnBehalf {
        s.triggerOneTimeCommission(ctx, order)
    }
    
    // 4. 更新订单佣金状态
    s.orderStore.UpdateCommissionStatus(ctx, orderID, CommissionStatusCalculated)
}

func (s *CommissionCalculationService) updateAccumulatedRecharge(ctx, order) error {
    if order.OrderType == "single_card" && order.IotCardID != nil {
        return s.db.Model(&model.IotCard{}).
            Where("id = ?", *order.IotCardID).
            Update("accumulated_recharge", gorm.Expr("accumulated_recharge + ?", order.TotalAmount)).
            Error
    } else if order.OrderType == "device" && order.DeviceID != nil {
        return s.db.Model(&model.Device{}).
            Where("id = ?", *order.DeviceID).
            Update("accumulated_recharge", gorm.Expr("accumulated_recharge + ?", order.TotalAmount)).
            Error
    }
    return nil
}
```

**充值订单的佣金触发**：
```go
func (s *RechargeService) HandlePaymentCallback(ctx, rechargeNo, paymentMethod) error {
    return s.db.Transaction(func(tx *gorm.DB) error {
        // 1. 更新充值订单状态
        s.rechargeStore.UpdateStatus(ctx, rechargeNo, RechargeStatusPaid)
        
        // 2. 增加钱包余额
        s.walletStore.IncreaseBalance(ctx, walletID, amount)
        
        // 3. 更新累计充值
        s.updateAccumulatedRecharge(ctx, resourceType, resourceID, amount)
        
        // 4. 触发一次性佣金判断
        s.triggerOneTimeCommissionIfNeeded(ctx, resourceType, resourceID, amount)
        
        return nil
    })
}
```

---

### Decision 6: 强充金额来源

**选择**：首次充值使用阈值，累计充值使用独立配置字段。

**规则矩阵**：

| 触发类型 | 强充开关 | 强充金额来源 | 说明 |
|---------|---------|-------------|------|
| 首次充值 | 不可配置（必须强充） | `OneTimeCommissionThreshold` | 首充必须充值阈值金额 |
| 累计充值 | `EnableForceRecharge=true` | `ForceRechargeAmount`（独立配置） | 每次必须充值固定金额 |
| 累计充值 | `EnableForceRecharge=false` | - | 不强充，自由金额 |

**查询逻辑**：
```go
func getForceRechargeAmount(allocation *ShopSeriesAllocation) int64 {
    if allocation.OneTimeCommissionTrigger == "single_recharge" {
        // 首次充值：强充金额 = 阈值
        return allocation.OneTimeCommissionThreshold
    } else {
        // 累计充值：强充金额 = 配置字段（如果为0则使用阈值）
        if allocation.ForceRechargeAmount > 0 {
            return allocation.ForceRechargeAmount
        }
        return allocation.OneTimeCommissionThreshold
    }
}
```

**备选方案及拒绝原因**：
- ~~累计充值的强充金额也固定为阈值~~：不合理，会导致"买39元套餐要充1000元"的问题
- ~~累计充值的强充金额动态计算（阈值 - 当前累计）~~：不合理，每次充值金额不固定

---

### Decision 7: 模块依赖注入

**选择**：使用现有的 `bootstrap` 包统一管理依赖注入。

**注入结构**：
```go
// bootstrap/stores.go
type Stores struct {
    // ... 现有 stores
    Recharge *postgres.RechargeStore  // 新增
}

// bootstrap/services.go
type Services struct {
    // ... 现有 services
    Recharge *recharge.Service  // 新增
}

// bootstrap/handlers.go
type Handlers struct {
    // ... 现有 handlers
    H5Recharge *h5.RechargeHandler  // 新增
}

// 初始化顺序：Stores → Services → Handlers
func Bootstrap(deps *Dependencies) (*Handlers, error) {
    stores := initStores(deps.DB, deps.Redis)
    services := initServices(deps, stores)
    handlers := initHandlers(services)
    return handlers, nil
}
```

**理由**：
- 遵循现有架构模式
- 集中管理依赖，易于测试和维护
- 避免循环依赖

---

## Risks / Trade-offs

### Risk 1: 数据库迁移风险

**风险**：新增字段的迁移可能影响现有数据。

**缓解措施**：
- 所有新增字段都有默认值（`is_purchase_on_behalf DEFAULT false`）
- 分阶段迁移：先添加字段，再部署代码，最后更新数据
- 迁移前备份数据库
- 在测试环境完整验证迁移流程

---

### Risk 2: 支付回调幂等性

**风险**：充值订单和套餐订单都支持支付回调，可能重复处理。

**缓解措施**：
- 检查订单/充值订单状态，已支付则直接返回成功
- 使用数据库事务保证原子性
- 钱包余额更新使用乐观锁（version 字段）

```go
func (s *RechargeService) HandlePaymentCallback(ctx, rechargeNo, method) error {
    // 幂等性检查
    recharge := s.rechargeStore.GetByRechargeNo(ctx, rechargeNo)
    if recharge.Status == RechargeStatusPaid || recharge.Status == RechargeStatusCompleted {
        return nil  // 已处理，直接返回成功
    }
    
    // 事务处理
    return s.db.Transaction(func(tx *gorm.DB) error {
        // 更新充值订单状态（带状态检查）
        result := tx.Model(&RechargeRecord{}).
            Where("recharge_no = ? AND status = ?", rechargeNo, RechargeStatusPending).
            Updates(map[string]any{
                "status": RechargeStatusPaid,
                "payment_method": method,
                "paid_at": time.Now(),
            })
        
        if result.RowsAffected == 0 {
            return nil  // 已被处理，跳过
        }
        
        // 增加钱包余额（使用乐观锁）
        // ...
    })
}
```

---

### Risk 3: 强充验证被绕过

**风险**：前端或恶意用户可能绕过强充验证。

**缓解措施**：
- 后端创建订单/充值订单时强制验证，拒绝不符合要求的请求
- 记录验证失败的日志，监控异常行为
- API 接口使用认证中间件，防止未授权调用

---

### Risk 4: 佣金计算逻辑复杂度增加

**风险**：增加代购订单判断后，佣金计算逻辑更复杂，容易出错。

**缓解措施**：
- 单元测试覆盖所有场景（普通订单、代购订单、充值订单）
- 使用 table-driven tests 测试各种组合
- 添加详细的日志记录，便于排查问题

**测试场景**：
```go
func TestCommissionCalculation_PurchaseOnBehalf(t *testing.T) {
    tests := []struct {
        name                    string
        isPurchaseOnBehalf      bool
        expectUpdateAccumulated bool
        expectOneTimeCommission bool
    }{
        {"普通订单", false, true, true},
        {"代购订单", true, false, false},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            // 测试逻辑
        })
    }
}
```

---

### Trade-off 1: 预检接口性能 vs 实时性

**权衡**：预检接口需要查询系列分配配置，可能影响性能。

**选择**：不缓存系列分配配置，保证实时性。

**理由**：
- 系列分配配置变更频率低
- 单次查询性能可接受（< 10ms）
- 实时性更重要（避免用户看到过期的强充要求）
- 如果后续性能成为瓶颈，可以引入短期缓存（如 1 分钟）

---

### Trade-off 2: 充值订单和套餐订单独立 vs 统一

**权衡**：使用独立的 RechargeRecord 表增加了一定复杂度。

**选择**：保持独立，不合并到 Order 表。

**理由**：
- **语义清晰**：充值不是"订单"，是钱包操作
- **查询方便**：充值记录和订单记录可以独立查询和统计
- **扩展性好**：未来可能支持银行转账充值等，不适合放在 Order 表
- **复杂度可控**：只是多一个 Store/Service/Handler，符合分层架构

---

## Migration Plan

### 阶段 1: 数据库迁移（停机时间 < 1 分钟）

1. **创建迁移文件**：
   ```bash
   # 迁移文件 1
   000XXX_add_order_purchase_on_behalf.up.sql
   000XXX_add_order_purchase_on_behalf.down.sql
   
   # 迁移文件 2
   000XXX_add_shop_series_allocation_force_recharge.up.sql
   000XXX_add_shop_series_allocation_force_recharge.down.sql
   ```

2. **执行迁移**：
   ```bash
   # 测试环境验证
   migrate -path migrations -database "postgres://..." up
   
   # 生产环境执行
   migrate -path migrations -database "postgres://..." up
   ```

3. **验证迁移**：
   ```sql
   -- 检查字段是否添加成功
   SELECT column_name, data_type, column_default 
   FROM information_schema.columns 
   WHERE table_name IN ('tb_order', 'tb_shop_series_allocation');
   ```

---

### 阶段 2: 代码部署（灰度发布）

1. **部署顺序**：
   - 先部署 API 服务（包含新接口和修复后的佣金计算）
   - 再部署 Worker 服务（佣金计算任务处理）

2. **灰度策略**：
   - 第1天：50% 流量
   - 第2天：100% 流量
   - 监控错误率、响应时间、佣金计算准确性

3. **回滚策略**：
   - 如果发现严重问题，立即回滚到旧版本
   - 数据库字段保留（有默认值，不影响旧代码）
   - 充值订单数据保留，后续可重新处理

---

### 阶段 3: 功能验证

1. **充值功能验证**：
   - 个人客户创建充值订单
   - 微信/支付宝支付成功
   - 钱包余额正确增加
   - 累计充值正确更新
   - 达到阈值时正确触发佣金

2. **代购功能验证**：
   - 平台创建代购订单
   - 订单自动完成
   - 套餐正确激活
   - 差价佣金正确计算
   - 一次性佣金不触发
   - 累计充值不更新

3. **强充验证**：
   - 预检接口返回正确的强充要求
   - 创建订单时正确验证强充金额
   - 不符合要求的订单被拒绝

---

### 阶段 4: 数据监控

1. **监控指标**：
   - 充值订单创建数量、成功率
   - 代购订单创建数量
   - 佣金计算准确性（抽样检查）
   - 累计充值更新准确性
   - 预检接口响应时间
   - 支付回调成功率

2. **告警规则**：
   - 充值订单创建失败率 > 5%
   - 支付回调处理失败率 > 1%
   - 预检接口响应时间 > 200ms
   - 佣金计算失败率 > 0.1%

---

## Open Questions

### Q1: 代理能否为下级代理代购？

**当前设计**：平台可以为任何代理代购，代理暂不支持。

**待确认**：
- 代理是否需要为下级代理代购的能力？
- 如果需要，权限如何控制（只能为直属下级？还是所有下级？）
- 代购时使用谁的成本价（创建人的成本价？还是买家的成本价？）

**影响**：如果需要支持，Handler 层的权限检查需要调整。

---

### Q2: 充值订单是否需要取消功能？

**当前设计**：充值订单创建后不支持取消，只能超时自动关闭。

**待确认**：
- 用户是否需要主动取消充值订单？
- 如果支持取消，状态流转如何设计？

**影响**：如果需要支持，需要增加 Cancel 接口和状态流转逻辑。

---

### Q3: 强充金额是否需要支持范围（最小-最大）？

**当前设计**：强充金额是一个固定值（如100元）。

**待确认**：
- 是否需要支持金额范围（如 100-500 元之间任意金额）？
- 如果支持，配置字段如何设计？

**影响**：如果需要支持，ShopSeriesAllocation 需要增加 `force_recharge_min` 和 `force_recharge_max` 字段。

---

### Q4: 充值订单是否需要支持优惠券/折扣？

**当前设计**：充值订单不支持任何优惠。

**待确认**：
- 未来是否需要支持充值满减、折扣等营销活动？
- 如果需要，是否在本次实现？

**影响**：如果需要支持，需要设计优惠券系统，超出本次范围。

**建议**：留待后续实现，本次保持简单。
