日常报销和差旅报销都可以走通

This commit is contained in:
wandering
2026-06-12 12:06:06 +08:00
parent 3bd325e827
commit 07f5872027
21 changed files with 1342 additions and 810 deletions
+31 -29
View File
@@ -1,5 +1,5 @@
---
last_reviewed: 2026-06-11
last_reviewed: 2026-06-12
---
# src — 主源码目录
@@ -12,41 +12,42 @@ last_reviewed: 2026-06-11
|-----------|------|
| `__init__.py` | 包初始化:提供 `get_logger()` 日志工厂(支持终端 + 文件双输出,按日期自动分文件) |
| `config.py` | 配置加载:从 `config.json` 读取用户凭据和默认值,从环境变量读取服务端配置(SSO 地址、LLM 参数) |
| `pipeline.py` | 流程编排:串联发票提取 → 分类 → CSV 保存 → 浏览器填报,支持分步执行 |
| `pipeline.py` | 流程编排:串联发票提取 → 类型判断 → 差旅/普通信息提取 → 浏览器填报,支持分步执行 |
| `main.py` | CLI 入口:支持 `--step` 分步执行、`-u/-p` 覆盖凭据、`--cache-dir` 指定缓存目录 |
| `bot.py` | 浏览器自动化:Playwright 驱动的财务系统填报机器人(含差旅/普通两种模式,支持 headless) |
| `bot/` | 浏览器自动化:Playwright 驱动的财务系统填报机器人(仅负责接收信息并填报) |
| `doc/` | 文档处理模块:PDF 渲染、LLM 提取、支付匹配、发票分类、出库单生成 |
| `web/` | Web 界面模块:Flask 应用、SSE 日志、可编辑表格、移动端上传、会话隔离 |
## 数据流
```mermaid
graph TD
A[CLI/Web 入口] --> B["pipeline.py (编排)"]
B --> C["doc/extractor.py (统一提取入口)"]
C --> D["doc/pdf.py (PDF 渲染为图片)"]
C --> E["doc/llm_extractor.py (多模态 LLM 识别)"]
E --> F["发票 invoice_type=train/hotel/general"]
E --> G["支付记录 invoice_type=payment"]
E --> H["出差事前申请单 invoice_type=application"]
C --> I["doc/matcher.py (发票与支付记录按金额匹配)"]
I --> J["一对一匹配 发票数 == 刷卡数"]
I --> K["一对多匹配 贪心算法 相对容差 3%"]
C --> L["doc/invoice.py (CSV/JSON 读写)"]
L --> M["payment_records.csv (支付记录级别)"]
L --> N["invoice_summary.csv (发票级别)"]
L --> O["travel_applications.json (出差申请单)"]
B --> R{"判断报销类型"}
R -->|差旅| T["doc/llm_extractor.py (差旅信息提取)"]
R -->|普通| V["doc/llm_extractor.py (普通发票信息提取)"]
T --> W["travel_info.json (差旅信息: 交通/住宿明细、补贴、附件清单)"]
V --> X["normal_info.json (普通发票信息: 报销说明、发票总数、总金额、支付方式、附件清单)"]
W --> P["bot/ (浏览器填报 - 仅接收信息并填报)"]
X --> P
P --> Q["差旅模式: travel_info.json → 填报差旅单 → 上传差旅附件"]
P --> S["普通模式: 基本信息 → 录入明细 → 支付信息 → 上传附件"]
```
CLI/Web 入口 → pipeline.py (编排)
↓
doc/extractor.py (统一提取入口)
↓
┌──── doc/pdf.py (PDF 渲染为图片)
│
├── doc/llm_extractor.py (多模态 LLM 识别)
│ ├── 发票 (invoice_type=train/hotel/general)
│ ├── 支付记录 (invoice_type=payment)
│ └── 出差事前申请单 (invoice_type=application)
│
├── doc/matcher.py (发票与支付记录按金额匹配)
│ ├── 一对一匹配 (发票数 == 刷卡数)
│ └── 一对多匹配 (贪心算法,相对容差 3%)
│
└── doc/invoice.py (CSV/JSON 读写)
├── payment_records.csv (支付记录级别)
├── invoice_summary.csv (发票级别)
└── travel_applications.json (出差申请单)
↓
doc/fill_consumable_doc.py (普通发票 → Word 出库单)
↓
bot.py (浏览器填报)
├── 差旅模式: 差旅信息提取 → 填报差旅单 → 上传差旅附件
└── 普通模式: 基本信息 → 录入明细 → 支付信息 → 上传附件
```
**数据流变更(2026-06-11):** 差旅信息提取从 `bot.py` 提升到 `pipeline.py` 编排层。在发票提取和匹配完成后立即判断报销类型,差旅发票调用 LLM 提取 `travel_info.json`,普通发票调用 LLM 提取 `normal_info.json`。Bot 仅负责接收信息并填报,不再承担信息提取职责。
## 文档处理子模块 (`doc/`)
@@ -57,6 +58,7 @@ CLI/Web 入口 → pipeline.py (编排)
- **JSON 缓存**:提取结果缓存于 `.invoice_cache/`,避免重复处理
- **金额匹配**:支持一对多匹配,相对容差 3%,未匹配发票单独列为记录
- **差旅信息提取**:综合发票、支付记录和匹配结果,提取出差事由、地点、时间等
- **普通发票信息提取**:综合普通发票、支付记录和匹配结果,提取报销说明、发票总数、总金额、支付方式、附件清单
- **出库单生成**:将 CSV 数据填入 Word 模板(pywin32 COM,仅 Windows)
## Web 界面子模块 (`web/`)