diff --git a/docs/06-tasks.md b/docs/06-tasks.md index a750cb4..92b3f88 100644 --- a/docs/06-tasks.md +++ b/docs/06-tasks.md @@ -26,7 +26,7 @@ | T-003 | 建立 `init.ps1` 统一入口 | T-001, T-002 | 一条命令完成两端安装与基础验证并打印启动命令;未配置时主动失败而不是静默跳过 | | T-004 | 建立核心数据模型与状态机 | T-001 | `tasks`、`order_authorizations`、`order_submissions` 表与 `04-architecture.md` 一致;状态流转有单元测试;金额用十进制字符串 | | T-005 | 网页端 MVP 交互原型 | - | `docs/design/web-*.html` 单文件假数据原型覆盖登录、表格工作台、创建弹窗、批量开始试选、路由化详情抽屉与完整详情;键盘、窄屏、空态 / 错误 / 加载、围栏后调和状态可演示;经人工确认前保持 `DOING` | -| T-006 | 桌面端 MVP 交互原型 | - | `docs/design/desk-*.html` 单文件假数据原型覆盖“采购工具”的采购执行 / 配置固定页签、顶部轮询控制、当前任务图片、滚动日志、时间倒序执行记录和详情弹窗;明确 dry-run / 真实下单、App 版本失配、围栏后不可重试;经人工确认前保持 `DOING` | +| T-006 | 桌面端 MVP 交互原型 | - | `docs/design/desk-*.html` 单文件假数据原型覆盖“采购工具”的采购执行 / 配置固定页签、顶部轮询控制、当前任务图片、滚动日志、时间倒序执行记录,以及左侧当前任务 / 记录详情双视图;明确 dry-run / 真实下单、App 版本失配、围栏后不可重试;经人工确认前保持 `DOING` | ### Phase 1 · 真机取证(最高风险,必须先做) diff --git a/docs/08-interaction-checklist.md b/docs/08-interaction-checklist.md index 0c59af7..90d3e89 100644 --- a/docs/08-interaction-checklist.md +++ b/docs/08-interaction-checklist.md @@ -110,7 +110,7 @@ IX 编号一经引用不再重用。交互清单不能扩大需求范围。 - 关联用户故事:US-003、US-008 | 关联需求:F-005、F-011 - 页面 / 组件:desk 采购执行页 `PollControls` + `DeviceStatusBar` + `CurrentTaskPanel` + - `ExecutionLog` + `ExecutionRecordTable` / `ExecutionRecordDialog` + `ExecutionLog` + `ExecutionRecordTable` + `ExecutionRecordDetailPanel` - 目标角色:采购执行员 - 前置条件:web 端连接正常;设备已通过连接检查 @@ -119,8 +119,8 @@ IX 编号一经引用不再重用。交互清单不能扩大需求范围。 1. 用户确认 web、设备和已取证 App 版本三项状态都就绪,在顶部状态区点击「开始轮询」。 2. 每到间隔时间领取一条任务,界面显示**这一趟是试选还是下单**、商品、规格、当前步骤。 3. 第一趟试选完成后**退出商品页释放手机**,继续下一轮轮询。 -4. 执行结果按时间倒序进入右侧两列表格;单击只选中,双击、Enter 或可见查看命令打开记录 - 详情,关闭后焦点回到原行。 +4. 执行结果按时间倒序进入右侧两列表格;单击只选中,双击、Enter 或可见查看命令在左侧打开 + 记录详情。宽屏可继续选择其他记录;可见返回按钮或 `Esc` 回到当前任务并恢复当前行焦点。 **状态与异常清单** @@ -130,7 +130,8 @@ IX 编号一经引用不再重用。交互清单不能扩大需求范围。 | 轮询中 | 显示下次轮询倒计时与连续失败计数 | | 执行中 | 显示当前趟次与步骤;**真机步骤期间禁用硬取消和关闭窗口** | | 当前任务图片 | 无可信图片时显示空态;有图时标来源与采集时间,不用其他来源图片凑合 | -| 执行记录详情 | 左侧原始文字、右侧图片证据、下方结构化采购结果;不提供下单、重试提交或付款动作 | +| 执行记录详情 | 左栏在当前任务 / 记录详情间切换,不打开模态框;详情内左侧原始文字、右侧图片证据、下方结构化采购结果;顶部实时状态不中断;不提供下单、重试提交或付款动作 | +| 详情读取异常 | 加载、失败、无图和记录不存在分别说明;仅可重试读取同一稳定记录 ID,过期异步结果不得覆盖当前视图 | | 无可领任务 | 显示「暂无待领任务」并继续下一轮,**不当作错误、不计入失败计数** | | 待人工 | 整页显著变色,说明缺什么、下一步做什么;该任务不再被本端领取 | | 连续失败 | 达到阈值自动停止轮询并显示原因,**不无限重试** | diff --git a/docs/current-state.md b/docs/current-state.md index fa68646..45ad89c 100644 --- a/docs/current-state.md +++ b/docs/current-state.md @@ -22,7 +22,7 @@ - 标准启动路径:`./init.ps1`(Windows)/ `./init.sh`。已存在但会因两端目录未初始化而以 退出码 3 结束并列出待办任务——这是预期行为 - 标准验证路径:目前只有 `python scripts/validate_agent_context.py` 可跑通 -- 当前 blocker:T-005 第二轮 Web 表格工作台和 T-006 第二轮“采购工具”桌面工作区均已通过 +- 当前 blocker:T-005 第二轮 Web 表格工作台和 T-006 第三轮“采购工具”桌面工作区均已通过 自动检查;两者经人工确认前不开始对应生产 UI。 ## 当前目录要点 @@ -43,11 +43,12 @@ - 已完成:无。 - 正在进行:T-005(网页端 MVP 交互原型)、T-006(桌面端 MVP 交互原型)。T-005 第二轮 - 已将三泳道改为传统表格;T-006 第二轮已改为“采购工具”的采购执行 / 配置固定页签,并增加 - 顶部轮询控制、当前任务图片、滚动日志、执行记录表格和详情弹窗。两项自动验证均已完成, + 已将三泳道改为传统表格;T-006 第三轮已把执行记录详情从模态框改为左侧内联双视图,支持 + 连续选行、可见返回按钮、`Esc` 层级、异常读取状态和紧凑宽度单视图。两项自动验证均已完成, 都因 `needs_human_review: true` 保持 `DOING`。 -- **下一步:人工浏览 6 个原型,重点确认 Web 表格与详情抽屉,以及桌面端顶部状态区、三块 - 布局、图片证据、两列执行记录和详情弹窗。** 明确确认后才能把 T-005 / T-006 改为 `DONE`。 +- **下一步:人工浏览 6 个原型,重点确认 Web 表格与详情抽屉,以及桌面端顶部状态区、图片 + 证据、两列执行记录和左侧内联详情 / 返回路径。** 明确确认后才能把 T-005 / T-006 改为 + `DONE`。 - 原型使用假数据、不调用真实接口、不驱动真机;T-001 / T-002 骨架可在确认后并行, Phase 2 生产页面还必须等待相关真机结论。 diff --git a/docs/design/desk-execution.html b/docs/design/desk-execution.html index acfae2a..a6b415a 100644 --- a/docs/design/desk-execution.html +++ b/docs/design/desk-execution.html @@ -168,7 +168,7 @@ main { max-width: 1480px; margin: 0 auto; padding: 16px; } .prototype-tools { display: grid; - grid-template-columns: minmax(240px, 1fr) auto; + grid-template-columns: minmax(240px, 1fr) minmax(180px, .55fr) auto; gap: 12px; align-items: end; margin-bottom: 12px; @@ -224,7 +224,9 @@ .banner p { margin: 0; color: var(--text-primary); } .banner button[hidden] { display: none; } .workspace { display: grid; grid-template-columns: minmax(0, 1.85fr) minmax(320px, 1fr); gap: 12px; margin-top: 12px; align-items: stretch; } + .left-pane { min-width: 0; min-height: 0; } .stack { display: grid; grid-template-rows: auto minmax(240px, 1fr); gap: 12px; min-width: 0; } + .stack[hidden], .detail-workspace[hidden] { display: none; } .card { border: 1px solid var(--stroke); border-radius: var(--radius-card); background: var(--surface-raised); box-shadow: 0 2px 8px rgba(0,0,0,.04); overflow: hidden; } .card-header { display: flex; align-items: start; justify-content: space-between; gap: 12px; padding: 14px 16px 10px; border-bottom: 1px solid var(--divider); } .card-header h1, .card-header h2 { margin: 0; font-size: 17px; line-height: 1.35; } @@ -296,11 +298,17 @@ .dialog-body p { margin: 0 0 10px; } .dialog-body code { overflow-wrap: anywhere; } .dialog-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--divider); } - .record-dialog { width: min(940px, calc(100vw - 32px)); } - .record-dialog header { display: flex; justify-content: space-between; gap: 12px; padding: 16px 20px 12px; border-bottom: 1px solid var(--divider); } - .record-dialog header h2 { margin: 0; font-size: 18px; } - .record-dialog header p { margin: 3px 0 0; color: var(--text-secondary); font-size: 12px; } - .record-dialog-grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(260px, 2fr); gap: 16px; padding: 16px 20px; } + .detail-workspace { min-height: 540px; height: 100%; display: flex; flex-direction: column; } + .detail-header { align-items: center; } + .detail-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; } + .shortcut { margin-left: 5px; padding: 1px 5px; border: 1px solid var(--stroke); border-bottom-width: 2px; border-radius: 3px; color: var(--text-secondary); background: var(--surface-muted); font-size: 11px; } + .detail-scroll { min-height: 0; overflow: auto; flex: 1; } + .record-detail-grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(240px, 2fr); gap: 16px; padding: 16px 20px; } + .detail-feedback { margin: 16px 20px 0; padding: 16px; border: 1px solid var(--stroke); border-radius: 6px; background: var(--surface-muted); } + .detail-feedback[hidden] { display: none; } + .detail-feedback strong, .detail-feedback span { display: block; } + .detail-feedback span { margin-top: 4px; color: var(--text-secondary); } + .detail-feedback button { margin-top: 12px; } .detail-panel { min-width: 0; } .detail-panel h3, .record-result h3 { margin: 0 0 9px; font-size: 14px; } .detail-list { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 7px 12px; margin: 0; } @@ -322,6 +330,7 @@ .workspace { grid-template-columns: 1fr; } .stack { grid-template-rows: auto auto; } .record-card { min-height: 480px; } + .workspace[data-mode="record"] .record-card { display: none; } .log-list { max-height: 220px; } } @media (max-width: 640px) { @@ -346,7 +355,9 @@ .log-tools, .record-actions { justify-content: flex-start; } .log-list li { grid-template-columns: 58px 1fr; } .log-list li span:last-child { grid-column: 1 / -1; } - .record-dialog-grid { grid-template-columns: 1fr; } + .record-detail-grid { grid-template-columns: 1fr; } + .detail-header-actions { align-items: stretch; justify-content: flex-start; } + .detail-header-actions .badge { white-space: normal; } .evidence-grid { grid-template-columns: 1fr; } .detail-list { grid-template-columns: 1fr; gap: 2px; } .detail-list dd { margin-bottom: 7px; } @@ -403,6 +414,14 @@ +