From d36b0c231fb5a7b42ab37712c3fbdcdddb12e00d Mon Sep 17 00:00:00 2001 From: qhd <1766646056@qq.com> Date: Tue, 1 Sep 2026 11:53:16 +0800 Subject: [PATCH] =?UTF-8?q?docs(pricing):=20=E6=8C=89=20SubjectType=20?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=8F=AF=E9=80=89=E8=AE=A1=E8=B4=B9=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E6=8E=A5=E5=8F=A3=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- .../2026-09-01-subject-charge-modes-design.md | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-01-subject-charge-modes-design.md diff --git a/docs/superpowers/specs/2026-09-01-subject-charge-modes-design.md b/docs/superpowers/specs/2026-09-01-subject-charge-modes-design.md new file mode 100644 index 0000000..2ca9053 --- /dev/null +++ b/docs/superpowers/specs/2026-09-01-subject-charge-modes-design.md @@ -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/business,model 不入参 | 模型计费方式由类型/配置决定,前端无需选择(用户确认) | +| 无 subjectId、不调 model-gateway | 纯查常量,接口轻量稳定,与 `/pricing/subjects` 解耦 | +| 中文名放 consts map(`ChargeModeNames`) | 前端直接渲染,单一来源 | +| workflow 模式用 `WorkflowChargeModes` 常量 | 与计算器注册表三键一致,不耦合 `charge_calc` 内部 | +| business 并集按声明序、去重 | 新增业务模块只改 consts 即生效,响应顺序稳定 | + +## 7. 不改动 + +- `/pricing/subjects` 枚举响应、`pricing_config` 的 save 校验(unit∈ModelUnitSet 等)、计算器注册表、DB 结构均不变。