修改完成

This commit is contained in:
2026-07-21 07:53:03 +08:00
parent 01d246c47b
commit ff60119277
172 changed files with 7982 additions and 2999 deletions
@@ -0,0 +1,66 @@
# 全活动页面业务所有权收敛实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans task-by-task. Steps use checkbox syntax for tracking.
**Goal:** 移除活动页面对通用业务母版的依赖,使 52 个路由拥有正确、数据驱动且可本地审计的页面内容。
**Architecture:** 保留稳定视觉原语和模块资产,F/R/N/M 每个路由自己拥有业务数据、状态、校验和导航。`ModulePage.vue``page-catalog.js` 保留为封存历史文件,但活动路由和合同不再消费它们。
**Tech Stack:** uni-app、Vue 3 `<script setup>`、SCSS、PowerShell 合同、Chrome CDP runtime smoke。
## Global Constraints
- 不接接口,不导入 `@/utils/api.js`
- 不使用 worktree,不执行 git add/commit/push/reset/checkout。
- 不删除源码、测试、文档、长期截图或实际资产;不恢复 `unpackage/``docs/design/screens/runtime/`
- 普通内容使用文档流并支持未知数据量;定位与容量保留项必须进入精确白名单。
- 只复用现有真实视觉资产,不用 CSS/字符/占位图伪造可见资产。
---
### Task 1: 活动页面所有权合同
- [x] 新建合同枚举 52 个活动路由并拒绝活动页面引用 `ModulePage`
- [x] 为 F/R/N/M 建立页面专属字段、状态、动作和导航清单;先运行得到 RED。
- [x] 更新旧 ModulePage 合同,使其验证封存边界而非活动业务入口。
### Task 2: F 模块独立内容
- [x] F03 动态详情拥有正文、媒体、评论列表和评论动作。
- [x] F04 谱文列表拥有分类、搜索、列表、空/失败和新建入口。
- [x] F05 谱文详情拥有作者、时间、正文、收藏和失效回流。
- [x] F07 相册列表拥有封面、数量、权限、空/失败和新建入口。
- [x] 运行 F 聚焦合同与四档 smoke。
### Task 3: R 模块独立内容
- [x] R03/R04 实现贺礼列表与新增/编辑字段、校验和删除确认。
- [x] R05/R06/R07 实现礼仪列表、详情、编辑字段和失效状态。
- [x] R08/R09 实现成长与人生时间线、人物上下文和新增动作。
- [x] R10/R11 实现备忘和功德记录的专属数据结构与状态。
- [x] 运行 R 聚焦合同与四档 smoke。
### Task 4: N/M 模块独立内容
- [x] N02 实现消息详情、已读状态和类型对应去向。
- [x] M02–M10 分别实现资料、安全、密码、手机、帮助、反馈、推广、订单、关于的专属控件和状态。
- [x] 运行 N/M 聚焦合同与四档 smoke。
### Task 5: A/G/T 与共享组件复核
- [x] 逐页检查 A/G/T 是否错误复用业务结构;只修复确认问题。
- [x] 检查共享组件只承担视觉原语,不拥有页面业务。
- [x] 对发现的问题执行 RED/GREEN 并运行既有流程 smoke。
### Task 6: 全量压力与视觉复核
- [x] 52/52 路由 Vite 转换成功。
- [x] 四档视口运行全部活动页,检查横向溢出、内容裁切、末项与主动作可达。
- [x] 对列表 50 条、长文案三倍、字号 1.3 倍和表单长输入做压力验证。
- [x] 捕获代表截图到 `%TEMP%`,与长期同模块参考图同尺寸比较,修复后再审一次。
### Task 7: 最终回归与交接
- [x] 运行全 position、数据容量、资产、路由、页面专属合同和关键 runtime smoke。
- [x] 运行 `git diff --check`,确认已清理目录未恢复、Chrome 项目页仍为 1。
- [x] 更新验收规划、交接记录和审计报告,明确 H5/接口/Android 边界及用户复核停点。
@@ -0,0 +1,193 @@
# 全项目数据驱动布局审核实施计划
> **执行要求:** 使用 `superpowers:executing-plans` 在当前会话逐任务执行。用户明确禁止多代理、worktree 与全部 Git 写操作,因此在已获用户“开始”授权的当前 `main` 工作区内执行,不包含提交步骤。
**目标:** 让 52 条活动路由、共享组件及封存 A06 的布局能够承受数据数量、文案长度和字号增长,同时保留确有必要的固定视觉边界。
**架构:** 新增一个扫描固定容量风险的 PowerShell 合同和精确 JSON 白名单,作为规则单一所有者;新增一个 Chrome CDP 压力脚本,对代表性重复内容注入 1/10/50 条、2~3 倍文案和 1.3 倍字号。普通内容使用自然文档流,弹层使用限高滚动,世系树从数据计算画布边界。
**技术栈:** uni-app Vue 3、SCSS、PowerShell、Node.js、Chrome CDP。
## 全局约束
- 列表验证 1/10/50 条;弹层验证 2/6/12/50 条;相册验证 1/9/30 张。
- 世系树验证 1/5/10 代及单代 1/6/12 人。
- 文案验证正常、2 倍、3 倍;字号验证默认及约 1.3 倍。
- 固定视口为 320×568、360×640、360×800、412×915。
- 不接接口、不新增路由、不改变业务语义、不删除或重绘实际资产。
- 不执行多代理、worktree、git add/commit/push/reset/checkout。
- 每个问题记录五种方案:扩大固定尺寸、增加断点、限高滚动、自然撑高、数据计算边界;按内容类型选择最优方案。
---
### 任务 1:建立全局容量风险合同与审计报告
**文件:**
- 新建:`tests/data-driven-layout-risk-allowlist.json`
- 新建:`tests/data-driven-layout-contract.ps1`
- 新建:`docs/data-driven-layout-audit_2026-07-20.md`
**接口:**
- 合同扫描 `pages/**/*.vue``components/**/*.vue` 的 style 块。
- 风险类型固定为 `fixed-content-height``clipping-overflow``single-line-truncation``fixed-grid-track``fixed-capacity-canvas`
- 白名单项必须包含 `file``selector``risk``reason`,并拒绝失效条目。
- [ ] **步骤 1:编写失败合同**
合同提取选择器和声明,普通内容命中以下条件即失败:固定内容高度、`overflow: hidden``nowrap/ellipsis/line-clamp`、百分比或固定值 grid 行、固定容量 `repeat(N, ...)`
- [ ] **步骤 2:运行合同确认 RED**
运行:
```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\tests\data-driven-layout-contract.ps1
```
预期:FAIL,并至少报告 T01、G05、G06、T07、`GenealogyCard` 的已知风险。
- [ ] **步骤 3:逐项分类并写五方案审计表**
审计表每行包含:文件/选择器、真实风险、五个候选方案、最优方案、选择理由、验证用例。装饰背景、媒体比例、图标、固定导航和明确滚动视口才允许加入白名单。
- [ ] **步骤 4:运行白名单失效自测**
临时增加不存在的选择器,确认合同以“失效白名单”失败;随后移除该临时条目。
### 任务 2:共享卡片、目录和普通结果卡自然撑高
**文件:**
- 修改:`components/GenealogyCard.vue`
- 修改:`pages/tree/t07-member-directory.vue`
- 修改:`pages/genealogy/g06-search-genealogies.vue`
- 修改:相关聚焦合同
**接口:**
- 关键姓名、谱名、地区、支系和身份允许换行。
- 卡片使用 `min-height`,不得使用固定 `height` 裁切正文。
- 摘要省略仅在存在同屏完整值或明确详情入口时允许。
- [ ] **步骤 1:扩展聚焦合同并确认 RED**
明确禁止 `.directory-card` 固定高度、`.directory-card__name/.directory-card__meta` 单行截断、`.result-card` 裁切、共享卡关键字段 `nowrap`
- [ ] **步骤 2:记录五方案并选择自然撑高**
对上述普通卡片选择方案 4;方案 1 只延后溢出,方案 2 不解决数据量,方案 3 会制造卡片内滚动,方案 5 对普通文本过度复杂。
- [ ] **步骤 3:最小修改源码**
将固定高度改为 `min-height`,移除正文裁切和关键字段强制单行,使用 `flex-wrap``minmax(0, 1fr)` 和自然行高。
- [ ] **步骤 4:运行聚焦合同和现有 runtime smoke**
预期:聚焦合同、G06、T03—T08 与模块响应式 smoke 全部 PASS。
### 任务 3:G05 百分比轨道改为内容驱动
**文件:**
- 修改:`pages/genealogy/g05-genealogy-overview.vue`
- 修改:`tests/g05-document-flow-contract.ps1`
- 修改:`tests/g05-overview-runtime-smoke.js`
- [ ] **步骤 1:添加长谱名、长来源、长公开说明失败断言**
检查每个内容块 `scrollHeight <= clientHeight + 1` 或容器允许自然增长,操作按钮可达。
- [ ] **步骤 2:运行确认 RED**
预期:百分比固定行导致长内容裁切或重叠。
- [ ] **步骤 3:比较五方案并选择自然撑高**
普通概览正文选择方案 4;保留真实背景比例,但让内容层以 `auto/minmax` 和自然间距排列。
- [ ] **步骤 4:修改并验证**
移除正文百分比行轨道和固定详情行高,改为内容驱动 grid/flex;运行 G05 静态、运行时与四档压力检查。
### 任务 4:T01 世系树由数据计算画布
**文件:**
- 修改:`pages/tree/t01-tree-overview.vue`
- 修改:`tests/t01-tree-state-contract.ps1`
- 修改:`tests/t01-tree-state-runtime-smoke.js`
**接口:**
- `layoutMembers`:从成员的世代和同代顺序生成 grid 行列。
- `treeCanvasStyle`:根据最大列、最大行、节点尺寸和间距返回动态 `gridTemplateColumns``gridTemplateRows``width``height`
- `generationRows`:从实际成员世代分组生成,不维护固定轨道行高数组。
- [ ] **步骤 1:写动态 10 代/单代 12 人失败测试**
断言所有节点处于画布边界内、世代标签与对应节点纵向相交、画布可横纵滚动、节点正文不使用定位。
- [ ] **步骤 2:运行确认 RED**
预期:固定 `900rpx`、180×180 网格和固定世代轨道无法满足压力数据。
- [ ] **步骤 3:比较五方案并选择数据计算边界**
选择方案 5;方案 3 仅解决滚动而不解决画布容量,方案 4 无法表达关系图坐标,方案 1/2 仍有硬上限。
- [ ] **步骤 4:实现动态布局并验证**
用 computed 数据推导画布、节点和世代轨道;保留关系线局部绘制白名单。运行 T01 静态、全状态、运行时和定位合同。
### 任务 5:其余页面全量风险清零
**文件:**
- 修改:任务 1 合同报告的其余 `pages/**/*.vue``components/**/*.vue`
- 修改:对应聚焦测试
- [ ] **步骤 1:按风险类型逐项写 RED**
每次只处理一个选择器;普通正文优先方案 4,弹层列表优先方案 3,媒体网格优先方案 5 或稳定 `aspect-ratio` 白名单。
- [ ] **步骤 2:逐项实现最小修改**
不得顺手重构相邻代码;每行修改必须对应审计表中的风险和选择方案。
- [ ] **步骤 3:全局合同归零**
运行容量合同,预期零未白名单风险、零失效白名单。
### 任务 6:全项目压力运行和二次视觉审核
**文件:**
- 新建:`tests/data-driven-layout-runtime-smoke.js`
- 修改:`scripts/capture-chrome-page.js`(只在需要新增审计动作时)
- 修改:三份交接/验收文档与本计划
**运行接口:**
- 对代表性重复项选择器复制到 10/50 条或 9/30 项。
- 对关键文本替换为 2~3 倍真实中文长文案。
- 对页面根设置 1.3 倍字号压力类,不改变生产默认字号。
- 输出只写 `%TEMP%\jiapuapp-runtime\data-driven-layout-audit`
- [ ] **步骤 1:编写压力脚本并确认在未修页面 RED**
检查横向溢出、正文裁切、末项可达、弹层滚动、按钮可达和树节点边界。
- [ ] **步骤 2:运行四档全量压力 smoke**
预期:所有配置用例 PASS,且 9222 仍只有一个项目页面。
- [ ] **步骤 3:捕获并检查代表性截图**
至少覆盖共享卡、普通列表、弹层、G05、T01、T07、媒体网格;每张截图必须实际打开检查。
- [ ] **步骤 4:修改后再审核一次**
把修改前后同状态同尺寸图放入同一比较图,检查裁切、边距、字体、边框、圆角和装饰资产;发现问题回到对应任务继续 RED/GREEN。
- [ ] **步骤 5:最终验证与交接**
运行容量合同、定位合同、全部相关静态合同、关键 runtime smoke、`git diff --check`,确认 `docs/design/screens/runtime/` 不存在;不运行会恢复该目录的旧脚本。文档明确自动审核不等于用户新增 `[x]` 或 Android 完成。
## 2026-07-20 执行记录
- 任务 1—5 已完成:容量合同覆盖固定内容高度、裁切、单行截断、固定 grid 行和大固定画布;最终为零未解释风险、零失效白名单。
- TDD 记录已形成:共享卡/T07/G06、G05、T01、G08/G09/G11/G12 均先看到聚焦 RED,再完成最小实现和 GREEN。
- 任务 6 已完成 H5 自动化与二次目视审核:四档视口、50 条列表/弹层、30 项媒体、10×12 世系树、长文案和 1.3 倍字号模拟通过。
- 当前停点为用户视觉复核。所有有可见变化的旧 `[x]` 只能视为候选;用户再次明确“通过”前,不维护或新增验收勾选。
@@ -2,15 +2,23 @@
> **执行要求:** 使用 `superpowers:executing-plans` 当前会话内联执行。用户禁止多代理、worktree 及全部 Git 写操作;不执行提交步骤。
**目标:**用户指定 fixed 的顶部/底部导航与真实弹层外,清除全项目页面内容的脱离文档流定位,并保持现有业务状态与视觉语言。
**目标:**精确白名单内确有必要的定位职责外,清除全项目普通页面内容的全部无意义 `position` 声明(包括 `relative`,并保持现有业务状态与视觉语言。
**架构:** 以一个静态合同和精确 JSON 白名单为单一规则所有者;先完成 R02 样板,再迁移共享组件和模块页面。每批通过现有 CDP smoke、四档响应式及同尺寸截图后进入下一批。
**技术栈:** uni-app Vue 3、SCSS、PowerShell、Node.js、Chrome CDP。
## 2026-07-20 执行结果
- 合同已扫描全部 `position` 声明并去除注释干扰;初始基线为 35 个文件、390 条未白名单声明,其中 278 条为 `relative`。当前未白名单违规为 0,失效白名单为 0。
- F10 与 T01 完成后继续按 R → N → M → F → G → T → A 全面迁移,并覆盖共享组件、`ModulePage`、Tree 表单和封存 A06;没有把单页修复冒充全项目完成。
- 普通根容器、Header/Content、正文、字段、按钮和卡片使用正常文档流、flex、grid 或 grid 同单元叠放。白名单只保留固定导航、视口背景、真实弹层/Toast/遮罩/底部弹层/全屏预览、必要媒体覆盖、局部装饰与 T01 关系线等明确职责。
- 已完成迁移批次的聚焦合同、关键 H5 runtime smoke 与同尺寸前后对比;未观察到语义性可见变化。该自动结果不替代用户确认,本轮不新增 `[x]`A06 仅静态覆盖,Android 未验证。
- `tests/t07-module-baseline-runtime-smoke.js` 因会重新生成已清理的 runtime 截图且“清空搜索恢复全部成员”断言失败,不计入通过项;核心 `tests/t03-t08-member-flow-runtime-smoke.js` 独立通过。既有资产命名与仓库交接体积失败未通过放宽阈值或删除长期资料处理。
## 全局约束
- 禁止普通内容使用 `absolute/fixed/sticky`、负外边距或以位移 transform 承担布局;按钮按压等不改变排版的交互微动效可以保留。
- 禁止普通内容使用无明确必要的 `relative/absolute/fixed/sticky` 或其他 `position` 声明、负外边距或以位移 transform 承担布局;按钮按压等不改变排版的交互微动效可以保留。
- 允许定位的职责为固定顶部/底部导航、独立视口背景、真实弹层,以及受明确父容器约束的纯装饰、角标、红点和关系线,必须精确白名单。
- 不删除或重绘现有资产;装饰图优先改作 background/border-image,只有确需局部叠放时保留 absolute。
- 四档为 320×568、360×640、360×800、412×915。
@@ -24,12 +32,39 @@
- 新建:`tests/document-flow-position-allowlist.json`
- 新建:`tests/document-flow-position-contract.ps1`
- [ ] 白名单登记 `PageHeader.vue` 的固定顶部栏、`AppTabbar.vue` 的固定底部栏、`AppDialog.vue` 的弹窗层/皮肤和 `AppToast.vue` 的 Toast;其他页面本地弹层在迁移到对应批次时逐项审计后登记
- [ ] 合同扫描 `pages/**/*.vue``components/**/*.vue` 的 style 块,报告不在精确文件+选择器白名单内的 `absolute/fixed/sticky`
- [ ] 合同同时禁止普通选择器出现负 margin 和 `transform: translate(...)` 布局。
- [ ] 运行合同并保存初始 37 文件违规清单;预期 FAIL,不放宽规则
- [x] 白名单登记固定顶部/底部导航、真实弹层、Toast、独立视口背景及经审计确有必要的局部装饰、角标和关系线;每项使用精确文件+选择器+用途,不放行普通 `relative`
- [x] 合同扫描 `pages/**/*.vue``components/**/*.vue` 的 style 块,报告不在精确白名单内的所有 `position` 声明,包括 `relative`
- [ ] 合同继续补齐普通选择器负 margin 和 `transform: translate(...)` 布局检查
- [x] 2026-07-20 新口径初始基线为 35 个文件、390 条未白名单声明,其中 278 条为 `relative`;预期 FAIL,不再使用旧“37 文件/112 条”作为完整数字
### 任务 2R02 文档流样板
### 任务 2F10 无意义 relative 返工样板
**文件:**
- 修改:`pages/family/f10-video-list.vue`
- 修改:`tests/f10-video-status-contract.ps1`
- 验证:`tests/f10-video-status-runtime-smoke.js`
- [ ] 先扩展 F10 聚焦合同,禁止页面根容器、Header/Content 包装、导语正文、状态卡和状态卡正文使用 `position: relative`,保留已审计装饰层的精确白名单。
- [ ] 运行聚焦合同确认 RED。
- [ ] 使用正常文档流和 grid 同单元叠放移除 6 条无意义 `relative`,装饰图不得承担正文排版。
- [ ] 运行全局定位合同,确认 F10 的 6 条 `relative` 违规归零且其他基线未被掩盖。
- [ ] 复用唯一 51739222 项目页执行四档 smoke 和同尺寸前后截图;有可见变化时 F10 退回 `[~]`,只有用户重新明确通过才能维持 `[x]`
### 任务 3:T01 世代栏与成员节点文档流
**文件:**
- 修改:`pages/tree/t01-tree-overview.vue`
- 修改:`tests/t01-tree-state-contract.ps1`
- 修改:`tests/t01-all-states-visual-contract.ps1`
- 验证:`tests/t01-tree-state-runtime-smoke.js`
- [ ] 聚焦合同先禁止 `.generation-band``.generation-rail``.member-node` 使用定位摆放普通节点内容,关系线只保留经审计的局部绘制职责。
- [ ] 运行聚焦合同确认 RED。
- [ ] 世代栏、成员节点和节点正文改为 grid/flex 文档流;关系线使用 grid 边框或受父容器约束的精确白名单层。
- [ ] 运行 T01 状态合同、全状态视觉合同、运行时 smoke 和全局定位合同。
- [ ] 复用唯一项目页完成正常、状态、节点选择和四档同尺寸对比;有可见变化时 T01 退回 `[~]` 等待用户重新确认。
### 任务 4:R02 文档流样板复核
**文件:**
- 修改:`pages/records/r02-person-detail.vue`
@@ -42,7 +77,7 @@
- [ ] 题签 copy、字段 label/input、textarea、状态文案全部使用文档流;容器高度由内容和 min-height 控制。
- [ ] 运行 R02 合同、入口交互 smoke、四档 smoke,捕获 412×915 详情和编辑态供复核。
### 任务 3:共享基础组件
### 任务 5:共享基础组件
**文件:** `components/AppButton.vue``PageHeader.vue``AppTabbar.vue``ModulePageBackground.vue``GenealogyPageBackground.vue``GenealogyCard.vue`
@@ -51,7 +86,7 @@
- [ ] GenealogyCard 内容改 flex/grid,皮肤转背景。
- [ ] 对 G01、T07、F01、R01、N01、M01 六基准做四档和同尺寸回归。
### 任务 4:通用 ModulePage
### 任务 6:通用 ModulePage
**文件:** `components/ModulePage.vue` 及其聚焦测试
@@ -59,14 +94,14 @@
- [ ] 装饰图转背景;字段用 grid;卡片内容自然撑高。
- [ ] 执行全部消费 ModulePage 的路由 smoke 和四档回归。
### 任务 5:模块分批迁移
### 任务 7:模块分批迁移
- [ ] R → N → M → F:每页先合同 RED,再改文档流,再跑模块四档。
- [ ] G:保留真实弹层白名单,页面卡片、表单、Header、背景全部文档流
- [ ] T:目录和表单使用 grid/flex;T01 世系节点和关系线用 grid/border 重做
- [ ] G:保留真实弹层白名单,页面卡片、表单、Header 和普通内容全部文档流;独立视口背景只保留精确白名单
- [ ] TT01 完成后,继续把目录和表单迁移到 grid/flex。
- [ ] A:登录、注册、重置和封存 A06 的普通内容文档流;验证弹窗/Toast 保留精确白名单。
### 任务 6:最终收敛
### 任务 8:最终收敛
- [ ] `tests/document-flow-position-contract.ps1` 最终 PASS,输出零普通内容违规。
- [ ] 运行活动路由转换、关键交互 smoke、四档响应式和 `git diff --check`
@@ -0,0 +1,50 @@
# 全活动页面业务所有权与成熟度收敛设计
## 目标
在不接业务接口、不改变现有浅色国风视觉体系的前提下,把 52 个活动路由从“视觉覆盖稿”收敛为可独立理解、可本地操作、可扩容的 H5 产品候选。共享组件只负责背景、页头、按钮、弹窗、提示和加载等视觉原语;每个业务页面必须自己拥有字段、内容结构、状态语义、入口与下一步。
## 已确认根因
`components/ModulePage.vue``data/page-catalog.js` 当前同时拥有 F/R/N/M 23 个路由的业务结构和交互。不同任务只替换标题、字段数组或模板类型,造成动态详情、谱文、相册、贺礼、礼仪、成长日志、消息详情、个人资料、安全、帮助、反馈、推广、订单和关于页共享同一套“查看详情/提交后成功”行为。历史规划已经把它定义为第一版覆盖工具而非最终视觉答案,因此用户对同质化的怀疑成立。
## 五方案比较
1. **继续沿用单一 `ModulePage`**:改动最少,但业务含义继续由模板猜测,不能成为成熟产品,淘汰。
2. **扩大 `pageCatalog` 配置协议**:可补字段类型和动作,但会把页面逻辑继续集中到一个巨型解释器,配置与运行时容易分叉,淘汰。
3. **按 form/list/detail/timeline/settings 拆五个业务组件**:比单一母版清晰,但“同样是表单”不代表个人资料、密码、礼仪和反馈拥有相同验证与状态,仅作为视觉结构参考。
4. **每页复制完整视觉与业务代码**:业务独立但重复背景、页头、按钮和状态样式,后续全局调整风险过高,淘汰。
5. **共享视觉原语、页面拥有业务(最优)**:活动路由不再委托 `ModulePage``pageCatalog`;每页直接声明真实本地数据、字段类型、状态和动作,只复用 `ModulePageBackground``PageHeader``AppButton``AppDialog``AppToast``AppLoading` 等稳定视觉原语与公共样式。
## 所有权边界
- 页面拥有:业务文案、字段与输入类型、列表项目结构、空/加载/失败/权限/失效/成功状态、校验、确认动作、入口和返回目标。
- 公共组件拥有:模块长背景、顶部/底部导航、按钮表面、卷轴弹窗、Toast、Loading、稳定卡片皮肤映射。
- `ModulePage.vue``page-catalog.js` 不再是活动路由入口;为遵守现有文件保留要求,文件保留为封存历史实现,并由合同禁止活动页面引用。
- 不接 `utils/api.js`;页面使用真实语义的本地 mock 数据与查询参数状态,接口阶段替换数据源而不重写视觉结构。
## 分模块业务内容
- F:动态详情/评论、谱文列表与详情、相册列表必须各自拥有内容和动作;编辑、上传与待开放页沿用现有独立实现。
- R:贺礼、礼仪、成长日志、人生事、备忘、功德分别拥有对应金额/关系/时间/地点/人物/提醒/贡献字段,不再是通用卡片换标题。
- N:消息详情拥有消息类型、时间、正文、已读与业务去向。
- M:资料、安全、改密、改手机、帮助、反馈、推广、订单、关于分别拥有正确控件、校验、确认与状态。
- A/G/T:保留现有独立页面,重点复核共享组件边界、长数据、长文本、状态与导航,不为了统一而退回母版。
## 数据驱动与视觉规则
- 普通内容由文档流自然撑高;列表使用数组渲染,不写死项目数。
- 文字允许换行;只有真实媒体缩略图、图标和结构画布可精确裁切。
- 表单使用与语义匹配的 `input` 类型和 `textarea auto-height`;长列表末项必须可达。
- 四档 H5320×568、360×640、360×800、412×915;压力覆盖 1/10/50 条、三倍长文案和 1.3 倍字号模拟。
- 视觉继续使用仓库现有真实位图资产,不新增 CSS 伪装饰、占位资产或手绘 SVG。
## 验收
1. 52 个活动路由均能被 Vite 转换并通过静态资产、定位、数据容量合同。
2. 活动页面对 `ModulePage` 的引用为 0;页面目录不再是活动业务合同。
3. 每个替换页至少有一个页面专属合同,验证核心字段、状态、动作、路由和禁止项。
4. 四档运行 smoke 无横向溢出,长内容不裁切,主动作和末项可达。
5. 代表页面与同模块长期参考图同尺寸比较;视觉自审不能替用户的最终 `[x]`,但代码与候选状态必须完整记录。
6. 不宣称接口、Android/HBuilderX、系统字体缩放或真实系统权限完成。
@@ -0,0 +1,72 @@
# 全项目数据驱动布局审核设计
> 日期:2026-07-20
> 阶段:H5 视觉与布局韧性,不接接口,不宣称 Android 完成
> 约束:不使用多代理或 worktree,不执行 Git 写操作,不删除源码、测试、文档、长期截图或实际资产
## 目标
在全项目文档流迁移完成后,再以真实数据增长为前提审核 `pages/``components/`、52 条活动路由及封存 A06。当前 Mock 数量或短文案能显示正常,不再视为数据驱动布局通过。
审核必须证明:列表、卡片、表单、弹层、相册、世系树和共享组件能够由数据数量、文案长度和字号自然驱动;固定尺寸只用于图标、媒体比例、明确的装饰槽位和视口级导航等稳定视觉边界。
## 压力基线
- 列表:1、10、50 条。
- 弹层列表:2、6、12、50 条;内容先自然增长,达到视口上限后仅列表区滚动。
- 相册/上传网格:1、9、30 张。
- 世系树:1、5、10 个世代;单代 1、6、12 个成员;节点和关系线边界由数据计算。
- 文案:正常、2 倍、3 倍长度,覆盖长谱名、长姓名、堂号、地区、支系、身份、状态、说明和按钮文案。
- 字号:默认与约 1.3 倍。
- 视口:320×568、360×640、360×800、412×915。
## 审核分类
1. 普通页面和共享卡片:检查固定 `height`、固定 grid 行、`overflow: hidden`、单行截断、不可换行和固定项目数量假设。
2. 列表和目录:检查数据增加后页面自然增长、末项可达、底部导航避让和滚动所有权。
3. 弹层和底部层:检查少量内容自然增长、大量内容达到 `max-height` 后内部滚动、标题和操作区不被挤出。
4. 表单和状态页:检查错误文案、长标签、长输入值、键盘前后及成功/失败信息自然撑高。
5. 媒体网格:检查项目数量改变、长说明、失败状态和当前项标识;媒体缩略图可保留稳定 `aspect-ratio`
6. 世系树:检查画布宽高、世代轨道、节点坐标和关系线是否由数据边界推导;不允许固定 `900rpx` 或固定 180×180 网格成为容量上限。
## 每项问题的五方案决策
每个确认问题都必须记录下列五种候选方案,并按该问题的内容类型选择最优方案,不机械套用同一种 CSS:
1. **扩大固定尺寸**:改动最小,但只是推迟溢出,默认淘汰。
2. **增加尺寸断点**:适合设备差异,不解决未知数据量,通常只作补充。
3. **容器限高并滚动**:适合弹层、独立列表和全屏画布;普通卡片不使用。
4. **正常文档流自然撑高**:适合正文、表单、状态卡、普通列表卡和长文案;为普通内容首选。
5. **由数据计算布局边界**:适合世系树、媒体网格、可变列数和结构化关系;由数据推导行列、画布和连接关系。
选择顺序:普通内容优先方案 4;独立滚动容器优先方案 3;结构化画布优先方案 5。方案 1 不作为最终修复,方案 2 只处理确实由视口造成的差异。
## 实施规则
- 先建立全局静态容量合同,列出风险选择器,但对白名单视觉边界做精确说明,不能简单禁止所有固定尺寸。
- 每个确认问题先添加最小失败测试并看到预期 RED,再修改源码。
- 卡片默认使用 `min-height` 和自然撑高;文本默认允许换行。只有同时存在完整值查看路径、非关键摘要语义和明确空间边界时才允许省略号。
- 页面主列表使用正常文档流;弹层列表、固定导航下的独立区域和世系画布可以拥有明确滚动容器。
- 背景图使用 `background`、九宫格或稳定比例承载装饰,不让装饰图高度决定正文容量。
- 不改变接口、路由、业务状态含义、当前视觉资产和用户已确认的色彩/字体/装饰语言。
## 验证与证据
1. 静态容量合同为零未解释风险。
2. 每类页面运行压力数据 smoke,检查横向溢出、内容裁切、末项可达、滚动所有权和操作区可达。
3. 使用唯一 51739222 Chrome 项目页,在四档尺寸获取当前审核运行的新截图。
4. 修改后再次获取同状态、同尺寸截图;将修改前后放入同一比较图检查可见变化。
5. 自动化与截图只能证明候选稳定,不能代替用户视觉确认或新增 `[x]`
## 已知首轮风险
- T01 使用固定 `900rpx` 画布、固定 180×180 网格及固定世代轨道行高,属于高风险。
- G05 使用百分比固定行轨道和局部固定行高,长文案可能挤压。
- G06 结果卡在可增长内容上保留 `overflow: hidden`,存在裁切风险。
- T07 成员卡固定高度,姓名和成员信息强制单行省略,存在长数据风险。
- 共享 `GenealogyCard` 的谱名、元信息、角色与更新时间多处不换行,存在真实数据截断风险。
- G01 切换家谱弹层已验证 2/6/12 条可增长与滚动,是可复用的弹层容量参考。
## 完成边界
本轮完成只表示 H5 数据容量候选通过源码合同、压力运行和同尺寸视觉回归。A06 封存路由只做静态检查;Android/HBuilderX、系统键盘、真实接口数据和设备级字体缩放仍需后续单独验证。既有 `foundation-asset-audit``repository-handoff-size-contract` 失败不得通过放宽阈值或删除长期资料处理。
@@ -6,7 +6,11 @@
## 当前证据
只读审计发现 37 个 Vue 文件包含 `position: absolute|fixed|sticky`。用法混合了正常内容、装饰图层、页面背景、Tabbar、世系关系线和真实弹层,不能机械删除。R02 已证明普通文字、字段标签和输入框也被定位到装饰图之上,系统字体、长文案、键盘或尺寸变化时存在重叠风险。
只读审计发现 37 个 Vue 文件包含 `position: absolute|fixed|sticky`,漏掉了普通容器上的 `relative`,因此旧“剩余 112 条”无效。2026-07-20 扩展合同后,新口径发现 35 个文件存在 390 条未白名单 `position` 声明,其中 278 条为 `relative`F10 一页即有 6 条无意义 `relative`。用法混合了正常内容、装饰图层、页面背景、Tabbar、世系关系线和真实弹层,不能机械删除。R02 已证明普通文字、字段标签和输入框也被定位到装饰图之上,系统字体、长文案、键盘或尺寸变化时存在重叠风险。
## 执行状态
2026-07-20 已按本设计完成全项目源码迁移。合同从上述 390 条未白名单声明收敛为零,并增加失效白名单检查,保证白名单与源码实际定位逐项对应。迁移覆盖共享组件、R/N/M/F/G/T/A 页面及封存 A06;普通内容改用正常文档流、flex、grid 或 grid 同单元叠放,只有本设计列出的明确职责保留定位。H5 同尺寸回归未发现语义性可见变化,但这不替代用户确认;本次不新增视觉 `[x]`,不宣称 Android 或接口完成。
## 单一合同
@@ -20,12 +24,13 @@
## 迁移顺序
1. 建立合同精确白名单 37 文件初始清单,测试先失败并输出全部违规位置。
2. R02 作为第一张页面样板:人物题签、档案卡、表单、状态卡全部改为背景 + flex/grid 文档流
3. 迁移共享控件:AppButton、PageHeader、AppTabbar、ModulePageBackground、GenealogyPageBackground、GenealogyCardPageHeader 与 AppTabbar 保留用户指定的 fixed 白名单,清除其内部普通内容和装饰定位;弹层组件保留白名单定位
4. 迁移 `ModulePage`,让普通 F/R/N/M 页面共享文档流结构
5. 按 R → N → M → F → G → T → A 迁移专属页面;A06 源码也纳入静态合同
6. 每批执行聚焦合同、现有交互 smoke、四档响应式、真实截图和 `git diff --check`
1. 建立扫描全部 `position`合同精确白名单,以 35 文件/390 条未白名单声明作为新初始基线;测试先失败并输出全部违规位置。
2. F10 先移除页面根容器、Header/Content、正文和卡片的 6 条无意义 `relative`,作为新口径最小返工样板
3. T01 随后迁移世代栏与成员节点;节点正文使用 grid/flex,关系线只保留经审计的局部绘制职责
4. 复核 R02 样板并迁移共享控件:AppButton、PageHeader、AppTabbar、ModulePageBackground、GenealogyPageBackground、GenealogyCardPageHeader 与 AppTabbar 保留用户指定的 fixed 白名单,清除其内部普通内容定位;弹层组件保留白名单定位
5. 迁移 `ModulePage`,让普通 F/R/N/M 页面共享文档流结构
6. 按 R → N → M → F → G → T → A 迁移其余专属页面;A06 源码也纳入静态合同
7. 每批执行聚焦合同、现有交互 smoke、四档响应式、真实截图和 `git diff --check`
## 冻结页
@@ -33,7 +38,7 @@
## 验收门槛
- 全项目合同最终为零违规白名单只含固定顶部/底部导航和真实弹层
- 全项目合同最终为零未白名单违规白名单只含固定顶部/底部导航、独立视口背景、真实弹层/Toast/遮罩/底部弹层/全屏预览,以及经审计确有必要的局部装饰、角标和关系线
- 52 条活动路由和封存 A06 源码均被扫描。
- 四档固定为 320×568、360×640、360×800、412×915。
- 长文案、约 1.3 倍字号、输入校验和键盘场景不重叠,操作区可滚动到达。