From 2b5fd6b1b725ccc44b4df512ead9b838ec119081 Mon Sep 17 00:00:00 2001 From: shunli Date: Fri, 29 May 2026 07:57:17 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=20Wave3=20=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E4=B8=8E=E7=A7=BB=E5=8A=A8=E4=BD=93=E9=AA=8C=EF=BC=8805-28-fro?= =?UTF-8?q?ntend-ux-wave3-business-mobile=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../check.jsonl | 4 + .../implement.jsonl | 4 + .../implement.md | 53 ++ .../prd.md | 160 ++++++ .../research/wave3-gap-audit.md | 51 ++ .../task.json | 26 + client/src/components/navigation/Sidebar.tsx | 2 +- client/src/pages/ContractsRegistryPage.tsx | 35 +- client/src/pages/MobileApprovalsPage.tsx | 45 ++ client/src/pages/MobileNotificationsPage.tsx | 28 + .../pages/MobilePurchaseRequestDetailPage.tsx | 16 +- .../pages/MobileReimbursementDetailPage.tsx | 52 +- client/src/pages/MobileReimbursementsPage.tsx | 23 +- client/src/pages/PortalHomePage.tsx | 4 +- client/src/pages/ProjectDetailPage.tsx | 58 +- client/src/pages/WorkflowTaskDetailPage.tsx | 57 +- .../e2e/pc-detail-mobile-visual-wave3.spec.ts | 501 +++++++++++++++++- 17 files changed, 1087 insertions(+), 32 deletions(-) create mode 100644 .trellis/tasks/05-28-frontend-ux-wave3-business-mobile/check.jsonl create mode 100644 .trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.jsonl create mode 100644 .trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.md create mode 100644 .trellis/tasks/05-28-frontend-ux-wave3-business-mobile/prd.md create mode 100644 .trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/wave3-gap-audit.md create mode 100644 .trellis/tasks/05-28-frontend-ux-wave3-business-mobile/task.json diff --git a/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/check.jsonl b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/check.jsonl new file mode 100644 index 00000000..a9b9de76 --- /dev/null +++ b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/check.jsonl @@ -0,0 +1,4 @@ +{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend validation entrypoint."} +{"file": ".trellis/spec/hyb-oa/frontend-react-vite-design.md", "reason": "Required frontend build, visual and mobile/detail checks."} +{"file": ".trellis/spec/hyb-oa/index.md", "reason": "hyb-oa spec entrypoint for governance, fact-source routing and frontend acceptance boundaries."} +{"file": ".trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/wave3-gap-audit.md", "reason": "Scope and expected checks for Wave3 refresh."} diff --git a/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.jsonl b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.jsonl new file mode 100644 index 00000000..2708124c --- /dev/null +++ b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.jsonl @@ -0,0 +1,4 @@ +{"file": ".trellis/spec/frontend/index.md", "reason": "Frontend task entrypoint and project-specific spec routing."} +{"file": ".trellis/spec/hyb-oa/frontend-react-vite-design.md", "reason": "Wave0-2 shell/header baseline plus detail/mobile surface rules."} +{"file": ".trellis/spec/hyb-oa/index.md", "reason": "hyb-oa spec entrypoint, including product fact-source routing and frontend authority."} +{"file": ".trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/wave3-gap-audit.md", "reason": "Current Wave3 gap audit and page scope decisions."} diff --git a/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.md b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.md new file mode 100644 index 00000000..27e35f6c --- /dev/null +++ b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/implement.md @@ -0,0 +1,53 @@ +# Implementation Plan + +## Current Decision + +This task is a Wave3 refresh after the newer Wave0-2 baseline, not a blank Wave3 rebuild. + +## Recommended Implementation Order + +1. PC detail surfaces: + - `WorkflowTaskDetailPage` + - `ProjectDetailPage` + - `ContractsRegistryPage` +2. Mobile key surfaces: + - `MobileApprovalsPage` + - `MobileNotificationsPage` + - `MobileReimbursementsPage` + - `MobileReimbursementDetailPage` + - `MobilePurchaseRequestDetailPage` only for deeplink/detail consistency +3. Test baseline: + - update focused Wave3 Playwright spec + - run typecheck/build/design rules/trellis gates +4. Deployment: + - only after user approval + - run trialrun deploy and public checks + +## Guardrails + +- No backend, schema, permission or workflow-state changes. +- Do not remove existing business actions. +- Do not add a new contract detail route in this task. +- For mobile pages, no desktop tables, no horizontal overflow and no sticky action overlap. + +## Completed Implementation + +2026-05-29: + +- Refreshed PC workflow task detail with a next-action command panel, clearer title/subtitle and evidence-oriented side meta. +- Refreshed PC project detail with a current project command panel covering next action, closure, risk and evidence counts. +- Refreshed PC contract registry with lifecycle summary metrics, expiring-contract command area and ledger row styling. +- Refreshed mobile approvals, notifications, reimbursements, reimbursement detail and purchase detail with mobile focus summaries. +- Cleaned residual forbidden UI copy in Sidebar and Portal home so the UI design rule scan has zero findings. +- Extended `client/tests/e2e/pc-detail-mobile-visual-wave3.spec.ts` to cover project detail, contract registry, mobile reimbursement detail and mobile purchase detail. + +## Local Verification + +- `cd client && npm run build` passed on 2026-05-29. +- `cd client && npx playwright test tests/e2e/pc-detail-mobile-visual-wave3.spec.ts --workers=1 --reporter=list` passed: 2 tests. +- `node scripts/qa/check-ui-design-rules.mjs` passed with 0 findings. +- `python3 ./.trellis/scripts/task.py validate 05-28-frontend-ux-wave3-business-mobile` passed. +- `node scripts/qa/check-trellis-governance.mjs` passed. +- `git diff --check` passed. + +Deployment remains gated by explicit user approval. diff --git a/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/prd.md b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/prd.md new file mode 100644 index 00000000..6e67664a --- /dev/null +++ b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/prd.md @@ -0,0 +1,160 @@ +# 前端体验 Wave3 业务详情与移动关键页 + +## Goal + +在已部署的 Wave0-2 全局体验基线之后,复审并补齐 Wave3 业务详情页和移动关键页,让用户从列表、通知、企业微信或移动首页进入具体业务后,仍然看到统一、简洁、可办理的 OA 工作界面。 + +## What I Already Know + +- 用户要求继续推进全站前端体验改进。 +- Wave0-2 已完成并部署:全局壳、导航、Topbar、页头基线、登录、工作台、审批中心、报销列表/详情和通知中心已按新基线整改。 +- 历史任务 `.trellis/tasks/archive/2026-05/05-27-pc-detail-mobile-visual-wave3/` 已做过一轮 Wave3,但发生在最新 Wave0-2 新基线之前。 +- 当前不应重复从零改造,而应做“Wave3 复审与补齐”。 +- `frontend-design` 是视觉与交互设计裁决来源。 +- 面向用户可测试的页面改动,只有部署和公网检查通过后才可告知用户测试。 + +## Scope + +本任务实施 Wave3 刷新,不改后端业务模型: + +- PC 业务详情/详情相邻页面: + - `/workflow/tasks/:taskId` + - `/projects/:projectId` + - `/contracts-registry` +- 移动关键页: + - `/mobile` + - `/mobile/approvals` + - `/mobile/approvals/:taskId` + - `/mobile/notifications` + - `/mobile/reimbursements` + - `/mobile/reimbursements/:reimbursementId` + - `/mobile/purchase-requests/:purchaseRequestId` 作为通知/移动深链一致性补充目标 +- 测试与证据: + - 更新或扩展 `client/tests/e2e/pc-detail-mobile-visual-wave3.spec.ts` + - 覆盖 PC 详情、移动列表/详情、企业微信 WebView 关键视口 + +## Product Direction + +- Tone:精密、克制、面向办理的 quiet command surface。 +- PC 详情页优先回答:当前是什么状态、我下一步做什么、动作有什么后果、证据在哪里。 +- 移动页优先回答:从消息/首页进入后,我是否能少步骤查看、补材料、审批或回到列表。 +- 合同和项目相关页面强调:摘要、生命周期、负责人、风险/归档位置,不上传或暴露涉密正文。 + +## Requirements + +### R1. PC 详情页一致性 + +- 复用 Wave0-2 的全局壳、页头和 detail surface 规则。 +- 审批详情强化当前节点、申请摘要、可执行动作、依据/附件、处理历史。 +- 项目详情强化项目状态、下一步动作、执行摘要、风险/交付/归档分组,减少局部卡片噪音。 +- 合同台账强化生命周期、到期预警、项目关联和导出边界,不新增合同正文存储能力。 + +### R2. 移动关键路径 + +- 移动审批列表/详情保持离线、草稿、同步和 sticky action 现有能力;只优化信息层级和操作分组。 +- 移动报销列表/详情突出状态、金额、发票/附件完整性和当前可做动作。 +- 移动通知保持“事件收件箱”定位,点击应直达业务详情、审批任务或给出可解释提示。 +- 企业微信 WebView 场景不得出现 PC 表格、横向滚动、按钮文字挤压或底部操作遮挡内容。 + +### R3. 文案与操作降噪 + +- 删除或收纳解释系统实现的文案。 +- 保留业务下一步、风险、不可逆操作、敏感附件和导出边界提示。 +- 不可用动作要解释原因;高风险动作继续保留确认。 + +### R4. 验证和发布 + +- 本地必须通过 typecheck/build 和 focused Playwright。 +- 移动/企微相关改动至少覆盖 390x844,并尽量覆盖现有企业微信多视口矩阵。 +- 若部署给用户测试,必须跑部署脚本和公网 readiness/只读巡检。 + +## Implementation Plan + +### Step 1. Gap-driven edits + +- 不全量重写大页面。 +- 优先改页面首屏、状态摘要、命令区、移动详情头和空态/错误态。 +- 保留所有现有 API 调用、权限判断、确认弹窗和 mutation 行为。 + +### Step 2. Shared pattern reuse + +- PC 使用 `page-header-shell`、`detail-workspace-grid`、`detail-command-panel`、`detail-fact-grid`、`detail-evidence-card`、`detail-action-stack` 等既有类。 +- 移动使用 `mobile-focus-card`、`mobile-command-surface`、`mobile-list-card--focus`、`mobile-list-card--unread`、sticky action 既有模式。 + +### Step 3. Focused test refresh + +- 扩展 `pc-detail-mobile-visual-wave3.spec.ts` 的 mock 页面检查。 +- 按影响范围补跑移动入口、企业微信渲染、UI 设计规则和 Trellis 治理检查。 + +## Acceptance Criteria + +- [x] Wave3 gap audit 已记录,且明确区别于历史 Wave3。 +- [x] PC 审批详情、项目详情、合同台账完成新基线后的体验补齐。 +- [x] 移动审批、移动通知、移动报销及移动深链目标完成新基线后的体验补齐。 +- [x] 没有改变后端 API、权限模型、审批状态机、数据库 schema、企业微信配置或公网真实数据。 +- [x] `cd client && npm run typecheck` 通过。 +- [x] `cd client && npm run build` 通过。 +- [x] Focused Playwright 覆盖 Wave3 页面并通过。 +- [x] `node scripts/qa/check-ui-design-rules.mjs` 通过。 +- [x] `python3 ./.trellis/scripts/task.py validate 05-28-frontend-ux-wave3-business-mobile` 通过。 +- [x] `node scripts/qa/check-trellis-governance.mjs` 和 `git diff --check` 通过。 +- [ ] 若部署给用户测试,已完成公网部署与公网检查并记录证据。 + +## Implementation Result + +2026-05-29 本地实施完成: + +- PC 审批详情新增当前状态/下一步命令区,并保留原审批动作确认、历史和转审能力。 +- PC 项目详情新增项目办理焦点,提前展示收口、风险、交付、合同和资料引用边界。 +- PC 合同台账改为生命周期台账入口,新增可见合同、生效中、草稿、归档和 30 天到期摘要,不新增合同详情路由或正文上传能力。 +- 移动审批、通知、报销列表、报销详情和采购详情新增首屏办理焦点,保留离线草稿、sticky action、原有权限与 mutation 行为。 +- 侧边栏和首页去除 UI 规则命中的口语化文案,保持工作台文案更克制。 + +本地验证完成;公网部署与公网检查待用户单独批准。 + +## Test Plan + +```bash +cd client && npm run typecheck +cd client && npm run build +cd client && npx playwright test tests/e2e/pc-detail-mobile-visual-wave3.spec.ts --workers=1 --reporter=list +node scripts/qa/check-ui-design-rules.mjs +python3 ./.trellis/scripts/task.py validate 05-28-frontend-ux-wave3-business-mobile +node scripts/qa/check-trellis-governance.mjs +git diff --check +``` + +Deployment gate, only after approval: + +```bash +SYNC_ENV=0 LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash deploy/trialrun/deploy.sh +LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-live-smoke-readiness.sh +OAOPS1_REPORT_DIR=.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/postdeploy--wave3-public \ + LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-oa-real-use-daily.sh +``` + +## Out Of Scope + +- 不新增合同详情路由或合同正文/附件库。 +- 不改后端接口、Prisma schema、审批规则、权限、通知投递、企业微信 OAuth、SMTP 或生产配置。 +- 不执行真实付款、ERP 写入、企业微信写入、数据库重置或未授权真实业务写入。 +- 不恢复差旅主线能力。 +- 不把移动端改造成完整 PC 后台。 + +## Research References + +- `research/wave3-gap-audit.md` — 确认历史 Wave3 已存在,本任务应做新基线后的复审补齐。 +- `.trellis/tasks/archive/2026-05/05-27-pc-detail-mobile-visual-wave3/` — 历史 Wave3 范围、实现记录和测试基线。 + +## Technical Notes + +- 重点代码区域: + - `client/src/pages/WorkflowTaskDetailPage.tsx` + - `client/src/pages/ProjectDetailPage.tsx` + - `client/src/pages/ContractsRegistryPage.tsx` + - `client/src/pages/MobileApprovalsPage.tsx` + - `client/src/pages/MobileNotificationsPage.tsx` + - `client/src/pages/MobileReimbursementsPage.tsx` + - `client/src/pages/MobileReimbursementDetailPage.tsx` + - `client/src/pages/MobilePurchaseRequestDetailPage.tsx` + - `client/tests/e2e/pc-detail-mobile-visual-wave3.spec.ts` diff --git a/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/wave3-gap-audit.md b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/wave3-gap-audit.md new file mode 100644 index 00000000..9f537ba5 --- /dev/null +++ b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/research/wave3-gap-audit.md @@ -0,0 +1,51 @@ +# Wave3 Gap Audit + +## Method + +- Reviewed archived task `.trellis/tasks/archive/2026-05/05-27-pc-detail-mobile-visual-wave3/`. +- Reviewed current router and target page files under `client/src/pages/`. +- Compared current state against the newer Wave0-2 global shell/header baseline and `frontend-design` direction. + +## Important Finding + +Wave3 was not truly blank. A previous task already improved PC reimbursement detail, PC workflow detail, PC notifications and several mobile key pages, and added `client/tests/e2e/pc-detail-mobile-visual-wave3.spec.ts`. + +This new task should therefore be a **Wave3 refresh after Wave0-2**, not a full rewrite. The goal is to align existing detail/mobile pages with the latest shell/header/navigation language and close visible gaps. + +## Candidate Pages + +| Page | Current State | Recommended Action | +| --- | --- | --- | +| `/workflow/tasks/:taskId` | Already uses `EntityOverviewHero`, `detail-workspace-grid`, `SectionPanel`, status metrics and action panel. | Light refresh: stronger title/subtitle, next-action wording, evidence/history hierarchy, loading/error polish. | +| `/projects/:projectId` | Rich business page with `EntityOverviewHero` and many panels, but still mixes `card-std`, local metric grids and long sections. | Moderate refresh: introduce clearer current-state/next-step summary and reduce local card noise. | +| `/contracts-registry` | Contract table/list page exists, no dedicated contract detail route found in router. | Treat as contract ledger/detail-adjacent page; improve header, warning summary and lifecycle command area without adding backend routes. | +| `/mobile` | Uses mobile focus card and task list; already covered by mobile entry tests. | Light refresh only if needed for consistency with new copy and entry hierarchy. | +| `/mobile/approvals` and `/mobile/approvals/:taskId` | Large page; already has mobile list/detail surfaces, offline support and sticky action behavior. | Careful targeted refresh: no large rewrite; improve first-screen summary, command labels and detail action grouping. | +| `/mobile/notifications` | Mobile notification inbox exists with filters and direct link behavior. | Align copy and controls with PC notification inbox; avoid adding complexity. | +| `/mobile/reimbursements` | Mobile list already has focus summary and status tabs. | Improve list summary/action wording only; preserve create/delete behavior. | +| `/mobile/reimbursements/:reimbursementId` | Very large detail page with many editing flows. | Targeted polish around state summary, invoice/attachment sections and sticky actions; no business logic rewrite. | +| `/mobile/purchase-requests/:purchaseRequestId` | Existing mobile purchase detail page; useful for notification/deeplink coverage. | Include as secondary target if time permits; do not expand into full procurement redesign. | + +## Proposed Scope Decision + +Recommended MVP: + +1. PC detail refresh: + - workflow task detail + - project detail + - contract registry as contract ledger/detail-adjacent surface +2. Mobile key refresh: + - mobile approvals list/detail + - mobile notifications + - mobile reimbursements list/detail + - mobile purchase request detail only if it is needed to keep deeplink flows consistent +3. Test baseline refresh: + - update or extend `pc-detail-mobile-visual-wave3.spec.ts` + - run mobile route/design checks where relevant + +Out of scope: + +- No backend API/schema/permission/status-machine changes. +- No new contract detail route unless a separate task approves the product/API design. +- No full mobile rewrite; use focused improvements that preserve existing offline and sticky action behavior. + diff --git a/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/task.json b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/task.json new file mode 100644 index 00000000..a209e387 --- /dev/null +++ b/.trellis/tasks/05-28-frontend-ux-wave3-business-mobile/task.json @@ -0,0 +1,26 @@ +{ + "id": "frontend-ux-wave3-business-mobile", + "name": "frontend-ux-wave3-business-mobile", + "title": "前端体验 Wave3 业务详情与移动关键页", + "description": "在 Wave0-2 新全局体验基线后,复审并补齐业务详情页与移动关键页体验。", + "status": "in_progress", + "dev_type": null, + "scope": "client/frontend-ux-wave3-business-mobile", + "package": null, + "priority": "P2", + "creator": "shunli", + "assignee": "shunli", + "createdAt": "2026-05-28", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": null, + "relatedFiles": [], + "notes": "", + "meta": {} +} \ No newline at end of file diff --git a/client/src/components/navigation/Sidebar.tsx b/client/src/components/navigation/Sidebar.tsx index dc1911b1..23a512b8 100644 --- a/client/src/components/navigation/Sidebar.tsx +++ b/client/src/components/navigation/Sidebar.tsx @@ -11,7 +11,7 @@ export function Sidebar() { 今日优先 -
先处理待办,再进入报销、项目和财务流程。
+
待办、报销、项目和财务流程按优先级进入。
diff --git a/client/src/pages/ContractsRegistryPage.tsx b/client/src/pages/ContractsRegistryPage.tsx index 75200dec..5b466783 100644 --- a/client/src/pages/ContractsRegistryPage.tsx +++ b/client/src/pages/ContractsRegistryPage.tsx @@ -25,6 +25,8 @@ import { PageHeader } from "../components/common/PageHeader"; import { StatusBadge } from "../components/common/StatusBadge"; import { DateTextInput } from "../components/common/DateTextInput"; import { WorkspaceNotice } from "../components/patterns/ListWorkspace"; +import { MetricCard } from "../components/patterns/MetricCard"; +import { PageScaffold } from "../components/patterns/PageScaffold"; import { Button } from "../components/ui/button"; import { Input } from "../components/ui/input"; import { Label } from "../components/ui/label"; @@ -244,6 +246,10 @@ export function ContractsRegistryPage() { ? "保留现有责任人" : "默认当前用户"; const amountInvalid = Boolean(editor.amount.trim()) && !AMOUNT_PATTERN.test(editor.amount.trim()); + const activeContractCount = visibleContracts.filter((item) => item.status === "active").length; + const draftContractCount = visibleContracts.filter((item) => item.status === "draft").length; + const archivedContractCount = visibleContracts.filter((item) => item.status === "archived").length; + const expiringContractCount = expiringQuery.data?.total ?? expiringItems.length; const refreshAll = async () => { await Promise.all([ @@ -305,10 +311,18 @@ export function ContractsRegistryPage() { }); return ( -
+ + 可见 {visibleContracts.length} 份 + 30 天到期 {expiringContractCount} 份 + 私密正文不入库 + + } actions={