229 lines
8.3 KiB
Markdown
229 lines
8.3 KiB
Markdown
# Responsive Foundation Phase 1 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:** 建立全项目响应式基础契约,并让 AppDialog、AppButton 与 ModulePage 使用统一九宫格素材档案和内容驱动高度。
|
||
|
||
**Architecture:** `styles/adaptive-frame-profiles.scss` 是九宫格切片的唯一所有者;组件只调用具名 mixin。`project-responsive-layout-contract.ps1` 根据覆盖清单扫描已迁移文件,根据唯一白名单放行结构性固定尺寸;第一阶段覆盖三个公共内容组件,后续阶段只增加覆盖范围。
|
||
|
||
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell、MuMu Android
|
||
|
||
## Global Constraints
|
||
|
||
- 内容容器不得使用固定高度表达内容容量。
|
||
- 可变内容背景不得使用 `100% 100%` 整图拉伸。
|
||
- 固定高度和固定装饰例外只能由 `tests/responsive-layout-allowlist.json` 所有。
|
||
- 第一阶段覆盖 `AppDialog.vue`、`AppButton.vue`、`ModulePage.vue`;已覆盖文件不得退出。
|
||
- AppDialog 短内容自然收紧、长内容自然增高、超过视口才滚动。
|
||
- 不修改业务逻辑、路由、文案和数据状态。
|
||
- 不执行 Git 操作,不启用多代理。
|
||
|
||
---
|
||
|
||
### Task 1: 唯一九宫格素材档案
|
||
|
||
**Files:**
|
||
- Create: `styles/adaptive-frame-profiles.scss`
|
||
- Create: `tests/adaptive-frame-profiles-contract.ps1`
|
||
|
||
**Interfaces:**
|
||
- Produces: `adaptive-auth-dialog`、`adaptive-scroll-button($type)`、`adaptive-module-content`、`adaptive-module-field` 四个 SCSS mixin。
|
||
|
||
- [ ] **Step 1: 写入失败合同**
|
||
|
||
合同要求档案存在并包含:
|
||
|
||
```powershell
|
||
foreach ($token in @(
|
||
'@mixin adaptive-auth-dialog',
|
||
'@mixin adaptive-scroll-button($type)',
|
||
'@mixin adaptive-module-content',
|
||
'@mixin adaptive-module-field',
|
||
'a01-scroll-dialog-v3.png',
|
||
'border-image-slice: 260 240 360 240 fill;',
|
||
'border-image-slice: 56 300 fill;',
|
||
'border-image-slice: 105 150;',
|
||
'border-image-slice: 70 100 fill;'
|
||
))
|
||
```
|
||
|
||
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/adaptive-frame-profiles-contract.ps1`
|
||
|
||
Expected: FAIL,素材档案不存在。
|
||
|
||
- [ ] **Step 2: 创建素材档案**
|
||
|
||
`adaptive-auth-dialog` 使用:
|
||
|
||
```scss
|
||
border-width: 48rpx 34rpx 72rpx;
|
||
border-image-slice: 260 240 360 240 fill;
|
||
border-image-width: 48rpx 34rpx 72rpx;
|
||
```
|
||
|
||
`adaptive-scroll-button` 使用现有主/次卷轴素材、`10rpx 26rpx` 边框和 `56 300 fill` 切片。
|
||
|
||
`adaptive-module-content` 使用动态 `var(--module-content-asset)`、`18rpx 20rpx` 边框和 `105 150` 切片。
|
||
|
||
`adaptive-module-field` 使用动态 `var(--module-field-asset)`、`12rpx 16rpx` 边框和 `70 100 fill` 切片。
|
||
|
||
所有 mixin 使用透明实体边框、`border-image-repeat: stretch` 和 `box-sizing: border-box`。
|
||
|
||
- [ ] **Step 3: 验证档案合同**
|
||
|
||
Expected: `ADAPTIVE-FRAME-PROFILES-CONTRACT PASS`。
|
||
|
||
### Task 2: 全局扫描合同、覆盖清单与例外白名单
|
||
|
||
**Files:**
|
||
- Create: `tests/project-responsive-layout-contract.ps1`
|
||
- Create: `tests/responsive-layout-coverage.json`
|
||
- Create: `tests/responsive-layout-allowlist.json`
|
||
|
||
**Interfaces:**
|
||
- Consumes: 覆盖文件列表与按文件/选择器/属性登记的例外。
|
||
- Produces: 已迁移文件中固定内容高度、可变背景整图拉伸和重复九宫格切片的失败门禁。
|
||
|
||
- [ ] **Step 1: 创建第一阶段覆盖清单**
|
||
|
||
```json
|
||
{
|
||
"covered": [
|
||
"components/AppButton.vue",
|
||
"components/AppDialog.vue",
|
||
"components/ModulePage.vue"
|
||
]
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 2: 创建唯一白名单**
|
||
|
||
第一阶段只允许 `ModulePage.vue` 的 `.module-lead` 使用固定分隔线背景;不允许 AppDialog、AppButton 或 ModulePage 内容表面使用固定内容高度/整图拉伸。
|
||
|
||
- [ ] **Step 3: 创建扫描合同并确认失败**
|
||
|
||
合同解析覆盖文件的样式块,遇到以下情况失败:
|
||
|
||
```text
|
||
height: <数字>rpx(不含 min-height/max-height)
|
||
background: ... 100% 100%
|
||
页面或组件直接出现 border-image-slice(素材档案本身除外)
|
||
```
|
||
|
||
白名单按规范化文件路径、选择器和属性精确匹配。覆盖清单中的路径不存在也失败。
|
||
|
||
Run: `powershell -NoProfile -ExecutionPolicy Bypass -File tests/project-responsive-layout-contract.ps1`
|
||
|
||
Expected: FAIL,指出 AppDialog 固定 `520rpx` 或 ModulePage 内容表面整图拉伸。
|
||
|
||
### Task 3: AppDialog 与 AppButton 消费统一档案
|
||
|
||
**Files:**
|
||
- Modify: `components/AppDialog.vue`
|
||
- Modify: `components/AppButton.vue`
|
||
- Modify: `tests/app-dialog-responsive-content-contract.ps1`
|
||
- Modify: `tests/app-button-compact-contract.ps1`
|
||
|
||
**Interfaces:**
|
||
- Consumes: Task 1 的 `adaptive-auth-dialog` 与 `adaptive-scroll-button`。
|
||
- Produces: 内容驱动的全局弹窗和默认关闭的紧凑按钮。
|
||
|
||
- [ ] **Step 1: 更新失败合同**
|
||
|
||
AppDialog 合同禁止 `min-height: 520rpx`、旧 `background ... contain` 和 `margin-top: auto`,要求:
|
||
|
||
```text
|
||
@include adaptive-auth-dialog;
|
||
max-height: calc(var(--app-viewport-height, 100vh) - 160rpx)
|
||
margin-top: 26rpx
|
||
```
|
||
|
||
AppButton 合同要求调用 `adaptive-scroll-button(primary|secondary)`,不再在组件内重复切片值。
|
||
|
||
- [ ] **Step 2: 运行合同并确认失败**
|
||
|
||
Expected: AppDialog 因固定高度失败,AppButton 因本地切片重复失败。
|
||
|
||
- [ ] **Step 3: 修改 AppDialog**
|
||
|
||
在 scoped style 开头导入档案。`.app-dialog` 删除固定最小高度和旧背景,调用 `adaptive-auth-dialog`。`.app-dialog__content` 删除固定最小高度,使用:
|
||
|
||
```scss
|
||
max-height: calc(var(--app-viewport-height, 100vh) - 160rpx);
|
||
padding: 16rpx 20rpx 12rpx;
|
||
overflow-y: auto;
|
||
```
|
||
|
||
操作区改为 `margin-top: 26rpx`,不再使用 `auto`。
|
||
|
||
- [ ] **Step 4: 修改 AppButton**
|
||
|
||
导入档案;主/次紧凑类分别调用 `@include adaptive-scroll-button(primary)` 和 `secondary`;删除组件内重复边框切片声明。
|
||
|
||
- [ ] **Step 5: 运行共享组件合同**
|
||
|
||
Run AppDialog、AppButton、共享无障碍、共享文档流和全局响应式合同,Expected: 全部 `PASS`。
|
||
|
||
### Task 4: ModulePage 内容表面迁移
|
||
|
||
**Files:**
|
||
- Modify: `components/ModulePage.vue`
|
||
- Modify: `tests/module-page-visual-contract.ps1`
|
||
- Test: `tests/module-series-responsive-runtime-smoke.js`
|
||
|
||
**Interfaces:**
|
||
- Consumes: Task 1 的 module-content 与 module-field mixin。
|
||
- Produces: F/R/N/M 通用页面的内容驱动卡片和表单表面。
|
||
|
||
- [ ] **Step 1: 更新失败合同**
|
||
|
||
要求 ModulePage 导入档案,字段组调用 `adaptive-module-field`,内容组调用 `adaptive-module-content`;禁止内容表面 `100% 100%`。
|
||
|
||
- [ ] **Step 2: 运行合同并确认失败**
|
||
|
||
Expected: FAIL,指出旧 `var(--module-*-asset) center / 100% 100%`。
|
||
|
||
- [ ] **Step 3: 修改 ModulePage**
|
||
|
||
- `.form-row, .settings-row` 调用 `adaptive-module-field`。
|
||
- `.list-card, .detail-card, .timeline-row, .status-card` 调用 `adaptive-module-content`。
|
||
- `.module-lead` 自己承担 flex 居中,删除子文本的 `height: 100%`。
|
||
- 保留现有 `min-height` 作为最低视觉基线,内容可继续增高。
|
||
|
||
- [ ] **Step 4: 验证 ModulePage**
|
||
|
||
运行视觉合同、响应式 runtime smoke 与全局响应式合同;若 H5 服务未运行,只记录 runtime 环境阻塞,不用浏览器代替 MuMu。
|
||
|
||
### Task 5: MuMu 三档基础验证
|
||
|
||
**Files:**
|
||
- Verify: `components/AppDialog.vue`
|
||
- Verify: `components/AppButton.vue`
|
||
- Verify: `components/ModulePage.vue`
|
||
- Save screenshots: `tmp/responsive-foundation-*.png`
|
||
|
||
**Interfaces:**
|
||
- Produces: G10 通过/拒绝弹窗和一个 ModulePage 页面在三档 Android 逻辑视口的原生证据。
|
||
|
||
- [ ] **Step 1: 运行全部聚焦合同**
|
||
|
||
必须包含素材档案、全局响应式、AppDialog、AppButton、ModulePage、共享无障碍和共享文档流合同。
|
||
|
||
- [ ] **Step 2: MuMu 验证 G10**
|
||
|
||
在 `360×640dp`、`360×800dp`、`412×915dp` 依次检查:
|
||
|
||
```text
|
||
通过确认:无固定大空白。
|
||
拒绝确认:输入框和按钮不压边。
|
||
拒绝错误:错误文字出现后仍可达按钮。
|
||
```
|
||
|
||
- [ ] **Step 3: MuMu 验证 ModulePage**
|
||
|
||
选择一个 ready 和一个 error 状态,确认内容卡随文字增高、边角不拉伸、按钮可达。
|
||
|
||
- [ ] **Step 4: 恢复 MuMu 原始尺寸**
|
||
|
||
每档验证后恢复用户当前 `720×1280` 物理尺寸和原密度,并把 G10 恢复到默认列表。
|