Files
jiapuapp/docs/superpowers/specs/2026-07-21-project-mobile-viewport-adaptation-design.md
T
2026-07-21 10:30:38 +08:00

136 lines
7.9 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.
# 全项目手机自适应重构设计
## 决策
采用分阶段治理:先重构 A01 并在 MuMu 验收,再迁移 A04、A05 和封存 A06,最后按页面类型治理其余活动路由。不得继续在旧的整屏叠层结构上追加 `vh``rpx``clamp()` 或机型专用补丁。
## 根因
当前问题不是 uni-app 的适配能力不足,而是页面把固定比例设计稿当成运行时坐标系:
- A 系列使用 `824×1830` 整页合成背景并以 `scaleToFill` 拉伸到任意屏幕比例。
- 背景、印章和交互内容叠放在同一个 `grid-area: 1 / 1`,表单位置依赖背景中的视觉地标。
- 旧 A01 使用 `1665rpx` 组织纵向画布;`rpx` 随屏宽换算,不能表达手机可用高度。在 MuMu 的约 `360×640dp` 视口中,该画布约为 `799dp`,必然超高。
- 固定视口高度、整页叠层和独立的内容定位形成多套坐标;调整其中一套只能修复一个屏幕比例。
对照项目 `3dyjsapp` 使用 `min-height: 100vh`、普通 Flex 文档流和装饰背景。内容尺寸由自身决定,空间不足时自然增长,因此不会依赖背景坐标或互相覆盖。
## 架构原则
### 背景与布局解耦
- 背景只负责装饰,不得决定标题、输入框、按钮或列表的位置。
- 禁止普通页面使用整页合成图的 `scaleToFill` 作为布局基准。
- 屋檐、横幅等有明确比例的头图必须放入独立槽位,使用 `widthFix` 或显式 `aspect-ratio`,高度由宽度推导,不做纵向拉伸。
- 宣纸、云纹、树影等可重复或可裁切纹理作为内容区背景,允许 `cover` 或分层装饰,但不得承载交互坐标。
- 装饰层可以重叠;交互内容必须处于正常文档流,除弹窗、浮层和真实画布节点外不得整页绝对定位或整页网格叠放。
### 单一视口所有者
`styles/global.scss` 只拥有以下全局原语:动态视口高度、安全区、共享 Header/Tabbar 占位、最小触控尺寸和少量连续间距变量。页面消费这些原语,但不得按品牌或具体型号复制视口规则。
全局视口变量只解决浏览器或 WebView 的可用高度差异,不能用于重新创建一套设计稿坐标系。
### 页面类型
每个活动路由必须且只能归入一种布局类型:
1. `document-flow`:列表、详情、文章和长表单。根容器使用最小视口高度,内容自然撑高,页面是唯一纵向滚动所有者。
2. `compact-flow`:登录、短确认和固定步骤页。默认字号、无键盘时应在目标基线视口完整显示;内容仍使用正常文档流,极端小屏、大字号、错误文案或键盘状态允许自然滚动。
3. `split-viewport`:固定 Header/筛选区加独立内容滚动区。页面自身不与内容区形成双重纵向滚动。
4. `interactive-canvas`:家谱关系图等真实画布。画布占据计算后的可用视口,内部负责缩放和平移;页面表单、说明和操作栏仍遵守正常流与安全区。
分类只定义高度和滚动所有权,不承载业务字段、状态或视觉内容。
## A 系列结构
新增共享认证页骨架,供 A01、A04、A05 和封存 A06 使用。骨架只拥有:
- 顶部安全区;
- 固定比例的品牌头图槽;
- 独立的宣纸内容区背景;
- 正常文档流内容槽;
- 底部安全区和溢出回退。
各认证页面继续拥有自己的标题、字段、状态、操作和业务逻辑。共享骨架不得成为业务配置中心,也不得用页面编号切换业务 DOM。
A01 默认态的纵向压缩顺序为:装饰留白、装饰尺寸、非关键间距、辅助说明;标题、正文、输入框、按钮和协议触控区域不得低于可读和可触控下限。禁止整页 `transform: scale()`
## 安全区、键盘与字体
- 同一安全区只能由一个层级计入;共享 Header、Tabbar 或认证页骨架拥有后,业务页面不得重复叠加。
- 默认系统字号执行各页面类型的首屏或滚动合同。
- 约 1.3 倍系统字号下允许 `compact-flow` 回退为自然滚动,但不得裁字、遮挡或丢失操作。
- 键盘弹出时必须能滚动到焦点字段、就近错误信息和当前主操作;键盘收起后页面恢复合理位置。
- 弹窗、底部弹层和全屏预览各自拥有最大高度、安全区和内部滚动,不计入页面默认内容高度。
## 分阶段迁移
### 阶段一:A01 结构证明
- 删除 A01 的整页合成背景布局职责和全屏叠层坐标。
- 将品牌头图、宣纸内容区和登录内容拆为独立结构。
- 保持登录方式、校验、协议和跳转逻辑不变。
- 只有 A01 在 MuMu 默认密码态和验证码态均通过后,才能提取共享认证页骨架。
### 阶段二:认证页迁移
- 从已验证的 A01 结构中提取最小共享骨架。
- 迁移 A04、A05 和封存 A06,不恢复 A06 路由。
- 验证长表单、错误、提交中、成功、键盘和返回保护状态。
### 阶段三:项目页面分类治理
- 建立活动路由到四类页面的唯一清单。
- 优先处理现有整屏 `grid-area: 1 / 1``scaleToFill`、固定大块高度和 `overflow: hidden` 风险页。
- 再迁移普通列表、详情、文章、表单和共享 Header/Tabbar/Dialog。
- 真正的家谱画布保留独立视口策略,不套用普通文档页规则。
每一批迁移必须独立验收,不允许一次性机械替换全部页面后再集中修复。
## 静态合同
新增或修订项目级合同,至少检查:
- `pages.json` 的全部活动路由均有且只有一个布局分类,封存页面单独声明。
- 普通交互页禁止整页 `scaleToFill` 合成背景、整页交互叠层和固定设计稿画布高度。
- `document-flow` 只有一个纵向滚动所有者,末项可达。
- `compact-flow` 保留自然溢出回退,禁止通过裁切或整页缩放满足首屏。
- `split-viewport` 明确固定区和唯一内容滚动区。
- 固定高度白名单必须精确到文件、选择器、风险类型和理由,失效条目使合同失败。
## 运行时与设备验收
自动化视口检查覆盖至少:`320×568``360×640``375×812``390×844``412×915``480×1040` CSS px。
共同要求:
- 无水平溢出、关键控件越界、正文裁切和双重纵向滚动。
- 固定 Header/Tabbar 与安全区不遮挡首项、末项或主操作。
- 头图保持比例,背景裁切不改变内容坐标。
- 大字号、错误文案和键盘状态下所有字段及操作可达。
Android 视觉结论必须来自模拟器或真机,H5 只能作为自动化辅助,不能替代 Android 验收。第一基线为当前 MuMu `720×1280 / 320dpi`(约 `360×640dp`)。
A01 阶段一完成条件:
- 默认密码态和验证码态无需纵向滑动即可看到完整协议区。
- 页面没有屋檐与标题重叠,宣纸分界与内容之间保留稳定留白。
- 头图无纵向拉伸,输入、按钮和协议区域满足最小触控尺寸。
- 未勾选协议、输入错误、键盘弹出和键盘收起状态均无裁切,操作可达。
- 用户查看 MuMu 原生画面并确认视觉方向后,才迁移其他认证页。
## 非目标
- 不改变业务接口、路由、字段、状态机和文案语义。
- 不借自适应重构重新设计整个视觉主题。
- 不为单个品牌或型号建立专用断点。
- 不承诺在任意内容量、任意字号和键盘同时打开时完全无滚动;承诺默认基线首屏完整,异常条件下无裁切且可自然到达。
## 完成条件
- A01、认证页和其余活动路由按阶段完成真实设备验收。
- 所有活动路由拥有唯一布局分类,并通过对应静态和运行时合同。
- 旧固定设计稿画布、整页合成背景坐标、重复视口规则和失效白名单从运行时、测试、设计记录与交接记录中同步移除。
- Android 结论只覆盖实际验证的设备、分辨率和状态,不把单一模拟器结果扩写为所有真机已通过。