docs(pricing): 按 SubjectType 查询可选计费方式接口设计

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-09-01 11:53:16 +08:00
co-authored by Claude
parent 3eab69034c
commit d36b0c231f
@@ -0,0 +1,90 @@
# 按 SubjectType 查询可选计费方式 设计
> 版本:v0.1(本期)—— 在 v0.3 计价对象枚举化基础上,提供前端「选择计费方式」所需的轻量查询接口。
> 范围:shop-user-trade **pricing 计价模块**。交付「按 subjectType 查可选 chargeMode」接口 + 计费方式中文名常量。**不触碰 model 主体**。
> 前置:依赖 v0.3 枚举设计 `2026-08-28-pricing-enum-design.md`SubjectType / ChargeMode / BusinessSubjects 已在代码落地)。
---
## 1. 背景与目标
v0.3 把计价对象固定枚举为 `workflow / model / business`。管理端为工作流配置价格时,需要从三套计费方式(`per_item` / `per_second` / `per_token`)中**选择一种**;为业务模块配置时选择周期订阅(`per_period`)。当前没有任何接口告诉前端「某类型可选哪些计费方式」,且计费方式枚举**缺中文名**,前端无法渲染下拉。
**model 主体不需要此查询**:模型的计费单位(unit)由其模型类型自适应决定、在模型配置编辑器内随 rules 一起配置,不存在"选择计费方式"这一步(用户确认)。故接口只服务需要「选」的类型。
目标:一个 `GET /pricing/controller/subjects/charge-modes?subjectType=X` 接口,返回该类型可选计费方式(mode + 中文名),**纯查常量、零外部依赖**。
## 2. 接口契约
```
GET /pricing/controller/subjects/charge-modes?subjectType={workflow|business}
```
| 参数 | 必填 | 校验 |
|---|---|---|
| `subjectType` | 是 | `in:workflow,business`;**model 非法**——模型计费方式无需选择,误传 400 |
响应(前端下拉直接渲染 `name``mode` 作提交值):
```json
{
"subjectType": "workflow",
"chargeModes": [
{ "mode": "per_item", "name": "按条" },
{ "mode": "per_second", "name": "按秒" },
{ "mode": "per_token", "name": "按token" }
]
}
```
`subjectType=business``chargeModes` = 全部 `BusinessSubjects[].ChargeModes` 的**并集**(现为 `[per_period]`)。
## 3. 数据来源(纯常量,零外部依赖)
| subjectType | chargeModes | 来源 |
|---|---|---|
| `workflow` | `[per_item, per_second, per_token]` | `consts/pricing/subject.go` 新增 `WorkflowChargeModes` |
| `business` | 各主体 ChargeModes 并集 | `consts/pricing/subject.go` 既有 `BusinessSubjects[].ChargeModes` |
- 不调 model-gateway、不查 `pricing_config`、**无 subjectId 参数**。
- model 由校验层拦截(`v:"required|in:workflow,business"`)。
## 4. 计费方式中文名
`consts/pricing/charge_mode.go` 新增 `ChargeModeNames map[ChargeMode]string`,覆盖全部 10 个枚举(单一来源,前端直接渲染):
| mode | name |
|---|---|
| `per_item` | 按条 |
| `per_second` | 按秒 |
| `per_token` | 按token |
| `per_1K` | 每千token |
| `per_1M` | 每百万token |
| `per_1` | 每张/每个 |
| `per_minute` | 每分钟 |
| `per_hour` | 每小时 |
| `per_char` | 每字 |
| `per_period` | 周期订阅 |
## 5. 改动清单
1. `consts/pricing/charge_mode.go`:加 `ChargeModeNames` map(§4 全表)
2. `consts/pricing/subject.go`:加 `WorkflowChargeModes = []ChargeMode{per_item, per_second, per_token}`(与 `charge_calc.go``workflowCalculators` 三键一致)
3. `model/dto/pricing/subject_dto.go``ChargeModeListReq``path:"/subjects/charge-modes" method:"get"``subjectType v:"required|in:workflow,business"`+ `ChargeModeListRes{SubjectType string, ChargeModes []ChargeModeInfo}` + `ChargeModeInfo{Mode string, Name string}`
4. `service/pricing/subject_service.go``ListChargeModes(ctx, req)` — workflow→`WorkflowChargeModes`business→`BusinessSubjects``ChargeModes` 并集(去重、保持声明序)
5. `controller/pricing/pricing_controller.go`:注册 `ChargeModes` 方法(复用既有 Subjects 的 Controller 模式)
6. `go build ./...` 验证
## 6. 设计决策汇总
| 决策 | 理由 |
|---|---|
| 只服务 workflow/businessmodel 不入参 | 模型计费方式由类型/配置决定,前端无需选择(用户确认) |
| 无 subjectId、不调 model-gateway | 纯查常量,接口轻量稳定,与 `/pricing/subjects` 解耦 |
| 中文名放 consts map`ChargeModeNames` | 前端直接渲染,单一来源 |
| workflow 模式用 `WorkflowChargeModes` 常量 | 与计算器注册表三键一致,不耦合 `charge_calc` 内部 |
| business 并集按声明序、去重 | 新增业务模块只改 consts 即生效,响应顺序稳定 |
## 7. 不改动
- `/pricing/subjects` 枚举响应、`pricing_config` 的 save 校验(unit∈ModelUnitSet 等)、计算器注册表、DB 结构均不变。