竖版 UI 重构 — 实施蓝图 v1
日期:2026-06-24 依据:mobile-portrait-rulebook.md + mobile-portrait-ui-iteration-spec.md 方向:纯 DOM 重构(方向 A) — 废弃 8 张 slice 图,竖版整体用 Tailwind 重做。
1. 问题根因(与本次排查一致)
竖版 UI 用了 8 张「切片图」(01_top_bar.png / 02_status_cards.png / 03_main_scene.png / 04_bottom_panel.png / 06_bottom_nav.png 等)当背景,但这些切片图本身就是完整的 UI 设计稿——自带了所有可交互元素(图标+文字+按钮+数据)。代码里又用 DOM 在同一位置重新渲染了一遍。两套 UI 在同一个位置完全重叠。
更糟的是,InnCourt 在 mobileLayout="full" 模式下也已经渲染了清洁/安全 + 同福大堂 + 桌位 grid + 底部 4 按钮。所以是三层堆叠:
- slice 图(死的)
- PortraitWorkspacePanel 顶部 status(DOM)
- InnCourt 内部 mobile 卡片(DOM)
2. 竖版 viewport 信息架构(要展示的所有元素)
A. 顶部 status bar
| ID | 元素 | 数据 | 字号/约束 |
|---|---|---|---|
| A1 | 同福客栈 logo + 版本号 | TONGFU_ICON_ASSETS.facilityHammer / APP_VERSION | 主标题 ≥16px(rulebook §文本规则) |
| A2 | 系统门厅按钮 | onOpenSystemHubHome | 触达 ≥44px |
| A3 | 路线图按钮 | onOpenRoadmap | 触达 ≥44px |
| A4 | 静音按钮 | onToggleMute | 触达 ≥44px |
| A5 | 时间 chip(gameTime + 时辰 + 营业状态) | gameTimeLabel / timeOfDayLabel / businessPhase | 正文 ≥13px |
| A6 | 联机/房间 ID chip | peerId | 正文 ≥13px |
| A7 | 铜钱 | coins | 主标题 ≥16px(红色强强调) |
| A8 | 声望 | reputation | 主标题 ≥16px |
| A9 | 清洁进度条 | cleanliness | 数字 + 颜色梯度条 |
| A10 | 安防进度条 | safety | 数字 + 颜色梯度条 |
| A11 | 状态 chips | portraitStatusChips(飞贼/杂物/候菜+用膳/空桌) | 11px chip |
B. 中部 main scene(InnCourt)
| ID | 元素 | 数据 | |---|---|---| | B1 | 「同福大堂」标题 + 副标题 | unlockedAreaCount/12 + 入座/桌位 | | B2 | 状态 chip 行(杂物/飞贼/空白招呼) | garbageList / thiefList | | B3 | 桌位 grid(4×2,8 桌必完整可见) | tables / customers | | B4 | staff mini avatars / 飞贼/垃圾浮标(横版布局,竖版不需要) | activeStaffIds |
删除项(避免重复):
- ❌ InnCourt 内部的清洁/安全卡片(与 A9/A10 重复)
- ❌ InnCourt 底部 4 个 mobile 按钮(叫客入座/对账/清理/点穴)—— 用 portraitAction FAB 代替
C. 中下部 info panel
| ID | 元素 | 数据 | |---|---|---| | C1 | 「江湖消息」标题 + 4 个 filter(全部/警报/系统/经营) | portraitLogFilter | | C2 | 日志列表(默认 3-4 行,可展开全文) | portraitLogEntries |
D. 底部 nav
| ID | 元素 | 数据 | |---|---|---| | D1 | 5 个 nav 按钮(账本/门客/菜谱/设施/更多) | portraitNavItems | | D2 | 圆形浮窗 FAB(动态切换:确认开张/点穴/洒扫/叫客入座/催菜翻台/对账) | portraitAction |
3. 数据源映射表(已有 / 需新增)
| 元素 | 数据 | 现状 | |---|---|---| | A1-A4 | TONGFU_ICON_ASSETS / APP_VERSION / handlers | ✅ 已有 | | A5 | gameTimeLabel / timeOfDayLabel / businessPhase | ✅ App.tsx state | | A6 | peerId | ✅ App.tsx state | | A7 | coins | ✅ App.tsx state | | A8 | reputation | ✅ App.tsx state | | A9 | cleanliness | ✅ App.tsx state | | A10 | safety | ✅ App.tsx state | | A11 | portraitStatusChips | ✅ App.tsx useMemo (line 2347) | | B1-B3 | tables / customers / areaExpansions / staff | ✅ | | B4 | activeStaffIds / garbageList / thiefList | ✅ | | C1 | portraitLogFilter | ✅ App.tsx state | | C2 | portraitLogEntries | ✅ App.tsx useMemo (line 2402) | | D1 | portraitNavItems | ✅ App.tsx useMemo (line 2492) | | D2 | portraitAction | ✅ App.tsx useMemo (line 2427) |
无新增数据源需求。
4. 组件拆分方案
4.1 新增目录结构
src/components/portrait/
├── PortraitTopBar.tsx # A1-A4:logo + 系统门厅 + 路线图 + 静音
├── PortraitStatusStrip.tsx # A5-A8:时间 + 联机 + 铜钱 + 声望
├── PortraitCleanSafetyBars.tsx # A9-A10:清洁 + 安防进度条
├── PortraitStatusChips.tsx # A11:状态 chips
├── PortraitLogPanel.tsx # C1-C2:江湖消息 + filter + 日志列表
├── PortraitNavBar.tsx # D1:5 个 nav
└── PortraitActionFAB.tsx # D2:圆形浮窗按钮
4.2 改造现有组件
InnCourt.tsx:
mobileLayout="full"模式下:- 删除 line 197-247 的清洁/安全卡片(移到 PortraitCleanSafetyBars)
- 删除 line 627-674 的底部 4 个 mobile 按钮(用 PortraitActionFAB 代替)
mobileLayout="scene-only"模式:保持不变- 横版大地图:保持不变
PortraitWorkspacePanel.tsx:
- 完全重写:移除所有 slice 图背景,组合新组件 + InnCourt mobileLayout="full"
- 严格按 mobile-portrait-rulebook 字号阶梯(不出现 7-8px 字号)
4.3 删除资源
public/assets/ui/slices/ 下 9 张图:
01_top_bar.png01_top_header.png02_status_bars.png02_status_cards.png03_main_scene.png04_action_tabs.png04_bottom_panel.png05_progress_action.png06_bottom_nav.png
→ 全部移到 public/assets/ui/slices/_archive/(不删,留作回滚备份)
5. 实施顺序(与 todolist 对应)
| 阶段 | 工作量 | 关键产出 | |---|---|---| | 阶段 1 | 0.5 天 | 本文档 + slice 图退役 | | 阶段 2 | 0.5 天 | 顶部 status bar(4 个新组件 + PortraitWorkspacePanel 重构) | | 阶段 3 | 1 天 | 中部 InnCourt mobileLayout=full 简化 + 同福大堂卡片优化 | | 阶段 4 | 0.5 天 | 底部 info panel(日志列表视觉降噪) | | 阶段 5 | 0.5 天 | 底部 nav(5 个 nav + FAB) | | 阶段 6 | 0.5 天 | 真机验证 + 视觉降噪 + 极端情况 |
总计:3-3.5 天。
6. 关键约束(来自 rulebook)
- ❌ 首页不允许页面级滚动(rulebook §核心硬规则)
- ✅ 8 桌必须在首屏完整可见
- ✅ 日志默认 3-4 行
- ✅ 底部主操作必须始终可见
- ✅ 任何固定入口都必须先吃掉
env(safe-area-inset-*) - ✅ 主标题 ≥16px、正文 ≥13px、次级说明 ≥12px、11px 仅徽章角标
- ✅ 任何按钮和卡片的最小触达高度为 44px
- ✅ 装饰层必须
pointer-events: none
7. 不在本轮范围
- 横版(Desktop)UI 不动
- 竞标、行囊、闯荡等二级模块 UI 不动
- 主题色 / 设计 token 改造(可后续单独做)
- 真正的拟物化纹理(可后续单独做)