# Proposa AI 文件检测接口对接文档 版本日期:2026-09-20。适用范围:当前仓库实现。 本文路径、文件名、大小和摘要均为示例,不是线上检测结果。将 `https://api.example.com` 替换为实际服务地址。后端入库前建议采用本文的 JSON 三字段请求。 ## 1. 接口信息 | 项目 | 说明 | | --- | --- | | 用途 | 入库前检测文件是否为有效 DOCX 或可提取文字的 PDF | | 请求方法 | `POST` | | 请求路径 | `/api/v1/files/validate` | | 请求格式 | `application/json`;兼容 `multipart/form-data` 单文件上传 | | 响应格式 | `application/json`,直接返回对象,无 `code` / `data` 外层包装 | | 执行方式 | 同步检测,当前请求直接返回结果,不需要轮询 | | 鉴权 | 当前应用不要求 token;如部署网关设置鉴权,按网关要求提供 | | 其他参数 | 不需要 `txbId`、`CALLBACK_URL` 或生成任务参数 | 本接口只检测文件,不负责入库,不创建投标生成任务,不调用 LLM、不执行 OCR、不发送回调。 源文件保持不变,检测副本在成功或失败后自动清理。 **放行规则:仅 HTTP 200 且响应 `valid=true` 时继续入库。其他状态或网络异常均不能视为通过。** ## 2. JSON 请求体 ```json { "file_path": "static/file/参考投书.docx", "file_role": "REFERENCE_BID", "is_absolute": false } ``` | 字段 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `file_path` | string | 是 | 服务端本地文件路径,不能为空;不是 HTTP URL,也不是调用方电脑上仅本机可见的路径 | | `file_role` | string | 是 | 业务用途,见下表;枚举值区分大小写 | | `is_absolute` | boolean | 是 | `true` 直接读取清理后的路径;`false` 根据业务用途拼接配置目录。必须传 JSON 布尔值,不能传字符串 `"false"` 或数字 0/1 | ### 2.1 业务用途与目录 | `file_role` | 业务用途 | `is_absolute=false` 时的目录 | | --- | --- | --- | | `TENDER_FILE` | 招标文件 | `TPC_DIR` | | `PROCUREMENT_FILE` | 采购需求 | `TPC_DIR` | | `CLA_FILE` | 澄清公告 | `TPC_DIR` | | `REFERENCE_BID` | 参考投书 | 依次查找 `REFERENCE_DIR`、`REFERENCE_DIR1` | `file_role` 是业务用途,`file_type` 是响应中的实际文件格式(`docx` / `pdf`),两者不同。 **当前检测接口中,业务用途只决定路径解析规则,各用途均可检测 DOCX 或文字型 PDF。** 原生成接口仍要求招标文件为文字 PDF、采购需求和参考投书为 DOCX;检测通过不代表已满足 生成接口对应字段的格式要求。澄清公告在原生成接口中仍仅接收记录、不参与生成。 ### 2.2 路径解析顺序 1. 去除 `file_path` 首尾空白,删除独立的 `static/` 或 `static\` 目录段。 `mystatic/`、文件名 `static.docx` 不受影响,配置目录本身不清理。 2. `is_absolute=true`:按清理后的路径直接读取,不拼接业务目录。调用方应提供服务端绝对路径。 为兼容原接口,此模式不会额外拒绝相对文本;若误传相对路径,会按服务进程当前工作目录解析。 3. `is_absolute=false`:去掉清理后路径开头的 `/` 或 `\`,按上表拼接配置目录。 即使传入路径以 `/` 开头,也不会自动改成绝对路径模式。 4. 参考投书选择第一个实际存在的文件。两个目录都有文件时优先 `REFERENCE_DIR`; 第一份存在但内容不合法时,直接返回检测失败,不跳到第二份。 5. 将选中的源路径转为完整绝对路径后检测,并在响应中返回。 路径按 API 所在操作系统解释。Windows 路径建议使用 `E:/uploads/a.docx`,或在 JSON 中 正确转义反斜杠。相对配置目录也按服务进程工作目录解析,生产环境建议配置绝对目录。 示例配置(请替换为实际服务端配置): ```dotenv TPC_DIR=/data/tender REFERENCE_DIR=/data/shenqin REFERENCE_DIR1=/data/dms/dms_upload ``` | 请求路径 | 用途 | 模式 | 解析结果 | | --- | --- | --- | --- | | `static/file/招标文件.pdf` | `TENDER_FILE` | false | `/data/tender/file/招标文件.pdf` | | `/static/file/采购需求.docx` | `PROCUREMENT_FILE` | false | `/data/tender/file/采购需求.docx` | | `static/file/参考投书.docx` | `REFERENCE_BID` | false | 先查 `/data/shenqin/file/参考投书.docx`,未找到再查 `/data/dms/dms_upload/file/参考投书.docx` | | `/data/uploads/澄清公告.pdf` | `CLA_FILE` | true | `/data/uploads/澄清公告.pdf` | ### 2.3 调用示例 Linux / macOS Shell: ```bash curl -X POST "https://api.example.com/api/v1/files/validate" \ -H "Content-Type: application/json" \ --data '{"file_path":"static/file/参考投书.docx","file_role":"REFERENCE_BID","is_absolute":false}' ``` PowerShell: ```powershell $body = @{ file_path = "static/file/参考投书.docx" file_role = "REFERENCE_BID" is_absolute = $false } | ConvertTo-Json Invoke-RestMethod -Method Post ` -Uri "https://api.example.com/api/v1/files/validate" ` -ContentType "application/json; charset=utf-8" ` -Body ([System.Text.Encoding]::UTF8.GetBytes($body)) ``` ## 3. 成功响应 HTTP 200,DOCX 示例: ```json { "valid": true, "file_type": "docx", "is_text_pdf": null, "file_role": "REFERENCE_BID", "resolved_path": "/data/shenqin/file/参考投书.docx", "filename": "参考投书.docx", "size": 12345, "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "message": "文件检测通过" } ``` | 字段 | 类型 | 说明 | | --- | --- | --- | | `valid` | boolean | 成功时为 true | | `file_type` | string | `docx` 或 `pdf` | | `is_text_pdf` | boolean / null | PDF 成功时为 true;DOCX 为 null | | `file_role` | string | 请求中的业务用途,仅 JSON 路径模式返回 | | `resolved_path` | string | 实际选中源文件的完整路径,仅 JSON 路径模式成功时返回 | | `filename` | string | 文件名,不含目录 | | `size` | integer | 检测文件大小,单位字节 | | `sha256` | string | 检测内容的 SHA-256,64 位十六进制字符串 | | `message` | string | 展示或排查用提示语,不要按文案字符串做业务判断 | PDF 成功时 `file_type="pdf"`、`is_text_pdf=true`,其余字段规则一致。 检测后应将同一份内容入库;文件可能被替换时,可用摘要确认内容一致。 ## 4. 失败响应与完整路径 可处理的检测/参数错误返回非 2xx 状态码,并统一包含以下字段: | 字段 | 类型 | 说明 | | --- | --- | --- | | `valid` | boolean | false | | `message` | string | 失败原因;能解析路径时包含完整源路径或所有完整候选路径 | | `detail` | string | 与 message 相同,兼容原有读取 detail 的调用方 | | `resolved_path` | string / null | 只有一个已确定源路径或候选时返回该完整路径;不代表文件一定存在。多个候选或无法解析时为 null | | `candidate_paths` | array[string] | 本次已确定的完整源路径或未找到文件时的完整候选列表;无法解析时为空数组 | `message` 中的完整路径是清理 `static`、拼接业务目录后的服务端路径,不是用户传入的 部分路径,也不是内部检测临时副本路径。路径分隔符以实际服务端系统为准。 ### 4.1 内容不合法 HTTP 400: ```json { "valid": false, "message": "REFERENCE_BID 不是有效的 DOCX 文件;完整文件路径:/data/shenqin/file/参考投书.docx", "detail": "REFERENCE_BID 不是有效的 DOCX 文件;完整文件路径:/data/shenqin/file/参考投书.docx", "resolved_path": "/data/shenqin/file/参考投书.docx", "candidate_paths": ["/data/shenqin/file/参考投书.docx"] } ``` 无文字 PDF、文件为空、文件无法读取、格式不支持、文件超限等场景同样包含完整源路径, 具体原因和 HTTP 状态码不同。 ### 4.2 参考投书两个目录都未找到 HTTP 400(按上文示例目录配置): ```json { "valid": false, "message": "REFERENCE_BID 在 REFERENCE_DIR 和 REFERENCE_DIR1 下均不存在: file/参考投书.docx;完整文件路径:/data/shenqin/file/参考投书.docx;/data/dms/dms_upload/file/参考投书.docx", "detail": "REFERENCE_BID 在 REFERENCE_DIR 和 REFERENCE_DIR1 下均不存在: file/参考投书.docx;完整文件路径:/data/shenqin/file/参考投书.docx;/data/dms/dms_upload/file/参考投书.docx", "resolved_path": null, "candidate_paths": [ "/data/shenqin/file/参考投书.docx", "/data/dms/dms_upload/file/参考投书.docx" ] } ``` 只配置了一个参考目录时,仅列出该目录对应的候选路径。 ### 4.3 无法确定完整路径 例如相对模式未配置 `TPC_DIR`,HTTP 400: ```json { "valid": false, "message": "TENDER_FILE 为相对路径,但未配置 TPC_DIR", "detail": "TENDER_FILE 为相对路径,但未配置 TPC_DIR", "resolved_path": null, "candidate_paths": [] } ``` 必填参数缺失、业务用途无效、JSON 格式错误等发生在路径解析之前,也无法提供完整路径; 服务会明确返回原因,不会猜测配置目录或虚构文件路径。 ## 5. HTTP 状态码 | 状态码 | 含义及处理 | | --- | --- | | 200 | 检测通过;确认 valid=true 后继续入库 | | 400 | 文件不存在/无法读取/为空、后缀或内容无效、PDF 加密或无文字、路径配置缺失、JSON 语法错误等;读取 message 排查 | | 413 | 超过 `PROPOSA_API_MAX_UPLOAD_MB` 文件大小限制 | | 415 | 请求 Content-Type 不是 application/json 或 multipart/form-data | | 422 | JSON 三个必填字段缺失/类型不正确/用途无效,或上传字段缺失、不是文件、上传多个文件 | 网络异常、网关错误或未处理的服务异常(例如 HTTP 500)不能视为检测通过;这些响应不保证 包含本接口的 JSON 字段。建议保存 HTTP 状态码和响应正文,若存在 `message` 优先展示它。 ## 6. 检测范围与限制 - 文件后缀仅允许 `.docx`、`.pdf`,不区分大小写;同时检查实际内容,不只检查后缀或 MIME。 - DOCX 检查 ZIP 容器、必需 OOXML 部件、主文档内容类型、包关系及正文 XML; 改后缀的旧版 `.doc`、普通 ZIP、无效主文档会被拒绝。DOCX 不要求包含文字。 - PDF 必须未加密、可逐页解析,并至少一页可提取非空文字;纯扫描或无文字 PDF 不通过。 - 混合文字/扫描页 PDF、有 OCR 文字层的 PDF 可能通过;不保证每页都有文字, 不判断 OCR 正确率,也不判断业务内容是否完整。 - 文件大小沿用 `PROPOSA_API_MAX_UPLOAD_MB`,默认 512 MB;JSON 本地路径也受此限制。 PDF 检测会读入内存,服务端应按容量设置上限。 - 后续生成接口仍会再次校验文件。本接口通过不保证后续 Step1-6 一定成功。 ## 7. 兼容的文件上传方式 无需服务端文件路径时,可使用 `multipart/form-data` 上传一个小写 `file` 字段。 该模式不需要 `file_path`、`file_role`、`is_absolute`,不参与业务目录拼接。 ```bash curl -X POST "https://api.example.com/api/v1/files/validate" -F "file=@待检测文件.pdf" ``` 成功字段与第 3 节相同,但不包含 `file_role` 和 `resolved_path`。 失败使用第 4 节的统一结构;由于不存在服务端源路径,`resolved_path=null`、 `candidate_paths=[]`,message 仅包含失败原因,不暴露内部临时路径。 ## 8. 后端接入顺序 1. 将待检测文件放入 API 服务能够读取的存储位置。 2. 根据文件业务用途发送 JSON 三字段请求,等待同步响应。 3. HTTP 200 且 valid=true:继续业务入库;需要时保存 file_type、size、sha256。 4. 其他响应:阻止入库,记录并展示 message;完整路径可直接用于核对目录、文件名及权限。 5. 修正文件或路径配置后重新检测。检测和入库之间应保持文件内容一致。 服务部署后可在 `/docs` 试用接口,`/openapi.json` 提供机器可读的请求契约。