Files
jiapuapp/docs/superpowers/plans/2026-07-17-app-loading-red-seal-redesign.md
T
2026-07-20 06:52:33 +08:00

7.2 KiB
Raw Blame History

AppLoading 红金印牌重设计 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. 本项目明确禁止多代理、worktree、git addcommitpushresetcheckout

Goal: 将公共 AppLoading 的临时细线方框替换为已批准的红金家谱印牌加载视觉,并保持页面级、区域级调用契约不变。

Architecture: components/AppLoading.vue 继续作为唯一加载视觉所有者,页面只传入 varianttextdescription。组件复用 foundation 中的 brand-seal.pngauth-divider-knot.png,不让各业务页面重复定义加载资产或动画。

Tech Stack: uni-app、Vue 3 <script setup>、SCSS、PowerShell 契约测试、Chrome DevTools Protocol 截图脚本。

Global Constraints

  • 当前只做浅色国风主题,不接接口。
  • 不修改 G01 状态判断、文案、背景、头部或底部导航。
  • 不使用 CSS 绘制印章、SVG、emoji 或占位图形;只使用仓库内真实资产。
  • 不使用多代理或 worktree,不执行任何 Git 写操作。
  • 复用现有资产,不生成重复资产。
  • H5 截图仅为内部候选证据;Android/HBuilderX 仍需复核。

Task 1: 收紧公共加载视觉契约

Files:

  • Modify: tests/app-loading-contract.ps1
  • Test: tests/app-loading-contract.ps1

Interfaces:

  • Consumes: components/AppLoading.vue 的模板与 scoped SCSS。

  • Produces: 红金印牌、如意结、双尺寸和减弱动效的稳定契约。

  • Step 1: 写入失败契约

tests/app-loading-contract.ps1 中将旧方框尺寸与 1.35s 断言替换为以下要求:

Assert-Match -Content $component -Pattern 'class="app-loading__seal"\s+src="/static/assets/foundation/transparent/brand-seal\.png"' -Message 'AppLoading must render the approved real red-gold seal asset'
Assert-Match -Content $component -Pattern 'class="app-loading__knot"\s+src="/static/assets/foundation/transparent/auth-divider-knot\.png"' -Message 'AppLoading must render the approved real gold knot asset'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--page\s+\.app-loading__seal\s*\{[^}]*width:\s*132rpx;[^}]*height:\s*136rpx;' -Message 'AppLoading page seal must use the approved size'
Assert-Match -Content $component -Pattern '(?s)\.app-loading--section\s+\.app-loading__seal\s*\{[^}]*width:\s*88rpx;[^}]*height:\s*90rpx;' -Message 'AppLoading section seal must use the approved size'
Assert-Match -Content $component -Pattern 'app-loading-seal-breathe\s+1\.6s' -Message 'AppLoading seal must use the approved restrained breathing rhythm'
Assert-Match -Content $component -Pattern '@media\s*\(prefers-reduced-motion:\s*reduce\)' -Message 'AppLoading must respect reduced-motion preferences'
if ($component -match 'app-loading__mark|border:\s*4rpx\s+double') { throw 'AppLoading must not retain the legacy CSS box mark' }
  • Step 2: 运行失败测试

Run: powershell -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1

Expected: FAIL,首个错误为缺少 brand-seal.png 真实印牌。

Task 2: 实现红金印牌公共加载组件

Files:

  • Modify: components/AppLoading.vue
  • Test: tests/app-loading-contract.ps1

Interfaces:

  • Consumes: /static/assets/foundation/transparent/brand-seal.png/static/assets/foundation/transparent/auth-divider-knot.png

  • Produces: 调用方式不变的 AppLoading 页面级与区域级视觉。

  • Step 1: 替换模板主体

将旧 .app-loading__mark 替换为:

<view class="app-loading__emblem" aria-hidden="true">
  <image class="app-loading__seal" src="/static/assets/foundation/transparent/brand-seal.png" mode="aspectFit" />
  <image class="app-loading__knot" src="/static/assets/foundation/transparent/auth-divider-knot.png" mode="aspectFit" />
</view>
  • Step 2: 写入最小视觉实现

使用以下边界实现,不改变 props

.app-loading__emblem { display: flex; flex-direction: column; align-items: center; }
.app-loading__seal { animation: app-loading-seal-breathe 1.6s ease-in-out infinite; }
.app-loading__knot { margin-top: 8rpx; opacity: .72; animation: app-loading-knot-breathe 1.6s ease-in-out infinite; }
.app-loading--page .app-loading__seal { width: 132rpx; height: 136rpx; }
.app-loading--page .app-loading__knot { width: 56rpx; height: 18rpx; }
.app-loading--section .app-loading__seal { width: 88rpx; height: 90rpx; }
.app-loading--section .app-loading__knot { width: 42rpx; height: 14rpx; margin-top: 5rpx; }
@keyframes app-loading-seal-breathe { 0%, 100% { opacity: .82; transform: scale(.96); } 50% { opacity: 1; transform: scale(1); } }
@keyframes app-loading-knot-breathe { 0%, 100% { opacity: .44; } 50% { opacity: .76; } }
@media (prefers-reduced-motion: reduce) { .app-loading__seal, .app-loading__knot { animation: none; opacity: 1; transform: none; } }
  • Step 3: 调整文字间距

页面级主文案从印牌组合下方 22rpx 开始,区域级从 14rpx 开始;保留页面级 30rpx/24rpx 与区域级 24rpx/22rpx 字号。

  • Step 4: 运行契约测试

Run: powershell -ExecutionPolicy Bypass -File tests/app-loading-contract.ps1

Expected: APP-LOADING-CONTRACT PASS

Task 3: 回归所有接入页面并完成视觉证据

Files:

  • Verify: pages/genealogy/g01-my-genealogies.vue
  • Verify: pages/genealogy/g06-search-genealogies.vue
  • Verify: tests/g01-loading-state-contract.ps1
  • Verify: tests/g-series-app-loading-contract.ps1
  • Verify: tests/module-app-loading-contract.ps1
  • Create: docs/design/screens/runtime/2026-07-17/03-g01-loading-red-seal-412x900.png

Interfaces:

  • Consumes: 更新后的 AppLoading 公共视觉。

  • Produces: 同一浏览器中的 G01 页面级与 G06 区域级回归证据。

  • Step 1: 运行加载契约和编译审计

Run:

powershell -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/g-series-app-loading-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/module-app-loading-contract.ps1
powershell -ExecutionPolicy Bypass -File tests/compile-audit.ps1

Expected: 四项均输出 PASS

  • Step 2: 在同一个可控 Chrome 标签页截图 G01

Run:

node scripts/capture-chrome-page.js "http://localhost:5173/#/pages/genealogy/g01-my-genealogies?state=loading" ".state-panel--loading" "docs/design/screens/runtime/2026-07-17/03-g01-loading-red-seal-412x900.png" 412 900

Expected: 输出 CAPTURED,页面只有一个 Chrome 标签并显示红金印牌加载状态。

  • Step 3: 检查四档响应式尺寸

分别使用 320×568360×640360×800412×915 运行同一截图命令,确认印牌、文字和底栏无裁切、无横向滚动。

  • Step 4: 运行差异检查

Run: git diff --check -- components/AppLoading.vue tests/app-loading-contract.ps1

Expected: 退出码 0;允许 Git 报告现有 LF/CRLF 提示,不允许空白错误。

Execution Choice

按用户最新授权选择 Inline Execution:在当前会话使用 superpowers:executing-plans 顺序执行。由于用户明确禁止,不创建 worktree、不使用子代理、不执行提交。