# 铁路系统发票批量处理使用说明 ## 原则 - 只使用铁路 12306 官方页面/App 完成开票。 - 本工具不保存 12306 账号密码,不绕过验证码或身份核验。 - 公司抬头、税号、接收邮箱从本地配置读取;不要写入 `.env`。 - `config.local.json` 已被 `.gitignore` 忽略,不要把真实公司信息写进 `config.example.json`。 ## 初始化 ```bash python3 scripts/invoice_tool.py init ``` 先复制一份本地配置: ```bash cp config.example.json config.local.json ``` 然后把 `config.local.json` 里的三项改成真实值: ```json { "company_title": "公司全称", "tax_id": "统一社会信用代码", "receiver_email": "统一收票邮箱" } ``` ## 导入开票码 把旅行社给的二维码图片或 PDF 放到: ```text data/input/开票码批次/ ``` 执行: ```bash python3 scripts/invoice_tool.py import-codes ``` 输出台账: ```text work/invoice_tasks.csv ``` 如果本机没有二维码解码器,任务会进入 `待补码`。人工扫码后,把链接或码写入: ```text data/input/开票码批次/manual_codes.csv ``` 再执行一次 `import-codes`。 如果这是铁路“扫码开票单”截图,二维码通常只能用 12306 App 扫。可以在 `manual_codes.csv` 里用 `APP_SCAN` 补录开票单号和代办人: ```csv source_file,passenger,ticket_ref,code data/input/开票码批次/ScreenShot_xxx.png,张*木,EKP37846902581249178,APP_SCAN ``` ## 真实手工 POC 第一次必须用 1-3 张真实开票码在 Mac 上跑通: 1. 把真实二维码图片/PDF 放进 `data/input/开票码批次/`。 2. 执行 `python3 scripts/invoice_tool.py import-codes`。 3. 打开 `work/invoice_tasks.csv` 看状态: - `待网页开票`:说明二维码可在 Mac 网页端继续,后续可做更强的网页自动化。 - `待人工扫码` / `待补码`:说明大概率要 12306 App 扫码,Mac 端只能做台账、收票和归档自动化。 4. 手动登录 12306,完成身份核验。 5. 执行 `python3 scripts/invoice_tool.py rpa-plan`,打开 `output/rpa_helper.html`。 6. 用辅助页逐条打开官方页面,填写统一公司抬头、税号、邮箱并提交。 7. 收到邮件后,把 `.eml` 放入 `data/mail/`,或把附件放入 `data/attachments/`。 8. 执行归集和汇总命令,检查 `output/发票汇总.xlsx`。 ## Android 自动填写身份证后 8 位 适用场景:12306 App 扫码后,页面显示脱敏姓名(如 `张*岩`),要求输入身份证后 8 位验证码。 ### 本地 Web UI 启动本地页面: ```bash python3 scripts/web_ui.py ``` 打开: ```text http://127.0.0.1:8765 ``` 页面支持上传 `.xlsx/.xlsm/.csv` 名单、查看成功/失败/处理中/未操作统计、显示手机连接/当前 App 状态、启动手机 12306、抓取当前页队列、启动/停止批处理,并持续读取: ```text work/android_invoice_progress.csv ``` 这个 CSV 是逐人处理结果表,页面里的“下载进度表”会直接下载它。 ### 1. 导入 Excel 名单 名单里至少要有“姓名”和“身份证/证件号码”两类列名。支持 `.xlsx/.xlsm/.csv`: ```bash python3 scripts/invoice_tool.py import-roster --input /path/to/名单.xlsx ``` 输出: ```text work/passenger_roster.csv ``` 先离线验证一个脱敏姓名: ```bash python3 scripts/invoice_tool.py match-roster --masked-name '张*岩' ``` 如果出现 `ambiguous`,说明同名脱敏后匹配到多人,必须人工确认。 ### 2. 连接 Android 手机 手机开启 USB 调试后连接 Mac: ```bash /opt/homebrew/share/android-commandlinetools/platform-tools/adb devices ``` 先手工在 12306 App 扫码,进入要求填写身份证后 8 位的页面。 读取当前页面文字: ```bash python3 scripts/invoice_tool.py android-dump --output work/android_page.txt ``` 如果能看到 `张*岩` 这类文字,就可以自动匹配并输入身份证后 8 位: ```bash python3 scripts/invoice_tool.py android-type-id --tap 500,1200 ``` `--tap` 是输入框坐标,需要按手机页面实际位置改。也可以用按钮/输入框可访问文字: ```bash python3 scripts/invoice_tool.py android-type-id --click-text '证件号码后8位' --contains ``` ### 3. 后续点击流程 复制并修改模板: ```bash cp templates/android_flow.example.json templates/android_flow.local.json python3 scripts/invoice_tool.py android-run-flow --flow templates/android_flow.local.json ``` 模板支持这些动作: | action | 用途 | |---|---| | `click_text` | 按完整文字点击 | | `click_contains` | 按包含文字点击 | | `tap` | 按坐标点击 | | `input_id8_for_visible_masked_name` | 从当前页面识别 `张*岩` 并输入身份证后 8 位 | | `input_config` | 输入 `config.local.json` 中的公司抬头、税号、邮箱 | | `input_text` | 输入固定文本 | | `sleep` | 等待 | | `keyevent` | 发送 Android keyevent | 真实 12306 App 页面可能不暴露全部控件文字。遇到找不到控件时,用 `android-dump` 看文字;如果没有文字,就改用 `tap` 坐标。 ### 4. 单步状态机 当前页面已校准后,优先用单步命令。它每次只做一步动作,默认等待 `10 秒`,未出现目标状态再等 `20 秒`,仍不成功就暂停: ```bash python3 scripts/invoice_tool.py android-invoice-step ``` 如果当前在“发票开具成功”页,默认会点 `继续开票` 回列表。需要先发邮件时才加: ```bash python3 scripts/invoice_tool.py android-invoice-step --send-email ``` ### 5. 扫码列表页批处理队列 扫码开票单列表页不要用固定坐标。先抓当前可见的一页,按脱敏姓名和名单生成队列: ```bash python3 scripts/invoice_tool.py android-build-page-queue ``` 队列文件: ```text work/android_page_queue.csv ``` 然后反复跑: ```bash python3 scripts/invoice_tool.py android-page-step ``` 行为: - 当前在扫码列表页:按本页队列点击下一个可匹配人员的 `开具`。 - 当前在核验/发票管理/发票信息/成功页:执行普通单步状态机。 - 本页没有可处理人员:输出 `page_done`,不自动乱滑。 本页处理完后上滑到下一页并重建队列: ```bash python3 scripts/invoice_tool.py android-page-next --rebuild ``` 也可以让 `android-page-step` 在本页完成后自动上滑: ```bash python3 scripts/invoice_tool.py android-page-step --auto-next ``` ## 网页辅助开票 ```bash python3 scripts/invoice_tool.py rpa-plan ``` 打开: ```text output/rpa_helper.html ``` 先手动登录 12306 并完成核验,再逐条打开官方页面,复制公司抬头、税号和邮箱提交。 ## 邮件和附件归集 如果有 `.eml` 邮件文件: ```bash python3 scripts/invoice_tool.py collect-mail ``` 如果已经把 PDF/OFD/XML 附件下载到 `data/attachments/`: ```bash python3 scripts/invoice_tool.py collect-attachments ``` 归集后的发票在: ```text output/invoices/ ``` ## 汇总和查漏 ```bash python3 scripts/invoice_tool.py export-summary ``` 输出: ```text output/发票汇总.xlsx ``` 工作簿包含: - `发票汇总` - `缺票清单` - `合规检查` ## 状态含义 | 状态 | 含义 | |---|---| | `待补码` | 未能自动识别二维码,需要人工扫码补录 | | `待人工扫码` | 码不是网页链接,通常需要 12306 App 扫码 | | `待网页开票` | 可以从辅助页打开官方页面处理 | | `已收票` | 已匹配到发票附件 |