autotrain/docs/web-ui-adaptation-log.md
xinxin6623 7a01ed4db9 feat: add invoice batch wrap-up (name extraction + roster annotation) and web ui automation improvements
- add scripts/annotate_roster_invoices.py: match passenger names to invoice PDFs, write status + relative encoded hyperlinks into roster xlsx
- add scripts/add_invoice_passenger_name.py, scripts/calibrate.py
- add .opencode/skills/invoice-wrapup skill
- improve invoice_tool.py / web_ui.py / vision_fallback.py automation
- add device/screen/windows adaptation docs
- ignore out/ (delivered invoice PDFs contain sensitive data)
2026-07-10 00:11:45 +08:00

5.2 KiB
Raw Blame History

Web UI 换手机适配改造 · 操作记录

2026-07-09 会话产出的操作经验沉淀。换手机后开票流程报错的排查与改造全过程。

配套文档:device-adaptation.md(截屏节点与适配清单)、screen-adaptation.md(理论全链路识图点)。

背景

用户换了手机后开票流程总报错。异常关机重启 UI 后,对话上下文丢失。通过跟踪 work/web_runner.log 实时日志 + 对照代码,定位换手机适配的三个根因,并完成 Web UI 的改造(校准入口 + 查缺补漏开关 + 进度表排序)。

关键决策

  1. 不新建排查文档体系,复用已有 calibrate.py:项目里已有完整的设备校准工具(scripts/calibrate.py + Web UI /calibrate 页),只是 work/device_profile.json 从未生成。换手机第一步是跑校准生成 profile而非另造轮子。
  2. 校准入口放首页顶部状态栏:用 .pill 样式做链接按钮,与状态指示同区,不占用主操作区。
  3. 查缺补漏做成 toggle 按钮而非 checkbox:放"开始运行"按钮同一排,绿色=开/灰=关,状态可见。功能原本默认开启(final_retry_pass=True),之前用户不可见不可控。
  4. 总进度表按 progress 行序排:用户要求"完全按开票顺序"。android_invoice_progress.csv 的行顺序 = 处理顺序,以此为排序键,未处理项放最后。

调查与修改

1. 定位换手机报错根因(见 device-adaptation.md

跟踪 work/web_runner.log 实测一次完整开票流程,确认 8 个截屏节点的触发频率:

节点 触发次数 风险
vision_list_rows列表识行 13 低(归一化坐标)
_vision_find_button("查看") 3全 found:false 中(误判纠偏)
vision_detect_page探测页面 3
_vision_find_button("开具") 3全 found
_vision_find_button("确认") 3全 found H5 必走视觉)
_vision_find_button("继续开票") 3全 found:false (当前机型已失效)
_vision_find_button("扫码开票") 2 recover 路径)
_vision_find_qr_thumbnail 2

根因三类A 硬编码像素坐标(防熄屏 tap / 滑动、B 滑动幅度按绝对像素、C 视觉 fallback 找不到按钮。A/B 已有 device_profile.json 机制但从未生成。

2. 首页加「设备校准」按钮

scripts/web_ui.py:562 header statusbar 加链接:

<a class="pill calibrate-link" href="/calibrate" title="换手机屏幕适配">📱 设备校准</a>

配套 CSSweb_ui.py:480.pill.calibrate-link 蓝色高亮可点击样式。

3. 首页加「查缺补漏」toggle 按钮

  • HTMLweb_ui.py:607<button id="finalRetryPass" class="toggle-on"> 放 run-actions 排最后
  • CSSweb_ui.py:504button.toggle-on(绿)/ button.toggle-off(灰)
  • JSweb_ui.py:938):点击切换 class + 文案
  • 后端 start_runnerweb_ui.py:295)加 final_retry_pass 参数False 时 append --no-final-retry-pass
  • /api/start handlerweb_ui.py:1141)传参,前端 onclickweb_ui.py:934)读 classList

4. 总进度表按开票顺序排列

status_payloadweb_ui.py:208):给每条 roster_status 记 _progress_idxprogress 表行号),排序后清除临时键。未在 progress 的用 len(progress) 排最后。

progress_idx = next((i for i, r in enumerate(progress) if r is progress_row), len(progress))
# ...
roster_status.sort(key=lambda r: (r.get("_progress_idx", 0), r.get("_roster_idx", 0)))

产出物

  • docs/device-adaptation.md(新建):换手机适配截屏节点清单 + 操作步骤
  • docs/web-ui-adaptation-log.md(本文件):操作经验记录
  • scripts/web_ui.py(修改):校准入口 + 查缺补漏按钮 + 进度表排序

踩坑与启示

  1. 浏览器缓存是前端改动的头号陷阱:改完 web_ui.py 后用户点按钮"没执行",根因是浏览器跑旧 JS。强制刷新 Cmd+Shift+R 或加 URL 参数 ?nocache=1 绕过。后端用 curl 验证比盯浏览器快。
  2. 截图单文件覆盖无法回溯work/last_screenshot.pngwork/_vision_find_tmp.png 都是覆盖式,报错时已被后续节点覆盖。换手机排错时需手动备份或改代码按节点留档。
  3. "继续开票"按钮视觉恒 found:false:当前机型已失效,靠 XML 硬编码 bounds 兜底。新手机 bounds 不同会直接失败--这是换手机的高风险点。
  4. after_verify 必超时 12s:每个乘客都走 network_or_loading 超时纠偏,全靠视觉兜底。新手机 XML 更不稳时会放大。
  5. is 比较字典引用可行by_person_key 存的是 progress 列表里的字典引用,next((i for i, r in enumerate(progress) if r is progress_row), ...) 能正确找到行号。

未尽事项

  • work/device_profile.json 仍未生成(需在 /calibrate 页点「保存设备配置」)
  • 截图留档机制未改(仍是单文件覆盖)
  • 校准工具缺「扫码开票」节点的 steprecover 路径无校准项)
  • 真换手机后需实测验证滑动比例适配