222 lines
6.1 KiB
Markdown
222 lines
6.1 KiB
Markdown
|
|
# 设计文档:修改拉取行内流水接口返回值
|
|||
|
|
|
|||
|
|
**日期:** 2026-03-04
|
|||
|
|
**状态:** 已批准
|
|||
|
|
**作者:** Claude Code
|
|||
|
|
|
|||
|
|
## 1. 概述和目标
|
|||
|
|
|
|||
|
|
### 目标
|
|||
|
|
修改 `/watson/api/project/getJZFileOrZjrcuFile` 接口的返回格式,从当前的错误格式改为返回 logId 数组。
|
|||
|
|
|
|||
|
|
### 当前实现
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": "200",
|
|||
|
|
"data": {"code": "501014", "message": "无行内流水文件"},
|
|||
|
|
"status": "200",
|
|||
|
|
"successResponse": true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 修改后实现
|
|||
|
|
|
|||
|
|
**成功场景:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": "200",
|
|||
|
|
"data": [19154],
|
|||
|
|
"status": "200",
|
|||
|
|
"successResponse": true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**错误场景(通过 `error_501014` 标记触发):**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": "501014",
|
|||
|
|
"message": "无行内流水文件",
|
|||
|
|
"status": "501014",
|
|||
|
|
"successResponse": false
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 关键特性
|
|||
|
|
- logId 通过随机数生成(范围:10000-99999)
|
|||
|
|
- 独立简化管理,不存储到 `file_records`,不支持后续操作
|
|||
|
|
- 保留错误模拟功能(通过 `error_XXXX` 标记触发)
|
|||
|
|
|
|||
|
|
## 2. 技术实现
|
|||
|
|
|
|||
|
|
### 修改文件
|
|||
|
|
- `services/file_service.py` - 修改 `fetch_inner_flow()` 方法
|
|||
|
|
|
|||
|
|
### 具体实现
|
|||
|
|
|
|||
|
|
在 `FileService` 类中修改 `fetch_inner_flow()` 方法:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
def fetch_inner_flow(self, request: Union[Dict, object]) -> Dict:
|
|||
|
|
"""拉取行内流水(返回随机logId)
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
request: 拉取流水请求(可以是字典或对象)
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
流水响应字典,包含随机生成的logId数组
|
|||
|
|
"""
|
|||
|
|
import random
|
|||
|
|
|
|||
|
|
# 随机生成一个logId(范围:10000-99999)
|
|||
|
|
log_id = random.randint(10000, 99999)
|
|||
|
|
|
|||
|
|
# 返回成功的响应,包含logId数组
|
|||
|
|
return {
|
|||
|
|
"code": "200",
|
|||
|
|
"data": [log_id],
|
|||
|
|
"status": "200",
|
|||
|
|
"successResponse": True,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 关键变化
|
|||
|
|
1. 移除原来的"无行内流水文件"硬编码错误响应
|
|||
|
|
2. 使用 `random.randint(10000, 99999)` 生成随机 logId
|
|||
|
|
3. 返回格式改为 `{"code": "200", "data": [log_id], ...}`
|
|||
|
|
4. `import random` 放在方法内部,避免顶层导入(保持简单)
|
|||
|
|
|
|||
|
|
### 无需修改的部分
|
|||
|
|
- `routers/api.py` - 错误检测逻辑保持不变
|
|||
|
|
- `utils/error_simulator.py` - 错误码定义已包含 501014
|
|||
|
|
- `config/settings.py` - 无需新增配置
|
|||
|
|
|
|||
|
|
## 3. 测试计划
|
|||
|
|
|
|||
|
|
### 测试文件
|
|||
|
|
- `tests/test_api.py`
|
|||
|
|
|
|||
|
|
### 新增测试用例
|
|||
|
|
|
|||
|
|
#### 3.1 测试成功场景
|
|||
|
|
```python
|
|||
|
|
def test_fetch_inner_flow_success(client, sample_inner_flow_request):
|
|||
|
|
"""测试拉取行内流水 - 成功场景"""
|
|||
|
|
response = client.post(
|
|||
|
|
"/watson/api/project/getJZFileOrZjrcuFile",
|
|||
|
|
data=sample_inner_flow_request
|
|||
|
|
)
|
|||
|
|
assert response.status_code == 200
|
|||
|
|
data = response.json()
|
|||
|
|
assert data["code"] == "200"
|
|||
|
|
assert data["successResponse"] == True
|
|||
|
|
assert isinstance(data["data"], list)
|
|||
|
|
assert len(data["data"]) == 1
|
|||
|
|
assert isinstance(data["data"][0], int)
|
|||
|
|
assert 10000 <= data["data"][0] <= 99999
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3.2 测试错误场景
|
|||
|
|
```python
|
|||
|
|
def test_fetch_inner_flow_error_501014(client):
|
|||
|
|
"""测试拉取行内流水 - 错误场景 501014"""
|
|||
|
|
request_data = {
|
|||
|
|
"groupId": 1001,
|
|||
|
|
"customerNo": "test_error_501014",
|
|||
|
|
"dataChannelCode": "test_code",
|
|||
|
|
"requestDateId": 20240101,
|
|||
|
|
"dataStartDateId": 20240101,
|
|||
|
|
"dataEndDateId": 20240131,
|
|||
|
|
"uploadUserId": 902001,
|
|||
|
|
}
|
|||
|
|
response = client.post(
|
|||
|
|
"/watson/api/project/getJZFileOrZjrcuFile",
|
|||
|
|
data=request_data
|
|||
|
|
)
|
|||
|
|
assert response.status_code == 200
|
|||
|
|
data = response.json()
|
|||
|
|
assert data["code"] == "501014"
|
|||
|
|
assert data["successResponse"] == False
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 测试命令
|
|||
|
|
```bash
|
|||
|
|
# 运行所有行内流水相关测试
|
|||
|
|
pytest tests/test_api.py -k "fetch_inner_flow" -v
|
|||
|
|
|
|||
|
|
# 运行单个测试
|
|||
|
|
pytest tests/test_api.py::test_fetch_inner_flow_success -v
|
|||
|
|
pytest tests/test_api.py::test_fetch_inner_flow_error_501014 -v
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 4. 文档更新
|
|||
|
|
|
|||
|
|
### 4.1 README.md
|
|||
|
|
更新接口说明部分,将"模拟无数据场景"改为"返回随机logId"。
|
|||
|
|
|
|||
|
|
### 4.2 CLAUDE.md
|
|||
|
|
在架构设计部分补充说明行内流水接口的特殊性:
|
|||
|
|
- 简化管理(不存储到 file_records)
|
|||
|
|
- 随机 logId(无需持久化)
|
|||
|
|
- 无后续操作支持(无需解析状态检查)
|
|||
|
|
|
|||
|
|
## 5. 设计决策
|
|||
|
|
|
|||
|
|
### 为什么选择随机生成 logId?
|
|||
|
|
- **简化管理**:行内流水拉取是独立的简化流程,不需要与文件上传共用复杂的状态管理
|
|||
|
|
- **无需持久化**:logId 仅用于返回,不需要存储或后续查询
|
|||
|
|
- **测试友好**:每次调用返回不同的值,避免固定值导致的测试假阳性
|
|||
|
|
|
|||
|
|
### 为什么不使用配置文件?
|
|||
|
|
- 响应数据需要运行时动态生成(随机 logId)
|
|||
|
|
- 配置文件适合静态或模板化的响应,不适合需要随机值的场景
|
|||
|
|
- 保持代码简单直接,避免过度设计
|
|||
|
|
|
|||
|
|
### 为什么保留错误模拟?
|
|||
|
|
- Mock 服务器的核心功能之一是模拟各种场景
|
|||
|
|
- 501014 错误是真实的业务场景(无行内流水文件)
|
|||
|
|
- 通过 `error_XXXX` 标记触发错误,与项目整体设计一致
|
|||
|
|
|
|||
|
|
## 6. 影响范围
|
|||
|
|
|
|||
|
|
### 直接影响
|
|||
|
|
- `services/file_service.py` - 修改 1 个方法
|
|||
|
|
- `tests/test_api.py` - 新增/修改测试用例
|
|||
|
|
|
|||
|
|
### 间接影响
|
|||
|
|
- API 文档自动更新(FastAPI Swagger UI)
|
|||
|
|
- README.md 需要更新示例
|
|||
|
|
|
|||
|
|
### 无影响
|
|||
|
|
- 其他 6 个接口的返回格式
|
|||
|
|
- 错误模拟机制
|
|||
|
|
- 前端集成(假设前端已按新格式设计)
|
|||
|
|
|
|||
|
|
## 7. 风险和限制
|
|||
|
|
|
|||
|
|
### 风险
|
|||
|
|
- **logId 冲突**:理论上可能生成重复的 logId,但由于不存储,不会造成实际问题
|
|||
|
|
- **前端兼容性**:如果前端已按旧格式实现,需要协调更新
|
|||
|
|
|
|||
|
|
### 限制
|
|||
|
|
- 不支持后续的解析状态检查
|
|||
|
|
- 不支持通过 logId 查询流水数据
|
|||
|
|
- 不支持删除操作
|
|||
|
|
|
|||
|
|
这些限制是设计决策的一部分,符合"简化管理"的目标。
|
|||
|
|
|
|||
|
|
## 8. 验收标准
|
|||
|
|
|
|||
|
|
- [ ] 修改后接口返回正确的格式(包含 logId 数组)
|
|||
|
|
- [ ] logId 在指定范围内(10000-99999)
|
|||
|
|
- [ ] 错误模拟功能正常工作
|
|||
|
|
- [ ] 所有测试用例通过
|
|||
|
|
- [ ] 文档已更新
|
|||
|
|
- [ ] 代码通过 pytest 测试
|
|||
|
|
|
|||
|
|
## 9. 时间线
|
|||
|
|
|
|||
|
|
预计实施时间:30 分钟
|
|||
|
|
- 代码修改:10 分钟
|
|||
|
|
- 测试编写和验证:15 分钟
|
|||
|
|
- 文档更新:5 分钟
|