""" 报销全流程编排 将发票提取 → OCR 识别 → 浏览器填报串联为一条管道, 数据在内存中流转,同时生成 CSV / Markdown 中间产物。 """ import sys from pathlib import Path from . import get_logger from .config import load_config from .extractor import extract_invoices, save_csv as save_invoice_csv, save_markdown as save_invoice_md from .ocr import enrich_with_ocr, _save_csv as save_ocr_csv, save_markdown_from_csv, _load_csv log = get_logger("pipeline") def run_pipeline(step: str = "all", username: str = None, password: str = None): """执行报销流程 Args: step: all | invoice | ocr | submit username: 覆盖 config.json 中的用户名 password: 覆盖 config.json 中的密码 """ config = load_config() if username: config["username"] = username if password: config["password"] = password # 工作目录(项目根目录) project_dir = Path(__file__).parent.parent # -------------------------------------------------- # Step 1: 发票提取 # -------------------------------------------------- invoices = None if step in ("all", "invoice"): log.info("=" * 60) log.info("[1/3] 发票提取") log.info("=" * 60) invoices = extract_invoices(str(project_dir)) if not invoices: log.error("未提取到任何发票数据") return 1 save_invoice_csv(invoices, project_dir / "invoice_summary.csv") save_invoice_md(invoices, project_dir / "invoice_summary.md") if step == "invoice": log.info("[1/3] 发票提取 完成") return 0 # -------------------------------------------------- # Step 2: OCR 识别 # -------------------------------------------------- if step in ("all", "ocr"): log.info("=" * 60) log.info("[2/3] OCR 识别") log.info("=" * 60) csv_path = project_dir / "invoice_summary.csv" if invoices is None: rows = _load_csv(csv_path) if rows is None: return 1 else: # 将 dict 列表转为 CSV 风格的 dict(对齐列名) from .extractor import CSV_COLUMNS rows = [] for idx, inv in enumerate(invoices, 1): items = inv.get("_items", []) first_item = items[0] if items else {} rows.append({ "序号": str(idx), "发票号码": inv.get("发票号码", ""), "开票日期": inv.get("开票日期", ""), "项目名称": first_item.get("项目名称", inv.get("项目名称", "")), "规格型号": first_item.get("规格型号", inv.get("规格型号", "")), "价税合计": inv.get("价税合计", ""), "销售方名称": inv.get("销售方名称", ""), "人员姓名": inv.get("人员姓名", ""), "刷卡日期": inv.get("刷卡日期", ""), "公务卡号": inv.get("公务卡号", ""), "刷卡金额": inv.get("刷卡金额", ""), "备注": inv.get("备注", ""), "工号": inv.get("工号", ""), }) rows = enrich_with_ocr(rows, str(project_dir)) save_ocr_csv(csv_path, rows) save_markdown_from_csv(csv_path, rows) invoices = rows if step == "ocr": log.info("[2/3] OCR 识别 完成") return 0 # -------------------------------------------------- # Step 3: 浏览器填报 # -------------------------------------------------- if step in ("all", "submit"): log.info("=" * 60) log.info("[3/3] 报销提交") log.info("=" * 60) from .bot import load_invoice_data, run_bot csv_path = project_dir / "invoice_summary.csv" bot_invoices = load_invoice_data(str(csv_path), config) run_bot(config, bot_invoices) if step == "submit": log.info("[3/3] 报销提交 完成") return 0 # -------------------------------------------------- # 全流程完成 # -------------------------------------------------- log.info("=" * 60) log.info("全流程执行完毕") log.info("=" * 60) return 0