Files
jiapuapp/docs/superpowers/plans/2026-07-21-auth-pages-adaptive-migration.md
T
2026-07-21 11:25:57 +08:00

323 lines
13 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.
# 认证页自适应迁移 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans` to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 从已在 MuMu 放行的 A01 提取最小认证页骨架,并将 A04、A05 与封存 A06 从固定设计稿画布迁移为可自然增长的手机自适应文档流。
**Architecture:** `components/AuthPageShell.vue` 单一拥有认证页的可用视口、顶部品牌头图、已确认的 Logo 位置、宣纸内容背景与安全区。A01、A04、A05、A06 只拥有各自表单、状态、弹层和业务逻辑;长表单在空间不足、错误或键盘状态下自然滚动,不通过整页缩放或机型断点硬塞进首屏。
**Tech Stack:** uni-app、Vue 3、SCSS、PowerShell 静态合同、Node.js CDP 运行时辅助检查、HBuilderX Android、MuMu、ADB。
## Global Constraints
- 规格源:`docs/superpowers/specs/2026-07-21-project-mobile-viewport-adaptation-design.md`
- A01 已确认的头图比例、Logo 尺寸与位置、字号体系和内容比例不得因抽取骨架发生可见回退。
- 不改变注册、重设密码、账号状态的字段、校验、状态机、文案语义和路由行为。
- A06 保留源码和测试但不恢复到 `pages.json`
- 禁止认证页继续使用 `page-canvas``page-backdrop`、整页 `scaleToFill``1665rpx` 固定画布或交互内容整页叠层。
- 共享骨架只拥有背景、视口与安全区,不接收页面编号或业务配置。
- Toast 统一消费 `--status-bar-height`;同一安全区不得被骨架和业务页面重复计入。
- H5 只作自动结构验证;每个活动认证页最终视觉放行必须来自 MuMu。
---
### Task 1: 用失败合同锁定共享认证页骨架
**Files:**
- Create: `tests/auth-page-shell-contract.ps1`
- Test: `tests/auth-page-shell-contract.ps1`
**Interfaces:**
- Produces: `AuthPageShell` 的单一职责合同,以及 A01/A04/A05/A06 禁止旧画布的合同
- [ ] **Step 1: 写入失败合同**
合同读取 `components/AuthPageShell.vue` 和四个认证页,并断言:
```powershell
$shellPath = Join-Path $root 'components/AuthPageShell.vue'
if (-not (Test-Path -LiteralPath $shellPath)) { throw 'AuthPageShell is missing' }
$shell = Get-Content -LiteralPath $shellPath -Raw -Encoding utf8
foreach ($required in @(
'class="auth-shell__header"',
'class="auth-shell__header-image"',
'a01-vnext-header-v1.png',
'mode="widthFix"',
'class="auth-shell__paper"',
'auth-page-paper.jpg',
'<slot />',
'<slot name="overlay" />',
'min-height: var(--app-viewport-height);'
)) { Assert-Contains $shell $required "AuthPageShell is missing: $required" }
foreach ($pageName in @('a01-entry.vue','a04-register.vue','a05-reset-password.vue','a06-auth-status.vue')) {
$page = Get-Content -LiteralPath (Join-Path $root "pages/auth/$pageName") -Raw -Encoding utf8
Assert-Contains $page '<AuthPageShell' "$pageName must consume AuthPageShell"
foreach ($forbidden in @('class="page-canvas"','class="page-backdrop"','mode="scaleToFill"','1665rpx')) {
Assert-NotContains $page $forbidden "$pageName retains rejected page coordinates: $forbidden"
}
}
```
- [ ] **Step 2: 验证 RED**
Run: `powershell -ExecutionPolicy Bypass -File tests/auth-page-shell-contract.ps1`
Expected: FAIL,提示 `AuthPageShell is missing`
- [ ] **Step 3: 提交失败合同**
Run: `git add tests/auth-page-shell-contract.ps1`,然后 `git commit -m "测试认证页共享自适应骨架"`
---
### Task 2: 提取骨架并无损迁移 A01
**Files:**
- Create: `components/AuthPageShell.vue`
- Modify: `pages/auth/a01-entry.vue`
- Test: `tests/auth-page-shell-contract.ps1`
- Test: `tests/a01-a02-ui-contract.ps1`
- Test: `tests/a01-responsive-runtime-smoke.js`
**Interfaces:**
- Produces: `<AuthPageShell><slot /><template #overlay>…</template></AuthPageShell>`
- Consumes: `--app-viewport-height``--app-safe-top``--app-safe-bottom`
- [ ] **Step 1: 创建最小共享组件**
组件模板固定为品牌头图、Logo、宣纸默认槽和根级 overlay 槽:
```vue
<template>
<view class="auth-shell">
<view class="auth-shell__header">
<image class="auth-shell__header-image" src="/static/assets/modules/auth/opaque/a01-vnext-header-v1.png" mode="widthFix" />
<image class="auth-shell__seal" src="/static/assets/foundation/transparent/brand-seal.png" mode="aspectFit" />
</view>
<view class="auth-shell__paper"><slot /></view>
<slot name="overlay" />
</view>
</template>
```
根、头图、Logo 和宣纸样式逐项迁入组件;Logo 使用 A01 已放行的 `top: calc(var(--app-safe-top) + clamp(46px, 11.5vw, 58px))``width: clamp(56px, 17vw, 78px)``height: clamp(67px, 20.4vw, 94px)`
- [ ] **Step 2: 迁移 A01 模板**
`AuthPageShell` 包住 `.login-content`,将验证层和 Toast 放入 `#overlay`。删除 A01 内已迁移到组件的 `.auth-page``.auth-header``.auth-header__image``.brand-seal``.auth-paper` 样式;登录业务和其余样式不动。
- [ ] **Step 3: 验证 GREEN**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/auth-page-shell-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a01-a02-ui-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a01-asset-alpha-audit.ps1
node tests/a01-responsive-runtime-smoke.js
git diff --check
```
Expected: 四项 PASSdiff check exit 0MuMu A01 默认密码态与已放行截图无可见回退。
- [ ] **Step 4: 提交骨架**
Run: `git add components/AuthPageShell.vue pages/auth/a01-entry.vue tests/a01-a02-ui-contract.ps1`,然后 `git commit -m "提取认证页共享自适应骨架"`
---
### Task 3: 用失败合同锁定 A04 自适应结构
**Files:**
- Modify: `tests/a04-registration-contract.ps1`
- Modify: `tests/a04-registration-runtime-smoke.js`
**Interfaces:**
- Consumes: `AuthPageShell`
- Produces: A04 正常流、自然滚动、六档宽度和 Toast 状态栏合同
- [ ] **Step 1: 替换旧视觉坐标断言**
删除要求旧背景、`184rpx × 221rpx` Logo 和固定画布的断言;增加 `AuthPageShell``.register-content` Flex 文档流、`--app-touch-min``var(--status-bar-height, 0px)` 断言,并禁止 `page-canvas``page-backdrop``scaleToFill``1665rpx`
- [ ] **Step 2: 扩展运行时尺寸**
运行数组统一为 `320×568``360×616``360×640``360×800``412×915``480×1040`。采集 `scrollWidth``scrollHeight`、头图自然尺寸和比例、paper/header 边界、最后登录入口底部;断言无横向溢出、头图为 `824:340`、短屏允许自然滚动且末项可达。
- [ ] **Step 3: 验证 RED 并提交**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/a04-registration-contract.ps1
node tests/a04-registration-runtime-smoke.js
```
Expected: 至少一项因 A04 仍使用旧画布而 FAIL。
Run: `git add tests/a04-registration-contract.ps1 tests/a04-registration-runtime-smoke.js`,然后 `git commit -m "测试A04注册页自适应结构"`
---
### Task 4: 将 A04 迁移为长表单文档流
**Files:**
- Modify: `pages/auth/a04-register.vue`
- Test: `tests/auth-page-shell-contract.ps1`
- Test: `tests/a04-registration-contract.ps1`
- Test: `tests/a04-registration-runtime-smoke.js`
**Interfaces:**
- Consumes: `AuthPageShell`
- Produces: A04 默认、错误、协议和 Toast 状态的自然流布局
- [ ] **Step 1: 替换模板骨架**
导入 `AuthPageShell`,删除 `page-canvas``page-backdrop`,将 `.register-content` 放入默认槽,将 Toast 放入 `#overlay`
- [ ] **Step 2: 写入页面自有布局**
`.register-content` 使用 `display:flex; flex:1; flex-direction:column; box-sizing:border-box; width:100%; max-width:480px; margin:0 auto; padding:clamp(10px,2.2vh,20px) clamp(24px,8.5vw,44px)`。标题、输入行、按钮、协议和返回登录均处于普通流;输入行和操作目标最小高度为 `var(--app-touch-min)`;删除只为旧画布服务的 `@media max-width:340px` 坐标补丁。
- [ ] **Step 3: 统一 Toast 安全区**
将 Toast 顶部改为:
```scss
top: calc(var(--status-bar-height, 0px) + 24rpx);
```
- [ ] **Step 4: 验证 GREEN**
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/auth-page-shell-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a04-registration-contract.ps1
node tests/a04-registration-runtime-smoke.js
git diff --check
```
Expected: 三项 PASSdiff check exit 0。
- [ ] **Step 5: MuMu 用户门与提交**
在 MuMu 展示 A04 默认空表单;用户确认后再展示空提交错误和 Toast。只有用户明确通过当前状态后,提交相关源码和测试,提交信息为 `迁移A04为自适应文档流`
---
### Task 5: 迁移 A05 并保留结果弹层滚动所有权
**Files:**
- Modify: `tests/a05-reset-password-contract.ps1`
- Modify: `tests/a05-reset-password-runtime-smoke.js`
- Modify: `pages/auth/a05-reset-password.vue`
**Interfaces:**
- Consumes: `AuthPageShell`
- Produces: A05 四字段长表单、Toast 和成功结果弹层
- [ ] **Step 1: 写失败合同并验证 RED**
静态和运行合同采用与 A04 相同的六档结构断言,额外保留获取验证码、密码不一致、成功层和返回 A01 行为;成功层必须使用 `max-height: calc(var(--app-viewport-height) - 40px)` 和内部唯一纵向滚动。
Run: `powershell -ExecutionPolicy Bypass -File tests/a05-reset-password-contract.ps1`
Expected: 因旧画布或缺少共享骨架而 FAIL。
- [ ] **Step 2: 实现并验证 GREEN**
`AuthPageShell` 包住 `.reset-content`overlay 槽承载成功层和 Toast;页面表单改为正常 Flex 文档流,Toast 使用状态栏高度,结果弹层保留 fixed overlay 与内部滚动。
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/auth-page-shell-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a05-reset-password-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a05-success-asset-contract.ps1
node tests/a05-reset-password-runtime-smoke.js
git diff --check
```
Expected: 四项 PASSdiff check exit 0。
- [ ] **Step 3: MuMu 用户门与提交**
依次展示默认、字段错误、Toast、成功弹层;用户明确通过后提交,提交信息为 `迁移A05为自适应文档流`
---
### Task 6: 同步封存 A06 源码但不恢复路由
**Files:**
- Modify: `tests/a06-auth-status-contract.ps1`
- Modify: `pages/auth/a06-auth-status.vue`
**Interfaces:**
- Consumes: `AuthPageShell`
- Produces: 与活动认证页一致的封存源码;`pages.json` 继续不含 A06
- [ ] **Step 1: 写失败合同并验证 RED**
删除旧背景和固定 Logo 断言,要求 `AuthPageShell` 且禁止旧画布;继续断言 `pages.json` 不包含 A06、runtime smoke 明确 SKIP。
Run: `powershell -ExecutionPolicy Bypass -File tests/a06-auth-status-contract.ps1`
Expected: 因 A06 尚未消费共享骨架而 FAIL。
- [ ] **Step 2: 实现、验证并提交**
迁移页面骨架和内容流,不改变状态配置、恢复弹层、返回逻辑或路由清单。
Run:
```powershell
powershell -ExecutionPolicy Bypass -File tests/auth-page-shell-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a06-auth-status-contract.ps1
node tests/a06-auth-status-runtime-smoke.js
git diff --check
```
Expected: 静态合同 PASSruntime 输出 `A06-AUTH-STATUS-RUNTIME-SMOKE SKIP archived route`diff check exit 0。
Run: `git add pages/auth/a06-auth-status.vue tests/a06-auth-status-contract.ps1`,然后 `git commit -m "同步封存A06自适应骨架"`
---
### Task 7: 更新记录并执行认证页总回归
**Files:**
- Modify: `docs/交接记录.md`
- Modify: `docs/验收规划.md`
**Interfaces:**
- Consumes: 用户逐状态 MuMu 结论
- Produces: 区分自动合同、当前 MuMu 状态与未验证真机的准确记录
- [ ] **Step 1: 只记录用户明确通过的状态**
A04、A05 未逐态确认的状态继续保持待审核;不得把共享骨架合同通过写成整页或功能通过。A06 继续标明封存且不计入活动页。
- [ ] **Step 2: 运行总回归**
```powershell
powershell -ExecutionPolicy Bypass -File tests/auth-page-shell-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a01-a02-ui-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a04-registration-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a05-reset-password-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/a06-auth-status-contract.ps1
node tests/a01-responsive-runtime-smoke.js
node tests/a04-registration-runtime-smoke.js
node tests/a05-reset-password-runtime-smoke.js
node tests/a06-auth-status-runtime-smoke.js
git diff --check
git status --short
```
Expected: 活动页合同和 runtime 全部 PASSA06 runtime 明确 SKIP;工作区只包含本阶段有意记录。
- [ ] **Step 3: 提交记录**
Run: `git add docs/交接记录.md docs/验收规划.md`,然后 `git commit -m "记录认证页安卓自适应验收"`