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

13 KiB
Raw Blame History

认证页自适应迁移 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-canvaspage-backdrop、整页 scaleToFill1665rpx 固定画布或交互内容整页叠层。
  • 共享骨架只拥有背景、视口与安全区,不接收页面编号或业务配置。
  • 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 和四个认证页,并断言:

$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 槽:

<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 -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-minvar(--status-bar-height, 0px) 断言,并禁止 page-canvaspage-backdropscaleToFill1665rpx

  • Step 2: 扩展运行时尺寸

运行数组统一为 320×568360×616360×640360×800412×915480×1040。采集 scrollWidthscrollHeight、头图自然尺寸和比例、paper/header 边界、最后登录入口底部;断言无横向溢出、头图为 824:340、短屏允许自然滚动且末项可达。

  • Step 3: 验证 RED 并提交

Run:

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-canvaspage-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 顶部改为:

top: calc(var(--status-bar-height, 0px) + 24rpx);
  • Step 4: 验证 GREEN

Run:

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-contentoverlay 槽承载成功层和 Toast;页面表单改为正常 Flex 文档流,Toast 使用状态栏高度,结果弹层保留 fixed overlay 与内部滚动。

Run:

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 -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 routediff 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 -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 "记录认证页安卓自适应验收"