1
0
forked from erp-dev/erp

feat: settlement first api beta

This commit is contained in:
2026-02-27 18:26:12 +08:00
parent c564b1af32
commit 86f5dab32b
16 changed files with 1854 additions and 10 deletions

203
docs/settlement/API.md Normal file
View File

@@ -0,0 +1,203 @@
# Settlement API 设计文档
## 概述
本文档描述 settlement 模块的 API 设计,遵循项目 API 规范。
## API 列表
### 1. 开版订单统计 API
获取按客户分组的开版订单统计。
**基本信息**:
- **URL**: `/api/v1/settlement/plate-orders/summary/`
- **方法**: GET
- **认证**: 需要认证
- **权限**: 需要关联商户
**请求参数**:
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| date | string | 是 | 统计日期,格式 YYYY-MM-DD | 2026-02-08 |
**请求示例**:
```http
GET /api/v1/settlement/plate-orders/summary/?date=2026-02-08 HTTP/1.1
Authorization: Bearer <token>
```
**响应示例**:
```json
{
"data": [
{
"client_id": 101,
"client_name": "客户A",
"plate_order_count": [
{
"type": "首版-定位",
"today": 26,
"current_month": 45
},
{
"type": "修改-定位",
"today": 3,
"current_month": 7
},
{
"type": "首版-匹布",
"today": 3,
"current_month": 7
}
]
},
{
"client_id": 102,
"client_name": "客户B",
"plate_order_count": [
{
"type": "首版-定位",
"today": 10,
"current_month": 20
}
]
}
]
}
```
**响应字段说明**:
| 字段名 | 类型 | 说明 |
|--------|------|------|
| data | array | 客户统计列表 |
| data[].client_id | integer | 客户ID |
| data[].client_name | string | 客户名称 |
| data[].plate_order_count | array | 订单统计列表 |
| data[].plate_order_count[].type | string | 类型组合plate_type-production_method |
| data[].plate_order_count[].today | integer | 今日数量 |
| data[].plate_order_count[].current_month | integer | 本月累计数量 |
**业务规则**:
1. **商户隔离**: 只返回当前用户所属商户的数据
2. **客户可见性**: 应用客户可见性过滤
3. **过滤条件**:
- `plate_type` 不为空的订单才纳入统计
- `production_method` 不为空的订单才纳入统计
4. **统计维度**: 按 `customer_id``customer_name``plate_type``production_method` 分组(同名客户不会被合并)
5. **today**: 指定日期当天的订单数量(基于 plate_date 字段)
6. **current_month**: 从当月1日到指定日期的订单数量
7. **数据过滤**:
- 不返回没有数据的客户
- 客户中不显示全0数据的类型组合
**type 组合规则**:
- 格式: `{plate_type}-{production_method}`
- plate_type 可能的值: `首版``修改`
- production_method 可能的值: `定位``匹布`
- 组合示例: `首版-定位``首版-匹布``修改-定位``修改-匹布`
**错误响应**:
**400 Bad Request** - 缺少日期参数:
```json
{
"error": "缺少 date 参数"
}
```
**400 Bad Request** - 日期格式错误:
```json
{
"error": "日期格式错误,请使用 YYYY-MM-DD 格式"
}
```
**403 Forbidden** - 用户未关联商户:
```json
{
"error": "用户未关联商户"
}
```
**403 Forbidden** - 日期不存在:
```json
{
"error": "日期不存在"
}
```
---
## 实现细节
### View 层
- **文件**: `api_v1/views/settlement/views.py`
- **类**: `PlateOrderSummaryView`
- **继承**: `APIView`
- **职责**:
- 参数验证
- 商户隔离
- 调用 service 层
- 错误处理
### Service 层
- **文件**: `settlement/services.py`
- **函数**: `get_plate_order_summary_by_customer`
- **职责**:
- 复杂的统计逻辑
- 数据查询和聚合
- 数据格式化
### URL 配置
- **文件**: `api_v1/urls.py`
- **路由**: 添加到 settlement 路由组
---
## 测试用例
### 1. 正常情况
- 请求有效日期,返回正确数据
- 验证商户隔离
- 验证客户可见性过滤
- 验证 today 和 current_month 计算正确
### 2. 边界情况
- 请求当月第一天current_month = today
- 请求跨月日期
- 客户没有数据(不返回该客户)
- 类型组合全0不返回该类型
### 3. 错误情况
- 日期格式错误
- 日期不存在(如 2026-02-30
- 用户未关联商户
### 4. 数据过滤
- plate_type 为空的订单不纳入统计
- production_method 为空的订单不纳入统计
---
## 性能考虑
1. **查询优化**: 使用 Django ORM 的 `annotate` 和聚合函数,避免 N+1 查询
2. **条件聚合**: 使用 `Case`/`When` 一次查询获取 today 和 current_month
3. **索引优化**: 确保 `plate_date``customer``plate_type``production_method` 字段有索引
4. **分页**: 暂不需要分页(数据量不大)
### 数据库优化评估记录PostgreSQL
1. 已评估索引、视图、物化视图等数据库层优化路线
2. 当前阶段暂不实施数据库结构优化,以保持线上稳定性
3. 生产环境不可接受阻塞风险:后续若加索引必须使用 `CREATE INDEX CONCURRENTLY`,并采用低峰分批策略
4. 优化上线前必须完成预发压测与 `EXPLAIN ANALYZE` 对比
---
## 后续扩展
1. 支持日期范围查询start_date, end_date
2. 支持按商户过滤(管理员功能)
3. 支持导出 Excel
4. 支持缓存Redis