Commit Graph

7 Commits

Author SHA1 Message Date
Misaka
66bd8af421 阶段1:服务化骨架(FastAPI + Playwright worker + 任务队列)
- 新增 runtime.py:抽离共享核心 launch_and_prepare / dispatch_task / run_heartbeat /
  probe_* / launch_anneng / RuntimeContext,常量 SITES_CONFIG 等;main_router 复用
- 新增 server.py:FastAPI(主线程)+ Playwright worker(独立线程)+ 任务队列;
  API:POST/GET /tasks、GET /status、GET /data/{file}(防路径穿越)
- state_store:加 task_history 表 + create/update/get/list 接口
- 5 站点 with_retry 改为返回 True/False,供 dispatch_task 判成败
- main_router:重写为复用 runtime 的交互模式(行为不变)
- requirements:加 fastapi、uvicorn
- CLAUDE.md:补充运行模式与共享核心架构说明

线程模型:主线程 FastAPI 不碰 Playwright,worker 线程独占 page,经 Queue + SQLite 通信。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 00:04:39 +08:00
Misaka
5030e5b89b 统一各站成败反馈信号;修复中通报错卡死与提示框误判
成败信号统一化(顺心/中通/韵达/安能/百世):
- 各站 impl 开头清理上次的最终文件,避免无数据/失败时残留旧数据误导比对
- 轮询下载段加汇总校验:下载数 < 预期则 raise,堵住"零/部分下载被判成功"
- 正常完成统一显式 return True(原中通/韵达/安能靠 None 隐式成功)
- 无数据统一不落文件(安能实到不再落空 xlsx);韵达裸 except 改 except Exception
- 中通"票数0无空提示"分支改判失败

中通 bug 修复(site_zto.py):
- poll 加 stall 快速失败(连续4轮无进展即 raise)+ 刷新短超时 + 双失败 raise,
  避免页面被遮挡时干等 5 分钟才触发重试
- "生成离线导出任务成功"提示所在 iframe 提交后被销毁,wait_for 抛
  "Frame was detached" 属正常(提示已随 iframe 消失=任务已建立),改判成功

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-16 21:38:56 +08:00
Misaka
a71924ca1a Cap export-task poll loops at 5min to avoid infinite hang
顺心/中通/韵达/安能 的导出任务轮询循环原本只在"本批任务全部完成"时
退出,无任何时间上限:任务卡在生成中、或因时钟偏移没落进 40s 容差窗口
匹配不上时,会无限轮询、流程永不返回,连 with_retry 都没机会触发。

给这 5 处轮询加 300s deadline,超时即 raise → 流程返回 False → 触发
已有的重置重试机制。把"永久挂死"变成"有界失败→自动重试"。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-14 22:24:41 +08:00
Misaka
2d49c3d6f1 Add per-site exception fallback (reset + retry), router stays pure dispatch
每个站点模块自带"失败→重置回初始态→重试"兜底(最多 3 次,含首次;每次
失败都重置,含最终放弃那次清场),对外只暴露 xxx_download 公开入口,路由
层无感、只负责调度。

- 各站点模块新增:HOME_URL、xxx_reset、内联 with_retry;原流程拆为
  xxx_download(带重试) + xxx_download_impl(单次,供自动化测试探测原始失败)。
- 网页站重置=goto 首页 URL;安能(Electron)重置=关业务 tab+收菜单(实测
  reload 会留下杀不掉的僵尸 webContents,故不用 reload)。
- main_router:SITES_CONFIG 改引用各模块 HOME_URL(单一来源);菜单分派回归
  朴素调用;run_automation_test 改走 _impl 以保留"暴露问题"的测试本意。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-08 22:39:38 +08:00
Misaka
63ee8bbae1 Unify export-task matching to time tolerance only (≤40s)
去掉顺心/中通/韵达/安能(应到) 导出任务认领时的标题/模块名校验,
统一改为仅按提交时间容差 ≤40 秒匹配本批任务。

理由:单账号无并发,时间窗内的任务必为本批所建;而站点可能调整
任务标题名,写死标题会导致匹配失败、任务已创建却一直查不到。
同步清理因此变成死代码的局部变量与函数形参。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-06 22:04:22 +08:00
Misaka
dea9ad6e07 Add Anneng actual-data (scan) download and wire into automation test
安能站点第二阶段:实到数据下载 + 接入自动化测试。

- site_anneng.py:新增 anneng_actual_download()。网点到件扫描查询页是 Ant Design
  且无导出功能——综合查询→扫描查询→网点到件扫描查询(新)→ 设扫描时间(直接输入
  +回车)→ 选「子单」→ 每页 500(size-changer 用 mousedown 展开)→ 查询 → 直接
  从表格 DOM 抽数、逐页翻页取完 → 存 安能-实到货物数据.xlsx → 关 tab。复用应到的
  CDP/菜单/tab 辅助;扫描专有逻辑单独成段。main() 支持 `actual` 参数独立跑实到。
  修掉复用 tab 时首查读到旧总数的问题(查询后等总数变化再读)。
- main_router.py:菜单加 [11] 实到货物数据下载;run_automation_test 的 flow_table
  加入安能(expected/actual),执行循环对应用类站点(APP_SITES)走无 page 分支。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-21 22:12:23 +08:00
Misaka
9d3d3cbb78 Add Anneng (Electron) site: expected-data download + main_router integration
安能站点第一阶段:把应到数据(运单信息)下载流程接入主路由。

- site_anneng.py:用页面级 CDP 驱动「安能全网门户」Electron 应用(Playwright
  connect_over_cdp 被 Electron 浏览器域 CDP 拦截,故走页面级)。完整应到流程:
  菜单导航 → 进站交接单查询 → 设日期查询(“带小数点的 0”为加载完成判据)
  → 逐条交接单双击进运单信息并核对单号 → 导出(选中字段+→箭头转移全部列)
  → 关闭查询 tab → 导出下载页轮询 → 免对话框下载(x-auth+TGC 直连 GET)
  → 合并为 安能-应到货物数据.xlsx。CDP 端口可配;anneng_ready() 供路由就绪轮询。
- main_router.py:以调试模式启动安能(动态空闲端口,避免端口冲突),经 CDP
  判断首页就绪,菜单加 [10] 应到下载,退出时关闭应用;网页站点逻辑不变。
- config.example.yaml:补充 anneng.query_days 与 anneng.app_path 说明。
- docs/安能门户CDP连接指南.md:连接方案、独立 webContents/tab 处理、免对话框下载。
- .gitignore:忽略 Archive/(早期探查脚本归档)。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-21 19:38:44 +08:00