feat: add billing pricing rules
This commit is contained in:
+25
-10
@@ -70,8 +70,8 @@
|
||||
| AiModel | 迁移自 `cmbot/config/ai_models.json` | name、url、model、`api_type`、`capabilities`、`timeout_seconds`、`connect_timeout_seconds`、`extra_body`、`is_active`、**api_key_encrypted(Fernet 加密存储)** |
|
||||
| ModelAlias | 运营配置 | `operation_type + alias` → 映射到一个具体 AiModel;支持每个操作一个默认别名;调用方只见别名,不见 SKU |
|
||||
| AiConfigAuditLog | 后台自动写入 | AiModel / ModelAlias / api_key 变更审计;记录 actor、action、target、changed_fields、changes、created_at;只读 |
|
||||
| PricingRule | 运营配置 | 操作类型 × **能力别名**(+ 可选分辨率)→ 点数单价 |
|
||||
| ExchangeRate | 运营配置 | 金额 → 点数 的汇率(如 1 元 = N 点),可带生效时间 |
|
||||
| PricingRule | 运营配置 | 操作类型 × **能力别名字符串**(+ 可选分辨率)→ 点数单价;不外键到具体 AiModel |
|
||||
| ExchangeRate | 运营配置 | 金额 → 点数 的汇率(如 1 元 = N 点),按 `currency + effective_from` 取当前有效值 |
|
||||
|
||||
关键事实:
|
||||
|
||||
@@ -136,16 +136,31 @@ CREATE TABLE ai_config_audit_log (
|
||||
|
||||
-- 计费规则(按别名定价,换底层模型不影响计费)
|
||||
CREATE TABLE pricing_rule (
|
||||
id INTEGER PRIMARY KEY,
|
||||
operation_type TEXT NOT NULL, -- title / image
|
||||
alias TEXT NOT NULL REFERENCES model_alias(alias),
|
||||
resolution TEXT, -- 可空:按档位区分价格时使用
|
||||
points_cost BIGINT NOT NULL,
|
||||
UNIQUE(alias, resolution)
|
||||
id BIGINT PRIMARY KEY,
|
||||
operation_type VARCHAR(32) NOT NULL, -- title / image
|
||||
alias VARCHAR(64) NOT NULL, -- 能力别名字符串,不绑具体模型
|
||||
resolution VARCHAR(32) NOT NULL DEFAULT '', -- 空字符串表示该别名默认价
|
||||
points_cost BIGINT NOT NULL, -- > 0
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at DATETIME(6) NOT NULL,
|
||||
updated_at DATETIME(6) NOT NULL,
|
||||
UNIQUE(operation_type, alias, resolution)
|
||||
);
|
||||
|
||||
-- 金额换点数汇率(充值下单时锁定)
|
||||
CREATE TABLE exchange_rate (
|
||||
id BIGINT PRIMARY KEY,
|
||||
currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
|
||||
points_per_unit DECIMAL(12,4) NOT NULL, -- 1 currency unit = N points
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
effective_from DATETIME(6) NOT NULL,
|
||||
note VARCHAR(255) NOT NULL DEFAULT '',
|
||||
created_at DATETIME(6) NOT NULL,
|
||||
updated_at DATETIME(6) NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
T-102 已实现 `AiModel` / `ModelAlias` 的 Django models、admin、迁移与别名解析。T-103 已补 `AiConfigAuditLog`,admin 里保存/删除模型配置或能力别名时自动写审计日志。默认别名唯一性由 model validation、admin 与导入器保证;MySQL 不支持通用 partial unique index,后续若要强制数据库层约束可在 T-401 评估触发器或约束表。
|
||||
T-102 已实现 `AiModel` / `ModelAlias` 的 Django models、admin、迁移与别名解析。T-103 已补 `AiConfigAuditLog`,admin 里保存/删除模型配置或能力别名时自动写审计日志。T-202 已实现 `PricingRule` / `ExchangeRate` 与 `apps.billing.pricing` 计算函数:定价按 `operation_type + alias + resolution` 查 active 规则,优先 exact resolution,再回退到空 resolution 默认价;缺规则抛 `NoPricingRuleError(code="no_pricing_rule")`。默认别名唯一性由 model validation、admin 与导入器保证;MySQL 不支持通用 partial unique index,后续若要强制数据库层约束可在 T-401 评估触发器或约束表。
|
||||
|
||||
> 可选增强(接口预留、MVP 不实现):`account_alias_permission`(按账号授权可用别名,防止调用方点用未授权/昂贵模型);别名按比例分流到多个模型(灰度/AB/故障转移)。适配器接口需为此留口子。
|
||||
|
||||
@@ -238,7 +253,7 @@ CREATE TABLE call_record (
|
||||
|
||||
需要说明:
|
||||
|
||||
- 主键自增;`api_key.key_hash`、`recharge_order.order_no`、`user.username` 唯一。
|
||||
- 主键自增;`api_key.key_hash`、`pricing_rule(operation_type, alias, resolution)`、`recharge_order.order_no`、`user.username` 唯一。
|
||||
- 重要索引:`call_record(user_id, created_at)`、`points_ledger(user_id, created_at)`、`recharge_order(order_no)`、`api_key(key_hash)`。
|
||||
- 不软删除业务流水;用户/账号可标记 `disabled` 而非物理删;API Key 用 `revoked` 状态而非物理删。
|
||||
- 服务端生成字段:`api_key.key_hash`/`key_prefix`、`points_balance`、`balance_after`、各 `created_at` / `updated_at`。
|
||||
|
||||
Reference in New Issue
Block a user