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

10 KiB
Raw Blame History

阜阳师范大学财务报销系统 - 自动化脚本操作指南

适用场景:日常报销录入(基于 reimburse.py 脚本) 最后更新2026-05-23


一、系统概览

整体流程:

信息门户(SSO登录) → 财务系统入口 → 单点登录页 → 网络报销 → 日常报销录入
(tyrz.fynu.edu.cn)   (点击"财务系统")  (新标签页)   (a:has(img))   (/expen/common/common)

目标系统: http://210.45.32.214:8081
用户: 王建锋 (工号: 202407021)

关键 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 目标录入页面

二、数据准备

2.1 发票数据 CSV

脚本从 invoice_summary.csvGBK 编码读取发票数据CSV 需包含以下列:

列名 说明 示例
序号 发票序号 1, 2, 3...
发票号码 发票编号 26442000005432652421
开票日期 发票开具日期 2026/5/18
项目名称 采购项目名称 电阻一批
规格型号 规格型号
价税合计 发票金额 2900.00
销售方名称 商户/销售方 佛山市泓宇芯科技有限公司
人员姓名 报销人 王建锋(默认值)
刷卡日期 公务卡消费日期 2026/5/18 → 自动转为 2026-05-18
公务卡号 公务卡卡号 6282880139161682默认值
刷卡金额 实际刷卡金额 2900.00
备注 备注信息
工号 人员工号 202407021默认值

2.2 附件文件

脚本自动扫描当前工作目录下所有 .pdf 文件,按文件名排序后与发票一一对应上传。确保 PDF 文件名与发票顺序一致。


三、脚本执行流程

运行方式

python reimburse.py --data invoice_summary.csv

支持命令行覆盖配置:

python reimburse.py \
  --data invoice_summary.csv \
  --username 202407021 \
  --password "your_password" \
  --user-data-dir browser_profile

执行步骤

脚本按以下顺序自动执行,截图保存在 images/ 目录:

Step 0: 登录信息门户
  ├── 访问 SSO 登录页
  ├── 填写工号 + 密码
  ├── 勾选用户协议复选框
  ├── 点击"登录"按钮
  └── 等待跳转到信息门户 (zs-uip/oshall/portal)

Step 1: 进入报销系统
  ├── 点击"财务系统"快捷入口
  ├── 等待新标签页打开 (含 dddl 或 210.45.32.214)
  ├── 切换到新标签页
  ├── 关闭旧标签页
  ├── 通过 a:has(img[src*="wlbx"]) 定位"网络报销"链接
  ├── 提取链接 URL 并导航
  ├── 等待"报销录入"文本出现
  └── 导航到 /expen/common/common?v=4.0

Step 2: 创建新报销单
  ├── 等待 2 秒
  ├── 点击 button:has-text("新增")
  └── 等待表单加载 3 秒

Step 3: 填写基本信息
  ├── 填写 #EXPENEXPLAIN → "元器件采购报销"
  ├── 点击 #PROJECTCODE 打开项目选择弹窗
  ├── 在 #promodal .fixed-table-body tbody tr 中点击第一行
  └── 点击 #saveAndNext 进入下一步

Step 4: 录入报销明细(一条总明细)
  ├── 计算所有发票的刷卡金额合计
  ├── 点击 #insertDetail 打开增加明细弹窗
  ├── 点击 #economicscode2 打开经济科目选择
  ├── 在 #econmodal 中选择第 3 行经济科目
  ├── 填写单据数 = 发票张数
  ├── 填写报销总金额 = 刷卡金额合计
  └── 点击 #detailAdd 确认

Step 5: 录入支付方式(逐张发票)
  ├── 点击 "下一步(支付方式)"
  ├── 对每张发票循环:
  │   ├── 点击 #insertPay
  │   ├── 填写 #personid2 (工号)
  │   ├── 填写 #accountname2 (姓名)
  │   ├── 填写 #receiptdate2 (刷卡日期)
  │   ├── 填写 #localaccount2 (固定卡号: 6282880139161682)
  │   ├── 填写 #receiptmoney2 (刷卡金额)
  │   ├── 填写 #money2 (实报金额 = 刷卡金额)
  │   ├── 填写 #merchant2 (销售方名称)
  │   ├── 填写 #smark2 (备注)
  │   └── 点击 #payAdd 确认
  └── 所有发票录入完成

Step 6: 上传附件(逐张发票)
  ├── 点击 #next3 切换到附件清单页面
  ├── 对每张发票循环:
  │   ├── 点击 #insertAcc 打开附件弹窗
  │   ├── select_option #fjlx → '1' (发票类型)
  │   ├── 填写 #fpsmxx (项目名称 - 发票号码)
  │   ├── set_input_files #file (对应 PDF 文件)
  │   └── 点击 #cjtj 确认
  └── 所有附件上传完成

提交阶段:
  └── 点击 #submit (当前已注释,需手动取消注释)

四、页面元素速查

基本信息页 (Step 3)

字段 选择器 操作
报销说明 #EXPENEXPLAIN fill
项目代码 #PROJECTCODE click → 弹窗选择
项目弹窗 #promodal .fixed-table-body tbody tr 点击第一行
下一步按钮 #saveAndNext click

报销明细页 (Step 4)

字段 选择器 操作
增加按钮 #insertDetail click
经济事项代码 #economicscode2 click → 弹窗选择
经济科目弹窗 #econmodal .fixed-table-body tbody tr 点击第 3 行
单据数 input[name="expenPwCommondetail.HOWBILLS"] fill
报销总金额 #je_zwzcdz fill
确定按钮 #detailAdd click

支付方式页 (Step 5)

字段 选择器 操作
增加按钮 #insertPay click
人员编号 #personid2 fill
人员姓名 #accountname2 fill
刷卡日期 #receiptdate2 fill
公务卡号 #localaccount2 fill (固定值)
刷卡金额 #receiptmoney2 fill
实报金额 #money2 fill
商户 #merchant2 fill
备注 #smark2 fill
确定按钮 #payAdd click

附件清单页 (Step 6)

字段 选择器 操作
增加按钮 #insertAcc click
附件类型 #fjlx select_option → '1'(发票)
附件说明 #fpsmxx fill
文件上传 #file set_input_files
确定按钮 #cjtj click

提交

操作 选择器
提交按钮 #submit
提交按钮(备用) #submit2

五、数据流向

invoice_summary.csv (GBK)
    │
    ▼ load_invoice_data()
    │
    ├── 读取 CSV 行
    ├── 日期格式转换 (2026/5/18 → 2026-05-18)
    ├── 填充默认值 (姓名/卡号/工号)
    └── 输出: list[dict]
            │
            ▼ add_reimburse_items()
            ├── 计算: card_amount = sum(所有发票刷卡金额)
            ├── 单据数 = len(invoices)
            └── 录入 1 条总明细
            │
            ▼ fill_payment()
            └── 对每张发票录入 1 条支付记录
            │
            ▼ upload_attachments()
            ├── 扫描 *.pdf 文件
            └── 按索引匹配发票 → PDF逐张上传

六、关键设计说明

6.1 浏览器复用

脚本使用 launch_persistent_context 持久化浏览器上下文,登录状态保存在 browser_profile/ 目录。再次运行时复用已有会话,无需重复登录。

6.2 明细录入策略

脚本采用"一条总明细"策略:将所有发票合并为一条报销明细,报销总金额为所有发票刷卡金额之和,单据数为发票总张数。支付方式则逐张发票分别录入,每张发票对应一条支付记录。

6.3 经济科目选择

脚本在经济科目弹窗中固定选择第 3 行。如需更改科目,修改 rows[2] 的索引即可。

6.4 项目选择

脚本在项目选择弹窗中固定选择第 1 行。如需更改项目,修改 first_row 的选择逻辑即可。

6.5 网络报销链接动态获取

单点登录页的"网络报销"链接参数每次不同,脚本通过 a:has(img[src*="wlbx"]) 精确定位链接,动态提取 href 属性后导航,不硬编码 URL。

6.6 提交控制

脚本默认注释了 bot.submit() 调用。完成所有录入后停留在附件清单页面,需人工确认数据无误后,取消注释 bot.submit() 再运行,或手动点击提交按钮。


七、日志与调试

日志输出

  • 控制台实时输出DEBUG 级别)
  • 文件日志:reimburse.logUTF-8 编码)

截图保存

每个关键步骤自动截图到 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_submitted.png 提交完成
debug_error.png 异常状态

超时设置

  • 页面默认超时30 秒
  • 登录门户等待:最多 30 秒
  • 单点登录页等待:最多 15 秒

八、常见问题

问题 原因 解决方案
登录超时 SSO 需要手动验证码/微信扫码 手动完成验证后脚本继续
未找到财务系统入口 门户页面结构变化 检查 images/debug_* 截图定位
经济科目选择失败 弹窗加载延迟 检查超时设置,增加等待时间
附件上传失败 PDF 文件不存在或路径错误 确认 PDF 在当前工作目录
金额不匹配 明细合计 ≠ 支付合计 检查 CSV 数据中刷卡金额
提交被拦截 必填项为空 检查 reimburse.log 定位失败步骤