9.0 KiB
N01 消息中心基准页 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: 将 N01 重做为 N 系列消息中心视觉基准,并完成列表、已读、全部已读、加载、空、失败和审核跳转的 H5 审批状态。
Architecture: pages/notification/n01-message-center.vue 单独拥有本地演示数据、状态与交互;项目现有 PageHeader、AppButton、AppLoading、AppToast 和 ModulePageBackground 继续作为公共组件。N01 使用本模块独立的透明位图线框,不再引用家谱申请业务卡片。
Tech Stack: uni-app、Vue 3 <script setup>、SCSS、PowerShell 契约测试、Node CDP 运行时冒烟。
Global Constraints
- 只处理 N01,不对接接口,不修改 N02 或其他模块页面。
- 不使用子代理或 worktree。
- 不执行
git add、commit、push、reset或checkout。 - 保留当前全部已修改、未跟踪和忽略文件。
- 所有 Toast、Loading 和按钮使用项目自定义组件。
- 每次只向用户展示一个状态;用户全部明确“通过”后才标记 N01 为
[x]。 - Android/HBuilderX 仍未验证,H5 截图只作为内部候选证据。
Task 1: 锁定 N01 独立页面契约
Files:
- Create:
tests/n01-module-baseline-contract.ps1 - Modify:
pages/notification/n01-message-center.vue
Interfaces:
-
Consumes:
AppButton、AppLoading、AppToast、ModulePageBackground、PageHeader。 -
Produces: 可由
?state=loading|empty|error复现的 N01 页面,以及.notice-state--list、.notice-state--loading、.notice-state--empty、.notice-state--errorDOM 状态类。 -
Step 1: 写入失败契约
$source = Get-Content 'pages/notification/n01-message-center.vue' -Raw -Encoding UTF8
$required = @(
'n01-notice-card.png', 'AppLoading', 'AppToast',
'notice-state--loading', 'notice-state--list',
'notice-state--empty', 'notice-state--error',
'未读', '已读', '全部已读', '前往入谱审核'
)
foreach ($token in $required) {
if (-not $source.Contains($token)) { throw "N01 missing contract token: $token" }
}
if ($source.Contains('application-status-card.png')) {
throw 'N01 must not reuse the genealogy application card'
}
Write-Output 'N01-MODULE-BASELINE-CONTRACT PASS'
- Step 2: 运行契约并确认 RED
Run: powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/n01-module-baseline-contract.ps1
Expected: FAIL,至少指出缺少 n01-notice-card.png 或仍引用 application-status-card.png。
- Step 3: 只添加后续实现所需状态类和资产引用,保持测试继续驱动页面实现
将根节点状态类补齐为:
<view class="notice-page" :class="`notice-state--${noticeState}`">
资产引用统一为:
<image src="/static/assets/modules/notification/transparent/n01-notice-card.png" mode="scaleToFill" />
Task 2: 制作 N01 透明消息线框资产
Files:
- Create:
static/assets/modules/notification/transparent/n01-notice-card.png - Preserve:
tmp/imagegen/下的生成源图与后处理证据。
Interfaces:
-
Produces: 约 3:1 比例、四角透明、无文字无底色的古金色消息卡线框 PNG。
-
Step 1: 用内置 ImageGen 生成可抠色源图
Prompt:
Use case: ui-mockup
Asset type: scalable message-list card frame for a Chinese genealogy mobile app
Primary request: a restrained traditional Chinese archival card border made only from thin antique-gold linework
Style/medium: refined Song/Yuan inspired ornamental line art, visually consistent with the existing R01 transparent person card
Composition/framing: wide horizontal 3:1 frame, symmetrical corners, quiet center, generous inner text area
Scene/backdrop: perfectly flat solid #00ff00 chroma-key background inside and outside the border
Constraints: no fill panel, no paper texture, no white background, no red marks, no bell icon, no text, no badge, no shadow, no watermark; do not use #00ff00 in the ornament
- Step 2: 使用 imagegen 技能自带抠色脚本输出透明 PNG
Run:
& 'C:\Users\Rain\AppData\Local\Python\bin\python.exe' 'C:\Users\Rain\.codex\skills\.system\imagegen\scripts\remove_chroma_key.py' --input 'tmp/imagegen/n01-notice-card-chroma.png' --out 'static/assets/modules/notification/transparent/n01-notice-card.png' --auto-key border --soft-matte --transparent-threshold 12 --opaque-threshold 220 --despill
- Step 3: 检查资产透明度和边缘
Run:
& 'C:\Users\Rain\AppData\Local\Python\bin\python.exe' -c "from PIL import Image; p='static/assets/modules/notification/transparent/n01-notice-card.png'; im=Image.open(p); assert im.mode=='RGBA'; a=im.getchannel('A'); assert a.getpixel((0,0))==0; assert a.getbbox(); print('N01-ASSET-ALPHA PASS', im.size)"
Expected: N01-ASSET-ALPHA PASS。
Task 3: 实现 N01 列表与审批状态
Files:
- Modify:
pages/notification/n01-message-center.vue - Test:
tests/n01-module-baseline-contract.ps1
Interfaces:
-
readNotice(item):把单条item.unread设为false。 -
markAllRead():把全部消息设为已读,并显示“已全部标记为已读”自定义 Toast。 -
restoreList():把错误态恢复为列表态。 -
toReview():保留/pages/genealogy/g10-application-review?genealogyId=...路由。 -
Step 1: 将模板整理为四个明确分支
<AppLoading v-if="noticeState === 'loading'" text="正在整理消息" description="请稍候,正在同步家谱申请与家族提醒。" />
<view v-else-if="noticeState === 'list'" class="notice-list">...</view>
<view v-else class="notice-state-card">...</view>
列表卡片需使用以下文字层级:
<text class="notice-card__status" :class="{'is-unread': item.unread}">{{ item.unread ? '未读提醒' : '已读' }} · {{ item.time }}</text>
<text class="notice-card__title">{{ item.title }}</text>
<text class="notice-card__summary">{{ item.content }}</text>
- Step 2: 统一空态与失败态操作
<AppButton
block
:type="noticeState === 'error' ? 'secondary' : 'primary'"
:label="noticeState === 'error' ? '重新查看' : '前往入谱审核'"
@click="noticeState === 'error' ? restoreList() : toReview()"
/>
- Step 3: 让卡片自适应内容并移除白底来源
.notice-content { padding: 24rpx 28rpx 100rpx; }
.notice-list { display: flex; flex-direction: column; gap: 18rpx; }
.notice-card { position: relative; min-height: 220rpx; }
.notice-card__skin { position: absolute; inset: 0; width: 100%; height: 100%; }
.notice-card__copy { position: relative; z-index: 1; padding: 34rpx 44rpx; }
.notice-card__status { color: $ink-muted; }
.notice-card__status.is-unread { color: $brand-red; font-weight: 700; }
.notice-card__title { margin-top: 8rpx; color: $ink; font-family: STKaiti, KaiTi, serif; font-weight: 700; }
.notice-review-action { margin: 30rpx auto 0; }
- Step 4: 运行聚焦契约并确认 GREEN
Run: powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/n01-module-baseline-contract.ps1
Expected: N01-MODULE-BASELINE-CONTRACT PASS。
Task 4: 运行时验证并进入逐状态审批
Files:
- Create:
docs/design/screens/runtime/2026-07-19/n01-review/*.png - Modify only after all explicit approvals:
docs/验收规划.md
Interfaces:
-
Consumes: 单个现有 Chrome 项目标签页和调试端口 9222。
-
Produces: 412×915 的逐状态审批画面,以及四档响应式内部证据。
-
Step 1: 运行静态和运行时检查
Run:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/n01-module-baseline-contract.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File tests/root-pages-visual-contract.ps1
node tests/root-pages-runtime-smoke.js
node tests/module-series-responsive-runtime-smoke.js
git diff --check
Expected: 所有测试输出 PASS;git diff --check 退出码为 0,允许已有行尾提示。
- Step 2: 复用同一标签页显示 412×915 正常列表态
Run:
node scripts/capture-chrome-page.js 'http://localhost:5173/#/pages/notification/n01-message-center' '.notice-state--list' 'docs/design/screens/runtime/2026-07-19/n01-review/01-list-412x915.png' 412 915
Inspect: 打开保存的截图,确认没有白底块、裁切、错误页面或半加载内容,再等待用户审批。
- Step 3: 按顺序展示其余状态
顺序:单条已读 → 全部已读 Toast → 加载 → 空 → 失败 → 审核跳转。每次只显示一个状态并等待用户确认。
- Step 4: 内部检查四档尺寸
尺寸:320×568、360×640、360×800、412×915。发现问题只返工 N01;未发现问题不逐档打断用户。
- Step 5: 所有状态明确通过后更新审批记录
仅把 docs/验收规划.md 的 N01 行从 [~] 改为 [x],随后重新运行 Task 4 Step 1 的全部验证。