# 消息通知设置 · 设计说明（notifications.vue）

> 单元：`notifications` ｜ group=account ｜ P 依据：P13 工具区「消息通知设置」+ §0.5 订阅三时机
> 实现：`vue/src/pages/notifications.vue` ｜ 组状态帧 fixtures：`design/fixtures/account.states.json`

## 1. 区块与密度对照

| 区块 | 实现落点 | 密度 | 达成 |
|---|---|---|---|
| ① 交易提醒组 | 出价被超（开关）/中标待支付（**禁用灰显**+「关键交易提醒，不可关闭」）/发货物流（开关） | **开关 6（≥6）** | ✓ |
| ② 圈子互动组 | 评论回复（开）/点赞（关，notifySettings.circle.like=false 初值） | — | ✓ |
| ③ 系统公告 | 单开关（notifySettings.system） | — | ✓ |
| ④ 订阅授权状态行 | subscribeGranted=false →「未开启」+「去开启」按钮；说明「拒绝后站内消息中心兜底」（§0.5 双端价值） | — | ✓ |

## 2. 状态帧

| 帧 | 渲染 |
|---|---|
| normal | 三组开关+订阅授权行（初值=notifySettings） |
| loading | SkeletonList×3 |
| error | ErrorRetry「通知设置保存失败，已回滚」+回滚动作（快照恢复示意） |
| guest | EmptyState→login（必登录） |
| empty/extreme | N/A（na_reason：纯开关设置页无列表/无极端位） |

## 3. 九维 A–I

- **A**：差异=开关组；订阅授权两态（已开启/未开启）。
- **B**：开关禁用态（中标待支付灰显+禁用原因文字，dims B）；开关即时切换+toast（示意 POST）。
- **C**：N/A（开关非文本表单，na_reason）。
- **D**：N/A（无数据位）。
- **E**：授权弹层链路（去开启→notify 示意拉起）。
- **F**：订阅三时机 §0.5（出价被超/中标/审核通过），拒绝→站内消息中心兜底（状态行明示）。
- **G**：N/A（轻页面，na_reason）。
- **H**：开关状态双通道（底色+滑块位置）；禁用态 45% 透明+说明文字（不只靠颜色）。
- **I**：`GET/POST /user/notify-settings`（占位）。

## 4. 决策点

| 决策触点 | 对应 |
|---|---|
| 关键交易提醒不漏（被超/中标） | 交易组置顶+中标待支付不可关+订阅授权兜底说明 |

## 5. 占位

- 开关初值=notifySettings 示意；「保存失败回滚」为 error 帧语义演示（原型快照恢复）。

## 7. 视觉验收修复轮（2026-10-10）

| 验收问题 | 处置 | 落点 |
|---|---|---|
| [A] device-393.png 右缘裁 18px | **组内修不掉，已记录升级**：render.py:87 viewport 恒 375×812，?w=393 舞台被裁（fixtures `pipeline_issues P-1`）；DOM 几何已验证 393 舞台无溢出（embed393 pg=852） | scripts/render.py（底座） |
| [B] 「中标待支付」开关视觉关闭态与 aria-checked/fixture 矛盾 | 已修：补 `:class="{ on: sw.trade.win }"`，粉底+滑块右+禁用灰显三通道一致 | notifications.vue 交易组 |
| [C] 披露行两端贴屏边 | 已修：`.disc` 补水平内边距 | notifications.vue |
| [C] error 帧整页隐藏开关列表，违背 §0.4「错误保留缓存」 | 已修：error 帧黄条+开关列表同屏（快照值） | notifications.vue 渲染分支 |

### 2026-10-10 复验勘误与真修

上表 [C] 行当时标注「已修」与实现不符（复验发现仍是 v-if/v-else 互斥链，error 帧只剩黄条、开关列表整页隐藏）。本轮真修：渲染链改为 `ErrorRetry v-if=error`＋`SkeletonList v-if=loading`＋开关列表 `v-if=state!=='loading'`——error 帧黄条与缓存开关列表同帧（states.png 重拍：6 开关含 1 禁用，on/off/disabled 与 normal 快照一致）。断言入 scripts/repair_capture.py（errBar+cards≥4+sw=6+disabled=1）。
