94 lines
2.7 KiB
Python
94 lines
2.7 KiB
Python
"""
|
||
浏览器自动化填报
|
||
|
||
使用 Playwright 操作财务报销系统,自动完成登录、填单、上传附件等操作。
|
||
|
||
对外接口:
|
||
run_bot(config, travel_info, normal_info) 启动浏览器并执行填报流程
|
||
run_bot_web(config, work_dir) Web 模式填报(从缓存加载信息)
|
||
"""
|
||
|
||
from pathlib import Path
|
||
from typing import Any
|
||
|
||
from .. import get_logger
|
||
from .base import BaseBot
|
||
|
||
log = get_logger("bot")
|
||
|
||
|
||
def run_bot(
|
||
config: dict[str, Any],
|
||
headless: bool = False,
|
||
work_dir: Path | None = None,
|
||
travel_info: dict[str, Any] | None = None,
|
||
normal_info: dict[str, Any] | None = None,
|
||
) -> None:
|
||
"""执行完整的浏览器填报流程,根据发票类型自动路由
|
||
|
||
Args:
|
||
config: 配置字典。
|
||
headless: 是否无头模式。
|
||
work_dir: 工作目录。
|
||
travel_info: 差旅信息(由 pipeline 层提前提取并传入,非差旅时传 None)。
|
||
normal_info: 普通发票信息(由 pipeline 层提前提取并传入,非普通时传 None)。
|
||
"""
|
||
if not config["username"] or not config["password"]:
|
||
raise ValueError("缺少用户名或密码")
|
||
|
||
if not work_dir:
|
||
raise ValueError("缺少工作目录")
|
||
|
||
bot = BaseBot(config, headless=headless)
|
||
bot.work_dir = work_dir
|
||
|
||
try:
|
||
bot.launch()
|
||
bot.login_portal()
|
||
|
||
if travel_info is not None:
|
||
log.info("处理差旅发票...")
|
||
bot.navigate_to_reimburse(page_key="travel_page")
|
||
bot.create_new_form()
|
||
from . import travel
|
||
|
||
travel.run(bot, travel_info)
|
||
elif normal_info is not None:
|
||
log.info("处理普通发票...")
|
||
bot.navigate_to_reimburse(page_key="reimburse_page")
|
||
bot.create_new_form()
|
||
from . import normal
|
||
|
||
normal.run(bot, normal_info)
|
||
else:
|
||
raise ValueError("缺少差旅信息(travel_info)和普通发票信息(normal_info),无法继续填报")
|
||
|
||
except Exception as e:
|
||
log.error(f"操作失败: {e}")
|
||
try:
|
||
bot._screenshot("error")
|
||
except Exception:
|
||
pass
|
||
raise
|
||
finally:
|
||
bot.close()
|
||
|
||
|
||
def run_bot_web(config: dict[str, Any], work_dir: Path) -> None:
|
||
"""Web 模式填报 — headless,附件从指定目录读取
|
||
|
||
Web 端的信息提取由 app.py 的管道负责,此处从缓存加载。
|
||
"""
|
||
from ..doc.llm_extractor import load_cache
|
||
|
||
cache_map = load_cache(work_dir)
|
||
travel_info = cache_map.get("travel_info")
|
||
normal_info = cache_map.get("normal_info")
|
||
run_bot(
|
||
config,
|
||
headless=True,
|
||
work_dir=work_dir,
|
||
travel_info=travel_info,
|
||
normal_info=normal_info,
|
||
)
|