Files
cmautobuy/client/src/pdd_purchase_adapter.py
T

76 lines
2.3 KiB
Python

"""PDD 采购演练适配层的稳定边界。
应用服务只依赖本文件中的小接口,不直接认识 uiautomator2。接口故意不提供
“提交订单”或“付款”方法,因此演练代码没有可误调用的真实下单入口。
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Mapping
@dataclass(frozen=True)
class PurchasePageState:
"""一次重新读取页面后得到的采购相关事实。"""
page_kind: str
goods_id: str
selected_options: Mapping[str, str] = field(default_factory=dict)
quantity: int = 0
price_cent: int = 0
candidate_count: int = 1
class PddPurchaseError(RuntimeError):
"""适配层失败,包含稳定代码、步骤和是否可安全重试。"""
def __init__(
self,
code: str,
message: str,
*,
step: str,
retryable: bool = False,
diagnostics: Mapping[str, object] | None = None,
) -> None:
super().__init__(message)
self.code = str(code or "PURCHASE_ADAPTER_ERROR")
self.message = str(message or "PDD 采购演练失败")
self.step = str(step or "purchase_prepare")
self.retryable = bool(retryable)
self.diagnostics = dict(diagnostics or {})
class PddPurchaseAdapter(ABC):
"""一台设备的一次采购演练会话;只能由创建它的工作线程使用。"""
@abstractmethod
def open_goods(self, goods_url: str) -> None:
"""通过商品链接打开 PDD 商品页。"""
@abstractmethod
def read_state(self) -> PurchasePageState:
"""重新读取当前页面,不返回缓存状态。"""
@abstractmethod
def select_options(self, options: Mapping[str, str]) -> None:
"""按完整动态规格对象精确选择,不做相似匹配。"""
@abstractmethod
def set_quantity(self, quantity: int) -> None:
"""设置采购数量。"""
@abstractmethod
def enter_confirmation(self) -> None:
"""进入最终提交前确认页,但不得提交订单。"""
@abstractmethod
def stop_before_submit(self) -> None:
"""在提交订单按钮之前停止并保持页面可供人工核对。"""
@abstractmethod
def close(self) -> None:
"""释放设备会话;不得在此方法中产生页面点击。"""