Review changes batch 6 of 6

This commit is contained in:
2026-07-20 06:52:33 +08:00
parent db97d3da27
commit 5a31a75da0
160 changed files with 9206 additions and 572 deletions
@@ -0,0 +1,149 @@
# AppLoading 红金印牌重设计 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans` to 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` 断言替换为以下要求:
```powershell
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` 替换为:
```vue
<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:
```scss
.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
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:
```powershell
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、不使用子代理、不执行提交。