Files
Auto-Finance/docs/报销操作指南.md

454 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
last_reviewed: 2026-06-09
---
# 阜阳师范大学财务报销系统 - 自动化操作指南
> 适用场景:日常报销录入(支持 Web 界面和 CLI 两种方式)
> 最后更新2026-06-09
---
## 一、系统概览
```
整体流程:
信息门户(SSO登录) → 财务系统入口 → 单点登录页 → 网络报销 → 日常报销录入
(tyrz.fynu.edu.cn) (点击"财务系统") (新标签页) (a:has(img)) (/expen/common/common)
目标系统: http://210.45.32.214:8081
用户: 张三 (工号: xxxxxxx)
```
### 关键 URL
| 系统 | URL | 说明 |
|------|-----|------|
| SSO 登录 | `https://tyrz.fynu.edu.cn/sso/login` | 统一认证入口 |
| 信息门户 | `https://tyrz.fynu.edu.cn/oshall` | 登录后跳转目标 |
| 报销系统 | `http://210.45.32.214:8081` | 网络报销主系统 |
| 日常报销录入 | `/expen/common/common?v=4.0` | 目标录入页面 |
---
## 二、两种使用方式
### 方式一Web 界面(推荐)
适合日常使用,可视化操作,支持手机端拍照上传。
```bash
uv run python src/web/app.py
# 访问: http://localhost:5000
```
### 方式二CLI 命令行
适合脚本化、批量处理。
```bash
# 全流程(发票提取 → LLM 识别 → 浏览器填报)
uv run python src/main.py
# 分步执行
uv run python src/main.py --step invoice # 仅发票提取
uv run python src/main.py --step submit # 仅浏览器填报
# 覆盖登录凭据
uv run python src/main.py -u 202407021 -p "your_password"
```
---
## 三、数据准备
### 3.1 发票数据 CSV
上传 PDF 发票文件和支付截图,系统自动完成:
1. 从 PDF 提取发票信息
2. 多模态 LLM 识别支付截图中的刷卡信息
3. 生成 `invoice_summary.csv`
### 3.2 发票类型分类
系统自动将发票分为两类,影响后续处理流程:
| 类型 | 判断依据 | 出库单 | 报销流程 |
|------|----------|--------|----------|
| 差旅发票 | 高铁票、酒店住宿等 | 不生成 | 差旅报销 |
| 普通发票 | 其他(办公用品、耗材等) | 自动生成 | 普通报销 |
### 3.3 附件文件
PDF 发票文件需与支付截图配对上传。系统通过金额匹配自动关联发票和支付记录。
---
## 四、Web 界面操作流程
### 4.1 启动服务
```bash
uv run python src/web/app.py
# 访问: http://localhost:5000
```
### 4.2 上传文件
1. **发票 PDF**:点击或拖拽上传 PDF 文件(支持多选)
2. **支付截图**:点击或拖拽上传图片文件(支持多选)
3. **手机扫码上传**:扫描页面二维码,通过手机拍照上传支付截图
### 4.3 配置信息
填写以下配置项(也可通过上传 `config.json` 快速填充):
| 字段 | 说明 |
|------|------|
| 账号 | 财务系统工号 |
| 密码 | 登录密码 |
| 默认姓名 | 报销人姓名 |
| 公务卡号 | 公务卡卡号 |
| 人员编号 | 人员编号 |
| 存放地点 | 出库单存放地点 |
### 4.4 开始处理
点击"开始处理"按钮,系统自动执行:
1. **发票提取**:从 PDF 提取发票信息
2. **LLM 信息提取**:多模态 LLM 识别支付截图中的刷卡信息
3. **发票分类**:自动区分差旅发票和普通发票
4. **出库单生成**:普通发票自动生成易耗品出库单(差旅发票跳过)
处理过程中可在日志面板实时查看进度。
### 4.5 编辑发票数据
处理完成后,发票数据以可编辑表格形式展示:
- 直接点击单元格即可编辑
- 修改后点击"提交到财务系统"时自动保存
- 保存后会自动重新生成出库单
### 4.6 下载文件
处理完成后下载:
| 文件 | 说明 |
|------|------|
| `invoice_summary.csv` | 发票汇总数据 |
| `易耗品、出库单.doc` | 自动填写的出库单(仅普通发票) |
### 4.7 提交到财务系统
确认数据无误后,点击"提交到财务系统"按钮,系统自动:
1. 登录信息门户
2. 进入财务系统
3. 创建报销单
4. 填写基本信息
5. 录入报销明细
6. 录入支付方式
7. 上传附件
---
## 五、CLI 执行流程
### 5.1 全流程执行
```bash
uv run python src/main.py
```
执行步骤:
```
Step 1: 发票提取
├── 扫描 PDF 发票文件
├── 提取发票信息
├── 生成 invoice_summary.csv
└── 自动分类(差旅/普通)
Step 2: LLM 信息提取
├── 扫描支付截图
├── 多模态 LLM 识别刷卡信息
├── 回填 CSV 刷卡字段
└── 更新 invoice_summary.csv
Step 3: 报销提交
├── 登录信息门户
├── 进入财务系统
├── 创建报销单
├── 填写基本信息
├── 录入报销明细
├── 录入支付方式
├── 上传附件
└── 提交(需手动确认)
```
### 5.2 分步执行
```bash
# 仅发票提取
uv run python src/main.py --step invoice
# 仅浏览器填报
uv run python src/main.py --step submit
```
### 5.3 上传目录
CLI 模式自动发现 `src/web/uploads/` 下最新的会话文件夹,该文件夹包含上传的 PDF 和图片。
---
## 六、页面元素速查
### 基本信息页
| 字段 | 选择器 | 操作 |
|------|--------|------|
| 报销说明 | `#EXPENEXPLAIN` | fill |
| 项目代码 | `#PROJECTCODE` | click → 弹窗选择 |
| 项目弹窗 | `#promodal .fixed-table-body tbody tr` | 点击第一行 |
| 下一步按钮 | `#saveAndNext` | click |
### 报销明细页
| 字段 | 选择器 | 操作 |
|------|--------|------|
| 增加按钮 | `#insertDetail` | click |
| 经济事项代码 | `#economicscode2` | click → 弹窗选择 |
| 经济科目弹窗 | `#econmodal .fixed-table-body tbody tr` | 点击第 3 行 |
| 单据数 | `input[name="expenPwCommondetail.HOWBILLS"]` | fill |
| 报销总金额 | `#je_zwzcdz` | fill |
| 确定按钮 | `#detailAdd` | click |
### 支付方式页
| 字段 | 选择器 | 操作 |
|------|--------|------|
| 增加按钮 | `#insertPay` | click |
| 人员编号 | `#personid2` | fill |
| 人员姓名 | `#accountname2` | fill |
| 刷卡日期 | `#receiptdate2` | fill |
| 公务卡号 | `#localaccount2` | fill |
| 刷卡金额 | `#receiptmoney2` | fill |
| 实报金额 | `#money2` | fill |
| 商户 | `#merchant2` | fill |
| 备注 | `#smark2` | fill |
| 确定按钮 | `#payAdd` | click |
### 附件清单页
| 字段 | 选择器 | 操作 |
|------|--------|------|
| 增加按钮 | `#insertAcc` | click |
| 附件类型 | `#fjlx` | select_option → '1'(发票) |
| 附件说明 | `#fpsmxx` | fill |
| 文件上传 | `#file` | set_input_files |
| 确定按钮 | `#cjtj` | click |
### 提交
| 操作 | 选择器 |
|------|--------|
| 提交按钮 | `#submit` |
| 提交按钮(备用) | `#submit2` |
---
## 七、数据流向
```
PDF 发票 + 支付截图
▼ extract_invoices()
├── 读取 PDF 发票
├── 提取发票信息
├── 自动分类(差旅/普通)
└── 输出: invoice_summary.csv
▼ enrich_with_llm()
├── 多模态 LLM 识别支付截图
├── 回填刷卡字段
└── 更新 invoice_summary.csv
▼ fill_consumable_from_template()
├── 仅普通发票
├── 从模板复制出库单
└── 自动填写出库单
▼ run_bot()
├── 登录信息门户
├── 进入财务系统
├── 创建报销单
├── 填写基本信息
├── 录入报销明细
├── 录入支付方式
├── 上传附件
└── 提交
```
---
## 八、关键设计说明
### 8.1 浏览器启动
系统使用 Playwright 的 `sync_playwright()` 启动 Chromium 浏览器,支持 `headless` 模式。每次运行均启动新浏览器实例,需重新登录。可通过 `headless` 参数控制是否显示浏览器窗口。
### 8.2 明细录入策略
系统采用"一条总明细"策略:将所有发票合并为一条报销明细,报销总金额为所有发票刷卡金额之和,单据数为发票总张数。支付方式则逐张发票分别录入,每张发票对应一条支付记录。
### 8.3 经济科目选择
系统在经济科目弹窗中固定选择第 3 行。如需更改科目,修改 `rows[2]` 的索引即可。
### 8.4 项目选择
系统在项目选择弹窗中固定选择第 1 行。如需更改项目,修改 `first_row` 的选择逻辑即可。
### 8.5 网络报销链接动态获取
单点登录页的"网络报销"链接参数每次不同,系统通过 `a:has(img[src*="wlbx"])` 精确定位链接,动态提取 `href` 属性后导航,不硬编码 URL。
### 8.6 发票类型分流
- **差旅发票**(高铁票/酒店住宿):不生成易耗品出库单,走差旅报销流程
- **普通发票**:生成易耗品出库单,走普通报销流程
### 8.7 移动端同步
PC 端生成二维码指向移动端上传页面,手机端上传的图片通过轮询同步到 PC 端,实现跨设备协作。
---
## 九、配置说明
### config.json
项目根目录 `config.json` 包含默认配置:
```json
{
"username": "202407021",
"password": "your_password",
"sso_login_url": "https://tyrz.fynu.edu.cn/sso/login",
"portal_url": "https://tyrz.fynu.edu.cn/oshall",
"reimburse_url": "http://210.45.32.214:8081",
"reimburse_page": "/expen/common/common?v=4.0",
"default_name": "王建锋",
"default_card_no": "6282880139161682",
"default_person_id": "202407021",
"consumable_storage": "躬行楼 C205",
"llm": {
"model": "qwen3.5-9b",
"api_base": "http://100.123.83.115:1234/v1",
"api_key": "123456"
}
}
```
| 字段 | 说明 |
|------|------|
| `username` | 财务系统工号 |
| `password` | 登录密码 |
| `sso_login_url` | SSO 登录地址 |
| `portal_url` | 信息门户地址 |
| `reimburse_url` | 报销系统地址 |
| `reimburse_page` | 报销录入页面路径 |
| `default_name` | 默认报销人姓名 |
| `default_card_no` | 默认公务卡号 |
| `default_person_id` | 默认人员编号 |
| `consumable_storage` | 出库单存放地点 |
| `llm.model` | LLM 模型名称 |
| `llm.api_base` | LLM API 地址 |
| `llm.api_key` | LLM API 密钥 |
---
## 十、日志与调试
### 日志输出
- 控制台实时输出INFO 级别)
- 文件日志:`logs/<日期>.log`UTF-8 编码)
- Web 界面:实时 SSE 日志流
### 截图保存
每个关键步骤自动截图到 `images/` 目录:
| 截图文件 | 对应步骤 |
|----------|----------|
| `debug_portal_loaded.png` | 登录成功 |
| `debug_step3_project_modal.png` | 项目弹窗打开 |
| `debug_step3_project_selected.png` | 项目选择完成 |
| `debug_step3_done.png` | 基本信息完成 |
| `debug_after_add_click.png` | 点击新增后 |
| `debug_item_total.png` | 总明细录入完成 |
| `debug_step5_done.png` | 支付方式完成 |
| `debug_step6_done.png` | 附件上传完成 |
| `debug_error.png` | 异常状态 |
### 超时设置
- 页面默认超时30 秒
- 登录门户等待:最多 30 秒
- 单点登录页等待:最多 15 秒
- SSE 日志流超时10 分钟600 秒)
---
## 十一、常见问题
| 问题 | 原因 | 解决方案 |
|------|------|----------|
| 登录超时 | SSO 需要手动验证码/微信扫码 | 手动完成验证后脚本继续 |
| 未找到财务系统入口 | 门户页面结构变化 | 检查 `images/debug_*` 截图定位 |
| 经济科目选择失败 | 弹窗加载延迟 | 检查超时设置,增加等待时间 |
| 附件上传失败 | PDF 文件不存在或路径错误 | 确认 PDF 在当前工作目录 |
| 金额不匹配 | 明细合计 ≠ 支付合计 | 检查 CSV 数据中刷卡金额 |
| 提交被拦截 | 必填项为空 | 检查 `logs/<日期>.log` 定位失败步骤 |
| LLM 多模态提取失败 | llama-index 版本不兼容 | 确保使用 llama-index-core >= 0.14.x多模态消息使用 `blocks` 格式 |
| 出库单生成失败 | 缺少 pywin32 或模板文件 | 安装 `pywin32`,确保项目根目录有 `易耗品、出库单.doc` 模板 |
| 差旅发票生成了出库单 | 分类不准确 | 检查发票内容是否包含"高铁票""酒店住宿"等关键词 |
---
## 十二、相关 CLI 命令
### 单独填写出库单
```bash
uv run python -m src.doc.fill_consumable_doc --csv invoice_summary.csv --doc "易耗品、出库单.doc"
```
### 分步执行管道
```bash
# 仅发票提取
uv run python src/main.py --step invoice
# 仅浏览器填报
uv run python src/main.py --step submit
```
### 启动 Web 服务
```bash
uv run python src/web/app.py
# 访问: http://localhost:5000
```
---
## 附录API 文档
详细的 API 接口文档见 [API.md](./API.md)。