2026-03-13 15:13:18 +08:00
|
|
|
|
"""
|
|
|
|
|
|
流水分析Mock服务器 - 主应用入口
|
|
|
|
|
|
|
|
|
|
|
|
基于 FastAPI 实现的 Mock 服务器,用于模拟流水分析平台的 7 个核心接口
|
|
|
|
|
|
"""
|
2026-03-22 12:59:12 +08:00
|
|
|
|
import argparse
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
2026-03-13 15:13:18 +08:00
|
|
|
|
from fastapi import FastAPI
|
2026-03-23 15:21:51 +08:00
|
|
|
|
from routers import api, credit_api
|
2026-03-13 15:13:18 +08:00
|
|
|
|
from config.settings import settings
|
|
|
|
|
|
|
|
|
|
|
|
# 创建 FastAPI 应用实例
|
|
|
|
|
|
app = FastAPI(
|
|
|
|
|
|
title=settings.APP_NAME,
|
|
|
|
|
|
description="""
|
|
|
|
|
|
## 流水分析 Mock 服务器
|
|
|
|
|
|
|
2026-03-23 15:21:51 +08:00
|
|
|
|
模拟流水分析平台的 7 个核心接口,并补充征信解析接口,用于开发和测试。
|
2026-03-13 15:13:18 +08:00
|
|
|
|
|
|
|
|
|
|
### 主要功能
|
|
|
|
|
|
|
|
|
|
|
|
- **Token管理** - 创建项目并获取访问Token
|
|
|
|
|
|
- **文件上传** - 上传流水文件,支持异步解析(4秒延迟)
|
|
|
|
|
|
- **行内流水** - 拉取行内流水数据
|
|
|
|
|
|
- **解析状态** - 轮询检查文件解析状态
|
|
|
|
|
|
- **文件删除** - 批量删除上传的文件
|
|
|
|
|
|
- **流水查询** - 分页获取银行流水数据
|
2026-03-23 15:21:51 +08:00
|
|
|
|
- **征信解析** - 上传 HTML 并返回结构化征信 payload
|
2026-03-13 15:13:18 +08:00
|
|
|
|
|
|
|
|
|
|
### 错误模拟
|
|
|
|
|
|
|
|
|
|
|
|
在请求参数中包含 `error_XXXX` 标记可触发对应的错误响应。
|
|
|
|
|
|
|
|
|
|
|
|
例如:`projectNo: "test_error_40101"` 将返回 40101 错误。
|
|
|
|
|
|
|
|
|
|
|
|
### 使用方式
|
|
|
|
|
|
|
|
|
|
|
|
1. 获取Token: POST /account/common/getToken
|
|
|
|
|
|
2. 上传文件: POST /watson/api/project/remoteUploadSplitFile
|
|
|
|
|
|
3. 轮询解析状态: POST /watson/api/project/upload/getpendings
|
|
|
|
|
|
4. 获取流水: POST /watson/api/project/getBSByLogId
|
2026-03-23 15:21:51 +08:00
|
|
|
|
5. 征信解析: POST /xfeature-mngs/conversation/htmlEval
|
2026-03-13 15:13:18 +08:00
|
|
|
|
""",
|
|
|
|
|
|
version=settings.APP_VERSION,
|
|
|
|
|
|
docs_url="/docs",
|
|
|
|
|
|
redoc_url="/redoc",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# 包含 API 路由
|
|
|
|
|
|
app.include_router(api.router, tags=["流水分析接口"])
|
2026-03-23 15:21:51 +08:00
|
|
|
|
app.include_router(credit_api.router, tags=["征信解析接口"])
|
2026-03-13 15:13:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/", summary="服务根路径")
|
|
|
|
|
|
async def root():
|
|
|
|
|
|
"""服务根路径,返回基本信息"""
|
|
|
|
|
|
return {
|
|
|
|
|
|
"service": settings.APP_NAME,
|
|
|
|
|
|
"version": settings.APP_VERSION,
|
|
|
|
|
|
"swagger_docs": "/docs",
|
|
|
|
|
|
"redoc": "/redoc",
|
|
|
|
|
|
"status": "running",
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.get("/health", summary="健康检查")
|
|
|
|
|
|
async def health_check():
|
|
|
|
|
|
"""健康检查端点"""
|
|
|
|
|
|
return {
|
|
|
|
|
|
"status": "healthy",
|
|
|
|
|
|
"service": settings.APP_NAME,
|
|
|
|
|
|
"version": settings.APP_VERSION,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-22 12:59:12 +08:00
|
|
|
|
def parse_args(argv=None):
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
|
|
parser.add_argument("--rule-hit-mode", choices=["subset", "all"], default="subset")
|
|
|
|
|
|
return parser.parse_args(argv)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def apply_rule_hit_mode(rule_hit_mode: str) -> None:
|
|
|
|
|
|
os.environ["RULE_HIT_MODE"] = rule_hit_mode
|
|
|
|
|
|
settings.RULE_HIT_MODE = rule_hit_mode
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-13 15:13:18 +08:00
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
import uvicorn
|
|
|
|
|
|
|
2026-03-22 12:59:12 +08:00
|
|
|
|
args = parse_args()
|
|
|
|
|
|
apply_rule_hit_mode(args.rule_hit_mode)
|
|
|
|
|
|
|
2026-03-13 15:13:18 +08:00
|
|
|
|
# 启动服务器
|
|
|
|
|
|
uvicorn.run(
|
|
|
|
|
|
app,
|
|
|
|
|
|
host=settings.HOST,
|
|
|
|
|
|
port=settings.PORT,
|
|
|
|
|
|
log_level="debug" if settings.DEBUG else "info",
|
|
|
|
|
|
)
|