autotrain/nextgen/autotrain_next/navigation.py
2026-07-24 10:37:32 +08:00

85 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""扫码开票单入口的原子导航工具。二维码必须由任务显式提供。"""
from __future__ import annotations
import time
from pathlib import Path
from . import device, vision
from .tools import ToolError, observe_screen, tap_normalized
REMOTE_QR = "/sdcard/Pictures/autotrain-next-qr.png"
def _image(context: dict) -> Path:
return Path(observe_screen({}, context)["screenshot"])
def _click(context: dict, label: str) -> dict:
target = vision.find_button(_image(context), label)
if not target.get("found"):
raise ToolError(f"未找到「{label}」按钮")
result = tap_normalized({"point": target["point"]}, context)
time.sleep(0.8)
return result
def push_qr(_: dict, context: dict) -> dict:
source = Path(str(context.get("qr_image") or ""))
if not source.is_file():
raise ToolError("任务未提供可用的 qr_image")
device.run(str(context["device_serial"]), ["push", str(source), REMOTE_QR])
context.setdefault("navigation", {})["phase"] = "open_scan"
return {"remote_qr": REMOTE_QR}
def open_scan(_: dict, context: dict) -> dict:
try:
result = _click(context, "扫码开票")
except ToolError:
context.setdefault("navigation", {})["phase"] = "open_orders"
return _click(context, "订单")
if not vision.find_button(_image(context), "相册").get("found"):
raise ToolError("点击扫码开票后未进入扫码界面")
context.setdefault("navigation", {})["phase"] = "open_album"
return result
def open_orders(_: dict, context: dict) -> dict:
result = _click(context, "电子发票")
context.setdefault("navigation", {})["phase"] = "open_scan"
return result
def open_album(_: dict, context: dict) -> dict:
result = _click(context, "相册")
context.setdefault("navigation", {})["phase"] = "select_qr"
return result
def select_qr(_: dict, context: dict) -> dict:
prompt = "在相册截图中找到文件 autotrain-next-qr.png 的二维码缩略图。只返回 JSON{\"found\":true,\"center\":[500,500]}center 是0-1000归一化坐标找不到则 found=false。"
target = vision.ask(_image(context), prompt)
center = target.get("center") or []
if not target.get("found") or len(center) != 2:
raise ToolError("相册未找到任务二维码缩略图")
point = [float(center[0]) / 1000, float(center[1]) / 1000]
if not all(0 <= value <= 1 for value in point):
raise ToolError("二维码缩略图坐标无效")
result = tap_normalized({"point": point}, context)
context.setdefault("navigation", {})["phase"] = "wait_list"
return result
def wait_list(_: dict, context: dict) -> dict:
nav = context.setdefault("navigation", {})
nav["wait_attempts"] = int(nav.get("wait_attempts", 0)) + 1
time.sleep(1)
page = vision.detect_page(_image(context)).get("page", "other")
if page == "list":
nav["phase"] = "done"
return {"list_ready": True}
if nav["wait_attempts"] >= 5:
raise ToolError(f"扫码后未进入列表页,当前页面={page}")
return {"list_ready": False, "page": page, "attempt": nav["wait_attempts"]}