228 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 前端域 · 设计主文档
> **这是什么**:绘境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),它们各司其职、互不重复。