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

12 KiB
Raw Blame History

G01 添加家谱宣纸底部弹层实施计划

执行要求: 使用 superpowers:executing-plans 在当前会话内联执行;禁止多代理、worktree、git addcommitpushresetcheckout。步骤使用复选框跟踪。

目标: 以已选定视觉目标重做 G01“添加家谱”:删除完整卷轴背景和无效装饰,改为宣纸底面、顶部收边、关闭图标,并原样复用现有 AppButton 卷轴按钮。

架构: g01-my-genealogies.vue 继续独占当前弹层结构和交互;现有 AppButton.vue 不修改。新增一个真实透明关闭图标 PNG,弹层使用现有 page-paper.jpga01-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 状态或其他页面。
  • 三个入口继续调用 applyToJoinjoinByInvitecreateGenealogy,不对接接口。
  • 按钮必须直接复用现有 AppButtona01-scroll-primary-v3.pnga01-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 生成单独图标候选

附加选定视觉目标作为参考,使用以下完整提示:

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 解释器和技能脚本:

& '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;现有 AppButtonaddDialogVisiblecloseAddDialog() 和三个导航函数。

  • 产出:.add-dialog__paper.add-dialog__edge.add-dialog__edge-image.add-dialog__close-icon;切换弹层选择器和表现保持不变。

  • 步骤 1:先改契约,要求旧实现失败

在读取 $page 后隔离添加弹层模板,并使用 Base64 解码中文断言:

$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 -NoProfile -ExecutionPolicy Bypass -File tests/g01-visual-contract.ps1

预期:失败信息为 G-01 paper sheet is missing class="add-dialog__paper",不是语法、编码或文件缺失错误。

  • 步骤 3:最小替换添加弹层模板
<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*

.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 -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

预期:四个测试全部 PASSgit 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]