feat: 新增客户自助查询 API (v1/available)
- wwwroot/api/v1/available.dspy: Bearer 认证,支持 product_type/product_name/request_amount 过滤 - init.py: get_available_vouchers_api 返回含 template_name 的完整数据 - README: 完善 API 文档,移除 dapi 依赖说明 - load_path.py: 注册 v1 端点权限
This commit is contained in:
parent
2c56aa904a
commit
2b9942f356
56
README.md
56
README.md
@ -108,21 +108,55 @@ accounting.record_order(order_id, total_amount,
|
|||||||
balance_deducted=result['remaining'])
|
balance_deducted=result['remaining'])
|
||||||
```
|
```
|
||||||
|
|
||||||
### dapi 模块(客户自助查询)
|
### 客户自助查询 API(voucher 模块提供)
|
||||||
|
|
||||||
```python
|
voucher 模块自身提供面向远端客户的查询 API,无需通过 dapi 转发。
|
||||||
# 客户通过 API 查询自己的可用代金券
|
|
||||||
# dapi 端点调用 voucher 引擎
|
**接口**: `GET /voucher/api/v1/available.dspy`
|
||||||
available = get_available_vouchers(sor, customer_id)
|
**认证**: Bearer Token(登录后用户)
|
||||||
|
**参数**:
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| product_type | string | 否 | 产品类型过滤(llm/image/video/audio) |
|
||||||
|
| product_name | string | 否 | 具体产品名过滤(如 gpt-4) |
|
||||||
|
| request_amount | float | 否 | 预期消费金额(用于规则预校验) |
|
||||||
|
|
||||||
|
**返回**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "xxx",
|
||||||
|
"code": "VCH-A1B2C3D4E5F6",
|
||||||
|
"face_value": 50.00,
|
||||||
|
"valid_from": "2026-01-01 00:00:00",
|
||||||
|
"valid_to": "2026-01-31 00:00:00",
|
||||||
|
"template_name": "新用户满减券"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 1
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**调用示例**:
|
||||||
|
```bash
|
||||||
|
# 查询所有可用券
|
||||||
|
curl -H "Authorization: Bearer <token>" \
|
||||||
|
https://ai.atvoe.com/voucher/api/v1/available.dspy
|
||||||
|
|
||||||
|
# 按产品类型过滤
|
||||||
|
curl -H "Authorization: Bearer <token>" \
|
||||||
|
"https://ai.atvoe.com/voucher/api/v1/available.dspy?product_type=llm&request_amount=100"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 集成点总结
|
### 集成点总结
|
||||||
|
|
||||||
| 调用方 | 场景 | 调用函数 |
|
| 调用方 | 场景 | 调用方式 |
|
||||||
|--------|------|----------|
|
|--------|------|----------|
|
||||||
| llmage | 推理/生成时抵扣 | `apply_voucher()` |
|
| llmage | 推理/生成时抵扣 | `apply_voucher()` 函数调用 |
|
||||||
| accounting | 月度账单结算 | `batch_apply_vouchers()` |
|
| accounting | 月度账单结算 | `batch_apply_vouchers()` 函数调用 |
|
||||||
| dapi | 客户查询可用券 | `get_available_vouchers()` |
|
| 远端客户 | 自助查询可用券 | `GET /voucher/api/v1/available.dspy` HTTP API |
|
||||||
| 任意模块 | 新增规则类型 | `@register_rule` + 模板管理界面 |
|
| 任意模块 | 新增规则类型 | `@register_rule` + 模板管理界面 |
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -146,8 +180,10 @@ voucher/
|
|||||||
│ ├── rule/ # 规则 CRUD
|
│ ├── rule/ # 规则 CRUD
|
||||||
│ ├── instance/ # 实例 CRUD
|
│ ├── instance/ # 实例 CRUD
|
||||||
│ ├── usage/ # 流水 CRUD
|
│ ├── usage/ # 流水 CRUD
|
||||||
|
│ ├── v1/ # 客户自助查询 API
|
||||||
|
│ │ └── available.dspy # 查询可用券(Bearer 认证)
|
||||||
│ ├── apply_voucher.dspy # 使用代金券
|
│ ├── apply_voucher.dspy # 使用代金券
|
||||||
│ ├── get_available.dspy # 查询可用券
|
│ ├── get_available.dspy # 内部查询可用券
|
||||||
│ └── rule_types.dspy # 获取规则类型列表
|
│ └── rule_types.dspy # 获取规则类型列表
|
||||||
├── models/ # 表定义 JSON
|
├── models/ # 表定义 JSON
|
||||||
├── json/ # CRUD 定义 JSON
|
├── json/ # CRUD 定义 JSON
|
||||||
|
|||||||
@ -58,6 +58,7 @@ def main():
|
|||||||
"/voucher/api/usage/voucher_usage_log_create.dspy",
|
"/voucher/api/usage/voucher_usage_log_create.dspy",
|
||||||
"/voucher/api/usage/voucher_usage_log_update.dspy",
|
"/voucher/api/usage/voucher_usage_log_update.dspy",
|
||||||
"/voucher/api/usage/voucher_usage_log_delete.dspy",
|
"/voucher/api/usage/voucher_usage_log_delete.dspy",
|
||||||
|
"/voucher/api/v1/available.dspy",
|
||||||
"/voucher/api/apply_voucher.dspy",
|
"/voucher/api/apply_voucher.dspy",
|
||||||
"/voucher/api/get_available.dspy",
|
"/voucher/api/get_available.dspy",
|
||||||
"/voucher/api/rule_types.dspy",
|
"/voucher/api/rule_types.dspy",
|
||||||
|
|||||||
@ -171,16 +171,27 @@ async def apply_voucher_api(customer_id, order_id, voucher_ids, context):
|
|||||||
|
|
||||||
|
|
||||||
async def get_available_vouchers_api(customer_id, context=None):
|
async def get_available_vouchers_api(customer_id, context=None):
|
||||||
"""外部调用:查询可用代金券"""
|
"""外部调用:查询可用代金券(含模板名称)"""
|
||||||
from voucher.rules.engine import get_available_vouchers
|
from voucher.rules.engine import get_available_vouchers
|
||||||
sor = DBPools().sqlorContext(_get_dbname())
|
sor = DBPools().sqlorContext(_get_dbname())
|
||||||
vouchers = get_available_vouchers(sor, customer_id, context)
|
vouchers = get_available_vouchers(sor, customer_id, context)
|
||||||
|
# 预加载模板名称
|
||||||
|
template_names = {}
|
||||||
|
for v in vouchers:
|
||||||
|
tid = v.template_id if hasattr(v, 'template_id') else v.get('template_id', '')
|
||||||
|
if tid and tid not in template_names:
|
||||||
|
t = sor.R('voucher_template', {'id': tid}).first()
|
||||||
|
if t:
|
||||||
|
template_names[tid] = t.name if hasattr(t, 'name') else t.get('name', '')
|
||||||
items = []
|
items = []
|
||||||
for v in vouchers:
|
for v in vouchers:
|
||||||
if hasattr(v, '__dict__'):
|
if hasattr(v, '__dict__'):
|
||||||
items.append(v.__dict__)
|
item = v.__dict__
|
||||||
else:
|
else:
|
||||||
items.append(v)
|
item = dict(v)
|
||||||
|
tid = item.get('template_id', '')
|
||||||
|
item['template_name'] = template_names.get(tid, '')
|
||||||
|
items.append(item)
|
||||||
return {'status': 'success', 'data': items}
|
return {'status': 'success', 'data': items}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
39
wwwroot/api/v1/available.dspy
Normal file
39
wwwroot/api/v1/available.dspy
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
# 获取当前登录用户的组织ID作为客户ID
|
||||||
|
customer_id = await get_userorgid()
|
||||||
|
|
||||||
|
# 构建查询上下文(可选过滤条件)
|
||||||
|
context = {}
|
||||||
|
if params_kw.get('product_type'):
|
||||||
|
context['product_type'] = params_kw.get('product_type')
|
||||||
|
if params_kw.get('product_name'):
|
||||||
|
context['product_name'] = params_kw.get('product_name')
|
||||||
|
if params_kw.get('request_amount'):
|
||||||
|
try:
|
||||||
|
context['request_amount'] = float(params_kw.get('request_amount'))
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 查询可用代金券
|
||||||
|
result = await get_available_vouchers_api(customer_id, context if context else None)
|
||||||
|
|
||||||
|
# 格式化输出
|
||||||
|
if result.get('status') == 'success':
|
||||||
|
vouchers = []
|
||||||
|
for v in result.get('data', []):
|
||||||
|
vouchers.append({
|
||||||
|
'id': v.get('id'),
|
||||||
|
'code': v.get('code'),
|
||||||
|
'face_value': float(v.get('face_value', 0)),
|
||||||
|
'valid_from': str(v.get('valid_from', '')),
|
||||||
|
'valid_to': str(v.get('valid_to', '')),
|
||||||
|
'template_name': v.get('template_name', ''),
|
||||||
|
})
|
||||||
|
return json.dumps({
|
||||||
|
'status': 'success',
|
||||||
|
'data': vouchers,
|
||||||
|
'total': len(vouchers)
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return json.dumps(result)
|
||||||
Loading…
x
Reference in New Issue
Block a user