# Design: 套餐系列分配佣金系统重构

## Context

当前系统使用简单的定价模式(pricing*mode/pricing_value)和一次性佣金(one_time_commission*\*)来管理套餐系列分配。随着业务发展,需要更复杂的佣金系统:

- 支持基础返佣(固定金额或百分比)
- 支持梯度返佣(根据销量或销售额分档返佣)
- 更清晰的数据模型和API接口

**背景约束**:

- 前后端需要同步部署(Breaking Change)
- 需要数据迁移方案
- 影响现有的套餐系列分配功能

## Goals / Non-Goals

**Goals**:

- 实现新的佣金配置模型,支持基础返佣和梯度返佣
- 提供清晰的UI界面让用户配置复杂的返佣规则
- 保证数据一致性和类型安全
- 提供良好的用户体验(表单验证、错误提示)

**Non-Goals**:

- 不处理历史数据的完整性验证(由后端负责)
- 不实现佣金计算逻辑(由后端负责)
- 不处理佣金结算流程(属于其他模块)

## Decisions

### 1. Data Model Design

**决策**: 采用嵌套对象结构表示佣金配置

**理由**:

- `base_commission: { mode, value }` - 清晰表达基础返佣的两个维度
- `tier_config: { period_type, tier_type, tiers[] }` - 梯度配置与基础配置分离,可选性强
- `tiers: [{ threshold, mode, value }]` - 每个档位都有独立的返佣模式和值

**替代方案考虑**:

- ❌ 平铺所有字段 - 会导致字段过多,语义不清晰
- ❌ 使用JSON字符串存储配置 - 失去类型安全,不利于表单编辑

### 2. UI Design Pattern

**决策**: 使用渐进式表单设计

**表单结构**:

```
1. 基础返佣配置 (必填)
   - 返佣模式: 单选 (固定金额/百分比)
   - 返佣值: 数字输入

2. 梯度返佣设置 (可选)
   - 启用开关: 是/否
   - [如果启用]:
     - 周期类型: 下拉 (月度/季度/年度)
     - 梯度类型: 下拉 (销量/销售额)
     - 档位列表: 动态表单
       * 阈值
       * 返佣模式
       * 返佣值
       * [添加]/[删除] 按钮
```

**理由**:

- 渐进式设计降低初始复杂度
- 只有启用梯度返佣时才显示相关配置
- 动态档位列表提供灵活性

**替代方案考虑**:

- ❌ 全部平铺展示 - 对不需要梯度返佣的用户造成困扰
- ❌ 使用向导模式 - 增加操作步骤,不适合编辑场景

### 3. Form Validation Strategy

**决策**: 分层验证 + 条件验证

**验证规则**:

1. 基础返佣配置:

   - mode: 必选
   - value: 必填,>= 0

2. 梯度返佣配置(当启用时):
   - period_type: 必选
   - tier_type: 必选
   - tiers: 至少一个档位
   - 每个档位:
     - threshold: 必填,> 0
     - mode: 必选
     - value: 必填,> 0
   - 档位阈值必须递增

**实现方式**:

- 使用 Element Plus 的表单验证
- 自定义validator处理档位阈值递增验证
- 使用 computed 动态生成验证规则

### 4. API Response Handling

**决策**: 统一使用 `list` 字段名,添加适配层

**理由**:

- 后端统一规范使用 `list` 而非 `items`
- 添加 `total_pages` 字段提供更完整的分页信息
- 保持前端代码与后端规范一致

**迁移策略**:

```typescript
// Before
const res = await getShopSeriesAllocations(params)
allocationList.value = res.data.items || []

// After
const res = await getShopSeriesAllocations(params)
allocationList.value = res.data.list || []
```

## Risks / Trade-offs

### Risk 1: Breaking Change导致部署协调困难

**风险**: 前后端必须同时部署,否则会出现接口不兼容

**缓解措施**:

- 与后端团队协调部署窗口
- 准备回退方案(前端代码分支)
- 在测试环境充分验证

### Risk 2: 复杂表单导致用户体验问题

**风险**: 梯度返佣配置较复杂,用户可能不理解

**缓解措施**:

- 提供清晰的字段说明
- 添加示例或帮助文档链接
- 使用默认值简化初次配置

### Risk 3: 数据迁移可能失败

**风险**: 旧数据无法完全转换为新模型

**缓解措施**:

- 要求后端提供数据迁移脚本和验证
- 在迁移后检查数据完整性
- 保留旧数据备份

## Migration Plan

### Phase 1: 准备阶段

1. 与后端确认API变更细节和时间表
2. 在开发环境实现前端变更
3. 与后端在测试环境联调

### Phase 2: 测试阶段

1. 功能测试: 创建、编辑、删除、列表展示
2. 集成测试: 与后端API集成
3. 用户验收测试: 业务人员验证

### Phase 3: 部署阶段

1. 准备回退方案
2. 与后端协调部署窗口
3. 同步部署前后端
4. 验证生产环境功能

### Phase 4: 监控阶段

1. 监控API错误率
2. 收集用户反馈
3. 修复遗留问题

### Rollback Plan

如果部署后发现严重问题:

1. 前端回退到上一版本
2. 后端回退API(如果可能)
3. 通知用户暂时不可用
4. 修复问题后重新部署

## Open Questions

1. **Q**: 梯度返佣的档位数量是否有上限?

   - **A**: 待后端确认,前端可以先不限制或设置合理上限(如10个)

2. **Q**: 返佣值的单位和精度如何处理?

   - **A**: 固定金额使用"分"为单位,百分比使用千分比(如200=20%),待后端确认

3. **Q**: 是否需要在列表页显示梯度返佣信息?

   - **A**: 暂时只显示基础返佣,梯度信息在详情或编辑时查看

4. **Q**: 旧数据如何映射到新模型?
   - **A**: 待后端提供迁移方案,前端需要能够正确显示迁移后的数据
