# 设计文档：修改拉取行内流水接口返回值

**日期：** 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 分钟
