Files
cmautobuy/client/AGENTS.md
T

118 lines
7.6 KiB
Markdown
Raw Normal View History

# Client 子项目规则
本文件适用于 `client/` 下的全部代码和测试,并继承仓库根目录 `AGENTS.md` 的工作流、Git、安全、文档和初级程序员维护规则。
## 开始工作前
- 从仓库根目录执行 Client 任务时,也必须先读取本文件。
- 第一次接手本项目,先看这两份:
- 环境和运行:[00 上手指南](../docs/client/00-getting-started.md)
- 看不懂的词:[00 术语表](../docs/client/00-glossary.md)
- 只读取与当前任务有关的长期基线,不必每次加载全部文档:
- 需求边界:[01 产品需求基线](../docs/client/01-requirements.md)
- 模块和线程:[02 系统架构](../docs/client/02-architecture.md)
- SQLite 与 JSON:[03 数据模型](../docs/client/03-data-model.md)
- Admin 对接:[04 接口契约](../docs/client/04-admin-api-contract.md)
- 页面和交互:[05 界面规范](../docs/client/05-ui-specification.md)
- 测试和采购安全:[06 质量与安全](../docs/client/06-quality-security.md)
- 文档仍是草案或存在未决事项时,不得自行选择会改变业务结果的答案,应按根目录工单流程确认。
## 技术栈
- 固定使用 **Python 3.10 + PyQt5 + Qt Widgets + PyQt-Fluent-Widgets**。
- 界面组件优先使用 `qfluentwidgets`;没有合适组件时再使用 PyQt5 标准控件。
- 只有两者都无法满足明确需求时才创建自定义控件,并说明原因。
- 不得混用 PyQt6、PySide2 或 PySide6,也不得安装其他 Qt 绑定对应的 Fluent Widgets 包。
- 当前开发和验证解释器为 `C:/Python310/python.exe`。
- 依赖及版本以 `client/requirements.txt` 为准,版本必须固定。
- 新增或升级依赖前先检查准确版本、许可证和打包影响,并经过工单确认;确认后同步更新 `requirements.txt`。
## 代码分层
- 界面层只负责显示和输入转发,不直接调用 Admin、SQLite 长查询或 uiautomator2。
- `src/ui_main.py` 负责应用和窗口装配;页面界面放 `src/<页面>_ui.py`,事件绑定放 `src/<页面>_ui_event.py`(当前有 `pdd_ui` / `settings_ui` 两组)。
- 每个文件顶部的模块 docstring 写明了该文件的约束,动手前先读那几行。
- 领域模型不导入 Qt、uiautomator2 或具体 HTTP 客户端。
- Admin 通过 Gateway 接口隔离,Mock 和 HTTP 实现必须遵守相同契约。
- SQLite 通过 Repository 访问,不在页面或自动化函数中散落业务 SQL。
- PDD 页面识别、采集和采购函数放在 PDD 适配层;演示脚本不得被正式流程直接导入。
- 类和函数骨架遵循根目录的初级程序员维护规则,优先补全现有清晰边界,不随意重做架构。
## 数据与接口
- 数据库字段、任务状态和 `pdd_data` 结构以 `docs/client/03-data-model.md` 为准。
- Admin 路径、字段和幂等语义以 `docs/client/04-admin-api-contract.md` 为准;Admin 未完成时使用 Mock,不臆造正式响应。
2026-08-06 17:57:49 +08:00
- Client 与 Admin 只有四个调用:登记、领取、提交结果、提交失败。**不得新增"向 Admin 查询状态"类接口。**
- 金额使用人民币分整数,时间使用带时区 ISO 8601,稳定任务编号不得使用表格行号代替。
- 文件路径一律通过 `data_dir()`(可写数据)和 `app_dir()`(只读资源)获取,见 [03 数据模型 §2.2](../docs/client/03-data-model.md)。**不许硬编码路径,不许用 `os.getcwd()` 或 `__file__` 直接拼**,打包成 exe 后会失效。
- PDD 结果必须先写入 SQLite,再通过 Outbox 提交 Admin。
- 任务领取后中途不查 Admin 状态;Admin 取消或重派一律不感知,做完照常提交。
## 线程与自动化
- QWidget 只能在 Qt 主线程创建和访问。
- 禁止在主线程执行 Admin 请求、uiautomator2/ADB、`time.sleep()`、轮询、大型 XML 解析或文件批量写入。
- 长任务统一使用 `QObject` + `moveToThread` 的 Worker 写法,模板见 [02 架构 §5.1](../docs/client/02-architecture.md);不得混用 `QThread` 子类、`QRunnable` 或 `threading`。
- 后台结果通过信号回到主线程;窗口关闭时按 [02 架构 §5.2](../docs/client/02-architecture.md) 断开连接,防止迟到结果访问已销毁控件。
- 一个 Android 设备同一时间只由一个工作线程控制,不跨线程共享 uiautomator2 Device 对象。
- 自动化任务必须处理启动、运行、安全停止、成功、失败、取消、超时、设备断开和迟到结果。
- 窗口或页面销毁后,后台回调不得再访问对应控件。
## 采购安全
- 真实下单开关默认关闭;未满足质量文档中的采购安全门禁不得启用。
- 高风险点击前必须使用最新页面状态重新校验商品、规格、数量、价格和目标坐标。
- 进入不可逆下单阶段前先持久化执行步骤。
- 不可逆阶段发生崩溃或结果不确定时,只能核对订单或转人工处理,禁止自动重新下单。
- 多个订单候选、验证码、登录失效、未知弹窗、价格超限或规格不确定时停止自动执行。
## 界面规则
- 顶级模块保持为“PDD 任务”和“设置”,页面使用唯一且稳定的 `objectName`。
- 优先使用 `FluentWindow`、Fluent 导航、主题和图标;不得使用表情符号充当结构图标。
- 使用布局、尺寸策略和伸缩项,不用固定坐标排列常规界面。
- 任务表格使用模型/视图和稳定任务编号,不把完整 `pdd_data` 放入隐藏列,也不为每个单元格创建常驻 QWidget。
- 会产生外部后果的命令只有“获取任务”“重新执行”和“重新上报”:重新执行只允许单条采集任务;重新上报只重发既有结果 Outbox,不操作手机、不创建新结果。搜索、筛选、刷新和详情仍只读本地数据库。
- 本地只保存已领取的任务,不缓存 Admin 任务池;已完成任务永久保留,不得清理。
- 普通成功更新页面状态即可;可恢复错误使用 `InfoBar`,只有必须阻断决策时才使用模态对话框。
- 主要流程必须支持键盘;表单具有可见标签;状态和错误不能只依赖颜色。
- 验证浅色、深色、Windows 贴靠和 100%–200% 显示缩放。
- 避免全局 QSS 覆盖 Fluent 控件;局部样式必须保留悬停、按下、焦点和禁用状态。
## 验证
全部命令从 `client/` 目录执行,可直接复制。
**1. 语法检查**(改了哪个文件就换成哪个)
```powershell
C:/Python310/python.exe -m py_compile src/ui_main.py
```
**2. 界面离屏冒烟测试**(不弹窗口,跑完自动退出,CI 和本地都用这条)
```powershell
$env:QT_QPA_PLATFORM="offscreen"
C:/Python310/python.exe -c "from src.ui_main import MainWindow; from PyQt5.QtWidgets import QApplication; app=QApplication([]); w=MainWindow(); print('OK'); app.quit()"
Remove-Item Env:QT_QPA_PLATFORM
```
打印 `OK` 即通过。
**3. 手动看界面**
```powershell
C:/Python310/python.exe buyer_main.py
```
当前 `buyer_main.py` 只装配并显示窗口,**不连接设备、不执行任何自动化**,可以随时运行。
将来“获取任务”接上真实设备后,**启动自动化的命令会产生真实外部操作,届时不得作为普通冒烟测试运行**;那时的日常验证仍以第 2 条离屏测试为准。
**4. 其他情况**
- 修改数据库时测试首次建库和从上一版本迁移。
- 修改 Admin Gateway 时运行 Mock 与 HTTP 共用的契约测试。
- 修改 PDD 解析时优先使用脱敏 XML 固件;真实设备测试必须单独标记并说明是否执行真实下单。
- 交付时说明已运行的命令、结果、未验证的设备行为和新增依赖。