7.2 KiB
AppLoading 红金印牌重设计 Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use
superpowers:executing-plansto implement this plan task-by-task. 本项目明确禁止多代理、worktree、git add、commit、push、reset和checkout。
Goal: 将公共 AppLoading 的临时细线方框替换为已批准的红金家谱印牌加载视觉,并保持页面级、区域级调用契约不变。
Architecture: components/AppLoading.vue 继续作为唯一加载视觉所有者,页面只传入 variant、text 和 description。组件复用 foundation 中的 brand-seal.png 与 auth-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×568、360×640、360×800、412×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、不使用子代理、不执行提交。