feat(mobile): 重做员工端首页、问答和训练页视觉

统一员工端 tabBar、共享卡片和三大核心页面的视觉基础,同时保持现有移动端业务流程不变。补充 H5 输入兼容、页面结构和训练回滚行为的回归测试。
This commit is contained in:
2026-07-11 01:13:14 +08:00
parent ebbc69eed6
commit ee396d1e7a
19 changed files with 2171 additions and 439 deletions
@@ -0,0 +1,450 @@
# Mobile Uni Employee Pages Visual Redesign Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 将员工端 `today / sop / practice` 三页及其强相关的 `tabBar / 共享卡片样式` 调整为接近设计基准稿的统一视觉,同时保持现有业务交互和接口行为不变。
**Architecture:** 采用“视觉优先、业务最小改动”的改法:先建立员工端共享视觉 token 与基础样式,再按首页、问师傅页、训练页的顺序逐页重排结构和样式。页面内部函数、接口调用与路由保留,主要改模板层级、类名、样式组织和少量静态资源引用。
**Tech Stack:** uni-app Vue3、Vite、TypeScript、CSS、Node 原生测试、H5 构建校验
---
### Task 1: 建立员工端共享视觉基座
**Files:**
- Modify: `mobile-uni/src/styles/base.css`
- Modify: `mobile-uni/src/pages.json`
- Test: `mobile-uni/tests/mobile-user-pages.test.mjs`
- [x] **Step 1: 写一个失败测试,锁住 Vue3 manifest 与员工端视觉约束继续有效**
```js
test('tabBar 继续保留员工端四个固定入口', async () => {
const source = await pageSource('../src/pages.json');
assert.match(source, /pages\/user\/today\/index/);
assert.match(source, /pages\/user\/practice\/index/);
assert.match(source, /pages\/user\/sop\/index/);
assert.match(source, /pages\/user\/profile\/index/);
});
```
- [x] **Step 2: 运行测试,确认新增断言先失败或当前文件尚未覆盖该约束**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: 新增测试如果还没加入会缺失;加入后在修改前至少能作为后续回归校验入口存在。
- [x] **Step 3: 在 `base.css` 中整理员工端共享 token,不扩大到全站侵入式重置**
```css
:root {
--employee-bg: #f4f6fb;
--employee-surface: #ffffff;
--employee-primary: #2f6bff;
--employee-primary-soft: #eaf1ff;
--employee-success: #34b368;
--employee-warning: #ff8a1f;
--employee-danger: #ff5b4d;
--employee-text: #182230;
--employee-muted: #6b7280;
--employee-card-radius: 24px;
--employee-card-shadow: 0 12px 32px rgba(47, 107, 255, 0.08);
}
.employee-card {
border-radius: var(--employee-card-radius);
background: var(--employee-surface);
box-shadow: var(--employee-card-shadow);
}
.employee-section-title {
color: var(--employee-text);
font-size: 20px;
font-weight: 900;
}
```
- [x] **Step 4: 调整 `pages.json` 的员工端 tabBar 视觉参数,保留四 tab 结构和路径**
```json
"tabBar": {
"color": "#7b8494",
"selectedColor": "#2f6bff",
"backgroundColor": "#ffffff",
"borderStyle": "white",
"height": "66px",
"fontSize": "12px",
"iconWidth": "25px",
"spacing": "3px",
"list": [
{ "pagePath": "pages/user/today/index", "text": "今日" },
{ "pagePath": "pages/user/practice/index", "text": "练" },
{ "pagePath": "pages/user/sop/index", "text": "问" },
{ "pagePath": "pages/user/profile/index", "text": "我" }
]
}
```
- [x] **Step 5: 更新回归测试,验证 tabBar 四入口与共享样式关键 token 存在**
```js
test('共享视觉基座包含员工端主色和卡片圆角 token', async () => {
const source = await pageSource('../src/styles/base.css');
assert.match(source, /--employee-primary:/);
assert.match(source, /--employee-card-radius:/);
});
```
- [x] **Step 6: 运行测试验证通过**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: PASS,且已有输入兼容与 manifest 测试继续通过。
- [ ] **Step 7: 提交这一阶段改动**
```bash
git add mobile-uni/src/styles/base.css mobile-uni/src/pages.json mobile-uni/tests/mobile-user-pages.test.mjs
git commit -m "feat: add employee visual foundation"
```
### Task 2: 重做员工端首页视觉
**Files:**
- Modify: `mobile-uni/src/pages/user/today/index.vue`
- Modify: `mobile-uni/src/styles/base.css`
- Test: `mobile-uni/tests/mobile-user-pages.test.mjs`
- [x] **Step 1: 为首页结构写失败测试,锁住设计稿要求的核心区块**
```js
test('员工首页保留师傅区、语音条、今日安排、我的地图四段结构', async () => {
const source = await pageSource('../src/pages/user/today/index.vue');
assert.match(source, /mentor-hero/);
assert.match(source, /voice-panel/);
assert.match(source, /今日安排/);
assert.match(source, /我的地图/);
});
```
- [x] **Step 2: 运行测试确认结构断言可作为改版护栏**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: 失败或在旧结构下不足以覆盖新样式目标,后续补全后通过。
- [x] **Step 3: 重排首页模板,保留原有交互函数但调整为设计稿节奏**
```vue
<view class="mentor-hero employee-hero">
<view class="hero-copy">
<text class="hero-role">{{ positionProfile.value }}</text>
<text class="hero-title">{{ positionProfile.heroTitle }}</text>
<text class="hero-sub">有问题,随时问老师傅</text>
</view>
<image class="mentor-image" src="/static/mentor.png" mode="aspectFit" />
<view class="mentor-bubble">
<text>{{ mentorBubbleText }}</text>
</view>
</view>
<view class="voice-panel employee-card">
<button class="voice-primary" @click="goSop">...</button>
<button class="voice-secondary" @click="goSop">...</button>
</view>
<view class="section-card employee-card" v-else-if="hasSchedule">...</view>
<view class="section-card employee-card" v-if="loggedIn">...</view>
```
- [x] **Step 4: 用 scoped 样式还原首页视觉,控制人物占屏不超过首屏约五分之一**
```css
.today-page {
background: radial-gradient(circle at top, #eef5ff 0%, #f7f9fc 38%, #f4f6fb 100%);
}
.mentor-hero {
min-height: 220px;
padding: 28px 24px 0;
}
.mentor-image {
right: 24px;
bottom: 0;
width: 108px;
height: 148px;
}
.voice-panel {
margin-top: -28px;
grid-template-columns: 1.4fr 1fr;
}
.map-tile {
border-radius: 22px;
min-height: 136px;
}
```
- [x] **Step 5: 更新测试,验证首页地图主标题继续显示真实 `tile.title`,避免回退成单字标题**
```js
test('员工首页地图主标题继续显示真实工具名称', async () => {
const source = await pageSource('../src/pages/user/today/index.vue');
assert.match(source, /<text class="map-title">\{\{ tile\.title \}\}<\/text>/);
});
```
- [x] **Step 6: 运行测试验证首页改版没有破坏护栏**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: PASS。
- [ ] **Step 7: 提交首页改版**
```bash
git add mobile-uni/src/pages/user/today/index.vue mobile-uni/src/styles/base.css mobile-uni/tests/mobile-user-pages.test.mjs
git commit -m "feat: redesign employee home page"
```
### Task 3: 重做问师傅页视觉与总结卡展现
**Files:**
- Modify: `mobile-uni/src/pages/user/sop/index.vue`
- Modify: `mobile-uni/src/styles/base.css`
- Test: `mobile-uni/tests/mobile-user-pages.test.mjs`
- [x] **Step 1: 为问师傅页写失败测试,锁住搜索主导与总结卡入口仍然存在**
```js
test('问师傅页保留搜索框、答案区和总结卡入口', async () => {
const source = await pageSource('../src/pages/user/sop/index.vue');
assert.match(source, /query-panel/);
assert.match(source, /answer-panel/);
assert.match(source, /summary-panel/);
});
```
- [x] **Step 2: 运行测试确认护栏建立成功**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: 断言可执行,作为后续视觉重排的结构保护。
- [x] **Step 3: 收紧问师傅页头部,改为“轻标题 + 强搜索框”的布局**
```vue
<view class="page sop-page">
<view class="sop-toolbar">
<text class="page-title">查SOP</text>
<text class="page-subtitle">直接搜 SOP、案例和常用话术</text>
</view>
<view class="panel query-panel employee-card">
<textarea v-model="query" class="textarea sop-query-textarea" ... />
<view class="chip-row">...</view>
<button class="primary-button query-submit" ...>问老师傅</button>
</view>
</view>
```
- [x] **Step 4: 调整答案卡、引用依据和总结卡为更接近设计稿的卡片层级与底部浮层感**
```css
.sop-page {
background: linear-gradient(180deg, #f7f9fc 0%, #f4f6fb 100%);
}
.query-panel {
border-radius: 22px;
padding: 18px;
}
.answer-panel {
border-left: 0;
border-radius: 22px;
}
.modal-card {
border-radius: 28px 28px 0 0;
max-width: 430px;
width: calc(100% - 16px);
}
```
- [x] **Step 5: 保持 H5 输入兼容测试存在,防止误把 `textarea` 再次改成 `border-box`**
```js
test('SOP 查询框不覆盖 textarea 的 box-sizing', async () => {
const source = await pageSource('../src/pages/user/sop/index.vue');
const queryPanelStyle = source.match(/\.query-panel \.textarea \{[\s\S]*?\n\}/)?.[0] || '';
assert.equal(queryPanelStyle.includes('box-sizing'), false);
});
```
- [x] **Step 6: 运行测试验证通过**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: PASS。
- [ ] **Step 7: 提交问师傅页改版**
```bash
git add mobile-uni/src/pages/user/sop/index.vue mobile-uni/src/styles/base.css mobile-uni/tests/mobile-user-pages.test.mjs
git commit -m "feat: redesign employee sop page"
```
### Task 4: 重做训练页视觉但保留训练逻辑
**Files:**
- Modify: `mobile-uni/src/pages/user/practice/index.vue`
- Modify: `mobile-uni/src/styles/base.css`
- Test: `mobile-uni/tests/mobile-user-pages.test.mjs`
- [x] **Step 1: 为训练页写失败测试,锁住训练关键区块仍存在**
```js
test('训练页保留场景区、对话区、回复区和结果区', async () => {
const source = await pageSource('../src/pages/user/practice/index.vue');
assert.match(source, /scenario-card/);
assert.match(source, /dialogue-card/);
assert.match(source, /reply-card/);
assert.match(source, /result-card/);
});
```
- [x] **Step 2: 运行测试确认结构护栏存在**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: 断言可运行,用于防止视觉重排时误删功能区块。
- [x] **Step 3: 调整训练页模板,让头部、场景卡、老师傅提示更接近设计稿的训练面板结构**
```vue
<view class="practice-head">
<text class="practice-eyebrow">数字师傅 · 场景训练</text>
<text class="page-title">{{ activeScenarioName }}</text>
<text class="page-subtitle">与业主、老师傅完成一轮真实工作对话</text>
</view>
<view v-if="loggedIn" class="panel scenario-card employee-card">...</view>
<view v-if="turns.length" class="panel dialogue-card employee-card">...</view>
<view v-if="status === 'active' || status === 'submitting'" class="panel reply-card employee-card">...</view>
```
- [x] **Step 4: 用样式强化三类角色区分与老师傅提示卡,但不引入每轮真实评分**
```css
.turn-row.customer {
background: linear-gradient(180deg, #fff8f1 0%, #ffffff 100%);
}
.turn-row.trainee {
background: linear-gradient(180deg, #f2fbf6 0%, #ffffff 100%);
}
.turn-row.coach {
background: linear-gradient(180deg, #eef5ff 0%, #ffffff 100%);
}
.reply-card .primary-button {
min-height: 52px;
border-radius: 18px;
}
.help-card,
.mentor-rewrite {
border-radius: 22px;
}
```
- [x] **Step 5: 保留并复用提交失败回滚测试,避免训练视觉改版时误伤已有状态修复**
```js
test('训练页提交失败会回滚本次乐观追加的对话', async () => {
const source = await pageSource('../src/pages/user/practice/index.vue');
assert.match(source, /const previousTurns = turns\.value\.slice\(\)/);
assert.match(source, /turns\.value = previousTurns/);
});
```
- [x] **Step 6: 运行测试验证通过**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: PASS。
- [ ] **Step 7: 提交训练页改版**
```bash
git add mobile-uni/src/pages/user/practice/index.vue mobile-uni/src/styles/base.css mobile-uni/tests/mobile-user-pages.test.mjs
git commit -m "feat: redesign employee practice page"
```
### Task 5: 全量验证与收尾
**Files:**
- Verify: `mobile-uni/src/pages/user/today/index.vue`
- Verify: `mobile-uni/src/pages/user/sop/index.vue`
- Verify: `mobile-uni/src/pages/user/practice/index.vue`
- Verify: `mobile-uni/src/styles/base.css`
- Verify: `mobile-uni/src/pages.json`
- Test: `mobile-uni/tests/mobile-user-pages.test.mjs`
- [x] **Step 1: 运行员工端页面回归测试**
Run: `node --test tests/mobile-user-pages.test.mjs`
Expected: PASS。
- [x] **Step 2: 运行全量单测**
Run: `npm run test:unit`
Expected: 全部 PASS;允许保留既有 WebSocket 噪音,只要没有失败。
- [x] **Step 3: 运行类型检查**
Run: `npm run typecheck`
Expected: PASS。
- [x] **Step 4: 运行 H5 构建**
Run: `npm run build:h5`
Expected: `Build complete.`
- [ ] **Step 5: 本地打开首页进行人工快速核对**
Run: `open "http://localhost:5175/h5/#/pages/user/today/index"`
Expected: 能看到新的首页首屏结构、语音条、今日安排、我的地图和统一 tabBar。
- [ ] **Step 6: 提交最终整体验证结果**
```bash
git add mobile-uni/src/pages/user/today/index.vue mobile-uni/src/pages/user/sop/index.vue mobile-uni/src/pages/user/practice/index.vue mobile-uni/src/styles/base.css mobile-uni/src/pages.json mobile-uni/tests/mobile-user-pages.test.mjs
git commit -m "feat: unify employee mobile page visuals"
```
## 计划自检
### Spec 覆盖检查
- 三页范围:Task 2、Task 3、Task 4 覆盖 `today / sop / practice`。
- 共享样式与 tabBar:Task 1 覆盖。
- 老师傅仅复用现有素材、不扩展业务:Task 2 与 Task 4 的模板调整限制在现有资源与逻辑内。
- SOP 不伪造能力:Task 3 明确保留真实能力,不新增假 tab 行为。
- 训练页不做每轮真实评分:Task 4 明确只改视觉分层,不新增该模块。
- 验证要求:Task 5 覆盖页面测试、全量单测、类型检查、H5 构建。
### Placeholder 扫描
- 无 `TODO`、`TBD`、`适当处理` 等空泛描述。
- 每个任务都包含具体文件、命令和代码片段。
### 类型与命名一致性
- 继续沿用现有页面类名:`scenario-card`、`dialogue-card`、`reply-card`、`summary-panel`、`voice-panel` 等。
- 复用现有关键回归点:`tile.title`、`previousTurns`、`box-sizing`、`vueVersion`。
@@ -0,0 +1,241 @@
# 员工端三页视觉改版设计
## 背景
当前 `mobile-uni` 员工端首页、问师傅页、训练页虽然已经有一轮样式调整,但整体仍然存在以下问题:
- 三页视觉语言不统一,像是独立拼接出来的页面,而不是同一套员工端产品。
- 信息层级和卡片节奏偏乱,重点入口不够聚焦,页面看起来“重、散、旧”。
- 与 `docs/feedback/2026070423/design/` 中已经采纳的 P1 视觉基准仍有明显差距。
- 当前诉求是优先解决“页面丑陋”的观感问题,而不是重写业务交互。
本次改版以视觉还原为主,业务交互保持最小改动。
## 目标
### 主要目标
- 统一员工端 `today / sop / practice` 三页视觉气质。
- 尽量向已采纳设计稿靠拢,优先还原布局、卡片层级、按钮形态、留白和色彩关系。
- 保持现有业务逻辑、接口调用、页面跳转、训练流程与登录流程不变。
- 允许联动调整员工端 `tabBar` 和少量共享基础样式,使三页不再割裂。
### 非目标
- 不新增后端字段或伪造后端能力。
- 不重写训练页状态机或 SOP 检索逻辑。
- 不做候选人端、主管端的同步视觉改版。
- 不在本次引入新的正式人物素材来源。
## 设计依据与约束
### 设计依据
- 首页视觉基准:`docs/feedback/2026070423/design/h5-redesign-employee-home.png`
- SOP 结果与总结卡基准:`docs/feedback/2026070423/design/h5-feedback-summary-modal.png`
- 训练页对手戏基准:`docs/feedback/2026070423/design/h5-feedback-voice-roleplay.png`
- 综合评审约束:`docs/feedback/2026070423/design/REVIEW.md`
### 必须遵守的约束
- 老师傅形象不照抄首页参考图中的女性写实形象,统一使用现有本地素材做“蓝工装插画风男性师傅”的近似表达。
- 首页人物只承担氛围与陪伴感,不大面积占屏;视觉占比控制在首屏约五分之一以内。
- 训练页不实现每轮真实评分,只保留轻提示或教练辅助信息。
- SOP 页如果设计稿出现“全部/SOP/案例/话术”类型 tab,在后端维度未落地前不得伪造成功能型筛选。
- 遵守 uni-app H5 输入兼容性规则,不对 `input` / `textarea` 设置 `box-sizing: border-box`。
## 范围
### 页面范围
- `src/pages/user/today/index.vue`
- `src/pages/user/sop/index.vue`
- `src/pages/user/practice/index.vue`
### 允许联动的共享部分
- `src/styles/base.css`
- `src/pages.json` 中员工端 `tabBar` 视觉配置
- 员工端页面使用的现有本地静态素材引用方式
### 明确不改的部分
- 页面路由结构
- 接口地址、参数与返回处理
- 训练开始、提交、结束、SOP 查询、总结卡生成等业务行为
- 登录与岗位确认流程
## 总体方案
采用“视觉优先还原型”方案:
- 保留现有业务结构和页面职责,不移动关键交互入口的语义。
- 对三页的首屏结构、标题区、功能卡、按钮区、辅助信息区进行重排和统一。
- 在共享样式层建立一套仅服务员工端三页的轻量视觉 token,包括背景、卡片、主色、辅助色、圆角、阴影、标题字号与留白节奏。
- 对 `tabBar` 做有限统一,让页面主视觉与底部导航形成同一套产品感知。
这条方案的核心是:让用户明显感觉“这是一套被设计过的产品”,而不是“旧页面换了点颜色”。
## 共享视觉系统
### 色彩
- 主蓝:用于首页主入口、主要行动按钮、SOP 核心操作。
- 辅橙:用于复盘、提醒、异议、次强调动作。
- 辅绿:用于师傅、建议、可执行正向反馈。
- 辅红:用于风险、命中红线、强提醒。
- 大面积背景:使用偏暖的浅灰白底,避免纯白页面带来的生硬感。
### 形态
- 卡片统一使用大圆角、轻阴影、弱边框。
- 主操作按钮统一做成更饱满的胶囊或大圆角矩形。
- 标签、chips、状态 badge 使用明显但不过分抢眼的弱底色。
- 页面内图文块尽量减少硬线分割,多用留白和卡片分区建立节奏。
### 文本层级
- 页面标题使用大号高对比字重。
- 模块标题明显强于正文,但弱于页面标题。
- 辅助说明统一压低饱和度,避免整页“处处都是重点”。
### TabBar
- 保留“今日 / 练 / 问 / 我”结构不变。
- 调整选中态、阴影、顶部边界和留白,让其更接近设计稿中的轻质底栏。
- 不改动页面跳转与当前 tab 逻辑。
## 分页面设计
### 1. 员工端首页 `today`
#### 目标
首页要尽量贴近 `h5-redesign-employee-home.png`:先建立“老师傅陪练”的第一印象,再把语音入口、今日安排、我的地图作为三个连续层级展开。
#### 结构
- 顶部使用浅背景氛围图区。
- 左侧为岗位与欢迎信息,右下为较小的老师傅形象与气泡。
- 头图区下方是大白卡语音入口,主入口明显、次入口收敛。
- 再下方是快捷 chips。
- 然后依次是“今日安排”“我的地图”“今日小贴士”。
#### 关键调整
- 头图不再追求“人物大图压场”,而是营造轻陪伴感。
- “问老师傅”作为首要入口,视觉上高于“打字问”。
- “今日安排”卡更像日程卡,而不是普通列表。
- “我的地图”保留四色功能块,但主标题显示真实业务名,单字仅作装饰符号。
- 整页通过更清晰的上下节奏建立首屏完成度。
### 2. 问师傅页 `sop`
#### 目标
页内重点从“普通查询页”升级为“搜索驱动的知识助手页”,并尽量贴近 `h5-feedback-summary-modal.png` 的结构氛围。
#### 结构
- 顶部收成更轻的标题与搜索区。
- 搜索框作为首屏主元素。
- 查询结果区按“直给答案 -> 要点 -> 提醒 -> 引用依据”分层。
- 总结卡入口保持单独区域。
- 总结卡展示形态从普通 modal 调整为更贴近设计稿的底部浮层信息图风格。
#### 关键调整
- 减少当前大块头图区的存在感,把注意力转回搜索行为。
- 查询按钮、快捷问题、答案卡的主次关系更明确。
- 总结卡内部采用更强的信息图分组感,但不新增保存、听一遍、跟读等未实现业务按钮。
- 若现阶段无法正确承载分类 tab,则不强行做功能性顶部分类。
### 3. 训练页 `practice`
#### 目标
把页面从“功能堆叠页”调整为更像训练对话面板的页面,同时遵守“不做每轮真实评分”的约束。
#### 结构
- 顶部为训练标题、场景标签和老师傅陪伴状态。
- 场景预习卡保留,但视觉上并入训练前准备区域。
- 对话区强化三类角色的视觉差异:业主、我、老师傅。
- 回复区的录音、转写、求助、提交按钮重新排版,但功能不变。
- 教练提示与 SOP 提示更像辅助卡,而不是和主流程抢层级。
- 结果卡在完成后仍独立呈现。
#### 关键调整
- 参考 `h5-feedback-voice-roleplay.png` 的对话氛围与角色卡感,但不照搬其每轮评分模块。
- 让“老师傅提醒”成为视觉上可信赖的辅助块。
- 保持现有训练逻辑顺序,不改开始、提交、结束时机。
## 组件与样式边界
本次优先在现有页面文件内完成视觉重排,不额外拆出大量新组件,理由如下:
- 用户当前诉求是快速改善三页视觉,而不是先做前端组件体系建设。
- 三页虽然要统一语言,但内容结构差异仍较大,过早抽象容易制造样式耦合。
- 共享部分只抽到 `base.css` 的 token 和少量通用类,避免引入新的复杂度。
允许的抽象上限:
- 共享 token
- 通用卡片/标题/按钮类
- 少量重复且完全稳定的视觉辅助类
不建议在本次新增多层组件封装。
## 验收标准
### 视觉验收
- 三页首屏都明显接近参考设计稿的节奏与气质。
- 员工端首页、SOP 页、训练页能够被一眼识别为同一套产品。
- 老师傅、语音入口、核心行动按钮、模块标题的层级明显优于当前版本。
- `tabBar` 与页面主视觉不再割裂。
### 行为验收
- 现有路由、接口、登录、训练、SOP 查询行为不回归。
- 不引入假交互、不新增无后端支持的视觉功能。
- 输入框与文本域在 H5 仍可正常聚焦、输入。
### 技术验收
- 至少完成类型检查、单测和 H5 构建验证。
- 如新增与视觉约束有关的轻量回归测试,应优先覆盖容易再次被误改的关键点。
## 风险与处理
### 风险 1:现有本地素材不足以完全贴近设计稿
处理:优先还原布局、比例、色彩和氛围;人物素材先做近似表达,不因素材不足阻塞页面改版。
### 风险 2:为了追视觉而误伤业务逻辑
处理:限定本次为视觉优先、交互最小改动,不重写流程函数和接口组织。
### 风险 3:共享样式改动波及其它页面
处理:共享样式只服务员工端相关页面,避免做全局侵入式 reset。
### 风险 4:SOP 设计稿含未落地能力
处理:只保留当前真实能力,视觉上做近似,不伪造功能。
## 实施顺序建议
1. 先整理员工端共享 token 和 tabBar 视觉基座。
2. 完成员工端首页改版,建立整套视觉语言。
3. 以首页风格为基准改 SOP 页。
4. 最后改训练页,避免其复杂交互拖慢整体节奏。
5. 跑类型检查、单测和 H5 构建验证。
## 规格自检结论
- 无占位符、TODO 或未定义术语。
- 方案范围清晰,聚焦三页与少量共享视觉层。
- 与用户已确认方向一致:优先还原视觉,业务交互最小改动。
- 与项目评审约束一致:人物统一、首页人物缩量、训练页不做每轮真评分、SOP 不伪造分类能力。