# 财务报销自动化 — API 文档 > 基础地址: `http://localhost:5000` > 启动: `python web/app.py` ## 总览 | # | 方法 | 路径 | 说明 | |---|------|------|------| | 1 | GET | `/` | PC 端主页 | | 2 | POST | `/api/session` | 创建会话 | | 3 | POST | `/api/upload/` | 上传文件(PDF/图片) | | 4 | POST | `/api/upload-csv/` | 上传 CSV 发票数据 | | 5 | GET | `/api/files/` | 列出会话目录中的文件 | | 6 | POST | `/api/process/` | 启动处理(提取+OCR+出库单) | | 7 | GET | `/api/logs/` | SSE 日志流 | | 8 | GET | `/api/download//` | 下载生成的文件 | | 9 | GET | `/api/data/` | 获取发票数据(JSON) | | 10 | POST | `/api/save/` | 保存编辑后的发票数据 | | 11 | POST | `/api/submit-financial/` | 提交到财务系统 | | 12 | GET | `/mobile/` | 移动端上传页面 | | 13 | POST | `/api/mobile-upload/` | 移动端上传图片 | --- ## 会话与目录 - 调用 `POST /api/session` 获得 `session_id` - 该会话下所有文件存放在 `web/uploads//` - 典型产物:`invoice_summary.csv`、`invoice_summary.md`、`易耗品、出库单.doc`、`config.json`、`session.log`、`result.json` --- ## 接口详情 ### 1. 创建会话 ``` POST /api/session ``` **响应:** ```json { "session_id": "a1b2c3d4e5f6" } ``` --- ### 2. 上传文件(PDF/图片) ``` POST /api/upload/ Content-Type: multipart/form-data ``` | 字段 | 类型 | 说明 | |------|------|------| | file | File | PDF 发票或支付截图 | **响应(成功):** ```json { "ok": true, "filename": "1. 电容一批.pdf" } ``` **响应(失败):** ```json { "error": "未选择文件" } ``` HTTP `400` --- ### 3. 上传 CSV 发票数据 ``` POST /api/upload-csv/ Content-Type: multipart/form-data ``` | 字段 | 类型 | 说明 | |------|------|------| | file | File | 发票汇总 CSV | **响应(成功):** ```json { "ok": true, "filename": "invoice_summary.csv" } ``` > 上传 CSV 后可跳过 PDF 提取和 OCR,直接进入处理/编辑流程。 --- ### 4. 列出会话文件 ``` GET /api/files/ ``` **响应:** ```json { "pdfs": ["1. 电容一批.pdf"], "images": ["payment_01.jpg"] } ``` `images` 包含扩展名:`.png`、`.jpg`、`.jpeg`、`.bmp`、`.webp`。 --- ### 5. 启动管道处理 ``` POST /api/process/ Content-Type: application/json ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | mode | string | 否 | `"pdf"` / `"csv"` / `"auto"`(默认 `auto`) | | username | string | 否 | 财务系统工号 | | password | string | 否 | 登录密码 | | default_name | string | 否 | 默认报销人姓名 | | default_card_no | string | 否 | 默认公务卡号 | | default_person_id | string | 否 | 默认人员编号 | | consumable_storage | string | 否 | 出库单存放地点;未填则用 `config.json` 中的值 | **mode 行为:** | mode | 行为 | |------|------| | `auto` | 仅有 CSV、无 PDF → CSV 模式;否则 → PDF 提取 + OCR | | `csv` | 使用已上传 CSV,跳过提取与 OCR | | `pdf` | 执行 PDF 提取 + OCR | **处理内容(PDF 模式):** 1. 从会话目录 PDF 提取发票信息 → `invoice_summary.csv` / `.md` 2. 对支付截图 OCR,回填刷卡字段 3. 从项目根目录复制 `易耗品、出库单.doc` 模板到会话目录并自动填写(需 Windows + Word) 配置会写入 `web/uploads//config.json`。 **响应(立即):** ```json { "status": "started" } ``` 处理在后台线程执行,进度与结果通过 `GET /api/logs/`(SSE)获取。 **SSE 完成时 `result` 示例(成功):** ```json { "ok": true, "elapsed": "45.2s", "invoice_count": 4, "csv_url": "/api/download//invoice_summary.csv", "md_url": "/api/download//invoice_summary.md", "doc_url": "/api/download//%E6%98%93%E8%80%97%E5%93%81%E3%80%81%E5%87%BA%E5%BA%93%E5%8D%95.doc", "doc_ok": true } ``` **出库单生成失败时(CSV 等仍可能成功):** ```json { "ok": true, "invoice_count": 4, "csv_url": "/api/download//invoice_summary.csv", "doc_ok": false, "doc_error": "服务器未安装 pywin32,无法生成 Word 出库单" } ``` --- ### 6. SSE 日志流 ``` GET /api/logs/ Accept: text/event-stream ``` **日志行格式:** ``` data: 2026-05-26 12:00:01 [INFO ] extractor: 正在提取发票... ``` **结束消息:** ```json { "type": "done", "result": { } } ``` `result` 结构取决于触发来源: | 来源 | 典型字段 | |------|----------| | `/api/process` | `ok`, `elapsed`, `invoice_count`, `csv_url`, `md_url`, `doc_url`, `doc_ok`, `doc_error` | | `/api/submit-financial` | `ok`, `submit_ok`, `submit_error` | --- ### 7. 下载文件 ``` GET /api/download// ``` **响应:** 文件二进制流,带 `Content-Disposition: attachment` 与 UTF-8 文件名。 | 扩展名 | Content-Type | |--------|----------------| | `.csv` | `text/csv; charset=utf-8` | | `.md` | `text/markdown; charset=utf-8` | | `.doc` | `application/msword` | | 其它 | `application/octet-stream` | **常见文件名:** | 文件名 | 说明 | |--------|------| | `invoice_summary.csv` | 发票汇总(含 OCR 结果) | | `invoice_summary.md` | Markdown 摘要 | | `易耗品、出库单.doc` | 自动填写的出库单 | | 用户上传的 CSV 名 | CSV 快捷模式下的原始文件 | **错误:** ```json { "error": "文件不存在" } ``` HTTP `404`。`filename` 仅允许会话目录内的文件名(防止路径穿越)。 --- ### 8. 获取发票数据 ``` GET /api/data/ ``` **响应:** ```json { "csv_filename": "invoice_summary.csv", "fields": [ "序号", "发票号码", "开票日期", "项目名称", "规格型号", "价税合计", "销售方名称", "人员姓名", "刷卡日期", "公务卡号", "刷卡金额", "备注", "工号" ], "data": [ { "__row": 0, "序号": "1", "发票号码": "26442000005432755951", "价税合计": "2900.00" } ] } ``` - `fields`:列顺序 - `data[].__row`:内部行索引(保存时不需要提交,服务端按数组顺序写回) **错误:** `404` 未找到 CSV;`500` 读取失败。 --- ### 9. 保存编辑后的发票数据 ``` POST /api/save/ Content-Type: application/json ``` **请求体:** ```json { "csv_filename": "invoice_summary.csv", "data": [ { "序号": "1", "发票号码": "26442000005432755951", "开票日期": "2026/05/18", "项目名称": "...", "规格型号": "...", "价税合计": "2900.00", "销售方名称": "...", "人员姓名": "", "刷卡日期": "2026/04/28", "公务卡号": "", "刷卡金额": "2850.00", "备注": "", "工号": "202407021" } ] } ``` **响应(成功):** ```json { "ok": true, "doc_ok": true, "doc_url": "/api/download//%E6%98%93%E8%80%97%E5%93%81%E3%80%81%E5%87%BA%E5%BA%93%E5%8D%95.doc" } ``` 保存后会根据最新 CSV **重新生成** 出库单 Word(与会话 `config.json` 中的 `consumable_storage` 等配置一致)。 若出库单生成失败: ```json { "ok": true, "doc_ok": false, "doc_error": "出库单模板不存在,请将模板放在项目根目录" } ``` --- ### 10. 提交到财务系统 ``` POST /api/submit-financial/ ``` **前置条件:** - 会话目录存在 `config.json`(由 `/api/process` 写入) - 存在可用的发票 CSV(通常为 `invoice_summary.csv`) **说明:** 前端一般在提交前调用 `/api/save` 保存表格修改。本接口**不会**自动执行发票提取或 OCR。 **响应(立即):** ```json { "status": "started" } ``` **SSE 完成示例:** ```json { "type": "done", "result": { "ok": true, "submit_ok": true } } ``` 失败时 `submit_ok: false`,`submit_error` 为错误描述。 --- ### 11. 移动端上传页面 ``` GET /mobile/ ``` 返回移动端 HTML 页面。扫码上传的图片与 PC 端共用同一会话目录;PC 通过轮询 `GET /api/files/` 同步文件列表。 --- ### 12. 移动端上传图片 ``` POST /api/mobile-upload/ Content-Type: multipart/form-data ``` | 字段 | 类型 | 说明 | |------|------|------| | file | File | 图片文件 | 逻辑与 `POST /api/upload/` 相同。 --- ## 错误码汇总 | HTTP | 场景 | |------|------| | 400 | 参数缺失、未找到配置等 | | 404 | `session_id` 不存在、文件不存在 | | 500 | CSV 读取失败等内部错误 | 统一错误体: ```json { "error": "错误描述" } ``` --- ## 端到端流程 ```mermaid sequenceDiagram participant PC as PC 端 participant Server as Server participant Mobile as 移动端 participant Word as Word COM PC->>Server: POST /api/session Server-->>PC: session_id PC->>Server: POST /api/upload/{sid} PC->>Server: POST /api/process/{sid} Note over Server: PDF 提取 + OCR + 写 config.json Server->>Word: 复制模板并填写出库单 Server-->>PC: SSE done (csv_url, doc_url, ...) PC->>Server: GET /api/data/{sid} Server-->>PC: fields + data PC->>Server: POST /api/save/{sid} Note over Server: 更新 CSV,重新生成出库单 Server-->>PC: doc_url PC->>Server: GET /api/download/{sid}/易耗品、出库单.doc PC->>Server: POST /api/submit-financial/{sid} Note over Server: Playwright 浏览器填报 Server-->>PC: SSE done (submit_ok) Mobile->>Server: POST /api/mobile-upload/{sid} PC->>Server: GET /api/files/{sid} (轮询) ``` --- ## 相关 CLI 不经过 Web、在本地直接填写出库单: ```bash python -m app.fill_consumable_doc --csv invoice_summary.csv --doc "易耗品、出库单.doc" ``` 详见 [README.md](./README.md)。