SAAS-UI-UPGRADE.md 11 KB

SaaS 观感与页面逻辑升级规格

落地总案(字段、路由、波次、组件抽取):docs/SAAS-UPGRADE-PLAN.md
组件索引(Agent 定位):docs/COMPONENT-INDEX.md

角色:本文件管视觉 token 与壳层。实现按波次执行,先改壳层与共享组件,再改旗舰页与下钻路由。
对标

  • 组件与 token:shadcn/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.scssg-* 高级灰、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 基数 10px0.625rem $radius-card: 10px;按钮 8px

_tokens.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 SidebarSidebarGroup + SidebarGroupLabel + SidebarMenuButton

  • 分组小号灰色 label(工作、洞察、行动、数据)。
  • 默认透明;hover = --sidebar-accent(浅灰);选中 = 同色更深一点 + 字重 600。不要左侧蓝条。
  • 折叠 232 / 64 逻辑保持。
  • 不增删导航项,不改 path。

主区

  • app.component.scss 画布跟 token。
  • 内容区内边距统一由页面自己控制,不要再叠一层旧 g-page 大空白。

6. 共享组件(先改这些,全站会跟着变)

组件 升级点
page-header 增加 crumbsbackLabelbackRoute;去掉 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.scssg-* 与新 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. 验收清单

  • 顶栏浅色、搜索是 pill、无拟态内凹
  • 侧栏选中为浅灰 accent,分组有 label
  • 主按钮炭黑,次按钮白底细边
  • 卡片 10px 圆角、细边、浅阴影
  • 页头支持返回 + 面包屑
  • 验证 / 分析运行 / 行动项可从列表进入独立子页,浏览器后退能回列表
  • 刷新实体 URL 仍能打开同一条
  • 不改业务数字、不造评论、不删现有路由(只加子路由)
  • npx ng build --configuration=development 通过

9. 禁止

  • 不要引入新 UI 框架(Material / ng-zorro / Tailwind),也不要在本仓执行 npx shadcn@latest init
  • 不要重写 ECharts 业务 option,只允许容器样式。
  • 不要改 docs/AI-VOC-NEXT-ITERATION.md 里的业务闭环逻辑。
  • 不要动 Parse / 后端契约。
  • 不要为了好看把抽屉里的创建流程改成强制跳页。