---
last_reviewed: 2026-06-09
---

# src/web 模块设计说明

## 设计思路

`src/web` 是一个基于 Flask 的轻量级 Web 界面，为财务报销自动化管道提供可视化操作入口。核心设计原则：

- **会话隔离**：每次上传生成独立 `session_id`，文件、日志、配置、结果各自隔离在 `uploads/<session_id>/` 目录下，避免并发冲突。
- **异步处理**：耗时的 PDF 提取、LLM 调用在后台线程执行，前端通过 SSE 实时查看日志流，不阻塞 HTTP 连接。
- **前后端分离最小化**：前端使用原生 JS + Bootstrap 5，不引入构建工具，保持单页应用轻量可维护。

## 文件结构

```
src/web/
├── app.py                  # Flask 应用入口，路由、管道编排、日志收集
├── templates/
│   ├── index.html          # PC 端主界面（上传、配置、处理、编辑、提交）
│   └── mobile_upload.html  # 移动端上传页面（拍照/相册选择）
└── static/
    ├── css/
    │   └── index.css       # 全局样式（上传区、日志面板、可编辑表格）
    └── js/
        └── index.js        # 前端逻辑（上传、SSE 日志、表格编辑、二维码同步）
```

## 数据流

```
用户上传文件 → 创建 session → 文件写入 uploads/<sid>/
     ↓
后台线程执行管道: extract_invoices() → enrich_with_llm() → save_csv()
     ↓
结果写入 session 目录: invoice_summary.csv / result.json / session.log
     ↓
前端 SSE 轮询 result.json 变化 → 显示完成状态
     ↓
前端加载 CSV 数据 → 可编辑表格展示 → 用户修改后保存
     ↓
用户点击提交 → run_financial_submit() → bot 自动填报财务系统
```

## API 路由

| 方法 | 路径 | 功能 |
|------|------|------|
| GET | `/` | 主界面 |
| POST | `/api/session` | 创建会话，返回 session_id |
| POST | `/api/upload/<sid>` | 上传 PDF/图片 |
| GET | `/api/files/<sid>` | 列出会话文件 |
| POST | `/api/process/<sid>` | 启动管道（后台线程） |
| GET | `/api/logs/<sid>` | SSE 日志流 |
| GET | `/api/data/<sid>` | 获取发票数据 JSON |
| POST | `/api/save/<sid>` | 保存前端编辑的发票数据 |
| GET | `/api/download/<sid>/<filename>` | 下载生成文件 |
| POST | `/api/submit-financial/<sid>` | 手动触发财务系统填报 |
| GET | `/mobile/<sid>` | 移动端上传页面 |

## 关键机制

### 日志收集

`_SSELogHandler` 将管道日志写入 `session.log`，SSE 端点通过文件偏移量增量读取，实现前端实时日志展示。日志收集器在管道启动时安装，完成后移除，确保线程安全。

### 发票类型分流

- **差旅发票**（高铁票/酒店住宿）：不生成易耗品出库单，走差旅报销流程
- **普通发票**：生成易耗品出库单（Word 文档），走普通报销流程

`classify_invoice_batch()` 根据发票内容自动分类，`_try_fill_consumable_doc()` 仅对普通发票生成出库单。

### 移动端同步

PC 端生成二维码指向 `/mobile/<sid>`，手机端上传的图片通过 `syncFiles()` 轮询同步到 PC 端内存中的 `imgFiles` 列表，实现跨设备协作。文件来源标记（`__source`）区分本地选择和服务器同步，避免重复。

### 配置管理

配置分两层：项目级 `config.json` 提供默认值，会话级 `uploads/<sid>/config.json` 存储当次会话覆盖值。前端支持通过上传 `config.json` 快速填充配置表单。