From 466075c4a9b695e2b2081818bddebf0165cddd11 Mon Sep 17 00:00:00 2001 From: shunli Date: Wed, 27 May 2026 14:10:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E6=95=9B=20PC=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E5=8F=B0=E8=A7=86=E8=A7=89=2005-27-pc-frontend-visual-consiste?= =?UTF-8?q?ncy-wave1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../check.jsonl | 5 + .../implement.jsonl | 6 + .../implement.md | 38 +++++ .../prd.md | 100 ++++++++++++ .../research/pc-visual-audit.md | 45 ++++++ .../task.json | 36 +++++ client/src/components/navigation/NavLinks.tsx | 10 +- client/src/components/navigation/Sidebar.tsx | 10 +- client/src/components/navigation/Topbar.tsx | 2 +- client/src/components/ui/button.tsx | 4 +- client/src/design/theme.css | 12 +- client/src/index.css | 78 ++++++---- client/src/pages/PortalHomePage.tsx | 109 +++++++++---- client/src/pages/ReimbursementsPage.tsx | 99 ++++++------ client/tests/e2e/login-portal-ux.spec.ts | 2 +- client/tests/e2e/visual-shell.spec.ts | 143 ++++++++++++++++-- 16 files changed, 551 insertions(+), 148 deletions(-) create mode 100644 .trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/check.jsonl create mode 100644 .trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.jsonl create mode 100644 .trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.md create mode 100644 .trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/prd.md create mode 100644 .trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md create mode 100644 .trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/task.json diff --git a/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/check.jsonl b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/check.jsonl new file mode 100644 index 00000000..fb56f2c3 --- /dev/null +++ b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/check.jsonl @@ -0,0 +1,5 @@ +{"file": ".trellis/spec/hyb-oa/project-governance.md", "reason": "Quality gate, commit and deployment governance"} +{"file": ".trellis/spec/hyb-oa/frontend-react-vite-design.md", "reason": "Frontend design, auth/PWA and PC visual consistency contracts"} +{"file": ".trellis/spec/hyb-oa/security-privacy.md", "reason": "Evidence and test output privacy boundaries"} +{"file": ".trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md", "reason": "Design rule validation baseline summarized for this task"} +{"file": ".trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md", "reason": "Acceptance-oriented visual audit baseline"} diff --git a/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.jsonl b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.jsonl new file mode 100644 index 00000000..94df54f2 --- /dev/null +++ b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.jsonl @@ -0,0 +1,6 @@ +{"file": ".trellis/spec/hyb-oa/index.md", "reason": "hyb-oa Trellis spec entry and read order for implementation"} +{"file": ".trellis/spec/hyb-oa/project-governance.md", "reason": "Trellis task, approval, commit and deployment boundaries"} +{"file": ".trellis/spec/hyb-oa/frontend-react-vite-design.md", "reason": "Frontend React/Vite design contracts and frontend-design authority"} +{"file": ".trellis/spec/hyb-oa/security-privacy.md", "reason": "Prevent exposing secrets, full accounts, raw payloads or sensitive business data in evidence"} +{"file": ".trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md", "reason": "Hyinda product design and PC workbench rules summarized for this task"} +{"file": ".trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md", "reason": "Public page sampling and design convergence notes"} diff --git a/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.md b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.md new file mode 100644 index 00000000..aabcaccb --- /dev/null +++ b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/implement.md @@ -0,0 +1,38 @@ +# 实施记录 + +## 设计方向 + +- 视觉基调按 `frontend-design` 收敛为“克制、精密、低噪音的 Hyinda 工作台”。 +- `docs/产品设计规则.md` 作为业务、品牌和验收参考;不使用营销式大卡、装饰光斑或多套页面局部风格。 +- 第一批只覆盖共享 PC 视觉底座、`/portal` 和 `/reimbursements`,不扩展到全站。 + +## 实施范围 + +- 降低全局背景、卡片、侧边栏、顶栏、按钮、指标卡和动作块的装饰强度。 +- `/portal` 员工视角保留核心指标、待处理、常用、团队状态和通知,把申请/资产/继续工作等低频内容收进“更多入口”。 +- `/reimbursements` 只突出“新建报销”,把统计、导出、批量和代提交范围切换降到工具行。 +- 补充视觉壳层 E2E mock,覆盖 `/portal` 与 `/reimbursements` 的 PC 收敛基线。 + +## 约束 + +- 不修改后端 API、权限模型、路由语义、数据库、真实业务数据或部署配置。 +- 不改变移动端业务结构;移动用例只作为回归保护。 +- 面向用户可测试前仍需部署和公网检查通过。 + +## Spec 更新判断 + +- 本轮没有新增 API、数据结构、权限、部署、环境变量或跨层契约。 +- `frontend-design` 作为最终视觉裁决、PC 工作台低噪音方向、截图证据路径等规则已由 `.trellis/spec/hyb-oa/frontend-react-vite-design.md`、`docs/产品设计规则.md` 和本任务 PRD 覆盖。 +- 因此不更新 `.trellis/spec/`,仅在当前任务实施记录中保留本轮样板页决策和验证结果。 + +## 验证记录 + +- `cd client && E2E_BASE_URL=http://127.0.0.1:3000 npx playwright test tests/e2e/visual-shell.spec.ts --workers=1 --reporter=list`:通过,5 passed。 +- `cd client && npm run typecheck`:通过。 +- `cd client && npm run build`:通过。 +- `cd client && E2E_BASE_URL=http://127.0.0.1:3000 npx playwright test tests/e2e/login-portal-ux.spec.ts --workers=1 --reporter=list`:首次 9 passed / 1 failed,旧断言仍查找“我的申请与资产 / 继续工作”;已更新为“更多入口”后重跑通过,10 passed。 +- `node scripts/qa/check-ui-design-rules.mjs --strict`:通过,0 findings。 +- `python3 ./.trellis/scripts/task.py validate 05-27-pc-frontend-visual-consistency-wave1`:通过。 +- `node scripts/qa/check-trellis-governance.mjs`:通过。 +- `git diff --check`:通过。 +- 截图证据:`output/playwright/pc-frontend-visual-consistency-wave1/` 已生成 PC 首页、PC 报销列表、壳层和移动回归截图。 diff --git a/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/prd.md b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/prd.md new file mode 100644 index 00000000..c5359f3b --- /dev/null +++ b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/prd.md @@ -0,0 +1,100 @@ +# PC 前端视觉一致性第一批 + +## Goal + +以 `frontend-design` 为视觉决策来源,把 PC 端从“多套页面局部样式并存”收敛为克制、精密、低噪音的 Hyinda 工作台。第一批只做设计底座和两个样板页:`/portal` 首页、`/reimbursements` 报销列表,形成后续页面迁移的可复用骨架。 + +## What I Already Know + +- 用户已确认执行“PC 前端视觉一致性第一批”建议。 +- 前端视觉最终裁决以 `frontend-design` skill 为准,`docs/产品设计规则.md` 作为业务、品牌和验收参考。 +- 公网页面抽样显示: + - `/portal` 当前首屏层级偏多:标题 9 个、链接 42 个、`SectionPanel` 8 个,信息像模块拼接。 + - `/reimbursements` 当前可见按钮约 19 个,主操作、状态切换、范围切换、导出和批量操作竞争注意力。 + - 代码中并存 `PageHeader`、`WorkspaceHeader`、`WorkbenchHero`、`SectionPanel`、`WorkspaceSection`、`card-std` 和页面局部卡片写法。 +- PC OA 应该像工作台:浅色、清晰边界、主任务突出、批量操作可达但不抢首屏。 + +## Research References + +- `research/pc-visual-audit.md`:公网只读抽样与代码样板审视结论。 + +## Requirements + +- 统一 PC 工作台基础样式: + - 降低全局背景、侧边栏、顶栏、卡片和指标卡的装饰噪音。 + - 保留 Hyinda 品牌蓝作为主行动色,不新增营销式视觉。 + - 收敛卡片圆角、阴影和渐变强度,让页面更像办公系统。 +- 首页 `/portal`: + - 首屏优先展示:欢迎/角色、核心指标、待处理、常用动作。 + - 员工视角下把“我的申请与资产、继续工作、常用入口、项目与协同”等低频或重复内容下沉到更轻的二级区域。 + - 保留经理/管理员视角的业务信息,但减少标题和大卡片堆叠感。 +- 报销列表 `/reimbursements`: + - 主操作只突出“新建报销”。 + - 导出、批量操作、统计分析等降为次级工具区,不和主按钮同权。 + - 状态切换保留,但视觉上应更像筛选控件而不是一排主按钮。 + - 不改变报销创建、导出、批量、删除草稿、筛选、分页和权限逻辑。 +- 自动化与视觉验证: + - 前端 typecheck/build 通过。 + - Focused Playwright 覆盖 `/portal`、`/reimbursements` 可见性和主要操作入口。 + - 补 PC 截图证据。 + +## Scope + +- 共享 PC 视觉底座:`client/src/design/theme.css`、`client/src/index.css`、PC 壳层导航和通用按钮样式。 +- 第一批样板页:`/portal` 首页、`/reimbursements` 报销列表。 +- 回归验证:登录/Portal 交互、PC 首页、PC 报销列表、移动首页和移动审批列表的既有视觉壳层基线。 +- 任务记录:当前 Trellis task 下的 PRD、研究记录、实施记录和验证记录。 + +## Acceptance Criteria + +- [x] PC 侧边栏/顶栏/卡片视觉更克制,阴影和渐变显著减少。 +- [x] `/portal` 员工视角首屏信息减少,不再出现多个同级大区块抢注意力。 +- [x] `/portal` 保留待处理、常用动作、通知/动态、最近访问等入口,但低频内容下沉。 +- [x] `/reimbursements` 只把“新建报销”作为主 CTA,导出/批量/统计分析成为次级工具。 +- [x] `/reimbursements` 原有列表、状态 tab、权限、删除草稿、批量模式入口仍可用。 +- [x] 不修改后端接口、权限模型、路由语义、数据库或真实业务数据。 +- [x] 前端 typecheck/build、UI 设计规则检查、focused E2E、Trellis governance、`git diff --check` 通过。 + +## Definition Of Done + +- 第一批 PC 视觉收敛代码、测试和任务记录完成。 +- 本地验证、视觉壳层回归、登录/Portal 回归、Trellis 治理校验和截图证据完成。 +- 下一步进入提交与部署批准;未经部署和公网检查,不告知用户可以公网测试。 + +## Test Plan + +- 本地验证通过: + - `cd client && npm run typecheck` + - `cd client && npm run build` + - `cd client && E2E_BASE_URL=http://127.0.0.1: npx playwright test tests/e2e/login-portal-ux.spec.ts --workers=1 --reporter=list` + - `cd client && E2E_BASE_URL=http://127.0.0.1: npx playwright test tests/e2e/visual-shell.spec.ts --workers=1 --reporter=list` 或新增 focused 用例。 + - `node scripts/qa/check-ui-design-rules.mjs --strict` + - `python3 ./.trellis/scripts/task.py validate 05-27-pc-frontend-visual-consistency-wave1` + - `node scripts/qa/check-trellis-governance.mjs` + - `git diff --check` +- 生成桌面截图证据,保存到 `output/playwright/pc-frontend-visual-consistency-wave1/`。 +- 提交代码后再请求部署批准;未经部署和公网检查,不告知用户可以公网测试。 + +## Out Of Scope + +- 不做全站页面一次性重构。 +- 不改移动核心业务流程。 +- 不新增第三方 UI 库。 +- 不改后端 API、权限、审批、报销状态机、数据库或部署环境变量。 +- 不删除业务功能,只调整信息层级、视觉密度和入口权重。 + +## Technical Notes + +- 设计源:`frontend-design` skill。 +- 产品规则:`docs/产品设计规则.md`。 +- 前端规范:`.trellis/spec/hyb-oa/frontend-react-vite-design.md`。 +- 主要文件: + - `client/src/index.css` + - `client/src/components/navigation/Sidebar.tsx` + - `client/src/components/navigation/Topbar.tsx` + - `client/src/components/patterns/ListWorkspace.tsx` + - `client/src/components/patterns/SectionPanel.tsx` + - `client/src/components/patterns/MetricCard.tsx` + - `client/src/components/patterns/WorkbenchHero.tsx` + - `client/src/pages/PortalHomePage.tsx` + - `client/src/pages/ReimbursementsPage.tsx` diff --git a/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md new file mode 100644 index 00000000..657a197c --- /dev/null +++ b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/research/pc-visual-audit.md @@ -0,0 +1,45 @@ +# PC 视觉一致性审视 + +## 方法 + +- 使用 `frontend-design` 的方向重新审视 PC 页面:目的、语气、约束、差异化。 +- 结合项目事实源 `docs/产品设计规则.md` 和前端规范。 +- 对公网 `https://oa.hyinda.com` 做只读抽样,页面包括 `/login`、`/portal`、`/reimbursements`、`/projects`、移动首页和移动报销。 +- 只记录结构性指标,不记录账号、密码、完整邮箱、完整手机号或原始业务 payload。 + +## 抽样结论 + +- `/portal`: + - 标题层级偏多,抽样可见 9 个标题。 + - 链接入口偏多,抽样可见 42 个链接。 + - `card-std` 9 个、`section-panel` 8 个,主次区块不像同一张工作台。 + - `rounded-2xl`、阴影和渐变使用偏多,形成“模块拼接”观感。 +- `/reimbursements`: + - 抽样可见按钮约 19 个,主按钮、导出、状态、范围、批量、删除等同屏竞争。 + - 当前业务功能可用,但首屏操作权重没有收敛。 + - 状态切换应保持高可用,但视觉上应降为筛选控件。 +- 代码样板: + - `PageHeader` 与 `WorkspaceHeader` 基本重复。 + - `SectionPanel` 与 `WorkspaceSection` 都承担“卡片分区”角色。 + - `WorkbenchHero`、`MetricCard`、`card-std` 当前仍保留较多装饰性背景、阴影或渐变。 + +## 推荐方向 + +设计语气:克制、精密、低噪音的 Hyinda 工作台。 + +- 保留品牌蓝用于主 CTA、选中态和状态强调。 +- 降低全局背景、卡片、侧边栏和顶栏装饰强度。 +- 首屏只保留一个明确工作流:需要处理什么、常用动作是什么、最新变化是什么。 +- 低频功能保留入口,但下沉到次级区块或工具菜单。 + +## 第一批范围 + +- 统一 PC 基础视觉 token 和共享组件,不新增 UI 库。 +- 首页 `/portal` 作为工作台样板。 +- 报销列表 `/reimbursements` 作为列表/筛选/表格样板。 + +## 风险 + +- 首页角色差异多,改动要保留管理员、经理、员工、财务视角的可用入口。 +- 报销列表涉及导出、批量、代提交、模板创建、差旅关联,不能只做视觉隐藏导致操作不可达。 +- 不应把移动端专项样式带回 PC,也不应让 PC 端变成营销页。 diff --git a/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/task.json b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/task.json new file mode 100644 index 00000000..cbd6c67d --- /dev/null +++ b/.trellis/tasks/05-27-pc-frontend-visual-consistency-wave1/task.json @@ -0,0 +1,36 @@ +{ + "id": "pc-frontend-visual-consistency-wave1", + "name": "pc-frontend-visual-consistency-wave1", + "title": "PC 前端视觉一致性第一批", + "description": "第一批收敛 PC 前端视觉体系,降低装饰噪音并以 /portal 与 /reimbursements 作为工作台和列表页样板。", + "status": "in_progress", + "dev_type": null, + "scope": "client/pc-visual", + "package": null, + "priority": "P2", + "creator": "shunli", + "assignee": "shunli", + "createdAt": "2026-05-27", + "completedAt": null, + "branch": null, + "base_branch": "main", + "worktree_path": null, + "commit": null, + "pr_url": null, + "subtasks": [], + "children": [], + "parent": null, + "relatedFiles": [ + "client/src/index.css", + "client/src/components/navigation/Sidebar.tsx", + "client/src/components/navigation/Topbar.tsx", + "client/src/components/patterns/ListWorkspace.tsx", + "client/src/components/patterns/SectionPanel.tsx", + "client/src/components/patterns/MetricCard.tsx", + "client/src/components/patterns/WorkbenchHero.tsx", + "client/src/pages/PortalHomePage.tsx", + "client/src/pages/ReimbursementsPage.tsx" + ], + "notes": "", + "meta": {} +} \ No newline at end of file diff --git a/client/src/components/navigation/NavLinks.tsx b/client/src/components/navigation/NavLinks.tsx index 88953899..c0877607 100644 --- a/client/src/components/navigation/NavLinks.tsx +++ b/client/src/components/navigation/NavLinks.tsx @@ -75,10 +75,10 @@ function renderNavItem(item: ResolvedNavItem, onNavigate?: () => void) { onClick={() => onNavigate?.()} className={({ isActive }) => cn( - "group flex items-center gap-3 rounded-2xl px-3 py-2.5 text-sm transition duration-200", + "group flex items-center gap-3 rounded-xl px-3 py-2.5 text-sm transition duration-150", isActive - ? "bg-primary text-white shadow-sm" - : "text-[var(--color-text-secondary)] hover:-translate-y-0.5 hover:bg-white/70 hover:text-[var(--color-text-primary)] hover:shadow-sm", + ? "bg-primary/10 text-primary ring-1 ring-primary/10" + : "text-[var(--color-text-secondary)] hover:bg-slate-50 hover:text-[var(--color-text-primary)]", ) } > @@ -86,9 +86,9 @@ function renderNavItem(item: ResolvedNavItem, onNavigate?: () => void) { <> diff --git a/client/src/components/navigation/Sidebar.tsx b/client/src/components/navigation/Sidebar.tsx index bffcf125..b04c56a1 100644 --- a/client/src/components/navigation/Sidebar.tsx +++ b/client/src/components/navigation/Sidebar.tsx @@ -3,19 +3,19 @@ import { NavLinks } from "./NavLinks"; export function Sidebar() { return ( -