docs: 建立面向初级程序员的文档基线

按初级程序员可读、可维护的目标重写项目文档,并定案三项设计决策。

新增
- docs/client/00-getting-started.md 上手指南:装环境、跑起来、常见报错
- docs/client/00-glossary.md 术语表:Outbox、幂等、不可逆阶段等
- docs/templates/task.md 工单与归档模板
- client/requirements.txt 固定依赖版本
- .gitignore 屏蔽 data/、打包产物和调试产物

设计定案
- 本地库只存已领取任务,不再镜像 Admin 任务池;已完成任务永久保留
- 去掉租约、心跳和状态回查;Admin 接口从 5 个降到 3 个
  (本项目人工付款,重复下单只产生未付款订单,由人工审核处理)
- 打包采用 PyInstaller one-dir:launcher.exe + app/ + data/,便携模式

文档改进
- 补齐可直接抄的代码模板:Worker 线程、事务写库、幂等键、增量加载、错误提示、路径解析
- 状态机由 ASCII 图改为完整转换表,并补充崩溃恢复规则
- 消除文档与现有代码的冲突,02 新增“现状与目标差异”清单
- 待确认事项一律给出临时默认值,避免阻塞开发
- AGENTS.md 新增“小改动直通”,工单必填项由 8 项压缩到 6 项

说明:Gitea 尚未配置,本次无对应工单号;AGENTS.md §0 的 Gitea 信息待补。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
chengma
2026-08-06 11:44:39 +08:00
co-authored by Claude Opus 5
commit 0b645ee8b3
14 changed files with 2842 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
# 00 Client 上手指南
- 文档状态:基线草案
- 读者:第一次接手本项目的开发者
- 目标:照着做完,能在自己电脑上把界面跑起来,并知道下一步该读哪份文档
这份文档只讲"怎么把环境搭好、怎么跑起来"。业务规则不在这里,见 [文档索引](../README.md)。
遇到不认识的词(Outbox、幂等、不可逆阶段……),先查 [术语表](00-glossary.md),不要跳过。
## 1. 准备电脑环境
本项目只在 **Windows** 上开发和运行。
| 需要什么 | 版本 | 怎么确认已经装好 |
|---|---|---|
| Python | 3.10 | 打开 PowerShell 执行 `C:/Python310/python.exe --version`,输出 `Python 3.10.x` |
| Git | 任意较新版本 | `git --version` 有输出 |
| adb(安卓调试工具) | 任意较新版本 | `adb version` 有输出 |
说明:
- 项目固定使用 `C:/Python310/python.exe`。**不要用 `python` 这个命令**,因为电脑上可能装了多个 Python,`python` 指向哪一个不确定。本文档所有命令都写全路径。
- adb 一般随 Android SDK Platform Tools 安装。装好后要把它所在目录加入系统环境变量 `Path`,否则 `adb` 命令找不到。
## 2. 安装依赖
在 PowerShell 里执行(`cd` 到仓库根目录,也就是有 `AGENTS.md` 的那一层):
```powershell
cd D:\chengma\cmautobuy\client
C:/Python310/python.exe -m pip install -r requirements.txt
```
预期:最后一行显示 `Successfully installed ...`。
如果报错 `Could not find a version that satisfies the requirement`,说明 `requirements.txt` 里钉的版本在你的网络源上没有。按下面两步处理:
```powershell
# 1. 先不指定版本装上(把 xxx 换成报错的那个包名)
C:/Python310/python.exe -m pip install xxx
# 2. 查出实际装了哪个版本
C:/Python310/python.exe -m pip freeze | Select-String "xxx"
```
然后把查到的版本号填回 `client/requirements.txt`,并在提交信息里说明改了哪个版本。**不要把版本号删掉留空**,`06-quality-security.md` 的发布门禁要求依赖版本必须是固定的。
## 3. 准备安卓手机
只做采集/采购的界面开发时**可以跳过这一步**,界面不连手机也能打开。
1. 手机打开「开发者选项」→「USB 调试」。
2. 用数据线连电脑,执行 `adb devices`,能看到一行设备号 + `device`。
3. 打开无线调试(这样后面不用一直插着线):
```powershell
adb tcpip 5555
adb connect 192.168.0.173:5555
```
把 `192.168.0.173` 换成手机的实际 IP(手机「设置 → 关于手机 → 状态信息」里能看到)。
4. 初始化 uiautomator2(只需做一次,它会往手机装一个辅助 App):
```powershell
C:/Python310/python.exe -m uiautomator2 init
```
5. 手机上登录好拼多多。**项目不做自动登录,也不绕过验证码**,见 `01-requirements.md` §9。
## 4. 跑起来
```powershell
cd D:\chengma\cmautobuy\client
C:/Python310/python.exe buyer_main.py
```
**这个命令是安全的**:它只打开界面,不会连手机、不会下单。放心随便跑。
仓库根目录还有一个 `run_buy.bat`,双击也能启动,但它用的是 `python` 而不是 `C:/Python310/python.exe`,多版本环境下可能启动失败。**开发时请用上面的命令,不要用 bat**。
## 5. 你应该看到什么
一个窗口打开,左边是导航栏,包含几个页面(pdd / 设备 / 设置)。窗口标题是「采集采购工具」。
看到窗口 = 环境没问题,可以开始干活了。
> 注意:现在的界面和 `05-ui-specification.md` 描述的**不一样**(页面数量、按钮文字都不同)。这不是你装错了,是代码还没改到目标状态。差异清单见 `02-architecture.md` §3.1。
## 6. 常见报错
| 报错 | 原因 | 怎么办 |
|---|---|---|
| `ModuleNotFoundError: No module named 'src'` | 你在仓库根目录跑的 `buyer_main.py` | `cd` 到 `client` 目录再跑 |
| `ModuleNotFoundError: No module named 'qfluentwidgets'` | 依赖没装,或装到了别的 Python 上 | 回到第 2 步,注意用 `C:/Python310/python.exe -m pip` |
| `ImportError: DLL load failed`(导入 PyQt5 时) | 装了多个 Qt 绑定互相冲突 | 卸载干净再装:`pip uninstall PyQt5 PyQt6 PySide2 PySide6 -y`,然后重新执行第 2 步 |
| 窗口一闪就没了 | 直接双击 .py 文件运行的 | 必须在 PowerShell 里跑,才能看到错误信息 |
| `adb: device offline` / `connect failed` | 手机和电脑不在同一个 WiFi,或手机重启过 | 重新执行 `adb connect <手机IP>:5555` |
| 跑 demo 后目录里多出 `xxx_home.xml`、`xxx_home.png` | `src/demo1/auto_v1.py` 会把控件树和截图写到当前目录 | 正常现象,这些是调试产物,**不要提交到 Git** |
界面相关的问题排查不了时,先确认是不是 Qt 主线程被卡住了 —— 见 `02-architecture.md` §5。
## 7. 数据库在哪、怎么看
程序自己产生的东西**全在 `data/` 目录下**,不会散落到别处:
```text
client/data/
├── client.db 数据库
├── logs/ 运行日志
└── artifacts/ 失败截图和控件树 XML
```
跑源码时它就在 `client\data\`;将来打包成 exe 后,它在 `launcher.exe` 旁边。
想看里面的数据,装一个免费工具 **DB Browser for SQLite**,用它打开 `client.db` 即可。表结构和每个字段什么意思,见 [03 数据模型](03-data-model.md)。
> 写代码时**不要自己拼这个路径**,调 `data_dir()` 函数,见 [03 数据模型](03-data-model.md) §2.2。
> 注意:程序正在运行时也可以用工具打开数据库读数据(项目用的是 WAL 模式)。但**不要用工具改数据**,容易和程序打架。
## 8. 常用代码模板在哪
写代码时不用自己从零想,这几段直接抄:
| 我要做 | 抄哪里 |
|---|---|
| 把耗时活儿放到后台线程 | [02 架构](02-architecture.md) §5.1 Worker 模板 |
| 后台结果安全地更新界面 | [02 架构](02-architecture.md) §5.2 |
| 任务状态和 Outbox 一起写库 | [03 数据模型](03-data-model.md) §5.1 |
| 生成幂等键 | [03 数据模型](03-data-model.md) §5.2 |
| 表格滚动到底自动加载更多 | [05 界面规范](05-ui-specification.md) §5.3 |
| 弹一个可重试的错误提示 | [05 界面规范](05-ui-specification.md) §9.1 |
## 9. 提交代码前的自检
```powershell
cd D:\chengma\cmautobuy\client
# 1. 语法能过
C:/Python310/python.exe -m py_compile src/ui_main.py
# 2. 界面不开窗口也能建起来(不会弹窗,跑完自动退出)
$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
```
第 2 条打印出 `OK` 就算通过。完整的验证要求见 [client/AGENTS.md](../../client/AGENTS.md) §验证。
## 10. 接下来读什么
不用一次读完全部文档。按你要做的事挑:
| 我要做的事 | 读这份 |
|---|---|
| 改界面、加页面、调表格 | [05 界面交互规范](05-ui-specification.md) |
| 加字段、改表、写 SQL | [03 数据模型](03-data-model.md) |
| 对接 Admin、写 Gateway | [04 接口契约](04-admin-api-contract.md) |
| 写自动化、点手机 | [02 架构](02-architecture.md) §9 + [06 质量与安全](06-quality-security.md) §4 |
| 搞不清这功能到底要不要做 | [01 产品需求基线](01-requirements.md) |
无论做哪一样,都必须先看一遍 [client/AGENTS.md](../../client/AGENTS.md)(技术栈和红线)。