Files
Fairscan_cyy/requirements/pc-api-spec.md
MobKBK 1848a88fcf
Some checks failed
Android CI / build (push) Has been cancelled
初步完成框架
- 实时图传:WebSocket JPEG 帧发送 + 帧率控制 + PC 浏览器预览
- PDF 上传与处理:上传/处理分离,支持 ocrpdf 和 markdown 两种类型
- MinerU 真实接入:markdown 处理 + images ZIP 打包
- OCRmyPDF 接入:ocrpdf 生成可搜索双层 PDF
- 手机端任务管理面板:轮询状态 + SAF 目录选择下载
- PC 管理面板:/dashboard 文件与任务管理
- 网络层:OkHttp 客户端、WebSocket 图传、局域网发现占位

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-04 17:03:18 +08:00

16 KiB
Raw Blame History

FairScan PC 端统一接口规范(草案 v0.1

本文档定义 FairScan 手机端与 PC 端之间的最小稳定接口契约。

适用对象:

  • 人工开发者
  • Claude Code
  • 其他 AI 编码代理

设计目标:

  • 让不同执行者都能按同一接口实现,不因上下文差异而跑偏
  • 优先稳定协议与字段,而不是优先绑定具体内部实现
  • 允许 PC 端先做“接口占位实现”,后续再逐步接入真实 MinerU / OCRmyPDF

1. 设计范围

本文档覆盖以下能力:

  1. 局域网服务发现配套信息
  2. 健康检查接口
  3. 实时图传接口
  4. PDF 上传接口
  5. 统一处理任务接口
  6. 任务状态查询接口
  7. 处理产物查询接口
  8. 处理产物下载接口

本文档约束以下内容:

  • PC 端内部具体使用什么库执行 MinerU
  • PC 端内部具体使用什么方式调用 OCRmyPDF
  • PC 端图传画面最终是显示在网页、桌面窗口还是其他 UI 中
  • Android 端 UI 的具体布局样式

也就是说:

  • 本文档约束的是“外部协议”
  • 不强制约束“内部实现”

2. 核心原则

2.1 图传与文档处理解耦

  • 实时图传只负责低延迟画面预览
  • 正式文档处理只基于手机本地生成的 PDF
  • 图传流不得直接作为 MinerU / OCRmyPDF 的正式输入

2.2 统一处理接口

PC 端后处理统一使用一套任务接口。

支持的处理类型:

  • markdown
  • ocrpdf

差异只体现在:

  • processType
  • 返回产物的 MIME 类型

2.3 手机主动下载结果

“PC 处理后结果回到手机”在工程上定义为:

  • 手机查询任务状态
  • 手机获取产物列表
  • 手机主动下载产物

不要求 PC 主动回连手机进行推送。

2.4 允许占位实现

第一阶段允许 PC 端:

  • 返回 mock 任务
  • 返回 mock 产物
  • 先不真正接入 MinerU / OCRmyPDF

只要对外接口契约稳定即可。


3. 术语定义

3.1 File

指手机上传到 PC 的原始 PDF 文件。

3.2 Task

指 PC 端异步处理任务。

3.3 Artifact

指任务完成后可下载的结果文件。

3.4 Primary Artifact

指该处理类型最核心的主产物:

  • markdown -> .md
  • ocrpdf -> .pdf

3.5 Auxiliary Artifact

指附加产物,例如:

  • 资源图片
  • 日志文件
  • JSON 中间结果
  • 识别报告

4. 协议总览

能力 方法 路径 说明
健康检查 GET /health 检查服务可用性与能力
实时图传 WS /stream 接收手机实时图像帧
上传 PDF POST /upload/pdf 上传正式文档 PDF
创建处理任务 POST /tasks/process 发起统一处理任务
查询任务状态 GET /tasks/{taskId} 查询任务执行状态
查询任务产物 GET /tasks/{taskId}/artifacts 获取结果文件列表
下载产物 GET /artifacts/{artifactId}/download 下载结果文件
下载原始文件 GET /files/{fileId}/download 下载已上传的原始 PDF

默认基础地址示例:

http://{host}:{port}

例如:

http://192.168.1.10:8080

5. 通用约定

5.1 编码与格式

  • JSON 请求与响应统一使用 UTF-8
  • 除下载接口外,默认返回 application/json
  • 图传 WebSocket 使用二进制消息承载 JPEG 帧

5.2 ID 规则

以下字段都视为不透明字符串

  • fileId
  • taskId
  • artifactId

客户端不得依赖这些 ID 的内部结构。

5.3 时间字段

如果服务返回时间字段,建议使用 RFC 3339 / ISO 8601例如

2026-06-04T12:34:56Z

时间字段不是第一阶段强制要求,但如果提供,应统一格式。

5.4 状态枚举

任务状态建议使用以下枚举:

queued
running
completed
failed

如后续需要,可扩展:

canceled

5.5 错误返回格式

推荐所有错误统一返回:

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "processType is required"
  }
}

推荐错误码:

  • INVALID_REQUEST
  • UNSUPPORTED_PROCESS_TYPE
  • FILE_NOT_FOUND
  • TASK_NOT_FOUND
  • ARTIFACT_NOT_FOUND
  • PROCESSING_FAILED
  • SERVICE_UNAVAILABLE

5.6 版本兼容原则

  • 第一阶段不强制引入 /api/v1 路径前缀
  • 通过 apiVersion 字段表达协议版本
  • 后续如需重大变更,再评估路径版本化

6. 局域网发现配套约定

6.1 mDNS 服务标识

  • service type_fairscan._tcp
  • service instance nameFairScan-PC-{deviceName}

6.2 推荐 TXT Record 字段

  • name:设备显示名
  • featuresstream,upload,process,download
  • apiVersion:如 1
  • versionPC 服务版本

6.3 关于 process 能力

这里建议广播能力使用:

  • process

而不是直接广播多个内部工具名。

原因:

  • 发现层只需表达“能不能处理”
  • 具体支持哪些 processType,可通过 /health 返回
  • 这样后续新增其他处理器时不需要修改发现层语义

7. 健康检查接口

7.1 GET /health

作用

  • 判断服务是否在线
  • 返回最小能力信息
  • 返回支持的处理类型

请求

无请求体。

成功响应示例

{
  "name": "FairScan-PC-Office",
  "status": "ok",
  "version": "0.1.0",
  "apiVersion": "1",
  "features": ["stream", "upload", "process", "download"],
  "processTypes": ["markdown", "ocrpdf"]
}

字段说明

字段 类型 必填 说明
name string 设备显示名
status string 固定为 ok
version string PC 服务版本
apiVersion string 接口版本
features string[] 服务能力
processTypes string[] 当前支持的处理类型

状态码

  • 200 OK

8. 实时图传接口

8.1 WS /stream

作用

接收手机端发送的实时画面帧。

连接方式

  • 客户端发起 WebSocket 连接
  • 连接成功后开始发送二进制帧
  • 每条二进制消息代表一张完整 JPEG 图像

帧格式

  • 二进制消息
  • 内容JPEG 文件完整字节流
  • 一条消息 = 一帧

服务端要求

  • 服务端可只保留最新帧
  • 服务端不要求逐帧确认
  • 服务端允许丢弃旧帧以保证实时性

客户端要求

  • 不得无限积压待发送帧
  • 若上一帧尚未发完,允许直接丢弃当前帧
  • 连接断开后由客户端自行决定是否重连

第一阶段最小可接受行为

  • 服务端只需能接收 JPEG 帧并显示或缓存最新一帧
  • 不要求复杂多端会话管理
  • 不要求录像、回放、时间轴等高级功能

状态码

  • WebSocket Upgrade 成功即视为可用

9. PDF 上传接口

9.1 POST /upload/pdf

作用

上传手机端正式生成的 PDF 文件。

请求类型

multipart/form-data

表单字段

字段 类型 必填 说明
file file PDF 文件

约束

  • file 的 MIME 类型应为 application/pdf
  • 服务端可根据需要限制上传大小
  • 若文件过大,建议返回 413 Payload Too Large

成功响应示例

{
  "fileId": "file-123",
  "fileName": "Scan 2026-06-04 12.34.56.pdf",
  "mimeType": "application/pdf",
  "sizeBytes": 1048576
}

字段说明

字段 类型 必填 说明
fileId string 服务端文件标识
fileName string 保存后的文件名
mimeType string 固定为 application/pdf
sizeBytes number 文件字节大小

状态码

  • 201 Created
  • 400 Bad Request
  • 413 Payload Too Large
  • 500 Internal Server Error

10. 统一处理任务接口

10.1 POST /tasks/process

作用

使用统一接口发起后处理任务。

请求示例

{
  "fileId": "file-123",
  "processType": "markdown",
  "options": {}
}

请求字段说明

字段 类型 必填 说明
fileId string 由上传接口返回的文件标识
processType string markdownocrpdf
options object 预留扩展字段,首版可为空对象

处理类型定义

processType 含义 预期主产物
markdown 执行 Markdown 转换 text/markdown
ocrpdf 执行 OCR PDF 处理 application/pdf

成功响应示例

{
  "taskId": "task-123",
  "status": "queued",
  "processType": "markdown",
  "fileId": "file-123"
}

状态码

  • 202 Accepted
  • 400 Bad Request
  • 404 Not FoundfileId 不存在)
  • 422 Unprocessable EntityprocessType 不支持时可选)
  • 500 Internal Server Error

第一阶段占位实现要求

如果真实 MinerU / OCRmyPDF 尚未接入,允许这样实现:

  • 接口正常收请求
  • 正常返回 taskId
  • 任务状态可直接从 queued -> completed
  • 产物可先返回 mock 文件或占位文件

这样做的目标是:

  • 先稳定客户端协议
  • 先打通 Android 联调链路
  • 后续再逐步替换成真实处理器

11. 查询任务状态接口

11.1 GET /tasks/{taskId}

作用

返回单个任务的当前状态。

成功响应示例

{
  "taskId": "task-123",
  "status": "running",
  "processType": "markdown",
  "fileId": "file-123",
  "progress": 50,
  "message": "processing",
  "artifactsAvailable": false
}

字段说明

字段 类型 必填 说明
taskId string 任务标识
status string queued / running / completed / failed
processType string 任务处理类型
fileId string 输入文件标识
progress number 建议 0~100
message string 当前状态说明
artifactsAvailable boolean 是否已有可下载产物

失败响应示例

{
  "error": {
    "code": "TASK_NOT_FOUND",
    "message": "task not found"
  }
}

状态码

  • 200 OK
  • 404 Not Found

12. 查询任务产物接口

12.1 GET /tasks/{taskId}/artifacts

作用

列出某个任务已经生成的所有产物。

成功响应示例

Markdown 任务示例

[
  {
    "artifactId": "artifact-1",
    "fileName": "result.md",
    "mimeType": "text/markdown",
    "role": "primary",
    "sizeBytes": 2048
  }
]

OCR PDF 任务示例

[
  {
    "artifactId": "artifact-2",
    "fileName": "result.pdf",
    "mimeType": "application/pdf",
    "role": "primary",
    "sizeBytes": 3145728
  }
]

字段说明

字段 类型 必填 说明
artifactId string 产物标识
fileName string 文件名
mimeType string MIME 类型
role string primary / auxiliary / log
sizeBytes number 文件大小

约束

  • markdown,应至少存在一个 role=primarymimeType=text/markdown 的产物
  • ocrpdf,应至少存在一个 role=primarymimeType=application/pdf 的产物

状态码

  • 200 OK
  • 404 Not Found

13. 产物下载接口

13.1 GET /artifacts/{artifactId}/download

作用

下载指定产物文件。

响应

  • 响应体为二进制文件流
  • Content-Type 应与产物 mimeType 一致
  • Content-Disposition 建议包含文件名

成功行为示例

  • 下载 MarkdownContent-Type: text/markdown
  • 下载 OCR PDFContent-Type: application/pdf

状态码

  • 200 OK
  • 404 Not Found

14. 原始文件下载接口

14.1 GET /files/{fileId}/download

作用

下载已上传但尚未处理的原始 PDF 文件。

响应

  • 响应体为二进制文件流
  • Content-Type: application/pdf
  • Content-Disposition 包含原始文件名

典型用途

  • PC 管理面板中直接下载查看手机上传的原始 PDF
  • 手机端重新获取已上传的文件

状态码

  • 200 OK
  • 404 Not Found(文件 ID 不存在或文件已从磁盘删除)

15. 两类处理任务的差异说明

15.1 processType=markdown

目标

把 PDF 处理为 Markdown 文档。

最低要求

  • 至少返回一个 .md 主产物

可选附加产物

  • 图片资源
  • 日志
  • JSON 中间结果

15.2 processType=ocrpdf

目标

把 PDF 处理为 OCR 后的可搜索 PDF。

最低要求

  • 至少返回一个 .pdf 主产物

可选附加产物

  • 日志
  • 识别报告

16. 典型调用流程

16.1 实时图传流程

  1. 手机发现并选择 PC 主机
  2. 手机调用 /health 确认支持 stream
  3. 手机建立 WS /stream
  4. 手机按抽帧策略发送 JPEG 帧
  5. PC 实时显示最新帧

16.2 文档处理流程

  1. 手机本地生成 PDF
  2. 手机 POST /upload/pdf
  3. 手机获得 fileId
  4. 手机 POST /tasks/process
  5. 手机获得 taskId
  6. 手机轮询 GET /tasks/{taskId}
  7. 任务完成后,手机调用 GET /tasks/{taskId}/artifacts
  8. 手机调用 GET /artifacts/{artifactId}/download
  9. 手机保存、打开或分享结果

17. 第一阶段可接受的占位实现

如果当前目标只是让 Android 端和 PC 端先联调通,这一阶段允许:

17.1 markdown 占位实现

  • 收到 processType=markdown
  • 直接生成一个示例 .md 文件
  • 任务短时间内进入 completed

17.2 ocrpdf 占位实现

  • 收到 processType=ocrpdf
  • 直接复制输入 PDF 为新文件,或生成一个占位 PDF
  • 任务短时间内进入 completed

17.3 为什么允许这样做

这样可以先验证:

  • 接口字段是否稳定
  • Android 端状态流是否完整
  • 下载逻辑是否可用
  • 不同 mimeType 的本地处理是否正确

等这些都稳定后,再接入真实处理器更安全。


18. 对执行者的约束说明

本节适用于任何执行这份接口文档的人或 AI。

18.1 必须遵守的约束

  • 不要为 markdownocrpdf 设计两套独立任务协议
  • 不要让 Android 端依赖 PC 内部执行器实现细节
  • 不要把图传流直接作为正式文档处理输入
  • 不要把“结果回到手机”实现成 PC 主动推送手机的唯一方式

18.2 优先级建议

如果执行资源有限,优先实现:

  1. /health
  2. /upload/pdf
  3. /tasks/process
  4. /tasks/{id}
  5. /tasks/{id}/artifacts
  6. /artifacts/{artifactId}/download
  7. WS /stream

说明:

  • 如果当前主要目标是联调文档处理链路,可先暂缓图传 UI
  • 如果当前主要目标是实时性验证,可先实现 WS /stream
  • 但无论如何,统一处理接口契约应保持不变

19. 与 Android 端实现的对应关系

PC 接口与 Android 模块建议对应如下:

PC 接口 Android 模块
/health discovery / server endpoint
WS /stream stream client
/upload/pdf upload client
/tasks/process task client
/tasks/{id} task polling logic
/tasks/{id}/artifacts artifact query logic
/artifacts/{artifactId}/download artifact download client
/files/{fileId}/download raw file download client

20. 后续扩展预留

后续如果需要扩展,可在不破坏主契约的情况下增加:

  • 更多 processType
  • 更多 options 字段
  • 任务取消接口
  • 批量任务接口
  • 任务日志查询接口
  • 结果 ZIP 打包下载接口

但第一阶段不建议过早加入这些扩展。


21. 一句话总结

这份接口规范的核心思想是:

  • 实时图传走一条轻量、低延迟链路
  • 文档处理走一条统一任务接口链路
  • MinerU 与 OCRmyPDF 共用同一处理协议,只通过 processType 区分
  • 允许先用占位实现把联调跑通,再逐步接入真实处理器