# SaaS 观感与页面逻辑升级规格 **落地总案**(字段、路由、波次、组件抽取):`docs/SAAS-UPGRADE-PLAN.md` **组件索引**(Agent 定位):`docs/COMPONENT-INDEX.md` **角色**:本文件管视觉 token 与壳层。实现按波次执行,先改壳层与共享组件,再改旗舰页与下钻路由。 **对标**: - 组件与 token:**[shadcn/ui](https://github.com/shadcn-ui/ui)**(New York / Neutral 默认) - 产品观感:Linear、Stripe Dashboard、Amplitude 的运营型 SaaS **不对标**:后台 4.0、Ant Design Pro 深色顶栏拟态、新拟态、把本仓改成 React/Tailwind。 **不要执行** `npx shadcn@latest init`:本仓是 Angular 17,没有 Tailwind。只借鉴其语义 token、圆角、按钮变体、侧栏分组和卡片结构,落到现有 SCSS / 共享组件。 --- ## 1. 当前诊断 1. **两套皮肤叠在一起**:`styles.scss` 的 `g-*` 高级灰、token 体系、以及 header / page-header / empty-state 残留的拟态阴影同时存在。 2. **顶栏最像旧后台**:`header.component.scss` 仍是深色拟态条,和白底侧栏、浅色内容区割裂。 3. **页面深度不够**:很多「详情」是抽屉/浮层(验证中心、分析运行),不像进入了属于该模块的子页面。 4. **同模块切换像换皮**:退款 / 新品 / 行动 / 监测用同一个 workbench + `data.section`,缺少「进了一层」的面包屑与返回。 5. **组件反馈弱**:卡片只有轻微阴影;空状态偏 emoji;按钮还带 neu 立体阴影。 6. **已经做得对的部分不要推倒**:经营概览信息密度、商品 VOC 详情、主题 `topics/:id`、竞品 `competitors/:productId`、VOC rail 子分页。 --- ## 2. 设计原则 1. **一层画布、两层表面**:画布用 `background`(近白/浅灰),卡片用 `card` 白底 + hairline `border` + `shadow-xs`。禁止双层拟态光影。 2. **主色跟 shadcn Neutral**:`--primary` 是炭黑(约 `#171717`),主按钮白字;`--secondary` / `--muted` / `--accent` 是浅灰底。蓝色只做链接、图表、信息态,不当默认 CTA。 3. **可点击必须像可点击**:指标卡、表格行、信号行、入口卡都要有 hover `accent` 底 / 细边变化,并尽量带真实路由。 4. **三种页面,不要混用**: - **Hub**:工作台、列表总览。丰富、可下钻。 - **Workspace**:模块内平级页(BoardTabs / rail)。同级切换,不是下钻。 - **Entity**:商品、主题、验证项、分析运行、单条反馈、行动项。独立路由,占满主区,带返回 + 面包屑。 5. **抽屉只承载次要动作**:创建、筛选、预览。主实体用独立子页。 6. **只升级观感与信息架构,不改业务口径、不编造数据、不重写分析逻辑。** --- ## 3. 跳转规则 | 场景 | 交互 | 路由形态 | | --- | --- | --- | | 模块内平级(趋势 / 情绪 / 店铺) | 顶部分段或 BoardTabs | 现有 sibling path,保留 | | 列表 → 实体 | 整行/整卡点击进入**新页面** | `/module/:id`,带 query 保留筛选 | | 工作台信号 / KPI | 进入对应实体或工作区,不是弹说明 | 已有 `go*` 接到真实页 | | 验证、分析运行 | 从抽屉改为独立子页 | `/validation/:id`、`/voc-insight/runs/:id` | | 反馈收件箱 | 桌面可保留分栏,但 URL 必须表达选中项;提供「展开为页面」 | `/feedback-inbox/:reviewId` | | 返回 | 页头返回到列表,保留 query | `PageHeader.backRoute` | 面包屑示例:`洞察中心 / 分析运行 / 2026-08-19 批次`。侧栏高亮父级,不把每个实体推进侧栏。 --- ## 4. 视觉 token(跟 shadcn Neutral 对齐) 官方主题:https://ui.shadcn.com/docs/theming 仓库:https://github.com/shadcn-ui/ui 语义对(Angular 里继续用 `$color-*`,但含义必须对上): | shadcn | 我们 | 近似值 | | --- | --- | --- | | `--background` / `--foreground` | `$color-bg` / `$color-text` | `#fafafa` / `#171717` | | `--card` | `$color-surface` | `#ffffff` | | `--muted` / `--muted-foreground` | `$color-surface-muted` / `$color-text-muted` | `#f4f4f5` / `#737373` | | `--accent` | hover / 选中浅底 | `#f4f4f5` | | `--primary` / `--primary-foreground` | `$color-primary` | `#171717` / `#fafafa` | | `--border` / `--input` / `--ring` | `$color-border` | `#e5e5e5`;focus ring 3px 半透明 | | `--destructive` | `$color-red` | 保持现有红 | | `--radius` | 基数 `10px`(`0.625rem`) | `$radius-card: 10px`;按钮 `8px` | 在 `_tokens.scss` 落地: ```scss $color-bg: #fafafa; $color-surface: #ffffff; $color-surface-muted: #f4f4f5; $color-border: #e5e5e5; $color-text: #171717; $color-text-muted: #737373; $color-primary: #171717; // shadcn 默认主按钮,不是蓝 $color-primary-hover: #262626; $color-primary-foreground: #fafafa; $color-accent: #f4f4f5; $color-blue: #2563eb; // 仅链接 / 信息 / 图表 $radius-card: 10px; $shadow-card-flat: 0 1px 2px rgba(15, 23, 42, 0.04); // shadow-xs $shadow-float: 0 8px 24px rgba(15, 23, 42, 0.08); ``` `focus-ring` 做成 shadcn 的 `ring-[3px] ring-black/20`,不要蓝光圈当默认。 `soft-neu-*` **保留 mixin 名**,视觉改为白底细边。 页面进入:`opacity + translateY(6px)` 180ms,只加在主内容第一层。 --- ## 5. 壳层 ### 顶栏 `header` - 高度保持 56px。 - **浅色顶栏**:`#ffffff` / `#fafafa`,底部分割线 `1px var(--border)`,去掉深色拟态。 - 品牌字 15px、字重 600、`--foreground`。 - 搜索做成居中 command pill(`h-9`、圆角 8–10px、`muted` 底、`border`,focus 用 3px ring)。**不要重写搜索逻辑**。 - 右侧用户/设置用 `ghost` / `outline` 按钮,不要内凹拟态。 ### 侧栏 `navigation` 对标 shadcn `Sidebar`:`SidebarGroup` + `SidebarGroupLabel` + `SidebarMenuButton`。 - 分组小号灰色 **label**(工作、洞察、行动、数据)。 - 默认透明;hover = `--sidebar-accent`(浅灰);选中 = 同色更深一点 + 字重 600。**不要左侧蓝条。** - 折叠 232 / 64 逻辑保持。 - **不增删导航项,不改 path。** ### 主区 - `app.component.scss` 画布跟 token。 - 内容区内边距统一由页面自己控制,不要再叠一层旧 `g-page` 大空白。 --- ## 6. 共享组件(先改这些,全站会跟着变) | 组件 | 升级点 | | --- | --- | | `page-header` | 增加 `crumbs`、`backLabel`、`backRoute`;去掉 neu 图标凹槽;标题 22px / 字重 700 | | 新建 `page-breadcrumb` | 可独立使用;最后一级纯文本,前面可点击 | | `content-card` | 对标 shadcn Card:10px 圆角、细边、`shadow-xs`,header 与 body 分区 | | `entry-card` / `summary-metric-card` | hover 用 `accent` 浅底,不要上浮过大;可点击显示 chevron | | `board-tabs` | 对标 Tabs:底部分割线 + active 下划线(炭黑或前景色),不要蓝胶囊 | | `empty-state` / `_state.scss` | 淡底圆标 + muted 文案;主按钮用炭黑 primary | | `data-table-shell` | 行 hover `accent`,可点击行 cursor | | `neu-button` | **改皮不改名**:default=炭黑底白字;outline=白底细边;ghost=hover muted;高度约 36px | | `alert-card` | 保持左边色条,阴影改扁平 | --- ## 7. 波次 ### Wave 1 — 壳层与设计系统(先做,全站立刻像样) 只动共享层: - `src/modules/shared/styles/_tokens.scss` - `src/modules/shared/styles/_card.scss` `_button.scss` `_state.scss` `_badge.scss` `_board-tabs.scss`(如需) - `src/app/app.component.scss` - `src/modules/shared/components/header/*`(样式为主,逻辑不动) - `src/modules/shared/components/navigation/*`(样式 + section label,path 不动) - `src/modules/shared/components/page-header/*` - 新建 `page-breadcrumb` - `board-tabs` `empty-state` `content-card` `entry-card` `summary-metric-card` `neu-button` - `src/styles.scss` 的 `g-*` 与新 token 对齐,**不要改** `.ai-visual-report-html` 大段 验收:登录后顶栏/侧栏不再是深色拟态;主按钮是炭黑(shadcn default);卡片是细边扁平面;侧栏选中是浅灰 accent 不是蓝条。 ### Wave 2 — 旗舰页丰富度(已落地) 在不改数据口径的前提下,把页面做成「工作区」而不是表单堆砌: 1. **工作台** `operating-overview`:命令栏做成 sticky 工具条;KPI 点击已有下钻保持;信号行加 chevron。 2. **反馈中心**:队列更像 Linear inbox(密度、未读点、选中高亮);详情区 sticky 头。 3. **商品 VOC / 主题探索**:列表行进详情的 affordance 加强。 4. **行动看板 / 验证中心**:卡片层级、空状态、筛选条统一。 ### Wave 3 — 真正的子页面(重点) 把「抽屉详情」升级为「属于该页的子页」: | 现况 | 目标路由 | 体验 | | --- | --- | --- | | 验证详情抽屉 | `/validation` + `/validation/:id` | 独立页,返回验证中心 | | 分析运行抽屉 | `/voc-insight/runs` + `/voc-insight/runs/:id` | 独立页,返回运行列表 | | 反馈仅 query | `/feedback-inbox/:reviewId` | 深链可开;桌面可仍是分栏布局,但要有「仅此页」的头 | | 行动项多在看板上 | `/action-suggestion/kanban/:id` | **已落地**:提案详情子页(只读+状态),创建仍用面板 | 已有且保持:`/voc-insight/topics/:id`、`/voc-insight/detail`、`/domestic/competitors/:productId`。 实现约束: - 用现有 detail 组件迁到 routed 页,不要复制一份业务逻辑。 - 列表页保持筛选 query;进子页用 `state` 或 query 把 `from` 带上。 - 侧栏仍高亮父菜单。 ### Wave 4 — 其余模块收口(已落地) 监测 workbench、退款、新品开发、知识库、数据中台、系统设置:套 Wave 1 组件,补面包屑,表格行能进已有详情就接线。 已补:退款高退款商品、监测竞品/类目行、新品成交/对标行、品类分析行整行进入已有详情;证据链接改为 `/feedback-inbox/:reviewId`。 --- ## 8. 验收清单 - [x] 顶栏浅色、搜索是 pill、无拟态内凹 - [x] 侧栏选中为浅灰 accent,分组有 label - [x] 主按钮炭黑,次按钮白底细边 - [x] 卡片 10px 圆角、细边、浅阴影 - [x] 页头支持返回 + 面包屑 - [x] 验证 / 分析运行 / 行动项可从列表进入独立子页,浏览器后退能回列表 - [x] 刷新实体 URL 仍能打开同一条 - [x] 不改业务数字、不造评论、不删现有路由(只加子路由) - [x] `npx ng build --configuration=development` 通过 --- ## 9. 禁止 - 不要引入新 UI 框架(Material / ng-zorro / Tailwind),也不要在本仓执行 `npx shadcn@latest init`。 - 不要重写 ECharts 业务 option,只允许容器样式。 - 不要改 `docs/AI-VOC-NEXT-ITERATION.md` 里的业务闭环逻辑。 - 不要动 Parse / 后端契约。 - 不要为了好看把抽屉里的创建流程改成强制跳页。