228 lines
19 KiB
Markdown
228 lines
19 KiB
Markdown
# 前端域 · 设计主文档
|
||
|
||
> **这是什么**:绘境AI 前端域的设计主文档,回答"**两个前端长什么样、靠什么撑起一致的体验**"。它聚焦设计体系(design system)这一层——即把颜色、间距、字体、组件、主题、多语言这些"视觉与交互的共同语言"统一沉淀下来,让所有界面看起来像同一个产品。
|
||
> **给谁看**:前端工程师、设计师、产品经理、新加入的同事、外部技术尽调。
|
||
> **怎么读**:先读本页建立全局认知——我们有哪两个前端、它们各服务谁、设计体系分几层、为什么这么分、创始人定下了哪些不可动摇的硬约束;需要某条具体令牌(token)的取值或某个组件的签名时,再回到代码里的权威源文件(文末有指针)。
|
||
> **读这一页 = 前端设计体系的当前真相**。它从子系统活档 `docs/architecture/前端/README.md` 蒸馏而来,只取其架构骨架与关键决策的"为什么";逐令牌清单、逐组件实现、构建与走查的具体命令不在这里(分别交给代码里的 `tokens.css` 与 `.agents/skills/` 下的操作手册)。
|
||
|
||
---
|
||
|
||
## 1. 绘境AI 有两个前端
|
||
|
||
绘境AI 把面向不同人群的界面拆成两个独立的前端应用,它们在[架构域](../架构/README.md)里都画在"前端应用层",但服务的人和承载的能力截然不同。
|
||
|
||
**game-studio** 是产品前端,同时服务**创作者**和**玩家**两类终端用户。创作者在这里一句话生成游戏、预览迭代、发布到多个渠道、查看收益;玩家在这里刷"游戏信息流"(类似短视频的竖屏即刷即玩流)、点赞分享评论。它用 **Vue3 + Vant** 构建——Vant 是一套移动优先的 Vue 组件库,天然适配游戏流的滑动交互。
|
||
|
||
**game-admin** 是管理后台前端,服务**平台运营**和**管理员**。他们在这里做内容审核、用户管理、数据看板、合规处置等后台工作。它用 **Vue3 + Element Plus** 构建——Element Plus 是 Huijing(我们 fork 的开源 Java 企业级后台框架)官方主推的桌面端组件库,二次开发友好。
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph STUDIO["game-studio — 产品前端(消费级)"]
|
||
direction LR
|
||
CRT["创作者<br/>生成 / 预览 / 发布 / 收益"]
|
||
PLY["玩家<br/>游戏信息流 / 互动"]
|
||
end
|
||
subgraph ADMIN["game-admin — 管理后台前端"]
|
||
direction LR
|
||
OPS["运营<br/>审核 / 数据看板"]
|
||
MGR["管理员<br/>用户 / 合规处置"]
|
||
end
|
||
STUDIO -.->|Vue3 + Vant<br/>移动优先| DS["共同的设计语言<br/>(品牌色 / 间距 / 字体 / 圆角)"]
|
||
ADMIN -.->|Vue3 + Element Plus<br/>桌面端| DS
|
||
```
|
||
|
||
> **范围说明**:本档的设计体系建设当前**聚焦 game-studio**——因为它是直面大众市场的消费级产品,卖相与一致性的要求最高,投入产出比也最高。game-admin 是内部后台工具,沿用 Element Plus 默认体系即可满足,只在品牌色这一层与 studio 对齐。下文除非特别标注 admin,默认讲的都是 studio 的设计体系。
|
||
|
||
---
|
||
|
||
## 2. 一句话定位:studio 的体系化波次
|
||
|
||
我们给 studio 的设计体系建设起了一个内部编号 **HJ-FE-DS-001**(HJ = Huijing/绘境,FE = Frontend,DS = Design System)。它不是零散地改几个页面,而是一次**体系化的波次**(wave,指一组围绕同一目标、成批推进并统一收口的工作),一次性把六件事立起来:
|
||
|
||
1. **设计 token 两层** —— 把所有颜色、间距、字号抽成可复用的"设计令牌",分两层管理(详见 §4)。
|
||
2. **vue-i18n 中英双语** —— 用 vue-i18n(Vue 的国际化插件)做中英文切换,杜绝组件里写死中文。
|
||
3. **通用组件库** —— 在 Vant 之上封装一层带绘境AI 品牌气质的组件。
|
||
4. **暗/浅/柔三档主题** —— 用户可在设置里切换暗色、浅色、柔和三种舒适度的配色。
|
||
5. **统一圆角矩形** —— 全站圆角风格统一,禁止药丸形、椭圆、正圆混用。
|
||
6. **SVG 图标** —— 用矢量图标替代 Unicode 字符和 emoji。
|
||
|
||
**现状 = 已全量收口并合入主干 `dev/2.0.0`。** 19 个视图全部接入新体系,6 道 mini-desktop(在一台模拟桌面环境里跑真实浏览器)构建门全绿,真机三主题 × 双语的 CDP 走查(经 Chrome DevTools Protocol 远程驱动真浏览器逐屏验收)全部通过。落地经过了六个有序的提交批次,从最初的"卖相批"(先把退出登录入口、品牌渐变、Inter 字体这些最影响第一印象的点修好)一路推进到代表性页面全量上体系、品牌统一为绘境AI。
|
||
|
||
---
|
||
|
||
## 3. 一个核心判断:学 demo 的"设计语言",不学它的"布局范式"
|
||
|
||
设计体系从哪里起步?我们手上有一份早期的投资人路演原型 `docs-design/huijing-ai-demo.html`(下文简称 **demo**)。对它,我们做了一个关键的取舍判断,这个判断决定了整个前端的形态。
|
||
|
||
**保留** demo 的"设计语言"——它的 token 体系、`cyan→green`(青到绿)的品牌渐变、暗色玻璃质感。这套视觉语言有辨识度,值得沿用。
|
||
|
||
**否决** demo 的"布局范式"。demo 是一个**桌面产品外壳**:固定 236px 宽的左侧栏 + 1140px 宽的工作台,把短视频流硬塞进一个 390×660 的模拟手机框里展示。这是投资人路演用的"控制台"叙事,不是真正给大众用户的消费级界面。
|
||
|
||
现行定位因此是**响应式优先的消费级 Web**:移动端做沉浸式全屏体验,桌面端做居中放大,一套组件适配两端。原生桌面 App、原生移动 App 都是更远期的层级,现在不做,但设计 token 提前为它们铺好了路(见 §4)。
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
DEMO["demo 原型<br/>huijing-ai-demo.html"]
|
||
DEMO -->|保留| KEEP["设计语言<br/>token 体系 + cyan→green 渐变 + 暗色玻璃质感"]
|
||
DEMO -->|否决| DROP["桌面侧栏控制台布局<br/>(236px 侧栏 + 1140px 工作台 + 模拟手机框)"]
|
||
KEEP --> NOW["现行:响应式优先消费级 Web<br/>移动沉浸 / 桌面居中放大 / 一套组件"]
|
||
DROP -. 远期 .-> LATER["原生桌面 App / 移动 App<br/>(仅 token 契约先就绪)"]
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 设计体系怎么搭:token 两层 + 组件库四层
|
||
|
||
这是整个前端域最核心的一张架构图。它由两条主线组成:一条是**设计 token 的两层结构**(为什么是"两层"见下),另一条是**组件库的四层封装**,两者在语义层交汇。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
subgraph TOKEN["设计 token · 跨端单一事实源"]
|
||
P["primitive 原始层<br/>原色板 / 灰阶 / 尺寸原子"] --> S["semantic 语义层<br/>语义令牌(bg / surface / accent / danger…)"]
|
||
S --> CT["component 组件层<br/>组件级令牌"]
|
||
end
|
||
S --> L0
|
||
subgraph LIB["组件库 · 四层封装"]
|
||
L0["L0 token<br/>CSS 变量落地"] --> L1["L1 Vant 适配<br/>把 Vant 变量映射到语义层<br/>复用 Vant 的交互 / 无障碍 / 键盘"]
|
||
L1 --> L2["L2 品牌基元<br/>AppButton / Field / Icon / Card / Chip<br/>EmptyState / NavHeader / TabBar / Skeleton / Toast"]
|
||
L2 --> L3["L3 业务组合<br/>GameCard / InteractBar / FilterTabs…"]
|
||
end
|
||
S -. 同一份 token JSON .-> APP["桌面 App 复用 Web 技术<br/>移动 App 用 RN / Flutter(远期)"]
|
||
```
|
||
|
||
### 4.1 为什么 token 要分两层
|
||
|
||
"token 两层"指的是**原始层(primitive)→ 语义层(semantic)** 的分离,组件层(component)是按需追加的第三层。
|
||
|
||
- **原始层**只描述"物理事实":`--cyan` 是某个青色、`--sp-3` 是 12px。它不带含义,只是调色板和尺子。
|
||
- **语义层**描述"用途":`--bg` 是页面背景、`--accent` 是强调色、`--danger` 是危险色、`--surface-1..3` 是从底到顶的层叠表面。组件**只准引用语义令牌**,绝不直接碰原始层。
|
||
|
||
这样分层带来一个关键好处:**换肤时零改组件**。主题切换只需在语义层重新指向不同的原始色(比如暗色主题下 `--bg` 指向深色、浅色主题下指向浅色),组件因为只认 `--bg` 这个语义名,会自动跟着变,一行组件代码都不用动。
|
||
|
||
### 4.2 token 作为"跨端单一事实源"
|
||
|
||
token 还承担一个长期使命:**做跨端的单一事实源**(single source of truth,即同一份事实只有一处权威定义)。同一份 token 现在服务 Web(吃 CSS 变量),未来桌面 App 复用 Web 技术栈直接沿用,移动 App 则把同一份 token 导出成 JSON 喂给 React Native 或 Flutter。这样无论平台怎么扩,品牌的颜色和尺寸只有一处定义,既服务"远期双 App",又避免长期沉淀出互相打架的垃圾代码。
|
||
|
||
### 4.3 组件库为什么是四层
|
||
|
||
组件库自底向上四层,每层职责单一:
|
||
|
||
- **L0 token 层**:把上面的设计令牌落地成 CSS 变量,是组件库的地基。
|
||
- **L1 Vant 适配层**:通过 `vant-theme.css` 把 Vant 自带的 `--van-*` 变量映射到我们的语义层。这一层的价值是**白嫖 Vant 的交互、无障碍、键盘支持**——这些是社区打磨多年的能力,不必自研。
|
||
- **L2 品牌基元层**:封装一批带绘境AI 品牌气质的基础组件,如 `AppButton`(应用按钮)、`Field`(输入域)、`Icon`(图标)、`Card`、`Chip`、`Badge`、`EmptyState`(空状态)、`NavHeader`(导航头)、`TabBar`(底部标签栏)、`Skeleton`(骨架屏)、`Toast`(轻提示)。
|
||
- **L3 业务组合层**:把基元拼成业务组件,如 `GameCard`(游戏卡片)、`InteractBar`(互动条)、`FilterTabs`(筛选标签)。
|
||
|
||
### 4.4 三条数据流
|
||
|
||
整个体系靠三条数据流串起来:
|
||
|
||
- **token 流**:`L0 token → L1 vant-theme → L2 品牌组件 → L3 业务面`,自底向上逐层消费。
|
||
- **theme 流**(主题/换肤):`localStorage(studio.theme) → <html data-theme> → 语义层覆盖 → 全组件自动反应`。为防止 FOUC(Flash of Unstyled Content,即页面首帧闪现未应用样式的难看瞬间),`index.html` 在首屏渲染前内联一段脚本,先读 `localStorage` 把 `data-theme` 和 `lang` 设好。
|
||
- **i18n 流**(国际化):`main.ts 注册 vue-i18n → 组件用 useI18n($t) 取文案 → localStorage(studio.lang) 与 <html lang> 同步`。
|
||
|
||
---
|
||
|
||
## 5. 创始人 5 项决议(已拍板 · 硬约束)
|
||
|
||
下面五条是创始人拍板的硬约束,不可动摇,是整个前端设计体系的地基。
|
||
|
||
1. **响应式优先消费级 Web**。否决 demo 的桌面侧栏控制台范式;移动端沉浸、桌面端居中放大,一套组件适配两端。
|
||
|
||
2. **暗色先行 + 设置内多档舒适主题可切**(暗 / 浅 / 柔和三档)。实现方式是在语义层用 `[data-theme]` 属性做覆盖,用 `localStorage` 持久化用户选择;**首次进入默认暗色**(`:root`,不写 `data-theme`),之后由用户在设置内显式切换。(跟随系统 `prefers-color-scheme` 信号是远期增强,当前尚未接入——代码只读 `localStorage`,无持久化值时一律回落暗色。)
|
||
|
||
3. **SVG 图标取代 Unicode/emoji**,取向 lucide(一套开源的线性 SVG 图标库)。
|
||
|
||
4. **金样板先行**。不一上来就全站铺开,而是先把"token + 组件库 + 1 个消费面(游戏信息流 Feed)+ 1 个创作面(Create)"打磨到位、双语化、验证通过,再批量推其余视图。这是项目"黄金模板先行"效率原则在前端的落地。
|
||
|
||
5. **统一圆角矩形**。禁止药丸形、椭圆、正圆混用;圆角半径按尺寸成比例分级——`xs/sm/md/lg/xl = 4/6/8/12/20`(像素),默认用 `md`(8px)。唯一例外是 loading 旋转环保留圆形。这条是铁律,单独立了一份规则文档 `.agents/rules/ui-uniform-rounded-rectangles.md` 约束。
|
||
|
||
---
|
||
|
||
## 6. 三大契约:token / 组件 / i18n
|
||
|
||
设计体系对外暴露三套契约(contract,即跨人协作时大家都遵守、不能私自破坏的约定)。三套都坚持 **additive**(增量式)原则——旧令牌一律保留为别名,各页面在迁移期新旧共存、逐面切换,绝不一刀切破坏现有引用。逐令牌的权威清单以代码里的 `game-studio/src/styles/tokens.css` 为准,这里只讲骨架与命名空间。
|
||
|
||
### 6.1 token 契约
|
||
|
||
旧令牌(`--cyan`/`--green`/`--radius`/`--shadow` 等)全部保留,其中 `--cyan` 等被设为新语义令牌 `--accent` 的别名,对现有引用零破坏。新增三组:
|
||
|
||
- **primitive 原始层**:原色板 `--cyan/--green/--pink/--amber/--danger/--violet`,以及一对"在彩色背景上的前景色"`--on-accent:#061014`、`--on-danger:#2a0608`。
|
||
- **semantic 语义层**:`--bg`、`--surface-1..3`、`--accent`、`--success`、`--warning`、`--danger`、`--border-1..2`、品牌渐变 `--grad-primary`、热区渐变 `--grad-hot`、焦点环 `--focus-ring`。
|
||
- **尺度令牌**:间距 `--sp-1..6 = 4/8/12/16/22/32`、圆角 `--radius-xs..xl = 4/6/8/12/20`(默认 `md`)、阴影 `--elev-1..3`、字号 `--fs-h1/h2/h3/body/caption`、字重 `--fw-*`。
|
||
|
||
三档主题 `[data-theme=light|dim]` **只覆盖语义层**,不碰原始层。另一条收口约定:手写的 `rgba()` 透明度一律改用 `color-mix(in srgb, var(--token) N%, transparent)`,让透明色也走令牌而非硬编码。
|
||
|
||
### 6.2 组件契约
|
||
|
||
`AppButton` 的 props 保持不变(`type/size/block/loading/disabled`),向后兼容;但 primary(主)按钮恢复了品牌的签名渐变(`--grad-primary` + `--fw-cta` 字重 + `--on-accent` 前景),并补齐全部交互态:`focus-visible` 焦点环、`disabled` 时 0.5 透明度、`active` 时 scale 0.98 的按压反馈。`Icon` 组件**禁用 emoji**。
|
||
|
||
### 6.3 i18n 契约
|
||
|
||
采用 **vue-i18n@10**。文案文件放在 `src/locales/*.{zh,en}.ts`,按业务域划分命名空间(`common/feed/create/profile/entry/taskflow/project/hub/biz`)。硬约束:**禁止组件内出现裸中文**;缺失的 key 回退(fallback)到 `zh-CN`;数字、日期、货币一律用浏览器原生的 `Intl` API 本地化;品牌字符串统一收敛到 `common.brand` 一个 key(其值 = "绘境AI"),改名时只改一处。
|
||
|
||
---
|
||
|
||
## 7. studio vs demo:勿误砍 / 勿误判清单
|
||
|
||
这一节是两份"记录型"结论,目的是防止后人把 demo 当成目标、反而削弱了 studio 已有的真实能力,或者把"有意砍掉的范围"误判成"缺陷"去返工。
|
||
|
||
### 7.1 反向超出(studio 有 / demo 无 · MVP 真实可用必需 · 勿砍)
|
||
|
||
这些是 studio 比 demo 多出来、且 MVP 真实可用所必需的能力,绝不能因为"demo 里没有"就砍掉:
|
||
|
||
- **真实试玩宿主**:iframe 沙箱 + SDK/Runtime 注入 + postMessage 双向桥接双校验 + manifest 的 sha256 校验。这是护城河的命门——demo 里的"试玩"只是一个 toast 提示加一块静态 div,根本不是真在跑游戏。
|
||
- **登录注册整屏**:短信登录即注册 + 协议同意门 + 登录后 redirect 回跳 + 匿名 id(anonId)衔接。demo 完全没有登录概念。
|
||
- **分享落地页**:独立的 `/share/:gameId` 页 + Open Graph 元数据(社交平台抓取生成卡片预览用)+ utm 渠道归因参数。demo 里分享仅是一个 toast。
|
||
- **失败/取消/重试闭环**:生成任务的七种失败原因有可读的中文映射 + 可取消可重试 + 进度色反馈。demo 用 720ms 模拟一卡到底的 complete,从不出现失败态。
|
||
- **发布门禁**:7 项客户端预检 + 服务端权威返回 `{admitted, gates}` + 三态展示。demo 是乐观直发,无审核。
|
||
- **鉴权守卫 + 全链路埋点**:路由守卫只认真实 token(`isRealLogin`)+ 性能/游玩/会话埋点。demo 是纯前端切屏,不接任何后端契约。
|
||
|
||
### 7.2 有意 MVP descope(是范围裁剪 · 不是缺陷 · 勿返工)
|
||
|
||
下面这些是有意排除在 MVP 之外的(descope = 主动缩减范围),不是漏做的缺陷:
|
||
|
||
- **首页门户**:投资人路演的载体,归 PC 官网/投资人 demo,远期。
|
||
- **素材中心**:属 P1/v2.0,不在 55 个 P0 之列;真要落地须先补素材契约 + 授权/分成支付模型,且采购流程必须走后端可信边界,不能停在前端 mock。
|
||
- **玩法模板中心**:注意——这里指的是 demo 那块"玩法品类层市场"屏,已被创始人 2026-06-12 的 W-CLEAN 清理(清理旧填参式模板的收口工作)废除。它与架构文档里"玩法模板 = 品类框架、未废、待建"是两回事,**不要混淆**。
|
||
- **创作者数据后台**:远期;落地须反向定义出回读 API + 把诊断接到生成侧,避免产生没有入口的孤儿数据。
|
||
- **多渠道发布**:抖音/微信/快手/TapTap 等渠道导出,归独立的渠道发行专项另行推进,游戏信息流的终裁不受影响。
|
||
- **工作坊 IDE 化**:六类资产台、智能体对话、授权 IP 模式、编辑态调参等;MVP 走的是"一句话 + 选模板 → 整包生成"的简化路径。
|
||
|
||
---
|
||
|
||
## 8. 现状:已完成与遗留
|
||
|
||
**已完成**(都已在 `dev/2.0.0`):
|
||
|
||
- 退出登录的孤儿入口已闭合——Profile 页调用既有的 `userStore.logout()`,真实清掉 5 个 localStorage 键。
|
||
- 主按钮品牌青绿渐变已回归(`AppButton.primary` 用 `--grad-primary` + `--on-accent`,字重约 800)。
|
||
- Inter 字体已 self-host(自托管,不依赖外部 CDN;`reset.css` 里 `@font-face` + `font-display:swap`,中文有兜底字体)。
|
||
- 消息中心一级入口已落地(底部标签栏从 3 个 tab 扩到 4 个,含 `/message`,带 `messageStore.unreadTotal` 未读角标)。
|
||
- B 端前端归属已定为 studio 承接(`src/views/biz/` 下已建 BizLeads/BizLeadDetail/BizTemplatePicker/BizCreate,接既有的 `/app-api/biz/*` 7 个端点)。
|
||
- 字号阶梯令牌已抽出(`--fs-h1/h2/h3/body/caption`)。
|
||
|
||
**遗留(小尾巴)**:
|
||
|
||
- `tokens.css:3` 的注释里还残留旧路径 `zaomeng-ai-demo.html`(实际文件是 `huijing-ai-demo.html`,品牌应为绘境AI),措辞漂移待清。
|
||
- 明确不做的范围:原生 App(仅 token 契约就绪)、RTL(从右到左书写,服务阿拉伯语等)、护眼/高对比主题(留作后续增量)。
|
||
|
||
**tier2 富游戏的前端承载(待建,归属已定)**:第二条生成轨 tier2 的产物是 Phaser 多文件工程、要渲入 game feed 真玩。它给前端域带来两件现在还没做的事——feed 同时承载两种产物(现有 LittleJS 单包 + tier2 Phaser 多文件工程)的装载分发,以及 studio 创作端体现"超休闲廉价线 / 富游戏 premium 线"的第二轨入口。这两件归前端域(运行时容器 + 创作入口);装载与渲染的 how 在架构域,见 `../架构/生成引擎/引擎与运行时.md` 与 `../架构/生成引擎/tier2实现详设.md`。详细前端设计等 tier2 临近过 0号 spike 再展开,现在只钉归属、不预先设计。
|
||
|
||
---
|
||
|
||
## 9. 关键指针
|
||
|
||
需要更深的细节时,回到这些权威源:
|
||
|
||
| 你想找 | 去哪里 |
|
||
|---|---|
|
||
| 逐令牌的权威取值 | `game-studio/src/styles/tokens.css`(token 单一事实源) |
|
||
| 子系统活档(本档的来源) | `docs/architecture/前端/README.md` |
|
||
| 可直接打开的设计稿(含实时中英 + 三主题切换,真 Chrome 验过) | `docs-design/studio-redesign-mockup.html` |
|
||
| 设计基准原型(只取设计语言,不取布局) | `docs-design/huijing-ai-demo.html` |
|
||
| 构建门与真机走查的操作配方 | `.agents/skills/staging-ops.md`(构建真门 = `npm run build` / `vue-tsc -b && vite build`;注意 `vue-tsc --noEmit` 是假门不算数)、`.agents/skills/ui-walkthrough-cdp.md`(CDP 三主题 × 双语走查) |
|
||
| 圆角铁律 | `.agents/rules/ui-uniform-rounded-rectangles.md` |
|
||
| 落地提交记录(均在 `dev/2.0.0`) | `42342e8c` 卖相批 → `f98ad0f8` token 层 → `ecae9025` i18n 脚手架 → `655673eb` 组件库 → `caa2e1ba` 代表面 → `2c96e63a` 品牌+收尾 |
|
||
|
||
> **纪律**:前端域只讲"两个前端长什么样、靠什么撑起一致体验";产品对用户提供什么记在[产品域](../产品/README.md),系统用什么技术搭起来记在[架构域](../架构/README.md),它们各司其职、互不重复。
|