Files
cmbuyer/docs/tasks/T-006.md
T
QiuSWandClaude Opus 5 9198134d0b chore(tasks): close T-005/T-006 after prototype sign-off
人工确认 6 个原型(web 登录 / 建单 / 工作台 / 详情,desk 执行 / 设备参数)
通过,两个任务的 needs_human_review 满足,转 DONE 并回填 vikunja_task_id。
两者内容已冻结,不迁入导出区块——转换只增加往返风险而无收益,门禁对无
区块的文件豁免检查 4。

这消解了 T-008 门禁上线时报出的存量违规(四处 write_paths 重叠),
validate_agent_context.py 现在 exit=0,未放宽任何检查。

同时修 vikunja_export.py 的一处不一致:文件有 vikunja_task_id 但无导出
区块时应跳过并说明,而不是硬失败;此前 --check 全量模式会因此报错。
半截标记(只有 BEGIN 或只有 END)仍然报错,已回归验证。

T-008 状态口径统一为 DOING:needs_human_review 的硬规则优先于草稿里的
BLOCKED 表述,工作可继续推进,只是未获人工确认前不得标 DONE。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 17:07:13 +08:00

365 lines
30 KiB
Markdown
Raw 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.
---
id: T-006
title: 桌面端 MVP 交互原型
phase: 0
deps: []
status: DONE
created: 2026-08-03
vikunja_task_id: 13
context_ref: 235abb4
work_branch: task/t-006-desk-inline-detail-revision
needs_device: false
needs_human_review: true
write_paths:
- docs/tasks/T-006.md
- docs/06-tasks.md
- docs/08-interaction-checklist.md
- docs/routes.md
- docs/current-state.md
- docs/design/desk-execution.html
- docs/design/desk-device-settings.html
---
## 问题 / 背景
desk 端将使用 PySide6 / Qt Widgets,但当前没有可确认的桌面应用信息架构。采购执行页同时
承载连接状态、轮询会话、真机步骤、dry-run、真实下单围栏与人工接管,若不先区分状态,
极易把「重新执行」错误地暴露在可能已创建订单的场景。先用 HTML 模拟 Windows 桌面壳,
确认页签、密度、主动作、键盘操作与安全反馈,再转换为 PySide6 控件。
本任务不连接 ADB、web 服务或拼多多,不构成真机验收,也不证明 Qt 原生焦点、主题、
无障碍和性能;这些必须在生产实现中重新验证。
### 2026-08-03 人工评审第二轮修订
人工评审确认桌面端产品名改为“采购工具”,采用顶部固定页签,默认打开“采购执行”,
“设备与参数”收敛为“配置”。采购执行页保留当前三块工作区,但重新分配职责:左上是带可选
商品预览的当前任务,左下是滚动日志,右侧是按时间倒序的执行记录表格。原底部轮询控制整行
删除,开始 / 停止轮询固定放在顶部状态区右侧。
本轮仍是 Phase 0 HTML 原型修订,不连接拼多多、ADB 或 web 服务。商品图片只演示“空态 / 已有
可信证据”两种展示能力;不得为了填满预览区访问真实拼多多或猜测图片来源。执行记录详情只
展示原始文字、证据图片和结构化采购结果,不增加提交订单、重试提交或付款动作。
### 2026-08-03 人工评审第三轮修订
人工评审认为执行记录属于高频只读核查,不应每次用模态窗口中断主工作区。双击右侧记录后,
改为在左侧原位显示记录详情;通过可见的“返回当前任务”按钮或 `Esc` 回到当前任务。详情态仍
保留顶部实时状态和宽屏右侧记录表,既能连续查看相邻记录,也不遮断轮询运行态。
本轮只改变详情呈现和导航,不改变执行状态机、数据契约或安全边界。历史详情只能展示已经
持久化且获准显示的文字与图片,界面不得为了补图直连拼多多;异步加载必须按记录 ID 与请求
代次丢弃过期结果,避免旧记录覆盖当前选择或已经恢复的当前任务视图。
## 关联需求与交互
- 功能:F-005、F-006、F-009、F-010、F-011、F-013、F-017
- 用户故事:US-003、US-005、US-008
- 交互:IX-007、IX-008、IX-011
- 界面:采购执行、配置两个固定页签
- 架构 / API:`04-architecture.md` 第四、五、六节;`api.md` 第二、三节
- 原型约定:`docs/design/README.md`
## 方案
### 文件与页面
1. `desk-execution.html`:Windows 桌面壳、两个页签、web / ADB / 拼多多版本状态、轮询主动作、
当前任务与步骤、租约、倒计时、失败计数、事件日志。原型状态切换器覆盖:未就绪、空闲、
轮询、第一趟试选、dry-run、真实第二趟围栏前、申请围栏中、围栏后核对、结果不明、待人工、
连续失败停止。
2. `desk-device-settings.html`:显式 serial、连接方式、ADB 路径、web 地址、假设备凭据占位、
轮询间隔、超时与连续失败阈值;校验错误、连接检查中、版本失配、保存成功、运行中冻结。
### 第二轮工作区修订
1. 应用壳名称统一为“采购工具”。“采购执行”和“配置”是稳定 ID 的固定静态页签,不可关闭、
不可拖动;切换后保留各自页面状态,默认目的地是采购执行。
2. 删除采购执行页底部 `poll-bar`。顶部就绪状态区增加会话状态与固定命令区,开始 / 停止轮询
始终位于右侧且只控制轮询会话;核查说明、导出诊断和前往配置等对象级动作留在状态提示区,
不借用轮询按钮。
3. 宽屏维持左约 65% / 右约 35% 的三块布局。左上当前任务内部使用文字约 2/3、商品预览约
1/3;无可信图片时显示明确空态,有图片时标注“商品原图 / 页面截图裁剪 / 规格证据”等来源
与采集时间。原型只能使用内联假证据。
4. 左下改为可滚动事件日志,并吸收原会话概览和底部轮询栏释放的高度;倒计时、失败计数和
本次完成等会话指标压缩到日志标题区,不再占用独立卡片。
5. 右侧改为“执行记录”表格并跨越左侧两块高度,数据按采集时间倒序。可见列仅“标题”和
“状态”;任务编号与时间作为标题单元格次行,既保留两列密度,也让倒序可核对。
6. 单击记录只设置当前行;双击非控件行区域、聚焦后按 Enter 或点击表头区“查看所选记录”
打开同一详情命令。记录 ID 是稳定身份,不能使用视图行号;排序、刷新后按 ID 恢复当前行。
7. 记录详情使用窗口级模态对话框:上部左侧显示原始文字和执行时间线,右侧显示可选证据图,
下部显示结构化采购结果。关闭按钮、Esc 和窗口关闭走同一取消协议,关闭后焦点返回原表格行。
8. 紧凑宽度按当前任务、日志、执行记录的顺序改为单列;图片落到文字下方,表格保持可用高度。
不以浏览器原型证明 Qt 原生 DPI、窗口、虚拟化或无障碍已经验收。
### 第三轮左侧内联详情修订
1. 左侧工作区使用两个互斥视图:`LIVE_TASK` 显示当前任务与滚动日志,
`RECORD_DETAIL(record_id)` 显示所选执行记录的原始文字、证据图片与采购结果。切换整个左栏,
不把详情塞进当前任务卡片,也不再使用执行记录详情模态框。
2. 单击记录在当前任务态只选中;双击、聚焦后按 Enter、可见的“查看所选记录”命令和右键菜单
进入同一详情命令。详情态单击另一行应直接更新左侧详情,记录身份始终使用稳定 ID。
3. 详情头部提供可见的“返回当前任务”按钮,并标注 `Esc` 快捷键。返回后保留记录选择、排序和
滚动位置,焦点恢复到触发详情的记录行;不能把 `Esc` 作为唯一返回入口。
4. `Esc` 按层级处理:先关闭右键菜单等临时浮层;信息对话框打开时由对话框消费;没有更高层
浮层时才从记录详情返回当前任务,避免一个按键同时执行两次导航。
5. 顶部连接 / 会话状态条不属于左侧切换区,详情显示期间仍实时更新。详情加载中、加载失败、
无图片和记录不存在都有明确状态;加载失败可安全重试读取,但不得出现重新下单或付款动作。
6. 宽屏保留右侧记录表形成主从工作区;紧凑宽度进入详情时暂时隐藏记录表,返回后恢复原列表
状态,避免把详情和表格纵向堆叠成过长页面。
### Windows / Fluent 交互基线
- 使用 `Segoe UI` 和语义 token,适合 Windows 生产力工具的中等偏紧密度;蓝色主操作、红色
危险、黄色不确定、绿色就绪。图标使用内联 SVG 或文字,不用 emoji。
- 导航只保留两个固定页签;同一任务区只有一个主动作。开始 / 停止轮询的位置稳定,
禁用时在控件附近说明原因。
- 适配 compact / medium / wide:窄宽度按当前任务、滚动日志、执行记录改为单列,宽屏显示
左侧上下两块与右侧跨行记录表格;不依赖 hover 才能看到关键信息。
- 支持键盘遍历、可见焦点、`aria-live`、高对比媒体查询、深浅色 token 与
`prefers-reduced-motion`。原型可以提供主题 / 状态切换,但必须标注为演示工具。
- 每个文件 CSS / JS 全内联、可复位假数据、零网络请求;不得调用 ADB、shell、API 或打开 App。
### 状态与安全表达
- web、设备、App 版本三项都就绪才允许开始轮询;App 实际版本与已取证版本不一致时
fail closed,并给出「停止轮询、重新取证」的下一步。
- 当前任务始终显示 `TRIAL` / `DRY-RUN` / `ORDER` 的中文含义;dry-run 固定显示
「只读演练,不会提交订单」。
- 申请围栏失败或响应不明时显示「未获点击许可」,不得出现继续 / 提交动作。
- 围栏成功后只恢复同一 `submission_id`;点击结果不明时显示「订单可能已创建」,只提供
导出证据 / 打开人工核查说明,不提供重试、重新领取或放弃授权。
- 外部支付、安全校验和真机断连立即停止;不提供绕过、继续付款或任何扣款操作。
- 运行中冻结设备切换与参数保存;关闭窗口受控并说明将停止轮询,围栏后不得让用户误以为
关闭即可重来。
### HTML 到 PySide6 映射
执行记录必须补一张映射表,至少覆盖:应用壳 / 页签、状态徽标、主动作、表单、进度、日志、
确认对话框、通知 / 错误、焦点与快捷键;说明推荐的 Qt Widgets 控件、信号和状态来源。
## 验收要点
- 两个 HTML 均可本地直接打开,页签入口互通,控制台无 error,除本地导航外无网络请求。
- 两页产品名均为“采购工具”,固定页签为“采购执行 / 配置”,且默认入口为采购执行。
- 采购执行页没有底部轮询控制整行;轮询会话按钮固定在顶部状态区右侧,禁用时就近说明原因。
- 三块工作区符合“当前任务 + 滚动日志 / 右侧执行记录”;当前任务图片支持可信证据与空态,
记录表格只有标题、状态两列并按时间倒序。
- 记录可由双击、Enter 和可见命令打开详情;详情替换左侧当前任务 / 日志,不打开模态框;宽屏
右侧列表保持可见,详情态选择另一行会刷新详情。
- 详情按原始文字 / 图片 / 采购结果分区,具有加载中、加载失败、无图片与记录不存在状态;可见
返回按钮与 `Esc` 均能恢复当前任务和原行焦点,且任何状态都没有下单、重试提交或付款操作。
- 所列运行状态均可通过显式原型控制区切换;切换后主动作、说明和可用控件与 IX 一致。
- 版本失配、服务端不可达、围栏响应不明、点击后结果不明、外部支付、安全校验均有明确
停止状态和下一步,且绝无重试提交或付款控件。
- compact / medium / wide 无内容覆盖;键盘可操作、焦点可见、状态不只靠颜色。
- 任务执行记录包含 HTML → PySide6 映射与人工评审清单。
- 运行:`python scripts/validate_agent_context.py`、`git diff --check`,并用浏览器逐页检查
accessibility snapshot、控制台与网络请求。
- 完成自动验证后任务保持 `DOING`,等待人确认页签、信息密度、主动作和安全状态表达。
## 边界
- 只修改 frontmatter `write_paths` 所列文件;共享任务表、IX、路由和当前状态只同步本轮已确认
的桌面信息架构,不扩大真机、API 或生产实现范围。
- 不实现 Python、PySide6、uiautomator2、ADB、HTTP、系统托盘、后台进程或安装包。
- 不从前序项目复制页面判据、选择器、常量或真机结论。
- 不提供任何点击支付、免密支付、先用后付或扣款相关控件;也不提供真实提交按钮。
- 原型 HTML 不能作为 Qt 原生行为、无障碍、主题或性能的验收证据。
## 执行记录
### 2026-08-03 · 第三轮左侧内联详情实现
- 任务继续保持 `DOING`:第三轮自动验证已经完成,但 `needs_human_review: true`,仍需人确认
工作区切换、返回路径、宽屏连续查看与紧凑窗口取舍。
- 执行记录详情已从模态 `dialog` 移到左侧双视图工作区。默认 `LIVE_TASK` 保持当前任务和滚动
日志;双击、Enter、可见命令或右键进入 `RECORD_DETAIL(record_id)`,右侧宽屏列表不被遮挡。
- 详情态单击或方向键选择另一行会按稳定记录 ID 更新左侧详情。可见“返回当前任务”按钮和
`Esc` 共用返回命令,保留列表选择 / 滚动,并把焦点还给当前记录行。
- `Esc` 先关闭右键菜单;信息对话框打开时不触发工作区返回。顶部连接、会话和安全 Banner
始终保留,详情头部另显示实时会话摘要,证明查看历史不会冻结当前任务状态表达。
- 原型控制器可演示详情正常、加载中、加载失败和记录不存在;缺图记录仍显示可信证据空态。
重新读取只读取同一记录,不执行采购。渲染带请求代次,切换记录或返回后丢弃旧异步结果。
- `windows-ui-ux` 使本轮采用非模态主从工作区、可见返回命令、分层 Escape、稳定选择与焦点
恢复,并明确紧凑宽度采用单视图,而不是把两个高密度面板纵向无限堆叠。
**第三轮 HTML → PySide6 / Qt Widgets 交接增量**
| 原型项 | 核心交互契约 | 推荐 Qt Widgets 映射 | 状态 / 线程要求 |
| --- | --- | --- | --- |
| 左侧双视图 | 当前任务 / 记录详情互斥;顶部状态不在切换区 | 左栏 `QStackedWidget`,整体 `QSplitter` | 页面切换不销毁当前任务模型、日志或列表状态 |
| 详情入口与连续选行 | 双击、Enter、按钮、右键共用命令;详情态换行立即换详情 | 共享 `QAction`;`QTableView.activated` 与按钮触发 | 记录身份使用模型中的稳定 ID,不使用代理行号 |
| 返回当前任务 | 可见按钮与 Escape 共用;恢复当前行焦点 | 共享返回 `QAction` + `QShortcut(Escape)` | 仅在无更高层浮层时启用;按稳定 ID 重新定位代理行 |
| 详情读取 | 加载 / 失败 / 缺图 / 不存在状态明确 | 状态页或 `QStackedWidget` + 只读详情控件 | worker 结果携带 record ID 与 request ID;GUI 线程拒绝过期结果 |
| 紧凑宽度 | 详情态暂时隐藏记录表,返回后恢复现场 | 响应窗口宽度调整 `QSplitter` 可见性 | 隐藏不重建模型,不丢选择、排序或滚动位置 |
**第三轮已运行验证**
- Node 静态检查:执行页 78 个 id 无重复,内联脚本可编译,执行记录详情 `dialog` 已不存在。
- Playwright 在 1440 px 验证双击、Enter、可见按钮 / 右键共用内联详情;详情态连续选行会更新
标题,返回按钮与 `Esc` 恢复当前记录行焦点;右键菜单和信息对话框的 Escape 层级正确。
- 详情正常、加载中、加载失败 / 重新读取、记录不存在、无图片均可演示;查看详情期间切换到
第一趟试选,顶部 Banner 和详情实时徽标继续更新,且详情不退出。
- 375 / 768 / 1024 / 1440 px 均无页面级水平溢出;375 / 768 px 详情态隐藏记录表,返回后
恢复表格与唯一选择;1024 / 1440 px 保持宽屏主从布局。浏览器 0 error / 0 warning,页面无
外部资源请求。
- `python scripts/validate_agent_context.py` 与 `git diff --check`:提交前运行并记录最终结果。
**第三轮未验证与待人工确认**
- 没有生产 PySide6、Model/View、worker、图片持久化、API、ADB 或真机行为;浏览器原型不能
证明原生 Qt 焦点、Narrator、UI Automation、DPI、线程或性能。
- 待人确认:宽屏查看详情时是否继续保留右表;紧凑宽度是否接受单视图;返回按钮位置、实时
状态徽标密度,以及详情加载 / 不存在文案。人工确认前任务不得改为 `DONE`。
### 2026-08-03 · 第二轮采购工具工作区实现
- 任务继续保持 `DOING`:第二轮自动验证已完成,但 `needs_human_review: true`,仍需人工确认
三块布局、图片证据密度、执行记录表格和详情弹窗。
- 两页应用壳统一为“采购工具”,固定页签改为“采购执行 / 配置”;HTML 文件名保持不变,避免
无业务价值的路径迁移。采购执行仍为默认入口。
- 删除底部轮询控制整行,把开始 / 停止轮询固定到顶部状态区右侧。按钮只控制会话:真机步骤、
围栏申请、围栏后和结果不明确时按安全规则禁用;核查说明、诊断导出和前往配置改放状态
Banner 的对象级动作区,不再借用会话按钮。
- 宽屏工作区为左约 65% / 右约 35%:左上当前任务使用文字约 2/3、预览约 1/3;默认空态,
有任务时只显示带来源和采集时间的内联假证据。左下改为滚动日志,并把倒计时、连续失败和
本次完成压缩到标题区。右侧执行记录跨两块高度。
- 执行记录以稳定记录 ID 管理当前行,按 ISO 采集时间倒序;可见列只有标题和状态,任务编号
与时间放在标题次行。单击只选择,双击、Enter、可见按钮和右键菜单共用同一打开详情命令。
- 详情 `dialog` 上部左侧显示原始文字和时间线、右侧显示图片证据,下部显示结构化采购结果;
缺图时保持明确空态。关闭按钮、Esc 和窗口关闭后焦点回到原表格行。任何记录都没有提交订单、
重试提交或付款控件。
- `windows-ui-ux` 使本轮明确了静态 Tab 身份、会话 / 对象命令分区、当前行与焦点分离、指针与
键盘等价入口、模态焦点恢复、紧凑宽度重排以及 HTML 不能替代 Qt 原生验收的边界。
**第二轮 HTML → PySide6 / Qt Widgets 交接增量**
| 原型项 | 核心交互契约 | 推荐 Qt Widgets 映射 | 状态 / 线程要求 |
| --- | --- | --- | --- |
| “采购执行 / 配置”固定页签 | 稳定 page id、默认采购执行、切换保留状态 | 不可关闭 `QTabWidget`;页面对象常驻或按明确策略缓存 | `currentChanged` 只切页面,不重置模型或运行任务 |
| 顶部轮询控制 | 只控制普通轮询会话,位置稳定;禁用就近说明原因 | 共享 `QAction` + `QPushButton` + 状态 `QLabel` | enabled / label / reason 由会话状态机单向派生 |
| 当前任务与商品预览 | 文字 2/3、图片 1/3;无可信图片保持空态,有图标来源与时间 | `QGridLayout` / `QSplitter` + 只读字段 + `QLabel` / `QPixmap` | 图片下载、解码和裁剪离开 GUI 线程;结果带任务 / 请求 ID,过期回调丢弃 |
| 滚动日志与指标 | 最新在上;日志脱敏;高频事件不阻塞 UI | `QTableView` + `QAbstractTableModel`,指标使用只读 `QLabel` | 批量 / 节流更新,模型只在 GUI 线程发通知 |
| 执行记录表格 | 仅标题 / 状态;时间倒序;稳定 ID 保留当前行 | `QTableView` + `QAbstractTableModel` + `QSortFilterProxyModel` | `clicked` 只选中,`doubleClicked` / `activated` 共用详情 `QAction`;不依赖视图行号 |
| 记录详情 | 原始文字 / 图片 / 采购结果;Esc 与关闭统一;恢复原行焦点 | 有所有者的 `QDialog` + 布局容器 + `QDialogButtonBox` | 打开时传记录 ID 快照;关闭后按代理模型映射回稳定 ID,记录已删除则聚焦表格 |
PySide6 / Qt 的精确版本仍需 T-002 初始化后核对;这里不承诺特定材质、主题 API 或原生表格
性能,也不把 HTML 的焦点 / 对话框行为当作 Narrator、UI Automation 或 DPI 验收证据。
**第二轮已运行验证**
- Node 内联静态检查:两个 `desk-*.html` 的 doctype、viewport、原型横幅、减少动画、唯一 id、
内联脚本语法、相对页签链接和零外部资源均通过;执行记录表头严格为“标题 / 状态”,页面无
`poll-bar`,按钮危险面未发现提交订单、重试提交、继续付款、免密支付或先用后付。
- Playwright 逐项切换采购执行页 18 个状态:轮询命令保持会话语义;真机、围栏和不明确状态
禁用原因正确;核查 / 导出 / 配置作为独立上下文动作;默认无图,有任务时显示内联假证据。
- 表格交互:四条假记录按 13:52、12:24、10:06、09:18 倒序;双击与 Enter 打开对应记录,
右键先选中命中行再显示查看菜单;详情三分区正确,缺图记录显示空态,Esc 关闭并恢复原行。
- 采购执行 / 配置两页在 375 / 768 / 1024 / 1440 px 共 8 个组合无页面级水平溢出;执行详情
在 1440 px 无内部滚动,在 375 px 单列且无水平溢出。浏览器累计 0 error / 0 warning,网络
只有当前本地 HTML 文档。
- `python scripts/validate_agent_context.py` 与 `git diff --check`:提交前运行并记录最终结果。
**未验证与待人工确认**
- 没有生产 PySide6、Model/View、图片采集、线程、ADB 或 web 代码,因此不证明真实图片能从
拼多多取得,也未运行桌面端单元测试、编译或打包。
- 待人确认:顶部状态区在常用窗口下的信息密度;当前任务 2/3 + 1/3、整体 65% + 35% 比例;
两列执行记录是否够用;详情 940 px 宽屏尺寸及窄屏滚动;“执行记录”术语是否沿用。
- 原生实现仍需验证 Windows 100%–200% DPI、多显示器、贴靠、浅 / 深 / 高对比、中文输入法、
Narrator / Inspect、表格虚拟化、线程与最终打包产物。本轮没有真机验收。
### 2026-08-03 · 原型待人工确认
状态保持 `DOING`。本轮只完成 Phase 0 浏览器原型,不连接 web、ADB 或拼多多,也不把浏览器
行为视为 Qt / 真机验收。
**已修改**
- `docs/design/desk-execution.html`:固定两页签桌面壳、三项就绪状态、当前任务与步骤、会话
指标、事件日志和唯一主动作。显式状态切换器覆盖 18 个状态:未连接、版本失配、空闲、
空轮询、试选、试选完成并释放手机、dry-run、dry-run 完成、真实第二趟围栏前、申请围栏、
围栏失败 / 响应不明、围栏后调和、待付款、结果不明、安全校验、外部支付、围栏前转人工、
连续失败停止。
- `docs/design/desk-device-settings.html`:显式 serial、USB / WiFi 标识、ADB 路径、web 地址、
假设备凭据、轮询 / 请求 / 真机步骤超时和连续失败阈值。覆盖默认、字段校验、检查中、
检查通过、web 失败、版本失配、保存成功、运行中冻结 8 个状态,以及未保存离开协议。
- 两页均使用 `Segoe UI Variable` / `Segoe UI` 回退、集中语义 token、浅色 / 深色 / 高对比
回退、`prefers-reduced-motion`、可见键盘焦点、`aria-live`、本地可复位假数据和内联 CSS / JS。
页面间只有本地相对链接;没有外部资源、生产地址请求或真实动作。
**HTML → PySide6 / Qt Widgets 交接映射**
| 原型项 | 核心交互契约 | 推荐 Qt Widgets 映射 | 信号 / 状态来源 |
| --- | --- | --- | --- |
| 应用壳与两个固定页签 | 固定同级页面;切换保留各页状态 | `QMainWindow` + 不可关闭的 `QTabWidget` | `currentChanged(int)`;稳定 page id,不用标题作业务身份 |
| web / 设备 / App 版本状态 | 三项全就绪才允许普通轮询;版本失配 fail closed | `QWidget` + 3 组 `QLabel`,状态色由语义 palette / 动态属性驱动 | `ReadinessViewModel.changed`;实际版本与证据版本由服务层提供 |
| 页面信息条 | 连接、失败、待人工和围栏状态占稳定位置,不抢焦点 | 语义 Banner `QWidget`(图形 + 标题 + 说明) | `state_changed` 经 GUI 线程队列连接;重要变化触发无障碍事件 |
| 唯一主动作 | 每个状态只暴露一个安全主动作;禁用旁边必须有原因 | 共享 `QAction` + `QPushButton` | `QAction.triggered`;enabled / text 由状态机单向派生 |
| 当前任务摘要 | 只读展示任务、规格、金额、租约和 submission | `QFormLayout` + 可复制的只读 `QLabel` / `QLineEdit` | 当前 execution 快照;金额保持十进制字符串 |
| 步骤列表 | 已完成 / 当前 / 等待不只靠颜色;稳定步骤 id | `QListView` + `QAbstractListModel` + `QStyledItemDelegate` | execution step event;模型更新必须在 GUI 线程 |
| 会话指标与事件日志 | 空任务不算失败;日志不含凭据、地址、手机号或页面全文 | 指标 `QLabel`;日志 `QTableView` + `QAbstractTableModel` | poll/session event;高频更新节流,记录使用稳定 event id |
| 设置表单 | 显式提交;字段错误就近显示,失败保留输入 | `QFormLayout`、`QLineEdit`、`QButtonGroup` + `QRadioButton`、`QSpinBox` | `textChanged` / `valueChanged` 只改草稿;`QValidator` 仅做格式层校验 |
| 保存与连接检查 | 保存是唯一主动作;检查只验证连接和安装,不打开 App | `QAction` + `QPushButton`;后台 worker + 页面进度 | `triggered` → worker;结果带 request id,过期结果忽略 |
| 运行中冻结 | 轮询中禁止换设备和保存参数 | 表单容器 / 相关 `QAction.setEnabled(False)` | session state;禁用原因用可见 `QLabel` 与 accessible description |
| 对话框与关闭协议 | Escape / 关闭使用同一取消路径;围栏后关闭不等于可以重来 | `QDialog` + `QDialogButtonBox` | `accepted` / `rejected`;关闭后焦点返回调用者 |
| 焦点与快捷键 | 自然 Tab 顺序、可见焦点、`Ctrl+S` 保存 | 标签 buddy、`QAction` + `QKeySequence.Save` | Qt 标准焦点链;原生实现重新用 Narrator / Inspect 验证 |
Qt 实现时不复制 DOM、CSS 或 JavaScript 状态对象。业务状态必须来自 web / execution 服务,
View 只渲染;I/O 离开 GUI 线程,通过 PySide6 `Signal` / `Slot` 回到 GUI 线程。PySide6 / Qt 的
精确版本要在 T-002 初始化后核对,版本敏感 API 在此任务中未作事实声明。
**验证证据**
- `python scripts/validate_agent_context.py`:通过(6 个任务路由,18 个有效仓库路径)。
- `git diff --check`:通过。
- Python 标准库 HTML 解析:两页可解析;`desk-execution.html` 39 个 id、
`desk-device-settings.html` 54 个 id,均无重复;除 `data:,` favicon 外无资源引用。
- 静态危险面扫描:未发现 `fetch`、`XMLHttpRequest`、WebSocket、外部脚本 / 图片 / iframe,
也未发现文案为「提交订单」「继续付款」「免密支付」「先用后付」「重试提交」的按钮。
- Chromium 本地逐页检查:最终控制台 0 error / 0 warning;网络面板只有当前本地 HTML 文档。
- 执行页 18 个状态、设置页 8 个状态逐项切换;围栏失败时主动作是「打开围栏核查说明」,
围栏后和结果不明时只显示同一 `submission_id` 的核查入口,危险按钮集合为空。
- 375 / 768 / 1024 / 1440 px 均无横向溢出;表单操作区与内容区在四个宽度下无覆盖。
1440 px 两页均做 full-page 视觉检查。
- 键盘路径检查到页面链接、主题、状态切换、按钮和表单字段,焦点轮廓可见;Enter 打开核查
对话框、Escape 关闭并把焦点还给调用按钮;表单提交聚焦第一个错误且保留输入,模拟异步
检查期间禁用保存,完成后恢复;未保存离开会打开确认对话框。
- 浏览器 accessibility snapshot 可识别 navigation、main、region、表单控件标签、按钮和状态
文本;深色主题已交互检查。`forced-colors` 与减少动画分支已静态检查,但不替代原生测试。
**未验证 / 待人工确认**
- 请人工确认:两个固定页签是否足够;执行页当前任务 / 日志的宽屏比例和紧凑页密度;
「开始 / 停止轮询」作为普通会话唯一主动作是否清楚;待人工、版本失配、围栏失败、围栏后、
结果不明与外部支付的严重度和文案是否足够明确。
- 请人工确认:设置页字段集合,以及轮询间隔、普通请求超时、真机步骤超时、连续失败阈值
是否应该允许用户配置。原型中的数字仅是假数据,不是产品默认值。
- T-103 真机取证后,必须回修 App 实际 / 已取证版本展示、可读字段和文案;本原型没有定义
任何拼多多页面判据、选择器、节点或已验证版本。
- 未验证原生标题栏、系统菜单、Snap Layouts、DPI / 多显示器、Qt palette / QSS、Windows
高对比、输入法、Narrator / UI Automation、线程、性能、打包与关闭真实后台任务。这些不能
由 HTML 证明,需在 T-002 及后续原生实现任务中重新验收。
- 本轮没有真机证据,也没有真实 web / ADB / API / 文件保存。人工确认前任务继续保持
`DOING`,不得自动改为 `DONE`。
### 2026-08-03 · 任务所有者独立复核
- 在 main 合入子任务提交后重新检查两个页面和任务记录,确认提交只触及 T-006 的
`write_paths`,未把浏览器截图或日志纳入 Git。
- 独立 Node 检查确认:两页 id 无重复、内联脚本可编译、相对 HTML 链接均存在、无外部资源,
固定原型横幅齐全。
- 独立 Playwright 检查 375 / 768 / 1024 / 1440 px:无页面级水平溢出、无外部资源请求,
控制台 0 error / 0 warning。逐项切换执行页 18 个状态,确认 dry-run / 围栏申请中没有提交
动作,围栏失败、围栏后、结果不明、外部支付与安全校验都只提供安全核查 / 说明动作。
- 目视复核 1440 px 空闲态与 `RECONCILIATION_REQUIRED`:三项就绪状态、唯一提交编号、
「订单可能已创建」和禁止再次点击的层级清楚。
- HTML → PySide6 映射覆盖壳、页签、状态、表单、日志、对话框、焦点与线程边界;未把 DOM / CSS
当成 Qt 实现。仍需人工设计确认及后续原生 Qt / Narrator / DPI / 真机验收,任务保持 `DOING`。
- 2026-08-03 人工确认:6 个原型(web 登录 / 建单 / 工作台 / 详情,desk 执行 / 设备参数)
已由人浏览确认,布局、信息层级、主动作与安全文案通过。`needs_human_review` 满足,
状态改为 `DONE`。Vikunja 对应任务 #13。
- 本任务未迁入导出区块:内容已冻结,转换只增加往返风险而无收益;仅回填 `vikunja_task_id`
作为连接键。门禁对无导出区块的文件豁免检查 4。