9.7 KiB
文档上传与列表 — 接口分析 & 接入方案
所有信息已逐文件验证。源代码位置均已标注。
一、后端接口(已验证)
1.1 POST /api/upload — 文档上传
源码: fastapi_modules/fastapi_leaudit/controllers/documentController.py:20-45
实现: fastapi_modules/fastapi_leaudit/services/impl/documentServiceImpl.py:44-246
URL: POST /api/upload
格式: multipart/form-data (扁平字段)
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
file |
UploadFile | 是 | — | 文件二进制 |
typeId |
int | typeId/typeCode 二选一 | None | 文档类型 ID |
typeCode |
str | typeId/typeCode 二选一 | None | 文档类型编码,如 contract.construction |
region |
str | 否 | "default" |
地区标识 |
fileRole |
str | 否 | "primary" |
文件角色:primary/attachment/template |
createdBy |
int | 否 | None | 上传用户 ID |
autoRun |
bool | 否 | false |
是否上传后自动触发评查 |
speed |
str | 否 | "normal" |
urgent / normal |
内部流程:
- 校验文件名/内容非空 → 解析文档类型(查
leaudit_document_types) - SHA-256 去重(仅 primary 文件):同名+同类型+同区域+同 hash → 复用已有记录,
duplicateUpload=true - 非重复:生成
internalDocumentNo,匹配前一版本,递增versionNo,写leaudit_documents - 存 MinIO OSS,路径
bdocs/{Region}/{TypeCode}/{Year}/... - 写
leaudit_document_files - 若
autoRun=true→ 调AuditService.Run()触发评查
响应 Result[DocumentUploadVO] (domian/vo/documentVo.py:8-27):
{
"code": 200,
"message": "ok",
"data": {
"documentId": 1,
"internalDocumentNo": 1712345678000000001,
"versionGroupKey": "abc123...",
"versionNo": 2,
"previousVersionId": 1,
"rootVersionId": 1,
"duplicateUpload": false,
"fileId": 5,
"typeId": 1,
"typeCode": "contract.construction",
"region": "meizhou",
"fileName": "建设工程合同.pdf",
"ossUrl": "http://minio/bdocs/...",
"speed": "normal",
"processingStatus": "waiting",
"autoRunTriggered": true,
"run": { "runId": 10, "status": "pending", ... }
}
}
1.2 GET /api/documents/list — 文档列表
源码: controllers/documentController.py:47-67
实现: documentServiceImpl.py:248-443
URL: GET /api/documents/list
格式: query params
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
page |
int | 否 (1) | 页码 |
pageSize |
int | 否 (20, max 100) | 每页条数 |
keyword |
str | 否 | 搜索文件名或归一化名 |
typeCode |
str | 否 | 文档类型编码过滤 |
region |
str | 否 | 地区过滤 |
processingStatus |
str | 否 | waiting/processing/completed/failed |
resultStatus |
str | 否 | pass/fail/partial/review/error |
内部流程:
leaudit_documents dJOINleaudit_document_files fONf.document_id = d.id- 条件:
d.is_latest_version=true,d.deleted_at IS NULL,f.is_active=true,f.file_role='primary' - LEFT JOIN
leaudit_document_types dt,leaudit_audit_runs ar - 子查询统计
total_versions(按version_group_key分组) - 批量加载历史版本(
is_latest_version=false的同组文档)
响应 Result[DocumentListPageVO] (domian/vo/documentVo.py:77-84):
{
"code": 200, "message": "ok",
"data": {
"total": 100, "page": 1, "pageSize": 20, "totalPages": 5,
"documents": [
{
"documentId": 1, "internalDocumentNo": 1712345678000000001,
"versionGroupKey": "abc123", "versionNo": 2,
"typeId": 1, "typeCode": "contract.construction",
"region": "meizhou", "normalizedName": "建设工程合同",
"fileId": 5, "fileName": "建设工程合同.pdf",
"fileExt": ".pdf", "mimeType": "application/pdf",
"fileSize": 1048576, "ossUrl": "http://minio/...",
"processingStatus": "completed",
"runStatus": "completed", "resultStatus": "pass",
"totalScore": 85, "passedCount": 10,
"failedCount": 2, "skippedCount": 0,
"hasHistory": true, "totalVersions": 2,
"historyVersions": [
{ "documentId": 1, "versionNo": 1, "fileName": "...", ... }
]
}
]
}
}
1.3 缺失的后端接口
| 操作 | 当前 | 需要 |
|---|---|---|
| 删除文档 | ❌ | DELETE /api/documents/{id} — 软删除 |
| 编辑元数据 | ❌ | PUT /api/documents/{id} — 更新备注、测试标记等 |
| 文档详情 | ❌ | GET /api/documents/{id} — 单文档查询 |
| 附件追加 | ❌ | POST /api/documents/{id}/attachments — fileRole=attachment |
二、前端调用现状(已验证)
2.1 上传 — uploadDocumentToServer()
源码: new_doc_review/app/api/files/files-upload.ts:374-443
URL: ${UPLOAD_URL}/upload (例: http://172.16.0.59:8096/upload)
格式: FormData { file: Blob, upload_info: JSON字符串 }
前端实际发送的 FormData:
file: Blob (文件二进制)
upload_info: '{"type_id":1,"evaluation_level":"normal","document_number":null,"remark":null,"is_test_document":false,"document_id":null,"is_reupload":false,"attribute_type":null}'
❌ 与后端完全不兼容。 后端期望扁平字段 typeId/typeCode/region/fileRole/autoRun/speed,不接受嵌套的 upload_info JSON。
2.2 附件追加 — appendContractAttachments()
源码: files-upload.ts:320-336
URL: ${UPLOAD_URL}/contracts/{documentId}/append_attachments
格式: FormData { attachments: File[] }
后端没有对应接口,需要补。
2.3 合同模板上传 — uploadContractTemplate()
源码: files-upload.ts:244-259
URL: ${UPLOAD_URL}/upload_contract_template
格式: FormData { file: Blob }
后端没有对应接口。
2.4 列表 — getDocumentsListFromAPI()
源码: new_doc_review/app/api/files/documents.ts:627-784
URL: ${API_BASE_URL}/api/documents/list ✅ 正确
✅ 列表已接入新后端,但存在两个问题:
- 字段映射层太厚:
LeauditListItem → DocumentUI转换 50+ 行,且把fileExt映射为fileType、ossUrl映射为path等 - 筛选项不全:
documentNumber、auditStatus、dateFrom/dateTo在后端列表接口未支持,前端写了void占位
2.5 删除 — deleteDocument()
源码: documents.ts:540-560
URL: /api/postgrest/proxy/documents?id=eq.{id}&user_id=eq.{userId}
方法: DELETE
❌ 走 PostgREST 直删,未接入新后端。
2.6 编辑 — updateDocument()
源码: documents.ts:485-510
URL: /api/postgrest/proxy/documents?id=eq.{id}
方法: PATCH
❌ 走 PostgREST,未接入新后端。
三、接入方案
第 1 步:上传接口对齐 ⭐ 最高优先级
前端改造 uploadDocumentToServer():
改前: FormData { file, upload_info: JSON.stringify({ type_id, evaluation_level, ... }) }
POST ${UPLOAD_URL}/upload
改后: FormData { file, typeId, typeCode, region, fileRole, createdBy, autoRun, speed }
POST ${API_BASE_URL}/api/upload
字段映射:
| 前端旧参数 | 新后端参数 | 说明 |
|---|---|---|
upload_info.type_id |
typeId |
直接传 |
| — | typeCode |
补充,从 document types 查 |
| — | region |
从 sessionStorage / user info 取当前用户地区 |
| — | fileRole |
"primary" |
| — | createdBy |
从 JWT payload 取 user_id |
evaluation_level |
speed |
urgent/normal 映射 |
| — | autoRun |
默认 true(参考前端现有流程:上传后自动 treatment) |
附件和模板上传合并方案:
- 主文件:
POST /api/upload+fileRole=primary - 附件:
POST /api/upload+fileRole=attachment(或批量复用主上传) - 模板:
POST /api/upload+fileRole=template
影响文件:
new_doc_review/app/api/files/files-upload.ts—uploadDocumentToServer()重写new_doc_review/app/routes/files.upload.tsx—startUpload()适配新参数
第 2 步:列表字段精简
前端字段直接对齐,逐步去掉 mapLeauditDocToAuditStatus、mapProcessingStatusToFileStatus 等映射函数。DocumentUI 接口增加新字段,旧字段保留兼容。
影响文件:
new_doc_review/app/api/files/documents.ts— 简化LeauditListItem → DocumentUI转换
第 3 步:补后端 CRUD
后端新增:
DELETE /api/documents/{id} → 软删除 (deleted_at = now())
PUT /api/documents/{id} → 更新元数据 (备注、测试标记)
GET /api/documents/{id} → 文档详情(含所有版本)
POST /api/documents/{id}/attachments → 追加附件
影响文件:
fastapi_modules/fastapi_leaudit/controllers/documentController.pyfastapi_modules/fastapi_leaudit/services/impl/documentServiceImpl.py
第 4 步:前端切割 PostgREST
deleteDocument、updateDocument 从前端 PostgREST 调用改为走新后端 /api/documents/...。
第 5 步:清理旧依赖
确认无其他 PostgREST 调用后,移除旧 RPC 函数。
四、涉及文件清单
| 层 | 文件 | 改动类型 |
|---|---|---|
| 后端 | documentController.py |
新增 3 个端点 |
| 后端 | documentServiceImpl.py |
新增 Delete/Update/GetById/AppendAttachments |
| 后端 | documentVo.py |
可能新增 VO |
| 前端 | files-upload.ts |
重写 uploadDocumentToServer |
| 前端 | files.upload.tsx |
适配新上传参数 |
| 前端 | documents.ts |
简化列表映射 + 切割删除/编辑到新后端 |
| 前端 | documents.list.tsx |
小改适配新字段 |
| 前端 | documents.edit.tsx |
切割到新后端 PUT |