阿里公益平台发票自动化流水线。扫描未规范命名的电子发票 PDF,用百炼 bl 多模态识别提取"交款人"字段,按公司名重命名后归档,再用 Playwright/CDP 自动按抬头匹配并上传到公益平台。
Resources
8Install
npx skillscat add sl820/invoice-pipeline Install via the SkillsCat registry.
SKILL.md
invoice-pipeline
把 E:\阿里发票\*\ 下没规范命名的电子发票 PDF,变成 {交款人}.pdf,按抬头归档,再自动按抬头匹配后上传到阿里公益平台报销。
本 skill 是端到端流水线,默认全自动(无人工复核点),但任何一步失败都进 out/failed/ 并写失败日志,不丢单。
触发条件
满足任一即激活:
- 用户说"处理发票 / 重命名发票 / 上传发票 / 跑发票流水线 / 阿里发票"
- 用户指向
E:\阿里发票\<某目录>\*.pdf - 用户跑
scripts/Invoke-Pipeline.ps1或scripts/Invoke-Upload.ps1
主流程(5 步)
scan -> ocr -> rename -> archive -> upload
(1) (2) (3) (4) (5)Step 1-4: 重命名(不变)
- 扫 PDF
- 复用
mapping_*.json缓存或调bl抽交款人 - 改名为
{交款人}.pdf,同公司加(2)(3)后缀 - 可选按抬头归档
Step 5: 上传(新流程)
对每个 {交款人}.pdf:
- 平台登录 + 打开
/open/workbench/employee/org/donation/invoice/manage(票据管理) - 填"开票抬头"= 交款人 + 点查询
- **筛选"待开具"**状态的行
- 匹配规则:
- 0 条"待开具" → skip(记 failed:已开具 / 平台未申请)
- 1 条"待开具" → 自动上传
- 2+ 条"待开具" → skip(记 failed:让用户人工确认)
- 点"立即开票" → 弹框 →
setInputFiles - 等
.ant-upload-list-item出现 - 点"确 定" → 等弹框关闭(仅
--yes时) - 记录到
uploaded-state.json(幂等)
前置条件:
- 跑
scripts/Start-Chrome-CDP.ps1启动带远程调试端口(9222)的独立 Chrome - 首次在新窗口里手动登录公益平台(cookie 落盘到
C:\codex\chrome-gongyi)
平台关键 selector(已验证):
- 搜索表单:
input#control-hooks_invoiceTitle(开票抬头) - 查 询:
button:has-text('查 询') - 重 置:
button:has-text('重 置') - 立即开票:
table tbody tr.ant-table-row button:has(span:text-is('立即开票')) - 弹框文件输入:
.ant-modal input[type=file] - 上传完成:
.ant-modal .ant-upload-list-item - 确 定:
.ant-modal .ant-btn-primary:has-text('确 定') - 取 消:
.ant-modal .ant-btn:has-text('取 消')
快速开始
# Step 1-4: 重命名
.\scripts\Invoke-Pipeline.ps1 -SourceDir "E:\阿里发票\阿里257张"
# Step 5: 上传
.\scripts\Start-Chrome-CDP.ps1 # 启动 Chrome(首次手动登录)
.\scripts\Invoke-Upload.ps1 -SourceDir "E:\阿里发票\阿里257张" -DryRun # 干跑
.\scripts\Invoke-Upload.ps1 -SourceDir "E:\阿里发票\阿里257张" -Limit 1 # 测 1 张
.\scripts\Invoke-Upload.ps1 -SourceDir "E:\阿里发票\阿里257张" -Yes # 真传全量文件落点
| 路径 | 用途 |
|---|---|
SourceDir\*.pdf |
输入 + 重命名后输出 |
SourceDir\mapping_*.json |
OCR 缓存,幂等复用 |
upload\uploaded-state.json |
上传状态记录,幂等复用 |
out\failed\upload-*.log |
上传失败日志(match-not-found / no-pending / match-multiple / error) |
out\reports\upload-*.txt |
每次运行摘要(ok/skipped/failed) |
C:\codex\chrome-gongyi |
Chrome 独立 profile(首次登录后 cookie 落盘) |
失败处理(Step 5)
每个文件独立 try/catch,分流到不同状态:
| 情况 | 动作 | 落点 |
|---|---|---|
match-not-found |
skip | out\failed\upload-*.log |
no-pending |
skip | out\failed\upload-*.log |
match-multiple |
skip | out\failed\upload-*.log(含候选列表) |
upload-failed |
retry 2 次后 fail | out\failed\upload-*.log |
| CDP 端口 9222 未就绪 | 中断 | exit code 1 |
| Chrome 未登录 | 中断 | exit code 1 |
与 modelstudioai 仓库的对齐
modelstudioai/cli/AGENTS.md— 分层 + 错误处理边界 + 禁止单字母变量modelstudioai/skills— 1st-party skill 必有SKILL.md+metadata.versionmodelstudioai/openwork— 多步任务 + 显式断点
元数据
version: 0.3.0
target_ocr_engine: bailian bl multimodal (Qwen-VL)
target_upload_platform: 阿里公益平台 (https://open.alibabafoundation.com/open/workbench/employee/org/donation/invoice/manage)
upload_tech: Playwright + CDP
match_strategy: 1-to-1 by invoice_title (待开具 status only)
scope: 电子发票 PDF
default_source_dir: E:\阿里发票\阿里257张\