feat: 修复接口参数并改为form-data格式
- 添加缺失的认证参数:appId, appSecretCode, role - 修复 analysisType 和 departmentCode 参数 - 将所有接口改为使用 Form 参数(form-data 格式) - 更新服务层支持字典参数 - 更新所有测试代码 - 所有测试通过(7/7)
This commit is contained in:
@@ -51,7 +51,11 @@ response = requests.post(
|
||||
"entityName": "测试企业",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"orgCode": "902000"
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000"
|
||||
}
|
||||
)
|
||||
token_data = response.json()
|
||||
@@ -102,7 +106,11 @@ response = requests.post(
|
||||
"entityName": "测试企业",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"orgCode": "902000"
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000"
|
||||
}
|
||||
)
|
||||
# 返回: {"code": "40101", "message": "appId错误", ...}
|
||||
|
||||
@@ -8,14 +8,17 @@ class GetTokenRequest(BaseModel):
|
||||
entityName: str = Field(..., description="项目名称")
|
||||
userId: str = Field(..., description="操作人员编号,固定值")
|
||||
userName: str = Field(..., description="操作人员姓名,固定值")
|
||||
appId: str = Field("remote_app", description="应用ID,固定值")
|
||||
appSecretCode: str = Field(..., description="安全码,md5(projectNo + '_' + entityName + '_' + dXj6eHRmPv)")
|
||||
role: str = Field("VIEWER", description="角色,固定值")
|
||||
orgCode: str = Field(..., description="行社机构号,固定值")
|
||||
entityId: Optional[str] = Field(None, description="企业统信码或个人身份证号")
|
||||
xdRelatedPersons: Optional[str] = Field(None, description="信贷关联人信息")
|
||||
jzDataDateId: Optional[str] = Field("0", description="拉取指定日期推送过来的金综链流水")
|
||||
innerBSStartDateId: Optional[str] = Field("0", description="拉取行内流水开始日期")
|
||||
innerBSEndDateId: Optional[str] = Field("0", description="拉取行内流水结束日期")
|
||||
analysisType: Optional[int] = Field(-1, description="分析类型")
|
||||
departmentCode: Optional[str] = Field(None, description="客户经理所属营业部/分理处的机构编码")
|
||||
analysisType: str = Field("-1", description="分析类型,固定值")
|
||||
departmentCode: str = Field(..., description="客户经理所属营业部/分理处的机构编码")
|
||||
|
||||
|
||||
class FetchInnerFlowRequest(BaseModel):
|
||||
|
||||
Binary file not shown.
@@ -1,16 +1,9 @@
|
||||
from fastapi import APIRouter, BackgroundTasks, UploadFile, File, Form
|
||||
from models.request import (
|
||||
GetTokenRequest,
|
||||
FetchInnerFlowRequest,
|
||||
CheckParseStatusRequest,
|
||||
GetBankStatementRequest,
|
||||
DeleteFilesRequest,
|
||||
)
|
||||
from services.token_service import TokenService
|
||||
from services.file_service import FileService
|
||||
from services.statement_service import StatementService
|
||||
from utils.error_simulator import ErrorSimulator
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
# 创建路由器
|
||||
router = APIRouter()
|
||||
@@ -23,18 +16,53 @@ statement_service = StatementService()
|
||||
|
||||
# ==================== 接口1:获取Token ====================
|
||||
@router.post("/account/common/getToken")
|
||||
async def get_token(request: GetTokenRequest):
|
||||
async def get_token(
|
||||
projectNo: str = Form(..., description="项目编号,格式:902000_当前时间戳"),
|
||||
entityName: str = Form(..., description="项目名称"),
|
||||
userId: str = Form(..., description="操作人员编号,固定值"),
|
||||
userName: str = Form(..., description="操作人员姓名,固定值"),
|
||||
appId: str = Form("remote_app", description="应用ID,固定值"),
|
||||
appSecretCode: str = Form(..., description="安全码"),
|
||||
role: str = Form("VIEWER", description="角色,固定值"),
|
||||
orgCode: str = Form(..., description="行社机构号,固定值"),
|
||||
entityId: Optional[str] = Form(None, description="企业统信码或个人身份证号"),
|
||||
xdRelatedPersons: Optional[str] = Form(None, description="信贷关联人信息"),
|
||||
jzDataDateId: str = Form("0", description="拉取指定日期推送过来的金综链流水"),
|
||||
innerBSStartDateId: str = Form("0", description="拉取行内流水开始日期"),
|
||||
innerBSEndDateId: str = Form("0", description="拉取行内流水结束日期"),
|
||||
analysisType: str = Form("-1", description="分析类型,固定值"),
|
||||
departmentCode: str = Form(..., description="客户经理所属营业部/分理处的机构编码"),
|
||||
):
|
||||
"""创建项目并获取访问Token
|
||||
|
||||
如果 projectNo 包含 error_XXXX 标记,将返回对应的错误响应
|
||||
"""
|
||||
# 检测错误标记
|
||||
error_code = ErrorSimulator.detect_error_marker(request.projectNo)
|
||||
error_code = ErrorSimulator.detect_error_marker(projectNo)
|
||||
if error_code:
|
||||
return ErrorSimulator.build_error_response(error_code)
|
||||
|
||||
# 构建请求数据字典
|
||||
request_data = {
|
||||
"projectNo": projectNo,
|
||||
"entityName": entityName,
|
||||
"userId": userId,
|
||||
"userName": userName,
|
||||
"appId": appId,
|
||||
"appSecretCode": appSecretCode,
|
||||
"role": role,
|
||||
"orgCode": orgCode,
|
||||
"entityId": entityId,
|
||||
"xdRelatedPersons": xdRelatedPersons,
|
||||
"jzDataDateId": jzDataDateId,
|
||||
"innerBSStartDateId": innerBSStartDateId,
|
||||
"innerBSEndDateId": innerBSEndDateId,
|
||||
"analysisType": analysisType,
|
||||
"departmentCode": departmentCode,
|
||||
}
|
||||
|
||||
# 正常流程
|
||||
return token_service.create_token(request)
|
||||
return token_service.create_token(request_data)
|
||||
|
||||
|
||||
# ==================== 接口2:上传文件 ====================
|
||||
@@ -53,47 +81,85 @@ async def upload_file(
|
||||
|
||||
# ==================== 接口3:拉取行内流水 ====================
|
||||
@router.post("/watson/api/project/getJZFileOrZjrcuFile")
|
||||
async def fetch_inner_flow(request: FetchInnerFlowRequest):
|
||||
async def fetch_inner_flow(
|
||||
groupId: int = Form(..., description="项目id"),
|
||||
customerNo: str = Form(..., description="客户身份证号"),
|
||||
dataChannelCode: str = Form(..., description="校验码"),
|
||||
requestDateId: int = Form(..., description="发起请求的时间"),
|
||||
dataStartDateId: int = Form(..., description="拉取开始日期"),
|
||||
dataEndDateId: int = Form(..., description="拉取结束日期"),
|
||||
uploadUserId: int = Form(..., description="柜员号"),
|
||||
):
|
||||
"""拉取行内流水
|
||||
|
||||
如果 customerNo 包含 error_XXXX 标记,将返回对应的错误响应
|
||||
"""
|
||||
# 检测错误标记
|
||||
error_code = ErrorSimulator.detect_error_marker(request.customerNo)
|
||||
error_code = ErrorSimulator.detect_error_marker(customerNo)
|
||||
if error_code:
|
||||
return ErrorSimulator.build_error_response(error_code)
|
||||
|
||||
# 构建请求字典
|
||||
request_data = {
|
||||
"groupId": groupId,
|
||||
"customerNo": customerNo,
|
||||
"dataChannelCode": dataChannelCode,
|
||||
"requestDateId": requestDateId,
|
||||
"dataStartDateId": dataStartDateId,
|
||||
"dataEndDateId": dataEndDateId,
|
||||
"uploadUserId": uploadUserId,
|
||||
}
|
||||
|
||||
# 正常流程
|
||||
return file_service.fetch_inner_flow(request)
|
||||
return file_service.fetch_inner_flow(request_data)
|
||||
|
||||
|
||||
# ==================== 接口4:检查文件解析状态 ====================
|
||||
@router.post("/watson/api/project/upload/getpendings")
|
||||
async def check_parse_status(request: CheckParseStatusRequest):
|
||||
async def check_parse_status(
|
||||
groupId: int = Form(..., description="项目id"),
|
||||
inprogressList: str = Form(..., description="文件id列表,逗号分隔"),
|
||||
):
|
||||
"""检查文件解析状态
|
||||
|
||||
返回文件是否还在解析中(parsing字段)
|
||||
"""
|
||||
return file_service.check_parse_status(
|
||||
request.groupId, request.inprogressList
|
||||
)
|
||||
return file_service.check_parse_status(groupId, inprogressList)
|
||||
|
||||
|
||||
# ==================== 接口5:删除文件 ====================
|
||||
@router.post("/watson/api/project/batchDeleteUploadFile")
|
||||
async def delete_files(request: DeleteFilesRequest):
|
||||
async def delete_files(
|
||||
groupId: int = Form(..., description="项目id"),
|
||||
logIds: str = Form(..., description="文件id数组,逗号分隔,如: 10001,10002"),
|
||||
userId: int = Form(..., description="用户柜员号"),
|
||||
):
|
||||
"""批量删除上传的文件
|
||||
|
||||
根据logIds列表删除对应的文件记录
|
||||
"""
|
||||
return file_service.delete_files(request.groupId, request.logIds, request.userId)
|
||||
# 将逗号分隔的字符串转换为整数列表
|
||||
log_id_list = [int(id.strip()) for id in logIds.split(",")]
|
||||
return file_service.delete_files(groupId, log_id_list, userId)
|
||||
|
||||
|
||||
# ==================== 接口6:获取银行流水 ====================
|
||||
@router.post("/watson/api/project/getBSByLogId")
|
||||
async def get_bank_statement(request: GetBankStatementRequest):
|
||||
async def get_bank_statement(
|
||||
groupId: int = Form(..., description="项目id"),
|
||||
logId: int = Form(..., description="文件id"),
|
||||
pageNow: int = Form(..., description="当前页码"),
|
||||
pageSize: int = Form(..., description="查询条数"),
|
||||
):
|
||||
"""获取银行流水列表
|
||||
|
||||
支持分页查询(pageNow, pageSize)
|
||||
"""
|
||||
return statement_service.get_bank_statement(request)
|
||||
# 构建请求字典
|
||||
request_data = {
|
||||
"groupId": groupId,
|
||||
"logId": logId,
|
||||
"pageNow": pageNow,
|
||||
"pageSize": pageSize,
|
||||
}
|
||||
return statement_service.get_bank_statement(request_data)
|
||||
|
||||
Binary file not shown.
@@ -1,8 +1,7 @@
|
||||
from fastapi import BackgroundTasks, UploadFile
|
||||
from models.request import FetchInnerFlowRequest
|
||||
from utils.response_builder import ResponseBuilder
|
||||
from config.settings import settings
|
||||
from typing import Dict, List
|
||||
from typing import Dict, List, Union
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
@@ -133,11 +132,11 @@ class FileService:
|
||||
"successResponse": True,
|
||||
}
|
||||
|
||||
def fetch_inner_flow(self, request: FetchInnerFlowRequest) -> Dict:
|
||||
def fetch_inner_flow(self, request: Union[Dict, object]) -> Dict:
|
||||
"""拉取行内流水(模拟无数据场景)
|
||||
|
||||
Args:
|
||||
request: 拉取流水请求
|
||||
request: 拉取流水请求(可以是字典或对象)
|
||||
|
||||
Returns:
|
||||
流水响应字典
|
||||
|
||||
@@ -1,28 +1,35 @@
|
||||
from models.request import GetBankStatementRequest
|
||||
from utils.response_builder import ResponseBuilder
|
||||
from typing import Dict
|
||||
from typing import Dict, Union
|
||||
|
||||
|
||||
class StatementService:
|
||||
"""流水数据服务"""
|
||||
|
||||
def get_bank_statement(self, request: GetBankStatementRequest) -> Dict:
|
||||
def get_bank_statement(self, request: Union[Dict, object]) -> Dict:
|
||||
"""获取银行流水列表
|
||||
|
||||
Args:
|
||||
request: 获取银行流水请求
|
||||
request: 获取银行流水请求(可以是字典或对象)
|
||||
|
||||
Returns:
|
||||
银行流水响应字典
|
||||
"""
|
||||
# 支持 dict 或对象
|
||||
if isinstance(request, dict):
|
||||
page_now = request.get("pageNow", 1)
|
||||
page_size = request.get("pageSize", 10)
|
||||
else:
|
||||
page_now = request.pageNow
|
||||
page_size = request.pageSize
|
||||
|
||||
# 加载模板
|
||||
template = ResponseBuilder.load_template("bank_statement")
|
||||
statements = template["success_response"]["data"]["bankStatementList"]
|
||||
total_count = len(statements)
|
||||
|
||||
# 模拟分页
|
||||
start = (request.pageNow - 1) * request.pageSize
|
||||
end = start + request.pageSize
|
||||
start = (page_now - 1) * page_size
|
||||
end = start + page_size
|
||||
page_data = statements[start:end]
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from models.request import GetTokenRequest
|
||||
from utils.response_builder import ResponseBuilder
|
||||
from config.settings import settings
|
||||
from typing import Dict
|
||||
from typing import Dict, Union
|
||||
|
||||
|
||||
class TokenService:
|
||||
@@ -11,15 +11,23 @@ class TokenService:
|
||||
self.project_counter = settings.INITIAL_PROJECT_ID
|
||||
self.tokens = {} # projectId -> token_data
|
||||
|
||||
def create_token(self, request: GetTokenRequest) -> Dict:
|
||||
def create_token(self, request: Union[GetTokenRequest, Dict]) -> Dict:
|
||||
"""创建Token
|
||||
|
||||
Args:
|
||||
request: 获取Token请求
|
||||
request: 获取Token请求(可以是 GetTokenRequest 对象或字典)
|
||||
|
||||
Returns:
|
||||
Token响应字典
|
||||
"""
|
||||
# 支持 dict 或 GetTokenRequest 对象
|
||||
if isinstance(request, dict):
|
||||
project_no = request.get("projectNo")
|
||||
entity_name = request.get("entityName")
|
||||
else:
|
||||
project_no = request.projectNo
|
||||
entity_name = request.entityName
|
||||
|
||||
# 生成唯一项目ID
|
||||
self.project_counter += 1
|
||||
project_id = self.project_counter
|
||||
@@ -28,8 +36,8 @@ class TokenService:
|
||||
response = ResponseBuilder.build_success_response(
|
||||
"token",
|
||||
project_id=project_id,
|
||||
project_no=request.projectNo,
|
||||
entity_name=request.entityName
|
||||
project_no=project_no,
|
||||
entity_name=entity_name
|
||||
)
|
||||
|
||||
# 存储token信息
|
||||
|
||||
@@ -20,11 +20,15 @@ def client():
|
||||
|
||||
@pytest.fixture
|
||||
def sample_token_request():
|
||||
"""示例 Token 请求"""
|
||||
"""示例 Token 请求 - 返回 form-data 格式的数据"""
|
||||
return {
|
||||
"projectNo": "test_project_001",
|
||||
"entityName": "测试企业",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000",
|
||||
}
|
||||
|
||||
@@ -10,12 +10,16 @@ def test_complete_workflow(client):
|
||||
# 1. 获取 Token
|
||||
response = client.post(
|
||||
"/account/common/getToken",
|
||||
json={
|
||||
data={
|
||||
"projectNo": "integration_test_001",
|
||||
"entityName": "集成测试企业",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -31,7 +35,7 @@ def test_complete_workflow(client):
|
||||
# 3. 检查解析状态
|
||||
response = client.post(
|
||||
"/watson/api/project/upload/getpendings",
|
||||
json={"groupId": project_id, "inprogressList": "10001"},
|
||||
data={"groupId": project_id, "inprogressList": "10001"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
status_data = response.json()
|
||||
@@ -40,7 +44,7 @@ def test_complete_workflow(client):
|
||||
# 4. 获取银行流水
|
||||
response = client.post(
|
||||
"/watson/api/project/getBSByLogId",
|
||||
json={
|
||||
data={
|
||||
"groupId": project_id,
|
||||
"logId": 10001,
|
||||
"pageNow": 1,
|
||||
@@ -61,12 +65,16 @@ def test_all_error_codes(client):
|
||||
for error_code in error_codes:
|
||||
response = client.post(
|
||||
"/account/common/getToken",
|
||||
json={
|
||||
data={
|
||||
"projectNo": f"test_error_{error_code}",
|
||||
"entityName": "测试企业",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -80,12 +88,16 @@ def test_pagination(client):
|
||||
# 获取 Token
|
||||
response = client.post(
|
||||
"/account/common/getToken",
|
||||
json={
|
||||
data={
|
||||
"projectNo": "pagination_test",
|
||||
"entityName": "分页测试",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000",
|
||||
},
|
||||
)
|
||||
project_id = response.json()["data"]["projectId"]
|
||||
@@ -93,14 +105,14 @@ def test_pagination(client):
|
||||
# 测试第一页
|
||||
response = client.post(
|
||||
"/watson/api/project/getBSByLogId",
|
||||
json={"groupId": project_id, "logId": 10001, "pageNow": 1, "pageSize": 1},
|
||||
data={"groupId": project_id, "logId": 10001, "pageNow": 1, "pageSize": 1},
|
||||
)
|
||||
page1 = response.json()
|
||||
|
||||
# 测试第二页
|
||||
response = client.post(
|
||||
"/watson/api/project/getBSByLogId",
|
||||
json={"groupId": project_id, "logId": 10001, "pageNow": 2, "pageSize": 1},
|
||||
data={"groupId": project_id, "logId": 10001, "pageNow": 2, "pageSize": 1},
|
||||
)
|
||||
page2 = response.json()
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ def test_health_check(client):
|
||||
|
||||
def test_get_token_success(client, sample_token_request):
|
||||
"""测试获取 Token - 成功场景"""
|
||||
response = client.post("/account/common/getToken", json=sample_token_request)
|
||||
response = client.post("/account/common/getToken", data=sample_token_request)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == "200"
|
||||
@@ -37,9 +37,13 @@ def test_get_token_error_40101(client):
|
||||
"entityName": "测试企业",
|
||||
"userId": "902001",
|
||||
"userName": "902001",
|
||||
"appId": "remote_app",
|
||||
"appSecretCode": "test_secret_code_12345",
|
||||
"role": "VIEWER",
|
||||
"orgCode": "902000",
|
||||
"departmentCode": "902000",
|
||||
}
|
||||
response = client.post("/account/common/getToken", json=request_data)
|
||||
response = client.post("/account/common/getToken", data=request_data)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == "40101"
|
||||
|
||||
Reference in New Issue
Block a user