Files
leaudit-platform-backend/docs/接口/新系统版_documents_list接口.md
T
2026-04-29 11:48:50 +08:00

7.3 KiB
Raw Blame History

新系统版 documents/list 接口

这份文档专门说明当前 leaudit-platform 里已经落地的“新系统版文档列表接口”。

目标很明确:

  • 前端文档列表只看“最新版本”
  • 同名文档的历史版本直接归到同一个版本链
  • 列表接口直接返回历史版本摘要,前端不用自己再拼版本关系

1. 接口路径

GET /api/documents/list

2. 当前接口语义

这个接口不是“把所有上传记录平铺出来”。

它的语义是:

  • 每个 version_group_key 只返回一条“最新版本文档”
  • 这条最新版本文档下面附带 historyVersions
  • historyVersions 里放的是同组下更老的版本摘要

也就是说,前端主列表看到的是:

  • 当前版本
  • 是否有历史版本
  • 一共有多少版本
  • 历史版本有哪些

3. 请求参数

参数 类型 必填 说明
page int 页码,从 1 开始,默认 1
pageSize int 每页数量,默认 20,最大 100
keyword string 按文件名或归一化名称模糊搜索
typeCode string 文档类型编码,例如 contract.sale
region string 区域
processingStatus string 文档处理状态
resultStatus string 最新 run 的结果状态

请求示例:

curl 'http://127.0.0.1:8096/api/documents/list?page=1&pageSize=5'

带筛选示例:

curl 'http://127.0.0.1:8096/api/documents/list?page=1&pageSize=2&keyword=版本归档&typeCode=contract.sale&region=default'

4. 返回结构

返回模型是分页结构:

{
  "code": 200,
  "message": "ok",
  "data": {
    "total": 1,
    "page": 1,
    "pageSize": 20,
    "totalPages": 1,
    "documents": []
  }
}

其中 documents[] 的单条结构核心字段如下:

字段 说明
documentId 当前最新版本文档 ID
internalDocumentNo 平台内部追踪号
versionGroupKey 版本归档组键
versionNo 当前版本号
rootVersionId 版本链根文档 ID
previousVersionId 上一版本文档 ID
typeId 文档类型 ID
typeCode 文档类型编码
region 区域
normalizedName 归一化后的名称
fileId 当前主文件 ID
fileName 文件名
fileExt 文件扩展名
mimeType MIME 类型
fileSize 文件大小
ossUrl 对象存储路径
processingStatus 文档处理状态
currentRunId 当前 run ID
runStatus 当前 run 状态
resultStatus 当前 run 结果状态
totalScore 总分
passedCount 通过数
failedCount 失败数
skippedCount 跳过数
updatedAt 更新时间
hasHistory 是否有历史版本
totalVersions 总版本数
historyVersions 历史版本摘要列表

historyVersions[] 结构:

字段 说明
documentId 历史版本文档 ID
fileId 历史版本文件 ID
versionNo 历史版本号
fileName 文件名
fileExt 文件扩展名
processingStatus 处理状态
runStatus 运行状态
resultStatus 结果状态
updatedAt 更新时间

5. SQL 逻辑

5.1 主列表计数 SQL

SELECT COUNT(*)
FROM leaudit_documents d
JOIN leaudit_document_files f
  ON f.document_id = d.id
LEFT JOIN leaudit_document_types dt
  ON dt.id = d.type_id
LEFT JOIN leaudit_audit_runs ar
  ON ar.id = d.current_run_id
WHERE d.is_latest_version = true
  AND d.deleted_at IS NULL
  AND f.is_active = true
  AND f.file_role = 'primary'
  -- 可选过滤:
  -- AND (f.file_name ILIKE :keyword OR d.normalized_name ILIKE :keyword)
  -- AND dt.code = :type_code
  -- AND d.region = :region
  -- AND d.processing_status = :processing_status
  -- AND ar.result_status = :result_status

5.2 主列表分页 SQL

SELECT
    d.id AS document_id,
    d.biz_document_id AS internal_document_no,
    d.version_group_key,
    d.version_no,
    d.root_version_id,
    d.previous_version_id,
    d.type_id,
    dt.code AS type_code,
    d.region,
    d.normalized_name,
    d.processing_status,
    d.current_run_id,
    d.updated_at,
    f.id AS file_id,
    f.file_name,
    f.file_ext,
    f.mime_type,
    f.file_size,
    f.oss_url,
    ar.status AS run_status,
    ar.result_status,
    ar.total_score,
    ar.passed_count,
    ar.failed_count,
    ar.skipped_count,
    vc.total_versions,
    COALESCE(vc.total_versions, 1) > 1 AS has_history
FROM leaudit_documents d
JOIN leaudit_document_files f
  ON f.document_id = d.id
LEFT JOIN leaudit_document_types dt
  ON dt.id = d.type_id
LEFT JOIN leaudit_audit_runs ar
  ON ar.id = d.current_run_id
LEFT JOIN (
    SELECT version_group_key, COUNT(*) AS total_versions
    FROM leaudit_documents
    WHERE deleted_at IS NULL
    GROUP BY version_group_key
) vc
  ON vc.version_group_key = d.version_group_key
WHERE d.is_latest_version = true
  AND d.deleted_at IS NULL
  AND f.is_active = true
  AND f.file_role = 'primary'
ORDER BY d.updated_at DESC, d.id DESC
LIMIT :limit OFFSET :offset

5.3 历史版本摘要 SQL

SELECT
    d.version_group_key,
    d.id AS document_id,
    d.version_no,
    d.processing_status,
    d.updated_at,
    f.id AS file_id,
    f.file_name,
    f.file_ext,
    ar.status AS run_status,
    ar.result_status
FROM leaudit_documents d
JOIN leaudit_document_files f
  ON f.document_id = d.id
 AND f.is_active = true
 AND f.file_role = 'primary'
LEFT JOIN leaudit_audit_runs ar
  ON ar.id = d.current_run_id
WHERE d.version_group_key = ANY(:group_keys)
  AND d.is_latest_version = false
  AND d.deleted_at IS NULL
ORDER BY d.version_group_key, d.version_no DESC, d.id DESC

6. 为什么新系统要这么做

因为现在我们已经不是老系统那种“文档记录 + 旁路版本信息”的模式了。

当前新系统已经有真正的版本链字段:

  • version_group_key
  • version_no
  • previous_version_id
  • root_version_id
  • is_latest_version
  • normalized_name

所以列表天然应该是:

  • 主列表 = 最新版本
  • 展开项 = 历史版本

而不是把所有版本平铺在一个列表里。


7. 当前代码落点

实现代码在这些文件:

  • 路由:fastapi_modules/fastapi_leaudit/controllers/documentController.py
  • 服务接口:fastapi_modules/fastapi_leaudit/services/documentService.py
  • VOfastapi_modules/fastapi_leaudit/domian/vo/documentVo.py
  • 具体实现:fastapi_modules/fastapi_leaudit/services/impl/documentServiceImpl.py

8. 当前验证结果

已经实际验证通过:

curl 'http://127.0.0.1:8096/api/documents/list?page=1&pageSize=5'

以及:

curl 'http://127.0.0.1:8096/api/documents/list?page=1&pageSize=2&keyword=版本归档&typeCode=contract.sale&region=default'

验证结论:

  • 接口正常返回
  • 主列表只返回最新版本
  • historyVersions 能正确带出历史版本摘要
  • 已验证版本组 4e02e455aa504cb9b75a254727f1bb4c
    • documentId=13 是当前最新 v3
    • documentId=12v2
    • documentId=11v1

9. 下一步建议

如果后面前端需要更完整的“版本展开页”,再补一个:

GET /api/documents/{documentId}/versions

但当前列表页场景下,/documents/list 已经够用了。