239 lines
11 KiB
Markdown
239 lines
11 KiB
Markdown
|
|
# FunMD 文档处理接口与测试说明
|
|||
|
|
|
|||
|
|
## 基本信息
|
|||
|
|
|
|||
|
|
- 基地址(内网):`http://192.168.110.58:8000`
|
|||
|
|
- 前端内网测试链接:`http://192.168.110.58:8000/ui/`
|
|||
|
|
- 统一返回结构(API v2):成功 `{"code":0,"msg":"ok","data":{...}}`,失败 `{"code":<错误码>,"msg":<错误>,"data":null}`(HTTP 状态保持 200)。
|
|||
|
|
- 建议前端设置:`localStorage.setItem('app.api.base','http://192.168.110.58:8000')`
|
|||
|
|
- 重要约定:当 MinIO 桶为私有时,优先使用返回的 `minio_presigned_url` 进行下载;直链 `minio_url` 可能 403。
|
|||
|
|
|
|||
|
|
## 接口列表
|
|||
|
|
|
|||
|
|
### 健康检查
|
|||
|
|
|
|||
|
|
- 方法:`GET /health`
|
|||
|
|
- 返回:`{"status":"ok"}`
|
|||
|
|
- 参考:`docling/app/server.py:99`
|
|||
|
|
|
|||
|
|
### 统一转换:DOCX/PDF → Markdown/HTML/JSON
|
|||
|
|
|
|||
|
|
- 方法:`POST /api/convert`
|
|||
|
|
- 表单字段:
|
|||
|
|
- `file` 与 `source_url` 二选一
|
|||
|
|
- `export`: `markdown|html|json|doctags`,默认 `markdown`
|
|||
|
|
- `engine`(可选):`word2markdown|docling`
|
|||
|
|
- `save`(可选):`true|false`
|
|||
|
|
- `filename`(可选):输出基名
|
|||
|
|
- 返回:
|
|||
|
|
- 未保存:`data.content` 为文本,`data.media_type` 指示类型
|
|||
|
|
- 已保存:`data.minio_url` 与 `data.minio_presigned_url`
|
|||
|
|
- 示例:
|
|||
|
|
```bash
|
|||
|
|
# 本地 PDF 转 Markdown(不保存)
|
|||
|
|
curl -X POST http://192.168.110.58:8000/api/convert \
|
|||
|
|
-F file=@/path/to/file.pdf \
|
|||
|
|
-F export=markdown
|
|||
|
|
|
|||
|
|
# 远程 URL 转 HTML(保存)
|
|||
|
|
curl -X POST http://192.168.110.58:8000/api/convert \
|
|||
|
|
-F source_url=https://example.com/page.pdf \
|
|||
|
|
-F export=html -F save=true -F filename=example
|
|||
|
|
```
|
|||
|
|
- 参考:`docling/app/server.py:2296`
|
|||
|
|
|
|||
|
|
### Markdown → DOCX/PDF(高级样式支持)
|
|||
|
|
|
|||
|
|
- 方法:`POST /md/convert`
|
|||
|
|
- 输入三选一:`md_file` | `markdown_text` | `markdown_url`
|
|||
|
|
- 必填:`target=docx|pdf`
|
|||
|
|
- 可选(高级设置):
|
|||
|
|
- 布局:`css_name`、`css_text`、`toc=true|false`、`header_text`、`footer_text`
|
|||
|
|
- 封面与 Logo:`cover_url|cover_file`、`logo_url|logo_file`
|
|||
|
|
- 封面文字:`product_name|document_name|product_version|document_version`
|
|||
|
|
- 版权:`copyright_text`
|
|||
|
|
- 保存:`save=true|false`
|
|||
|
|
- 行为说明:
|
|||
|
|
- `save=false` 时,封面/Logo 会内嵌为 `data:`,避免私有桶 403;`save=true` 时返回 MinIO 链接。
|
|||
|
|
- 例:
|
|||
|
|
```bash
|
|||
|
|
# 文本转 PDF(封面、Logo、目录、页眉页脚)
|
|||
|
|
curl -X POST http://192.168.110.58:8000/md/convert \
|
|||
|
|
-F markdown_text='# 标题\n\n内容' \
|
|||
|
|
-F target=pdf -F toc=true \
|
|||
|
|
-F header_text='Internal' -F footer_text='Confidential' \
|
|||
|
|
-F product_name='CMS' -F document_name='周报' \
|
|||
|
|
-F product_version='v1.0' -F document_version='2025-W48' \
|
|||
|
|
-F cover_file=@/path/to/cover.png -F logo_file=@/path/to/logo.png
|
|||
|
|
|
|||
|
|
# 文件转 DOCX(保存到 MinIO)
|
|||
|
|
curl -X POST http://192.168.110.58:8000/md/convert \
|
|||
|
|
-F md_file=@/path/to/doc.md \
|
|||
|
|
-F target=docx -F save=true -F filename='周报'
|
|||
|
|
```
|
|||
|
|
- 参考:`docling/app/server.py:1198`
|
|||
|
|
|
|||
|
|
### 本地文件夹批量处理(重写 MD 资源并上传)
|
|||
|
|
|
|||
|
|
- 方法:`POST /md/convert-folder`
|
|||
|
|
- 表单字段:
|
|||
|
|
- `folder_path`(必填):本地文件夹绝对路径(后端机器)
|
|||
|
|
- `prefix`(可选):MinIO 前缀(如 `assets`)
|
|||
|
|
- 返回:`{ ok, count, files: [{ source, minio_url, minio_presigned_url, asset_ok, asset_fail, mappings }] }`
|
|||
|
|
- 示例:
|
|||
|
|
```bash
|
|||
|
|
curl -X POST http://192.168.110.58:8000/md/convert-folder \
|
|||
|
|
-F folder_path='/Users/fanyang/Desktop/Others/CMS/达梦数据-各类示范文档/数+产品手册-MD源文件/DMDRS_Build_Manual_DM8' \
|
|||
|
|
-F prefix='assets'
|
|||
|
|
```
|
|||
|
|
- 参考:`docling/app/server.py:2075`
|
|||
|
|
|
|||
|
|
### 上传压缩包批量处理
|
|||
|
|
|
|||
|
|
- 方法:`POST /api/upload-archive`
|
|||
|
|
- 表单字段:`file`(zip/tar.gz/tgz),`prefix`(可选)
|
|||
|
|
- 返回:`{ code, msg, data: { count, files: [{ source, minio_url, minio_presigned_url, mappings }] } }`
|
|||
|
|
- 示例:
|
|||
|
|
```bash
|
|||
|
|
curl -X POST http://192.168.110.58:8000/api/upload-archive \
|
|||
|
|
-F file=@/path/to/archive.zip -F prefix='assets'
|
|||
|
|
```
|
|||
|
|
- 参考:`docling/app/server.py:2571`
|
|||
|
|
|
|||
|
|
### 归档分阶段处理
|
|||
|
|
|
|||
|
|
- 暂存上传:`POST /api/archive/stage`,返回 `{ id, name, size }`
|
|||
|
|
- 批量处理:`POST /api/archive/process`,字段:`id`(必填)、`prefix`(可选)、`versionId`(可选)
|
|||
|
|
- 说明:HTML 文件按“两阶段重写”策略处理(HTML 资源上传到 MinIO 并重写 → 转换为 Markdown → 再次重写 MD 中的资源与链接),支持 `data:image/*;base64,` 图片上传并替换为 MinIO 链接
|
|||
|
|
- 参考:`docling/app/server.py:2714,2728`
|
|||
|
|
|
|||
|
|
### MinIO 配置与测试
|
|||
|
|
|
|||
|
|
- 设置配置:`POST /config/minio`
|
|||
|
|
- 字段:`endpoint`、`public`、`access`、`secret`、`bucket`、`secure=true|false`、`prefix`、`store_final=true|false`、`public_read=true|false`
|
|||
|
|
- 示例:
|
|||
|
|
```bash
|
|||
|
|
curl -X POST http://192.168.110.58:8000/config/minio \
|
|||
|
|
-F endpoint='127.0.0.1:9000' -F public='127.0.0.1:9000' \
|
|||
|
|
-F access='minioadmin' -F secret='minioadmin123' \
|
|||
|
|
-F bucket='doctest' -F secure=false -F prefix='assets' \
|
|||
|
|
-F store_final=true -F public_read=true
|
|||
|
|
```
|
|||
|
|
- 注意:请使用 MinIO API 端口 `9000`(而非 `9001` 控制台端口);若填写控制台地址或 `:9001` 将被拒绝
|
|||
|
|
- 参考:`docling/app/server.py:488`
|
|||
|
|
|
|||
|
|
- 连通测试并应用策略:`POST /config/minio/test`
|
|||
|
|
- 同上字段,额外可携带 `create_if_missing=true`
|
|||
|
|
- 返回:`{ ok, connected, bucket_exists, created, error?, hint? }`
|
|||
|
|
- 参考:`docling/app/server.py:577`
|
|||
|
|
|
|||
|
|
- 获取配置快照:`GET /config`(参考:`docling/app/server.py:1047`)
|
|||
|
|
- 配置档案:`GET /config/profiles`、`POST /config/save_profile`、`GET /config/load_profile?name=xxx`(参考:`docling/app/server.py:1058,1068,1084`)
|
|||
|
|
|
|||
|
|
### 系统时间检查(MinIO 时间偏差排查)
|
|||
|
|
|
|||
|
|
- 方法:`GET /system/time/check`
|
|||
|
|
- 查询参数:`endpoint`、`public`、`secure`(可选,不传则使用当前运行时配置)
|
|||
|
|
- 返回:`{ ok, server_time, local_time, diff_sec, hint }`
|
|||
|
|
- 参考:`docling/app/server.py:720`
|
|||
|
|
|
|||
|
|
### 资源映射与代理下载(可选)
|
|||
|
|
|
|||
|
|
- Linkmap:`GET /config/linkmap`、`POST /config/linkmap`(参考:`docling/app/server.py:1583,1587`)
|
|||
|
|
- 代理下载:`POST /proxy/download`(参考:`docling/app/server.py:1635`)
|
|||
|
|
|
|||
|
|
## 前端集成要点
|
|||
|
|
|
|||
|
|
- 基地址读取:`frontend/src/services/api.ts:56-64`(localStorage `app.api.base` 优先,其次 `VITE_API_BASE_URL`)
|
|||
|
|
- 提供的方法:
|
|||
|
|
- `convertDoc` → `/api/convert`(`frontend/src/services/api.ts:96`)
|
|||
|
|
- `uploadArchive` → `/api/upload-archive`(`frontend/src/services/api.ts:104`)
|
|||
|
|
- `stageArchive` → `/api/archive/stage`(`frontend/src/services/api.ts:185`)
|
|||
|
|
- `processArchive` → `/api/archive/process`(`frontend/src/services/api.ts:193`)
|
|||
|
|
- `convertMd` → `/md/convert`(`frontend/src/services/api.ts:157`)
|
|||
|
|
- `convertFolder` → `/md/convert-folder`(`frontend/src/services/api.ts:164`)
|
|||
|
|
- MinIO 配置:`setMinioConfig`(`frontend/src/services/api.ts:112`)、`testMinioConfig`(`frontend/src/services/api.ts:128`)、`createBucket`(`frontend/src/services/api.ts:145`)
|
|||
|
|
- 私有桶注意:直链可能 403,前端应优先使用 `minio_presigned_url`(UI 已支持)。
|
|||
|
|
|
|||
|
|
## 测试说明(覆盖所有能力)
|
|||
|
|
|
|||
|
|
### 1. 健康检查
|
|||
|
|
|
|||
|
|
- 请求:`GET /health`
|
|||
|
|
- 断言:返回 `{"status":"ok"}`。
|
|||
|
|
|
|||
|
|
### 2. DOCX/PDF → Markdown/HTML/JSON
|
|||
|
|
|
|||
|
|
- 用例 A:本地 PDF → Markdown(不保存)
|
|||
|
|
- `POST /api/convert`,`file=@/path/to/file.pdf`,`export=markdown`
|
|||
|
|
- 断言:`code=0`,`data.content` 包含 Markdown 文本、`data.media_type` 为 `text/markdown; charset=utf-8`。
|
|||
|
|
|
|||
|
|
- 用例 B:远程 PDF → HTML(保存)
|
|||
|
|
- `POST /api/convert`,`source_url=http(s)://...pdf`,`export=html`,`save=true`,`filename=example`
|
|||
|
|
- 断言:返回 `minio_url` 与 `minio_presigned_url` 可访问;中文路径正确编码。
|
|||
|
|
|
|||
|
|
### 3. Markdown → DOCX/PDF
|
|||
|
|
|
|||
|
|
- 用例 C:文本 → PDF(高级参数,`save=false`)
|
|||
|
|
- 字段:`markdown_text`、`target=pdf`、`toc=true`、`header_text`、`footer_text`、封面/Logo 文件与封面文字
|
|||
|
|
- 断言:返回 PDF 二进制可打开;封面与 Logo 可见。日志中的 `word-break: break-word` 警告不影响生成。
|
|||
|
|
|
|||
|
|
- 用例 D:文件 → DOCX(`save=true`)
|
|||
|
|
- 字段:`md_file`、`target=docx`、`save=true`
|
|||
|
|
- 断言:`minio_presigned_url` 可下载;中文文件名编码正确。
|
|||
|
|
|
|||
|
|
- 用例 E:URL → PDF
|
|||
|
|
- 字段:`markdown_url=http(s)://...md`、`target=pdf`
|
|||
|
|
- 断言:生成成功;封面与 Logo 正常加载(若私有桶则走签名链接)。
|
|||
|
|
|
|||
|
|
### 4. 批量处理
|
|||
|
|
|
|||
|
|
- 用例 F:本地文件夹批量重写并上传
|
|||
|
|
- `POST /md/convert-folder`,`folder_path='/Users/fanyang/Desktop/Others/CMS/达梦数据-各类示范文档/数+产品手册-MD源文件/DMDRS_Build_Manual_DM8'`、`prefix='assets'`
|
|||
|
|
- 断言:`count>0`;各文件 `asset_ok/asset_fail` 合理;`minio_presigned_url` 可下载。
|
|||
|
|
|
|||
|
|
- 用例 G:上传压缩包批量处理
|
|||
|
|
- `POST /api/upload-archive`,`file=@/path/to/archive.zip`、`prefix='assets'`
|
|||
|
|
- 断言:`data.count` 正确;各文件链接可用。
|
|||
|
|
|
|||
|
|
### 5. MinIO 配置与策略
|
|||
|
|
|
|||
|
|
- 用例 H:设置配置
|
|||
|
|
- `POST /config/minio`(真实参数)
|
|||
|
|
- 断言:返回 `ok:true`。
|
|||
|
|
|
|||
|
|
- 用例 I:连通测试并应用策略
|
|||
|
|
- `POST /config/minio/test`,`public_read=true|false`,`create_if_missing=true`
|
|||
|
|
- 断言:返回连通状态;私有桶下使用 `minio_presigned_url` 可访问。
|
|||
|
|
|
|||
|
|
### 6. 资源映射与代理(可选)
|
|||
|
|
|
|||
|
|
- 用例 J:`GET/POST /config/linkmap` 设置静态映射;`POST /proxy/download` 验证代理下载功能。
|
|||
|
|
|
|||
|
|
## 兼容性与注意事项
|
|||
|
|
|
|||
|
|
- 路径编码:所有返回的对象路径已进行编码,适配中文、空格、括号等字符。
|
|||
|
|
- 私有桶:直链可能 403;前端测试请使用 `minio_presigned_url`。
|
|||
|
|
- 样式警告:WeasyPrint 不支持 `word-break: break-word`,建议 `overflow-wrap: break-word` 或 `word-break: break-all`。
|
|||
|
|
- 安全解压:ZIP/TAR 采用路径穿越防护,解压目标限定在工作目录内;同时自动修复常见文件名乱码编码
|
|||
|
|
- HTML 资产重写:批量处理对 HTML 的资源链接进行两阶段重写并上传至 MinIO;内嵌 Base64 图片自动上传并替换为可访问链接
|
|||
|
|
- 控制台端口限制:`/config/minio` 与 `/config/minio/test` 会拒绝 `:9001` 或带 `/browser`、`/minio` 的控制台地址;请使用 `9000` API 端口
|
|||
|
|
|
|||
|
|
## 本地运行(后端与前端)
|
|||
|
|
|
|||
|
|
- 后端(FastAPI,端口 `8000`):
|
|||
|
|
- `cd /Users/fanyang/Desktop/FunMD_Convert/docling`
|
|||
|
|
- `PYTHONPATH=. python -m uvicorn app.server:app --host 127.0.0.1 --port 8000`
|
|||
|
|
- 前端(Vite):
|
|||
|
|
- `cd /Users/fanyang/Desktop/FunMD_Convert/frontend`
|
|||
|
|
- `npm install`
|
|||
|
|
- `VITE_API_BASE_URL=http://127.0.0.1:8000 npm run dev`
|
|||
|
|
- 访问:
|
|||
|
|
- 后端 UI 首页:`http://127.0.0.1:8000/ui/`
|
|||
|
|
- 前端开发页面:Vite 控制台输出的本地地址(通常为 `http://127.0.0.1:5173/`)
|
|||
|
|
|
|||
|
|
### 前端配置 API Base(避免代理空响应)
|
|||
|
|
|
|||
|
|
- 打开前端页面右上角“数据库配置”弹窗,在“接口地址”一栏填写:`http://127.0.0.1:8000`,点击“保存配置”。
|
|||
|
|
- 保存后,前端会直连后端 `8000` 端口,不再通过 Vite 代理,避免长耗时请求在 `5173` 上出现 `ERR_EMPTY_RESPONSE`。
|