文件
OmniCard/docs/mpuniapp-ui-refactor-plan.md

776 行
34 KiB
Markdown

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

# mpuniapp UI 重构规范
面向实现代理。只改 `.uvue` 模板结构、scoped CSS、以及 `resolveXxxText` 文案分支。禁止改业务 API、状态机、请求参数、路由语义。`pages.json` 的 tabBar 仍是旧「官网/雷达/潜客」,本轮只在分析中指出,不改路由配置。
Token 一律来自 `mpuniapp/common/tokens.uts`,页面通过已有 `pageTheme` 注入 CSS 变量。禁止 Tailwind。禁止业务态内联 `style`(`pageTheme` 注入 CSS 变量除外)。暗色变量已定义,本轮先把 Light 变量用齐;能接 `prefers-color-scheme` 的页面在第 5 轮统一补。
---
## 0. 全局视觉语言(实现代理必遵)
1. **页面骨架**:`背景 surface #F7F8FA` + 顶栏白底(`bg #FFFFFF` + 底部分隔 `1px border #E3E7ED`)+ 内容区 `padding-inline: 16px` + 列表/表单卡片 + 底栏 1 个主 CTA。页面纵向:顶栏固定内容高度,中间 `flex:1` 滚动,底栏不随内容滚走。
2. **字号层次(只许 12/14/16/20/24/32/40)**:页标题 24/700/行高 1.25/`text`;区块标题 16/600;正文 14/行高 1.6/`text2`;辅助/标签 12/`text2`。禁止 11、13、15、17、18、22。按钮字 16/600。输入字 16。
3. **卡片**:白底、`1px border`、圆角 16、阴影只许 `0 1px 2px rgba(16,24,40,0.04)`。最多两层嵌套。列表行用卡片,不用重阴影、不用玻璃、不用渐变底。
4. **主 CTA 栏**:每屏 1 个主按钮。高 48、圆角 12、宽 100%、`primary #0B5CFF`、字 `#FFFFFF`。固定底栏:`padding 12px 16px` + `safe-area-inset-bottom`。内容区底部垫高 `88px + window-bottom + safe-area`。禁用态底 `border`、字 `text2`。次操作只能是文字链或描边 chip,不能再出现同级实心蓝按钮。
5. **空 / 错 / 加载**:加载用骨架(头像圆 72、标题条 24×60%、卡片条 72–88 高、底色 `border`、圆角 8/16),禁止转圈作为主反馈。空态:一句话 16/600 + 一句 14/`text2` + 一个主 CTA。错误态:同卡片结构,主 CTA = 重试/返回。
6. **分段 chips**:高 ≥44、左右 padding 16、圆角 12、默认白底+`border`、选中 `primarySoft` 底 + `primary` 边 + `primary` 字。横滑一行,禁止换行堆成两排。禁止选中填实心蓝底白字(语言选择除外可用描边选中)。
7. **安全区与触控**:可点区域 ≥44×44。输入高 44、标签在上、错误在下。删除徽标若视觉 18,外扩点击热区到 44。底栏避让 `env(safe-area-inset-bottom)` 与 `var(--window-bottom)`(有 tabBar 的页必须加 window-bottom)。
8. **RTL**:间距、padding、margin 用 logical(`padding-inline` / `margin-inline` / `border-inline-start`)。箭头、悬浮入口在 RTL 下左右对调。`direction` 跟当前 locale。
9. **动效**:点击透明度 0.85 或位移 0,时长 150ms,`cubic-bezier(0.2, 0.8, 0.2, 1)`。禁止 scale 放大。`prefers-reduced-motion: reduce` 时 animation/transition 全关。AI 只用 150ms 微光一次。NFC 脉冲 400ms 一次,不循环。
10. **禁止**:emoji、纯黑 `#000`、大面积渐变、重阴影、玻璃拟态、霓虹、拟物、装饰插画。品牌色只作按钮/链接/选中,语义红绿黄只表示状态。模板禁止硬编码中文,走 `getOmniText` / `resolveXxxText`。
11. **长列表**:`list-view` + `list-item`。禁止 `view` + `v-for` 渲染可能超过一屏的列表。Bento 网格、KPI(≤4)、语言 chips(7)、状态 chips(≤6)可用 `view` + `v-for`。
12. **不要改的范围**:`common/api.uts`、`common/request.uts`、`common/types.uts`、各页 `useXxx.uts` 的请求/状态机/跳转 URL。允许:`.uvue` 结构与 CSS;`resolveXxxText` 增补文案 key(不改函数签名语义)。本轮不改 `pages.json` tabBar。
---
## 1. 页面总表
| 路径 | 中文名 | 角色 | PRD 必须内容 | 当前缺口 | UX 改进点 | 重构优先级 |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `pages/portal/index` | Bento 微官网 | 访客首屏 | Hero、快捷动作、vCard 主 CTA、Bento、AI 入口、i18n/RTL | 顶栏三动作抢主 CTA;AI 浮层阴影过重;社交格全显空项;大量硬编码色;`collect` 文案写死 | 压顶栏、滤空社交、字号归位、AI 降为次入口 | P0 |
| `pages/portal/exchange` | 互换名片 | 访客留资 | 姓名/公司/WhatsApp/邮箱/留言;OCR 拍照填单 | 模板全中文硬编码;OCR 按钮高 36;无 RTL | 全走 i18n;表单标签上/错下;OCR 热区 44 | P0 |
| `pages/portal/case-detail` | 案例详情 | 访客阅读 | 轮播、KPI、PDF 预览、咨询 CTA | `CASE_DETAIL_COPY` 中文写死;PDF/视频只露 URL | 文案走 resolve;外链做成可点行;KPI 最多 3 张 | P0 |
| `pages/portal/article-detail` | 文章详情 | 访客阅读 | 杂志排版、分享 | 底栏「复制链接」语义弱;空态无卡片感 | 主 CTA 改「复制分享链接」层次;阅读列宽保持 720 | P1 |
| `pages/portal/ai-chat` | AI 顾问 | 访客问答/留资 | list-view 对话、留资卡、发送 | 输入+发送纵向占太高;成功色硬编码 | 输入行与发送合并为一行;微光保留 | P1 |
| `pages/common/login` | 登录 | 名片主认证 | 手机验证码、Magic Link、Google/Apple | 模板中文写死;无 token 变量;PRD 三通道未上屏;测试账号暴露 | 先视觉+i18n;测试入口降为 12 号弱链;预留 tab 位但不接新 API | P0 |
| `pages/owner/hall/index` | 名片大厅 | Tab「大厅」 | 人脉/团队/现场;搜;兑换码/现场码 | 顶栏过高;空态无 CTA;列表无头像位 | 压标题;三段 chip 单行;空态接底栏主 CTA | P1 |
| `pages/owner/card/index` | 我的名片 | Tab「名片」 | 卡片盒、状态、今日浏览、雷达红点、海报 | 普通列表;无浏览数/红点;底栏「刷新/海报」语义飘 | 行内状态+编辑;底栏固定「分享海报」;浏览数可占位不接新接口 | P0 |
| `pages/owner/radar` | 实时雷达 | 二级页 | 长列表足迹、停留、高意向标红 | 手填 cardId 过技术;空/错混为一句;无骨架;不高亮 | 去掉技术输入视觉(保留字段隐藏绑定);行内标红高停留 | P1 |
| `pages/owner/leads` | 客户 | Tab「客户」 | 意向筛选、搜索、电话/WhatsApp;高意向红点;雷达摘要 | 顶栏堆 6 块;红点用了品牌蓝;无一键联系 | 压成「标题+红点 / 雷达 2 行 / 搜索 / chips」;红点用 error | P0 |
| `pages/owner/profile/index` | 我的 | Tab「我的」 | 资料、语言、推送、企业 | 硬编码色;进度条内联 width;预览钮 32;删除热区 18;指标写死 | 改 token;热区 44;语言 chip 改描边选中 | P1 |
| `pages/owner/card/edit` | 极速编辑 | 二级 | 资料、社交、模块排序、AI 润色 | 无 slogan/排序/润色入口;删除热区 18 | 只补视觉空位与层次,不接新 API | P1 |
| `pages/owner/card/qrcode` | 分享海报 | 二级 | 高清码、大图、存相册 | 只有 URL 文本,无码无海报 | 中央 200 方码位+短链;主 CTA「复制链接」 | P0 |
| `pages/owner/leads-detail` | 跟进备忘 | 二级 | 轨迹、AI 话术、备忘 | 轨迹用 view 列表;无电话/WhatsApp;无 AI 话术位 | 轨迹改 list-view;预留话术卡;主 CTA 仍保存备忘 | P1 |
| `pages/owner/nfc/scan` | NFC 贴卡 | 二级 | 贴卡 0.5s、脉冲、成功震动 | 纯表单;无脉冲;H5 与 App 长一样 | 中央 120 脉冲环(一次 400ms);表单降为 H5 后备 | P1 |
| `pages/owner/nfc/mode` | 场景切换 | 二级 | 展会/社交、离线 vCard、状态 | 缺离线说明行 | 补一行说明;模式选项保持描边 | P2 |
| `pages/owner/nfc/security` | 挂失 | 二级 | 挂失、UID 校验、解绑 | `view v-for`;「处理中...」写死;危险按钮 `#D92D20`;底 `#FFFFFF` | 设备少可保留卡片;CTA 用 error token;文案 i18n | P2 |
| `pages/owner/team/overview` | 展会战报 | 二级 | 排行、KPI、转化柱 | 刷新当主 CTA;排行数字裸堆;双 list 分支重复 | 2×2 KPI 用 gap 12;主 CTA 改「回到客户」或保留刷新但降文案 | P2 |
**tabBar 现状(本轮不改文件)**:`pages.json` 仍为 官网=`portal/index` / 名片 / 雷达 / 潜客=`leads` / 我的。落地 IA 应为 大厅 / 名片 / 客户 / 我的,雷达从客户页进入。视觉重构按落地 IA 排信息,不改 `pages.json`。
---
## 2. 逐页规范
### 2.1 `pages/portal/index` · Bento 移动微官网
**用户目标**:5 秒内确认对方是谁,并保存到通讯录。
**必须保留**:`loadCardPortal`、停留上报、语言 persist、快捷动作、vCard 保存、Bento 跳转、互换/AI 跳转、收藏大厅、发音组件、骨架/错误重试。
**信息架构(上→下)**
```
┌─────────────────────────────────────┐
│ [语言选择] [交换 文字] │ 高 44,无第二实心按钮
├─────────────────────────────────────┤
│ 品牌 Logo(可选) │
│ ┌ Hero 卡 16 圆角 1px 边 ─────────┐ │
│ │ 头像 72 时区 pill 12 │ │
│ │ 姓名 24/700 [发音] │ │
│ │ 头衔 14 / 公司 14/600 │ │
│ │ 分隔线 + Slogan 14/1.6 │ │
│ └─────────────────────────────────┘ │
│ 快捷动作:仅渲染有值的项,每项 25% │
│ 宽、高 ≥56,字 12 │
│ Bento:1 列 50% / 2 列 100%,gap 12 │
│ spacer 140+safe │
├─────────────────────────────────────┤
│ 主 CTA 48:「保存到通讯录」 │
└─────────────────────────────────────┘
右下 AI 文字 chip(次入口,不是主 CTA)
```
**主 CTA**:底栏「保存到通讯录」`card.save_contact`。AI、交换、收藏都是文字/描边。
**空 / 错 / 骨架**:保持现有三态。错误卡居中,重试按钮高 40 改为 44。
**具体视觉改动**
- 顶栏去掉「收入大厅」与「交换」并列双 chip。交换保留一个 14 号文字链。收藏改为 Hero 内 12 号文字链,或登录后才显示。
- `collectLabel`、toast「已收入大厅」改为 `resolve` / locale key,禁止 `currentLang === 'zh-CN' ?`。
- 快捷动作:无链接的项不渲染(数据仍在 state,只是 `v-if`)。
- 字号:`action-icon-text` 11→12,`hero-title` 15→14,`hero-slogan` 13→14,`bento-title` 15→16,`bento-tag` 11→12,CTA 字 15→16。
- 颜色全部改 `var(--oc-*)`。页面背景 `surface`。
- `.ai-entry` 阴影改为 token 浅影,去掉紫影 `rgba(124,92,255,0.12)`。
- `.bento-card:active` 的 `scale(0.99)` 改为 `opacity: 0.85`,并加 `prefers-reduced-motion`。
- RTL:顶栏、姓名行、公司行改 `margin-inline`;AI 入口 `inset-inline-end: 16px`。
- 公司行保持可点,不改 `handleCompanyClick`。
**不要改的文件**:`usePortal.uts`、`useAudioPlayer.uts`、`useCache.uts`、`vcard-export.uts`、`components/i18n-selector`、`components/audio-pronounce`。
---
### 2.2 `pages/portal/exchange` · 无摩擦互换名片
**用户目标**:30 秒留下姓名和一个联系方式。
**必须保留**:`applyExchangeOptions`、`submitExchange`、OCR 上传/预览/删除、`canSubmit`/`submitting` 禁用。
**信息架构**
```
┌ 白卡 16 圆角 ──────────────────────┐
│ 标题 24:「交换名片」 │
│ 说明 14 │
│ 警告条(无 cardId 时) │
│ OCR 行:左文案 / 右 44 高描边按钮 │
│ 预览行:48 图 + 文 + 删除(热区 44) │
│ 字段×5:标签 14 在上,输入 44 │
└─────────────────────────────────────┘
底栏主 CTA 48:提交 / 提交中
```
**主 CTA**:提交留资。OCR 是次按钮(`primarySoft` 底 + `primary` 边)。
**空 / 错 / 骨架**:无 cardId 用警告条,主 CTA 禁用。无独立骨架(表单即首屏)。提交失败走现有 toast,不改 hook。
**具体视觉改动**
- 模板 10+ 处中文全部改为 `resolveExchangeText`。若 hook 无该函数,只在 `useExchange.uts` **新增文案 map**,不改 `submitExchange`。
- `.ocr-btn` 高 36→44。`.ocr-preview-delete` padding 扩到 min 44×44。
- 输入已是 44,保持。标签 14/600,间距 8。
- 页面加 `:class` RTL。`margin-right` 改 `margin-inline-end`。
- CTA 字 15→16。
**不要改的文件**:`useOcrExchange.uts` 的上传/识别流程;`submitExchange` 入参。
---
### 2.3 `pages/portal/case-detail` · 案例详情
**用户目标**:看懂成果,点「咨询」去留资。
**必须保留**:`loadCaseDetail`、swiper、KPI、pdf/youtube 字段、`openCaseExchange`、空态返回。
**信息架构**
```
标题 24
封面 swiper 220 / 单图 220,圆角 16
正文 16 / 行高 1.6
KPI 行:最多 3 张,每张 value 24 + label 12
外链行:左标签 12 / 右可点 URL 14 primary(看起来像行按钮,不是裸字符串)
spacer
底栏:「咨询」→ 现有 openCaseExchange
```
**主 CTA**:咨询。空态主 CTA = 返回。
**空 / 错 / 骨架**:保持。空态卡片加 `max-width` 不拉满刺眼。
**具体视觉改动**
- `CASE_DETAIL_COPY` 从模板剥离:模板改调 `resolveCaseDetailText`(可在 hook 把现有对象包一层函数)。禁止模板直接绑中文字面量。
- 外链行加 `min-height: 44`,整行可点打开/复制(若 hook 无 open,则只复制,不新写请求)。
- KPI `margin-inline-end` 改为 `gap: 8`,最后一张不要多余右边距。
- 无暗色/无 RTL class:补 `padding-inline` 与页面 rtl class。
**不要改的文件**:`loadCaseDetail` 解析逻辑。
---
### 2.4 `pages/portal/article-detail` · 文章
**用户目标**:不被打断地读完,再决定分享。
**必须保留**:`loadArticleDetail`、rich-text、复制分享、空态返回。
**信息架构**
```
封面 200 圆角 16(可无)
kicker 12/600 primary
标题 24
正文 16 / 行高 1.7,容器 max-width 720
spacer
底栏主 CTA:复制分享链接
```
**主 CTA**:复制链接(现有 `copyArticleShareLink`)。不要再加第二个分享按钮。
**空 / 错 / 骨架**:空态改与案例一致的白卡片+一句话+返回,不要只有灰字贴边。
**具体视觉改动**
- 空态加白底边框卡、居中。
- CTA 字 15→16。
- 保持杂志留白,不要把文章塞进卡片框。
**不要改的文件**:`useArticleDetail.uts`。
---
### 2.5 `pages/portal/ai-chat` · AI 顾问
**用户目标**:问一句、得到答复;有意向时留下姓名+联系方式。
**必须保留**:`sendStreamChat`、`submitLeadCard`、`list-view` 消息、留资卡状态机、缺 cardId 提示。
**信息架构**
```
┌ 圆角 20 顶 sheet ───────────────────┐
│ 把手 40×4(ai 色 20% 透明) │
│ 标题 24 │
│ list-view:空态一句 / 气泡 / 留资卡 │
│ 底作曲:标签 12 + [输入 44 | 发送 48]│
└─────────────────────────────────────┘
```
**主 CTA**:发送。留资卡内提交是卡片内次按钮(描边),不算第二屏主 CTA。
**空 / 错 / 骨架**:空态保持一句。发送中按钮禁用文案走 `sending`。无骨架(对话页)。
**具体视觉改动**
- 作曲区改为横向:`input flex:1` + 发送宽不固定、高 48,避免键盘顶起三行。若 uni-app x 横向不稳,保持纵向但去掉重复「输入标签」,只留 placeholder。
- 成功态绿底 `#ECFDF3` 改为 `surface` + 左边框 `success`,避免大块绿。
- `.ai-lead-error`、硬编码 `#12B76A`/`#F04438` 改 token 变量。
- 微光 animation 保留,`prefers-reduced-motion` 已有,保持。
- 用户气泡白字对比度足够,保留。
**不要改的文件**:`useAiChat.uts` 流式与留资提交。
---
### 2.6 `pages/common/login` · 登录
**用户目标**:用已有账号进入名片主。
**必须保留**:`submitPasswordLogin`、`fillTestAccount`、条款 toast、登录后 pending 收藏。
**信息架构**
```
居中列 max-width 340
Logo 36
标题 24(现 22 改 24)
说明 14
输入 用户名 44
输入 密码 44
弱文字链 12:测试账号(不要做成按钮)
错误 12 error 色
主 CTA 48:登录 / 登录中
底部条款 12 text2 + 链接
```
**主 CTA**:登录。不要同时放验证码/Google 实心按钮。PRD 的手机/邮箱/社交本轮只允许在标题下加 12 号「更多方式即将开放」一句,不接新 API。
**空 / 错 / 骨架**:错误在按钮上方。无骨架。
**具体视觉改动**
- 模板中文全部改 `resolveLoginText`(hook 已有 key:`title`/`desc`/`usernamePlaceholder`/`passwordPlaceholder`/`testAccountTip`/`login`/`terms*`)。
- 引入 `pageTheme` + `var(--oc-*)`。圆角 10→12。按钮高 44→48。
- 测试账号从高饱和蓝链改为 `text2`,点击仍 `fillTestAccount`。
- 页面背景 `bg`。补 RTL class。
- `aria-label` 走 i18n,禁止写死「登录」。
**不要改的文件**:`submitPasswordLogin`、token 写入、`consumePendingCollectCard`。
---
### 2.7 `pages/owner/hall/index` · 大厅(人脉 / 团队 / 现场)
**用户目标**:找到已收的人,或用码加入。
**必须保留**:三 tab、`refreshHall`、兑换码、现场码、`openHallPortal`、list-view。
**信息架构**
```
白顶栏:
标题 24
副标题 14(只 1 行,过长截断)
chips ×3 单行
搜索 44
条件第二输入 44(人脉=兑换码 / 现场=现场码)
list-view 行卡:
左 40 圆占位(无头像字段则纯色块,不请求新字段)
右:姓名 16 / 头衔 14 / 公司 14
空/错卡片
底栏主 CTA:按现有 ctaLabel(刷新 / 兑换 / 加入现场)
```
**主 CTA**:沿用现有三态文案,不要拆成两个底按钮。
**空 / 错 / 骨架**:空态必须能被底栏 CTA 服务(刷新/加入)。空态卡片不要再放第二个按钮。
**具体视觉改动**
- 顶栏 `padding-block-end` 保持 12,tab 与搜索间距 8,去掉多余 12+12 堆叠。
- 行卡加 8px 间隔,左占位 40×40 圆角 20,`surface` 底。不改数据类型。
- 错误态补「可点热区」靠底栏重试,不要在卡片里再做按钮。
**不要改的文件**:`useHall.uts`。
---
### 2.8 `pages/owner/card/index` · 我的名片
**用户目标**:看自己有哪些名片,去预览、编辑或分享。
**必须保留**:搜索、`refreshCards`、预览、编辑、`pickShareCard`+`openCardQrcode`、配额 subtitle。
**信息架构**
```
白顶栏:标题 24 / 配额句 14 / 搜索 44
list-view 行:
左:姓名 16 / 职位 14 / 公司 14
右:状态 12 primary
今日浏览 12 text2(无字段则显示 "—",不造假数、不改 API)
「编辑」文字热区 44
底栏主 CTA:有可分享名片 → 分享海报;否则刷新
```
**主 CTA**:保持现有 `handleRefresh` 分支(有卡则海报,无则刷新)。文案在有卡时应显示「分享海报」而不是「刷新」。实现:模板按 `pickShareCard(state.list) != null` 切换已有 `resolveCardHomeText`,不改函数。
**空 / 错 / 骨架**:空态一句话说明「还没有名片」,主 CTA 仍刷新。不要做「新建」除非已有 API。
**具体视觉改动**
- 行高 min 88 保持。状态不要和编辑抢成两个蓝按钮,编辑保持文字。
- PRD 的横向 swiper 本轮不做(会动结构),用列表+清晰状态代替。
- 补 `prefers-reduced-motion` 去掉行 `scale`。
**不要改的文件**:`useCardHome.uts`、`fetchCardQuota`。
---
### 2.9 `pages/owner/radar` · 实时雷达(二级)
**用户目标**:看到谁在看名片、看了多久。
**必须保留**:`refreshTracks`、`cardIdRaw` 绑定、list-view、停留/深度格式化。
**信息架构**
```
标题 24 + 说明 14
(cardId 输入默认隐藏;仅当 cardId 为空时显示,避免销售看到「填 ID」)
list-view:
地点 16/600
触达方式 12 标签
停留 + 深度 14
停留 ≥180s 或深度 ≥0.6:左边框 3px error(高意向,不改数据)
空态一句
底栏:刷新
```
**主 CTA**:刷新。
**空 / 错 / 骨架**:错与空拆开:`errorMessage` 用错误卡;`empty` 用空态句。补与大厅同款骨架(现无)。
**具体视觉改动**
- 列表底垫高加上 `window-bottom`(若从 tab 进)。
- `touchType` 原始值可显示,但用 12 号 `text2`,不要当标题。
- 无时间字段则不加。不请求新 API。
**不要改的文件**:`useRadar.uts` 请求。
---
### 2.10 `pages/owner/leads` · 客户
**用户目标**:按意向找到人,点进去跟进;必要时看雷达。
**必须保留**:状态 chips、搜索、`refreshLeads`、`hotUnread`、`radarTracks` 三行、跳转详情/雷达/战报、list-view。
**信息架构(压缩顶栏)**
```
标题 24 [红点 44:高意向 N] ← 点击仍 openRadar
雷达摘要卡(最多 2 行 + 「全部雷达」文字)
搜索 44
chips 单行横滑:全部/新/高意向/已联系/赢单/归档
list-view:姓名 16 / 公司 14 │ 分 12 + 状态 12
底栏:搜索/刷新(现有 cta)
```
**主 CTA**:底栏搜索刷新。红点、雷达、战报都是文字/描边。战报入口从顶栏挪走:放到雷达卡最后一行右侧,或本轮藏进雷达页/我的(数据函数保留,入口可移到「我的」已有战报行)。**本页只保留一个「战报」文字链,放雷达卡内,不再单独占一行大入口。**
**空 / 错 / 骨架**:保持。空态不要第二个按钮。
**具体视觉改动**
- `.radar-hot-badge`:底改极浅红(`error` 8% 不够就用白底+`error` 字+`error` 边),禁止 `primarySoft`。有未读才渲染。
- chips:去掉 `flex-wrap` 与 `margin-block-end`,只横滑。
- 行卡右侧状态:`hot` 用 `error` 字,其它用 `primary`。
- 不做电话/WhatsApp 图标(列表无号码字段则不编造)。进详情再联系。
- 顶栏总高目标:红点与标题同一行后,首屏至少露出 2 条客户。
**不要改的文件**:`useLeads.uts`、`openRadarPage`。
---
### 2.11 `pages/owner/profile/index` · 我的
**用户目标**:确认身份、改语言/推送、进 NFC 与战报、退出。
**必须保留**:头像选/删/预览、三项指标跳转、配额条、NFC 三入口、战报、两个 switch、语言 7 项、退出确认。
**信息架构**
```
Hero 卡:头像 56 + 名 16 + 套餐 pill + 公司/部门 14
分隔线 + 「预览微官网」文字链(热区 44,不再用 32 高按钮)
指标 3 格:数字 24 / 标签 12
配额卡:标题 + 用量 + 轨道 4 高 + 升级文字链
工作区列表(分隔线,不要每行一张卡)
通知 switch 行(热区 44)
语言 chips 描边选中(不要实心蓝底白字)
退出:text2 文字,居中
错误条
spacer(含 window-bottom)
```
**主 CTA**:本页无底栏主 CTA(设置页)。「预览微官网」是唯一强调文字链。退出不是主 CTA。
**空 / 错 / 骨架**:错误条移到 Hero 下,不要沉底。无骨架(本地设置)。
**具体视觉改动**
- 全部硬编码色改 token。加 `pageTheme`。
- 进度条:禁止内联 `:style width`。改用 10 档 class(`w-10`…`w-100`)或 `transform: scaleX(n)` 写在 class;`calculateQuotaPercent` 可映射到 class 名,不改计算函数。
- 删除徽标视觉 18,外层点击层 44×44。
- `.preview-btn` 高 32→44,或改纯文字链。
- 语言选中:`primarySoft` + `primary` 边 + `primary` 字,取消白字填蓝。
- 指标数字若仍是占位(12/5),保持,不编新接口。
- 补 RTL logical。
**不要改的文件**:`useProfile.uts` 的开关/语言/退出/配额请求。
---
### 2.12 `pages/owner/card/edit` · 极速编辑
**用户目标**:改姓名/职位/电话/社交并保存。
**必须保留**:头像选/预览/删、各 input、`submitCardEdit`、缺 id 空态。
**信息架构**
```
白表单卡:
标题 24
头像 80 + 上传/更换 44 文字按钮
字段:姓名 / 职位 / 公司 / 电话 / 邮箱 / WhatsApp / LinkedIn
(slogan、模块排序、AI 润色:本轮只在标题下加 12 号说明「更多编辑请用后台搭建器」,不接 API)
错误 12 error
底栏:保存
```
**主 CTA**:保存。
**空 / 错 / 骨架**:保持。
**具体视觉改动**
- 删除热区扩到 44。头像边框 2px primary 改为 1px `border`(降低装饰)。
- 错误色 `text2` → `error`。
- CTA 字 16。字段间距 16。
- 不要在本页做拖拽排序。
**不要改的文件**:`useCardEdit.uts`。
---
### 2.13 `pages/owner/card/qrcode` · 分享海报
**用户目标**:把码或链接给到对面。
**必须保留**:`loadPosterIntoState`、`copyPosterUrl`、空/错/骨架。
**信息架构**
```
白卡居中:
标题 24
200×200 码位(有 svg 就渲染;无 svg 用 surface 底 + 12 号「码生成中/不可用」)
短链 14,可断行
就绪句 12 text2
底栏:复制链接(现有 copyCta)
```
**主 CTA**:复制链接。不新增「存相册」除非 `useCardQrcode` 已有该方法。
**空 / 错 / 骨架**:保持三态。空态不要假装有码。
**具体视觉改动**
- 有 `state.svg` 时用 `rich-text` 或 `image` 展示(哪种能跑用哪种,禁止引入新库)。
- 码位边框 1px、圆角 16、居中。
- 不要做易拉宝背景、不要大渐变海报。
**不要改的文件**:`useCardQrcode.uts`。
---
### 2.14 `pages/owner/leads-detail` · 跟进备忘
**用户目标**:看清这人是谁、来过几次,写下一条跟进。
**必须保留**:画像、轨迹、`nextNote`、图片上传、`submitLeadNote`。
**信息架构**
```
画像卡:姓名 24 / 公司 14 / 分+状态
(电话/邮箱:有字段才显示 14 文字,无则省略)
轨迹:标题 16 + list-view(禁止 view v-for)
AI 话术卡(无接口则静态一句 resolve 文案 + 灰字「即将提供」,不要假数据)
备忘:已有笔记 14 + textarea min 88 + 上传
底栏:保存备忘
```
**主 CTA**:保存备忘。不要在底栏放 WhatsApp 实心按钮。
**空 / 错 / 骨架**:保持。
**具体视觉改动**
- `.lead-body` 底垫高改 `calc(88px + safe-area)`,现在写死 88 会贴 Home 条。
- 轨迹改 `list-view`/`list-item`。短列表也统一,避免超过一屏时卡顿。
- 状态 `hot` 用 error 字。
- 上传区上方加 12 号说明(i18n)。
**不要改的文件**:`useLeadDetail.uts`、`image-uploader`。
---
### 2.15 `pages/owner/nfc/scan` · 贴卡激活
**用户目标**:把实体卡贴上并完成绑定。
**必须保留**:`startScan`(APP)、`submitScan`、uid/cardId 输入、状态行。
**信息架构**
```
中央脉冲环 120(border 2px primary,opacity 脉冲 400ms 一次)
标题 24 + 说明 14
状态句 14
H5 或失败时才显示 uid / cardId 两个字段
底栏:激活
```
**主 CTA**:激活/写入。
**空 / 错 / 骨架**:状态行即反馈。不要循环动画。`prefers-reduced-motion` 时只显示静止环。
**具体视觉改动**
- App:突出环,表单折叠。H5:`manualInput` 时显示表单(已有条件编译,只改样式权重)。
- 禁止全息/多层光晕。一次脉冲:`opacity 0.4→1→0.4` 400ms,`animation-iteration-count: 1`。
- 不改 `startScan`。
**不要改的文件**:`useScan.uts`。
---
### 2.16 `pages/owner/nfc/mode` · 场景切换
**用户目标**:把这张卡切到展会或社交。
**必须保留**:uid/cardId、状态/场景展示、`selectSceneMode`、`submitApplyScene`。
**信息架构**
```
标题 24 + 说明 14
两个字段
只读状态行
模式两选项(描边,选中 primarySoft)
12 号说明:离线 vCard 由系统在弱网时写入(不接新按钮)
底栏:应用
```
**主 CTA**:应用场景。
**空 / 错 / 骨架**:无独立空态。提交中禁用。
**具体视觉改动**
- 选项不要做成两个主按钮。
- 补 RTL。CTA 字 16。
**不要改的文件**:`useMode.uts`。
---
### 2.17 `pages/owner/nfc/security` · 安全与挂失
**用户目标**:选中一张卡,挂失或解冻。
**必须保留**:选中、`freezeDevice`/`unfreezeDevice`、UID 校验展示、警告卡。
**信息架构**
```
标题 24 + 说明 14
设备卡列表(当前 1 张,view 可接受;≥8 必须改 list-view)
批次 12 / UID 16 等宽 / 状态 pill
防伪点 + 文案 12
警告卡(surface,不要黄底大块)
底栏:挂失 | 解冻(随选中状态,仍是 1 个主按钮)
```
**主 CTA**:挂失用 `error #F04438`(token),解冻用 `primary`。禁止 `#D92D20`。
**空 / 错 / 骨架**:空卡保持。`处理中...`、`操作异常` 改 `resolveSecurityText`。
**具体视觉改动**
- 页面背景改 `surface`,选中卡白底 + primary 边。
- pill 圆角 12,不要 9999 胶囊霓虹感。
- `#FFFFFF` / `#F8F9FB` / `#ECFDF3` 改 token 或 surface。
- 底栏加 `window-bottom`(从「我的」进无 tab,可只 safe-area)。
**不要改的文件**:`useSecurity.uts` 校验与冻结。初始 mock 设备数组可留。
---
### 2.18 `pages/owner/team/overview` · 展会战报
**用户目标**:看团队谁在获客、自己差多少。
**必须保留**:`refreshOverview`、四指标、排行 list-view、最近线索 list-view。
**信息架构**
```
标题 24 + 说明 14
2×2 KPI,gap 12(不要 48%+4% hack)
排行:名 16 / 「线索·触达·分」14 / 名次 12
最近线索:名 / 公司 / 状态(状态走已有 label,不要裸 new/hot)
底栏:刷新(或文案改为「更新战报」)
```
**主 CTA**:刷新。不要加「转存案例」按钮(无 API)。
**空 / 错 / 骨架**:错误条在 KPI 上。线索空用一句话。
**具体视觉改动**
- 删掉 `leads.length > 5` 与 `else` 两套重复 list,只留一个 `list-view`。
- `formatRankMeta` 显示可在模板改分隔为 ` · `,不改函数也可在模板拼三个 text。
- 状态 `hot` 用 error 字。
- 不要柱状图(无图表库)。第四格国家名过长则 14 号截断。
**不要改的文件**:`useOverview.uts`。
---
## 3. 实施波次
每轮只动该轮 `.uvue`(及该轮缺的 `resolveXxxText` 文案)。测完再进入下一轮。改完一页必须:亮色下主 CTA 仅 1 个、无模板中文、触控 ≥44、底栏不挡列表。
### 第 1 轮 · 访客 portal 4 页(P0 首屏)
范围:`portal/index`、`exchange`、`case-detail`、`article-detail`。
优先缺口:
1. `exchange` 全文硬编码中文。
2. `index` 顶栏交换/收藏与底栏保存抢主操作;社交空格占位。
3. `case-detail` 文案写死;PDF/视频不像可点。
4. 四页字号 11/13/15 与硬编码 hex 未归 token。
验收:扫码进 portal,保存通讯录是唯一实心蓝按钮;切阿语顶栏/CTA 不破;互换表单无中文死字。
### 第 2 轮 · login + hall + card/index + radar
优先缺口:
1. `login` 中文写死、无 token、圆角/字号偏离。
2. `card/index` 底栏文案与海报意图不符;无状态层次。
3. `hall` 顶栏过高,空态与 CTA 脱节。
4. `radar` 暴露 cardId,空/错不分,无高意向提示。
验收:登录页只一个登录按钮;大厅三段 chip 单行;名片底栏在有卡时是分享;雷达像通知流不是后台表单。
### 第 3 轮 · leads + leads-detail + profile + card/edit
优先缺口:
1. `leads` 顶栏过载,首屏看不到列表;高意向红点是蓝色。
2. `leads-detail` 轨迹 `view v-for`;底垫高无 safe-area。
3. `profile` 硬编码色、内联进度宽、32/18 热区。
4. `edit` 装饰边过重、错误色弱。
验收:客户页首屏可见 ≥2 条;红点可识别为警示;我的页语言 chip 非填蓝;编辑保存不被 Home 条挡住。
### 第 4 轮 · qrcode + nfc/scan + nfc/mode + ai-chat
优先缺口:
1. `qrcode` 没有码的视觉中心。
2. `scan` 没有「贴卡」焦点,只有表单。
3. `ai-chat` 作曲区太高。
4. `mode` 缺一句离线说明。
验收:海报页能看出「这是一张码」;扫卡页先看到环再看到表单;AI 发送仍是唯一实心按钮。
### 第 5 轮 · nfc/security + team/overview + 收尾
优先缺口:
1. `security` 危险色不在 token、文案写死、背景偏白。
2. `overview` 双 list 重复、KPI 间距 hack。
3. 本轮统一:能接的页面补 `prefers-color-scheme` 把 `pageTheme` 切到 `utsDarkColors`;检查 tab 页 `window-bottom`。
4. 记录但不改:`pages.json` tabBar 仍是官网/雷达/潜客。若另开业务任务,再改为 大厅/名片/客户/我的,且 portal 保持无 tab(访客扫码)。
验收:挂失按钮是 error token;战报 2×2 齐;暗色下无纯黑、无丢失对比(正文对比 ≥ 4.5:1)。
---
## 附:实现时的统一 CSS 片段(直接复用)
```css
/* 主 CTA 栏 */
.oc-cta-bar {
position: fixed;
left: 0;
right: 0;
bottom: var(--window-bottom, 0px);
padding: 12px 16px calc(16px + env(safe-area-inset-bottom, 0px));
background-color: var(--oc-bg, #FFFFFF);
border-top: 1px solid var(--oc-border, #E3E7ED);
z-index: 100;
box-sizing: border-box;
}
.oc-cta-btn {
height: 48px;
min-height: 44px;
width: 100%;
border-width: 0;
border-radius: var(--oc-radius-btn, 12px);
background-color: var(--oc-primary, #0B5CFF);
display: flex;
align-items: center;
justify-content: center;
}
.oc-cta-btn-text {
color: #FFFFFF;
font-size: 16px;
font-weight: 600;
}
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
```
列表底垫高统一:
```css
padding-block-end: calc(88px + var(--window-bottom, 0px) + env(safe-area-inset-bottom, 0px));
```
`pageTheme` 最少注入:`--oc-primary` `--oc-primary-soft` `--oc-ai` `--oc-bg` `--oc-surface` `--oc-border` `--oc-text` `--oc-text-2` `--oc-success` `--oc-warning` `--oc-error` `--oc-radius-btn` `--oc-radius-card` `--oc-radius-modal`。