From 0044442f5d088b70a2f047bb14b17539d92db1e3 Mon Sep 17 00:00:00 2001 From: chengma Date: Fri, 7 Aug 2026 16:13:48 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=BD=92=E6=A1=A3=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?#28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...omator2-设备连接与-pdd-商品采集基础服务.md | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/task/28-实现-uiautomator2-设备连接与-pdd-商品采集基础服务.md diff --git a/docs/task/28-实现-uiautomator2-设备连接与-pdd-商品采集基础服务.md b/docs/task/28-实现-uiautomator2-设备连接与-pdd-商品采集基础服务.md new file mode 100644 index 0000000..8155362 --- /dev/null +++ b/docs/task/28-实现-uiautomator2-设备连接与-pdd-商品采集基础服务.md @@ -0,0 +1,72 @@ +# 28 实现 uiautomator2 设备连接与 PDD 商品采集基础服务 + +- 类型:需求 +- 父级大工单:#1 +- 所属 MVP / 版本:#2 / MVP +- 状态:待验收 +- 日期:2026-08-07 +- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/28 + +## 背景与目标 + +Client 原来只有实验脚本和几个独立控件树工具,没有正式的 uiautomator2 设备连接边界,也没有可供后续任务引擎调用的商品采集入口。 + +本任务建立不依赖 Qt、SQLite 和 Admin 的 PDD 采集适配层。它负责独占连接一台已保存设备,打开商品页,并返回符合 `pdd_data` v1 的结构化数据。 + +## 最终方案 + +- `PddDeviceService.connect(serial)` 返回上下文管理的设备会话。 +- 同一个服务同时只允许一个活动会话;Device 只能在创建会话的线程使用。 +- `PddCollectService.collect(task)` 接收至少包含 `goods_url` 的任务对象,返回 `CollectResult`。 +- 商品页滚动收集标题、店铺、已拼数量和评价数量;数量保留整数、原文和近似标记。 +- 规格面板从当前位置横向、纵向分别扫描两个方向,不假设初始位置在列表起点。 +- 规格使用通用 `dimensions`;颜色、尺码使用可读键,其他维度使用由名称生成的稳定键。 +- 枚举规格组合,每个组合重新选择规格、读取当前价格并确认“已选”摘要;金额使用人民币分整数。 +- 标题、店铺、销量、评价、规格或可用价格缺失时停止并返回结构化错误,不返回不完整成功结果。 +- 区分设备地址无效、占用、离线、连接失败、跨线程访问、页面超时、登录失效、验证码、XML 错误、规格缺失和价格缺失。 +- 不连接 Qt 事件,不写数据库,不请求 Admin,也不执行采购、下单或付款。 + +与建单方案相比,商品页等待没有直接复用 `util/loaded_pdd.py`。旧函数只能返回 `True/False`,无法区分超时、登录和验证码,也没有取消检查;正式服务保留了简单轮询,但改为结构化错误和可注入时钟。规格入口继续复用 `util/get_size_panle_coord.py`。 + +## 改了哪些文件 + +- `client/src/pdd_device_service.py`:设备连接、独占会话和线程所有权检查。 +- `client/src/pdd_collect_service.py`:商品页等待、XML 解析、规格扫描、SKU 采集和结果组装。 +- `client/test/test_pdd_device_service.py`:设备连接、释放、错误分类和跨线程访问测试。 +- `client/test/test_pdd_collect_service.py`:数量、商品页、规格、错误和完整采集流程测试。 +- `client/test/fixtures/pdd_goods_page.xml`:脱敏商品页最小固件。 +- `client/test/fixtures/pdd_spec_panel.xml`:脱敏规格面板最小固件。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 使用传入设备号连接,不硬编码 IP、链接或路径 | 通过 | +| 正式代码不导入 `demo1` | 通过 | +| Device 单线程独占且会话可释放 | 通过 | +| 返回商品、店铺、数量、通用规格和 SKU 价格关系 | 自动测试通过 | +| 金额使用分整数,数量保留原文和近似标记 | 通过 | +| 结构化区分主要设备、页面和数据错误 | 通过 | +| XML 解析和主要错误分支不依赖真机测试 | 通过 | +| 不接 Qt、SQLite、Admin、采购和下单 | 通过 | +| 真机打开测试商品并输出脱敏结果 | 待用户真机验收 | + +## 测试 + +从 `client` 目录执行: + +```powershell +C:/Python310/python.exe -m pytest test -q --tb=short --disable-warnings +C:/Python310/python.exe -m compileall -q src test +``` + +并在项目根目录对本任务文件执行 `git diff --check`。 + +- 结果:Client 全量 116 项测试通过,其中 #28 新增 14 项;语法编译和差异检查通过。 +- 使用工作区已有 XML 做了只读兼容性检查,能够解析三份商品页标题和销量,以及三份规格面板的当前价格和可见颜色/尺码;这些含真实页面信息的文件没有加入提交。 +- **没验证到的部分**:尚未在真机执行完整 `collect`;因此未验证真实 PDD 版本中的滚动终点、店铺与评价所在位置、隐藏规格全集、动态库存、全部 SKU 组合价格、登录页和验证码页。未执行采购或下单。 + +## 相关提交 + +- `4aff22c` `feat: 实现 PDD 商品采集基础服务 (#28)` +