Files
jiapuapp/docs/superpowers/plans/2026-07-19-g01-add-genealogy-paper-sheet.md
T
2026-07-20 06:52:26 +08:00

217 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# G01 添加家谱宣纸底部弹层实施计划
> **执行要求:** 使用 `superpowers:executing-plans` 在当前会话内联执行;禁止多代理、worktree、`git add`、`commit`、`push`、`reset` 和 `checkout`。步骤使用复选框跟踪。
**目标:** 以已选定视觉目标重做 G01“添加家谱”:删除完整卷轴背景和无效装饰,改为宣纸底面、顶部收边、关闭图标,并原样复用现有 `AppButton` 卷轴按钮。
**架构:** `g01-my-genealogies.vue` 继续独占当前弹层结构和交互;现有 `AppButton.vue` 不修改。新增一个真实透明关闭图标 PNG,弹层使用现有 `page-paper.jpg``a01-paper-transition-v1.png`,切换家谱弹层仍使用原居中卷轴结构。
**技术栈:** uni-app、Vue 3 `<script setup>`、SCSS、现有 `AppButton`、PowerShell 契约测试、Chrome DevTools Protocol 9222、内置 Image Gen。
## 全局约束
- 唯一视觉目标:`docs/design/mockups/2026-07-19/g01-add-dialog-paper-sheet-target.png`
- 只修改 G01“添加家谱”弹层,不修改切换家谱弹层、其他 G01 状态或其他页面。
- 三个入口继续调用 `applyToJoin``joinByInvite``createGenealogy`,不对接接口。
- 按钮必须直接复用现有 `AppButton``a01-scroll-primary-v3.png``a01-scroll-secondary-v3.png`;不得生成、重绘或近似实现按钮皮肤。
- 不删除任何现有资产文件、历史截图、测试或文档;只删除当前 G01 添加弹层内已经失去引用的模板节点和专用样式。
- 只复用当前 9222 Chrome 窗口和唯一项目标签页。
- 不执行 Git 暂存、提交、推送、重置或检出。
- H5 截图只作为候选证据;Android/HBuilderX 仍为未验证。
- 没有用户明确“通过”,不得切换下一状态、冻结 G01 或更新为 `[x]`
---
### 任务 1:生成并验证真实关闭图标资产
**文件:**
- 参考:`docs/design/mockups/2026-07-19/g01-add-dialog-paper-sheet-target.png`
- 创建候选:`docs/design/assets/candidates/2026-07-19/g01-dialog-close-source-green.png`
- 创建成品:`static/assets/modules/genealogy/transparent/g01-dialog-close.png`
**接口:**
- 产出:带透明通道的朱砂细线关闭图标 PNG;后续模板只通过 `/static/assets/modules/genealogy/transparent/g01-dialog-close.png` 使用。
- [ ] **步骤 1:用内置 Image Gen 生成单独图标候选**
附加选定视觉目标作为参考,使用以下完整提示:
```text
Use case: background-extraction
Asset type: mobile UI close icon
Primary request: Create one standard close icon matching the selected G01 bottom-sheet mockup: two thin diagonal cinnabar-red ink strokes, balanced and optically centered, no circle, no label, no shadow, no texture inside the strokes.
Scene/backdrop: perfectly flat solid #00ff00 chroma-key background.
Composition: square canvas, icon centered, icon occupies about 34% of canvas width, generous equal padding.
Constraints: one icon only; crisp antialiased edges; no text; no watermark; no extra decoration; do not use #00ff00 in the icon.
```
将工具返回的原始图片复制为 `docs/design/assets/candidates/2026-07-19/g01-dialog-close-source-green.png`,保留原始生成文件。
- [ ] **步骤 2:移除色键并保留真实透明通道**
使用已安装的绝对 Python 解释器和技能脚本:
```powershell
& 'C:\Users\Rain\AppData\Local\Python\bin\python.exe' 'C:\Users\Rain\.codex\skills\.system\imagegen\scripts\remove_chroma_key.py' --input 'docs\design\assets\candidates\2026-07-19\g01-dialog-close-source-green.png' --out 'static\assets\modules\genealogy\transparent\g01-dialog-close.png' --auto-key border --soft-matte --transparent-threshold 12 --opaque-threshold 220 --despill
```
预期:命令退出码为 0,生成文件存在且非空。若依赖缺失,停止并报告,不安装新依赖、不切换到 CLI 图片模型。
- [ ] **步骤 3:检查图标成品**
`view_image` 打开成品,并用 `System.Drawing.Image` 确认 `PixelFormat` 包含 `Alpha`。拒绝绿色边缘、多余文字、圆圈、阴影或多图标输出;不从效果图裁切替代。
---
### 任务 2:用失败契约锁定宣纸结构和现有按钮
**文件:**
- 修改:`tests/g01-visual-contract.ps1`
- 修改:`pages/genealogy/g01-my-genealogies.vue`
- 不修改:`components/AppButton.vue`
**接口:**
- 消费:任务 1 的 `g01-dialog-close.png`;现有 `AppButton``addDialogVisible``closeAddDialog()` 和三个导航函数。
- 产出:`.add-dialog__paper``.add-dialog__edge``.add-dialog__edge-image``.add-dialog__close-icon`;切换弹层选择器和表现保持不变。
- [ ] **步骤 1:先改契约,要求旧实现失败**
在读取 `$page` 后隔离添加弹层模板,并使用 Base64 解码中文断言:
```powershell
$addMarkup = [regex]::Match($page, '(?s)<view v-if="addDialogVisible".*?<view v-if="switcherVisible"').Value
if (-not $addMarkup) { throw 'G-01 add sheet markup could not be isolated.' }
foreach ($token in @(
'class="add-dialog__paper"',
'page-paper.jpg',
'class="add-dialog__edge"',
'a01-paper-transition-v1.png',
'class="add-dialog__close-icon"',
'g01-dialog-close.png',
'aria-label="关闭"'
)) {
if ($addMarkup -notmatch [regex]::Escape($token)) { throw "G-01 paper sheet is missing $token" }
}
if ($addMarkup -match 'a01-scroll-dialog-v3\.png') { throw 'G-01 add sheet still uses the rejected complete dialog frame.' }
if ($addMarkup -match '>关闭</view>|>取消</view>') { throw 'G-01 add sheet still renders a text close control.' }
foreach ($token in @('label="搜索家谱"', 'label="邀请码加入"', 'label="继续创建家谱"')) {
if ($addMarkup -notmatch [regex]::Escape($token)) { throw "G-01 add sheet no longer reuses AppButton action $token" }
}
if ($page -match '(?s)\.add-dialog\s+\.app-button\s*\{') { throw 'G-01 add sheet must not restyle the existing AppButton.' }
```
在实际 PowerShell 文件中将“关闭、取消、搜索家谱、邀请码加入、继续创建家谱”通过 UTF-8 Base64 解码构造,避免 Windows PowerShell 5 脚本编码误读。
- [ ] **步骤 2:运行契约并确认 RED**
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
```
预期:失败信息为 `G-01 paper sheet is missing class="add-dialog__paper"`,不是语法、编码或文件缺失错误。
- [ ] **步骤 3:最小替换添加弹层模板**
```vue
<view v-if="addDialogVisible" class="add-dialog-layer" @click="closeAddDialog">
<view class="add-dialog" @click.stop>
<image class="add-dialog__paper" src="/static/assets/foundation/opaque/page-paper.jpg" mode="aspectFill" />
<view class="add-dialog__edge" aria-hidden="true">
<image class="add-dialog__edge-image" src="/static/assets/modules/auth/transparent/a01-paper-transition-v1.png" mode="widthFix" />
</view>
<view class="add-dialog__content">
<view class="add-dialog__heading">
<text class="dialog-title">添加家谱</text>
<text class="dialog-copy">建议先搜索已有家谱避免重复创建</text>
</view>
<view class="add-dialog__close" role="button" aria-label="关闭" hover-class="action-hover" @click="closeAddDialog">
<image class="add-dialog__close-icon" src="/static/assets/modules/genealogy/transparent/g01-dialog-close.png" mode="aspectFit" />
</view>
<AppButton block label="搜索家谱" @click="applyToJoin" />
<AppButton block type="secondary" label="邀请码加入" @click="joinByInvite" />
<AppButton block type="secondary" label="继续创建家谱" @click="createGenealogy" />
</view>
</view>
</view>
```
- [ ] **步骤 4:最小替换添加弹层专用样式**
保留 `.genealogy-switcher-*``.dialog-close` 规则,只替换 `.add-dialog*`
```scss
.add-dialog-layer { position: fixed; z-index: 40; inset: 0; display: flex; align-items: flex-end; justify-content: center; box-sizing: border-box; background: rgba(34, 20, 12, 0.68); }
.add-dialog { position: relative; width: 100%; max-height: calc(100vh - 80rpx); }
.add-dialog__paper { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.add-dialog__edge { position: absolute; z-index: 1; top: -50rpx; right: 0; left: 0; height: 92rpx; overflow: hidden; pointer-events: none; }
.add-dialog__edge-image { position: absolute; right: 0; bottom: 0; left: 0; width: 100%; }
.add-dialog__content { position: relative; z-index: 2; display: flex; max-height: calc(100vh - 80rpx); flex-direction: column; align-items: stretch; box-sizing: border-box; padding: 44rpx 52rpx calc(34rpx + env(safe-area-inset-bottom)); overflow-y: auto; }
.add-dialog__heading { padding-right: 96rpx; }
.add-dialog .dialog-title,
.add-dialog .dialog-copy { display: block; text-align: left; }
.add-dialog__close { position: absolute; z-index: 3; top: 22rpx; right: 30rpx; display: flex; width: 80rpx; height: 80rpx; align-items: center; justify-content: center; }
.add-dialog__close-icon { width: 36rpx; height: 36rpx; }
.add-dialog__content > .app-button:first-of-type { margin-top: 20rpx; }
.add-dialog__content > .app-button + .app-button { margin-top: 6rpx; }
```
删除被否决实现专用的 `.add-dialog__skin`、标题左偏移、关闭文字颜色字号、`right: 120rpx`、固定 `545rpx` 高度和 `.add-dialog .app-button` 覆盖;不删除共享或切换弹层样式。
- [ ] **步骤 5:运行契约并确认 GREEN**
运行步骤 2,预期输出:`PASS G-01 visual contract`
---
### 任务 3:聚焦回归与唯一标签页视觉验证
**文件:**
- 验证:`pages/genealogy/g01-my-genealogies.vue`
- 验证:`tests/g01-visual-contract.ps1`
- 验证:`tests/g01-empty-state-contract.ps1`
- 验证:`tests/g01-loading-state-contract.ps1`
- 验证:`tests/g01-error-state-contract.ps1`
- 生成候选:`docs/design/screens/runtime/2026-07-19/g01-approval/05-add-dialog-paper-sheet-412x915.png`
**接口:**
- 消费:5173 H5、9222 唯一项目标签页、G01 当前添加弹层。
- 产出:当前状态候选截图和真实运行时几何/交互证据;不改变审批勾选状态。
- [ ] **步骤 1:运行全部聚焦契约**
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-loading-state-contract.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File tests/g01-error-state-contract.ps1
git diff --check -- pages/genealogy/g01-my-genealogies.vue tests/g01-visual-contract.ps1 docs/superpowers/specs/2026-07-19-g01-add-genealogy-bottom-sheet-design.md docs/superpowers/plans/2026-07-19-g01-add-genealogy-paper-sheet.md
```
预期:四个测试全部 `PASS``git diff --check` 退出码 0。不得放宽任何既有阈值。
- [ ] **步骤 2:确认运行环境约束**
只读检查 5173、9222 和 `/json/list`。预期:5173 HTTP 200;恰好一个 `localhost:5173` 项目页;不启动新 Chrome。
- [ ] **步骤 3:仅检查当前弹层的两档几何**
在同一标签页保持 G01“添加家谱”打开,依次检查 320×568 和 412×915:弹层底边贴合视口;无横向溢出;标题、说明、关闭图标及三个按钮全部可见且互不遮挡;关闭触控区至少 `80rpx × 80rpx`;页面内仍有且只有三个现有 `.app-button`
- [ ] **步骤 4:检查交互并恢复 412×915**
点击弹层内部不得关闭;点击关闭图标应关闭;重新打开后点击遮罩应关闭;再打开后列表滚动位置不变。最后恢复 412×915,并保持添加弹层打开。
- [ ] **步骤 5:截取并检查原图**
通过当前 CDP `Page.captureScreenshot` 保存候选,使用 `view_image` 打开原图。拒绝矩形硬边、顶部收边裁坏、纸面接缝、关闭图标绿色边缘、按钮被重绘、文字裁切、空白过大或后方信息压不住。
- [ ] **步骤 6:交回当前状态审批**
只报告真实测试和 H5 证据,明确 Android/HBuilderX 未验证。等待用户明确“通过”,不得切换到“切换家谱弹层”,不得更新 G01 为 `[x]`