Files
junhong_cmp_fiber/openspec/specs/force-recharge-check/spec.md
huang b9733c4913
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m12s
fix: 修正零售价架构错误 + 清理旧微信配置 + 归档提案 + 前端接口文档
1. 修正 retail_price 架构:
   - 删除 batch-pricing 接口的 pricing_target 字段和 retail_price 分支
     (上级只能改下级成本价,不能改零售价)
   - 新增 PATCH /api/admin/packages/:id/retail-price 接口
     (代理自己改自己的零售价,校验 retail_price >= cost_price)

2. 清理旧微信 YAML 配置(已全部迁移到数据库 tb_wechat_config):
   - 删除 config.yaml 中 wechat.official_account 配置节
   - 删除 NewOfficialAccountApp() 旧工厂函数
   - 清理 personal_customer service 中的死代码(旧登录/绑定微信方法)
   - 清理 docker-compose.prod.yml 中旧微信环境变量和证书挂载注释

3. 归档四个已完成提案到 openspec/changes/archive/

4. 新增前端接口变更说明文档(docs/前端接口变更说明.md)

5. 修正归档提案和 specs 中关于 pricing_target 的错误描述
2026-03-19 17:39:43 +08:00

166 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Capability: 强充预检
## Purpose
本 capability 定义强充预检接口,在充值或购买套餐前返回强充要求、允许的充值金额等信息,帮助前端正确引导用户完成支付。
## Requirements
### Requirement: 代理层强充层级判断
系统 SHALL 在强充预检时按层级判断生效的强充配置:平台在 PackageSeries 中设置的强充具有最高优先级;平台未设强充时,读取客户所属销售代理(`order.SellerShopID`)对应的 ShopSeriesAllocation 强充配置。
#### Scenario: 平台已设强充,代理自设被忽略
- **WHEN** PackageSeries.enable_force_recharge=true平台层客户在代理A 的渠道下购买代理A 的 ShopSeriesAllocation.enable_force_recharge=false
- **THEN** 系统使用平台强充规则need_force_recharge=trueforce_recharge_amount=平台设定值
#### Scenario: 平台未设强充,代理自设生效
- **WHEN** PackageSeries.enable_force_recharge=false客户在代理A 的渠道下购买代理A 的 ShopSeriesAllocation.enable_force_recharge=trueforce_recharge_amount=10000
- **THEN** 系统使用代理A 的强充配置need_force_recharge=trueforce_recharge_amount=10000
#### Scenario: 平台未设强充,代理也未设强充
- **WHEN** PackageSeries.enable_force_recharge=false代理A 的 ShopSeriesAllocation.enable_force_recharge=false
- **THEN** 系统返回 need_force_recharge=false
#### Scenario: 平台未设强充,查询不到销售代理分配
- **WHEN** PackageSeries.enable_force_recharge=false系统查询不到 SellerShop 对应的 ShopSeriesAllocation
- **THEN** 系统返回 need_force_recharge=false降级处理不影响购买流程
---
### Requirement: 钱包充值预检
系统 SHALL 提供钱包充值预检接口,返回强充要求、允许的充值金额等信息。强充判断 MUST 按代理层级规则执行:优先使用平台强充,平台未设时使用销售代理自设强充。
#### Scenario: 无强充要求
- **WHEN** 客户查询卡钱包充值预检PackageSeries.enable_force_recharge=false销售代理 ShopSeriesAllocation.enable_force_recharge=false
- **THEN** 系统返回 need_force_recharge=false
#### Scenario: 首次充值强充(平台层)
- **WHEN** 客户查询卡钱包充值预检PackageSeries 配置为首次充值触发,阈值 10000 分,未发放佣金
- **THEN** 系统返回 need_force_recharge=trueforce_recharge_amount=10000trigger_type="single_recharge"
#### Scenario: 累计充值启用强充(平台层)
- **WHEN** 客户查询卡钱包充值预检PackageSeries.enable_force_recharge=trueforce_amount=10000
- **THEN** 系统返回 need_force_recharge=trueforce_recharge_amount=10000trigger_type="accumulated_recharge"
#### Scenario: 代理自设累计充值强充(平台未设)
- **WHEN** PackageSeries.enable_force_recharge=false销售代理的 ShopSeriesAllocation.enable_force_recharge=trueforce_recharge_amount=8000
- **THEN** 系统返回 need_force_recharge=trueforce_recharge_amount=8000
#### Scenario: 一次性佣金已发放
- **WHEN** 客户查询卡钱包充值预检,卡的一次性佣金已发放过
- **THEN** 系统返回 need_force_recharge = false不再强充
#### Scenario: 未启用一次性佣金
- **WHEN** 客户查询卡钱包充值预检,卡关联系列未启用一次性佣金
- **THEN** 系统返回 need_force_recharge = false
---
### Requirement: 套餐购买预检
系统 SHALL 提供套餐购买预检接口,计算实际支付金额、钱包到账金额等信息。强充判断 MUST 按代理层级规则执行。
#### Scenario: 无强充要求正常购买
- **WHEN** 客户购买 90 元套餐,平台和销售代理均未设强充
- **THEN** 系统返回 total_package_amount=9000need_force_recharge=falseactual_payment=9000wallet_credit=0
#### Scenario: 代理自设强充,套餐价低于强充金额
- **WHEN** 客户购买 50 元套餐,平台未设强充,销售代理设置 force_recharge_amount=10000
- **THEN** 系统返回 actual_payment=10000wallet_credit=5000
#### Scenario: 首次充值强充(平台层),套餐价低于阈值
- **WHEN** 客户购买 90 元套餐,首次充值阈值 100 元(平台层)
- **THEN** 系统返回 total_package_amount=9000need_force_recharge=trueforce_recharge_amount=10000actual_payment=10000wallet_credit=1000
#### Scenario: 首次充值强充,套餐价高于阈值
- **WHEN** 客户购买 150 元套餐,首次充值阈值 100 元
- **THEN** 系统返回 total_package_amount = 15000need_force_recharge = trueforce_recharge_amount = 10000actual_payment = 15000wallet_credit = 0message = "套餐总价150元无需额外充值"
#### Scenario: 首次充值强充,套餐价等于阈值
- **WHEN** 客户购买 100 元套餐,首次充值阈值 100 元
- **THEN** 系统返回 total_package_amount = 10000need_force_recharge = trueforce_recharge_amount = 10000actual_payment = 10000wallet_credit = 0
#### Scenario: 累计充值启用强充,套餐价低于强充金额
- **WHEN** 客户购买 50 元套餐,累计充值启用强充,强充金额 100 元
- **THEN** 系统返回 actual_payment = 10000wallet_credit = 5000message = "需充值100元购买套餐后余额50元"
#### Scenario: 累计充值启用强充,套餐价高于强充金额
- **WHEN** 客户购买 150 元套餐,累计充值启用强充,强充金额 100 元
- **THEN** 系统返回 actual_payment = 15000wallet_credit = 0message = "套餐总价150元无需额外充值"
#### Scenario: 购买多个套餐
- **WHEN** 客户购买 3 个套餐,总价 120 元,首次充值阈值 100 元
- **THEN** 系统返回 total_package_amount = 12000actual_payment = 12000wallet_credit = 0
---
### Requirement: 预检接口响应格式
预检接口响应 SHALL 包含完整的充值/购买指引信息。
#### Scenario: 充值预检响应字段
- **WHEN** 调用钱包充值预检接口
- **THEN** 响应包含need_force_recharge, force_recharge_amount, trigger_type, min_amount, max_amount, current_accumulated, threshold, message
#### Scenario: 购买预检响应字段
- **WHEN** 调用套餐购买预检接口
- **THEN** 响应包含total_package_amount, need_force_recharge, force_recharge_amount, actual_payment, wallet_credit, message
---
### Requirement: 预检接口性能
预检接口响应时间 MUST 小于 100ms。
#### Scenario: 快速响应
- **WHEN** 调用预检接口
- **THEN** 系统在 100ms 内返回结果
#### Scenario: 缓存系列分配配置
- **WHEN** 频繁查询同一卡的预检信息
- **THEN** 系统可以缓存系列分配配置,减少数据库查询
---
### Requirement: 预检接口错误处理
预检接口 SHALL 正确处理异常情况。
#### Scenario: 卡不存在
- **WHEN** 查询不存在的卡的充值预检
- **THEN** 系统返回错误 "卡不存在"
#### Scenario: 卡未关联系列
- **WHEN** 查询未关联套餐系列的卡的充值预检
- **THEN** 系统返回 need_force_recharge = false无系列分配无强充要求
#### Scenario: 设备不存在
- **WHEN** 查询不存在的设备的充值预检
- **THEN** 系统返回错误 "设备不存在"
#### Scenario: 套餐不存在
- **WHEN** 套餐购买预检时,套餐 ID 不存在
- **THEN** 系统返回错误 "套餐不存在"
---
### Requirement: 强充检查结果对客户端透出
系统 MUST 将强充检查结果输出给客户端接口(充值预检与购买预检),用于前端明确展示支付拆分。输出字段 SHALL 至少包含:`need_force_recharge``force_recharge_amount``trigger_type``total_package_amount``actual_payment``wallet_credit``message`。若无强充,`need_force_recharge=false``actual_payment=total_package_amount`
#### Scenario: 客户端购买预检命中强充
- **WHEN** 客户端调用购买预检且命中强充规则
- **THEN** 系统返回强充金额、实际支付金额和钱包入账金额
---
### Requirement: 前端展示套餐价与强充金额拆分
系统 SHALL 在强充场景提供可直接渲染的拆分语义套餐总价、需支付金额、充值入钱包金额并给出中文提示文案。当前端调用客户端下单接口D1若命中强充 MUST 返回 `order_type="recharge"``linked_package_info`,以便前端保持与预检展示一致。
#### Scenario: 套餐价低于强充金额
- **WHEN** 套餐总价 5000 分,强充金额 10000 分
- **THEN** 预检返回 `actual_payment=10000``wallet_credit=5000`、提示文案可用于前端直接展示