# P04 出价弹层及二次确认 · 设计说明（bid-sheet.vue）

> 单元：`bid-sheet` ｜ group=core ★★★ ｜ P04（挂载 P03 的半屏弹层，独立成单元）｜ 依据：pages.json unit#4 + 规格表 P04 + 执行方案 §5.4
> 实现：`vue/src/pages/bid-sheet.vue` ｜ 状态帧 fixtures：`design/fixtures/bid-sheet.states.json`

## 1. 页面形态与区块（7 区块硬指标）

页面=overlay：背景为压暗的拍品详情首屏示意（gallery .ph+标题+当前价+倒计时），**弹层本体=验收主体**（Sheet 恒开，`lockMask=true`：遮罩点击不关闭，仅「×」/「取消」——与 publish-sheet 可点遮罩形成对照差异，两处组件注释互指）。

| # | 区块 | 实现落点 | 达成 |
|---|---|---|---|
| ① | 拍品缩略行 | 图（wulu-figure-banner，item-card-cover 语义槽）+标题单行+PriceText 当前价（**金额只渲染此一处**） | ✓ |
| ② | 保证金余额行 | users.me.balance=128.60；nodeposit 帧红字 0.00+「去缴纳」（toast 占位） | ✓ |
| ③ | 金额输入框 | digit 键盘（inputmode=decimal），默认=当前价+加价幅度=466（data 推导非字面量）；confirm/submitting 只读 | ✓ |
| ④ | 快捷档胶囊 | +1档/+2档/+5档（onQuick=当前价+n×幅度→466/476/506）+「每档 ¥10.00」标注 | **3 档** ✓ |
| ⑤ | 最低出价提示行 | 「最低出价 ¥466.00 = 当前价 + 加价幅度」；低于时实时转红「至少 ¥466.00」+输入框红描边（FormField error） | ✓ |
| ⑥ | 确认出价主按钮 | AppButton block；submitting=loading 锁；nodeposit/norealname 禁用（禁用原因由 warline 说明） | ✓ |
| ⑦ | 违约提示小字 | 「出价后需按价付款；中标不付款将扣信用/保证金【占位规则】」 | ✓ |

## 2. 状态机（A 维：normal→confirm→submitting→success/outbid，失败不关弹层）

| 帧 | 渲染 | 验证点 |
|---|---|---|
| normal | 表单默认 466 | 最低价提示灰字 |
| confirm | 二次确认弹窗盖在弹层上：「出价后需按价付款，确认出价 ¥466.00？」+再想想/确认出价；输入只读 | 金额与输入一致 |
| submitting | 按钮「出价中…」转圈锁点；快捷档 disabled | 防连点成帧 |
| success | okline「出价成功，当前为你领先」+缩略行绿 Pill「领先」+按钮转「已领先，返回详情」；帧内不关层（随后回 item 刷新） | success 语义 |
| outbid | errline「已被超出，当前价已刷新至 ¥476.00」+缩略行当前价刷新为 **476（=456+2×10，对手出价必然高于我方 466）**+最低出价随之刷新为 **486=476+10（公式闭合，验收修复项）**+输入回 486+按钮转「重新出价」；**不关弹层** | 并发冲突语义 |
| nodeposit | 余额行红底「¥0.00」+去缴纳下划线；主按钮禁用 | 禁用+原因 |
| norealname | 警示条「实名开关已开启…」+去实名→realname；主按钮禁用 | 基准线第 4 条 |
| error | ErrorRetry inline「金额已保留」+重试；金额保留为无效值 400 → **同屏呈现「至少 ¥466.00」红字+输入框红描边**（belowMin 校验态视觉证据，C 维验收修复项；两提示语义独立：一个关于金额有效性、一个关于网络） | 失败保留+校验红字 |
| guest | 弹层本体替换为登录引导（一键登录→login） | §0.4 |
| buyout（追加演示帧） | 标题「一口价购买」+蓝 Pill「直购」+金额锁定 680.00 只读+隐藏快捷档与最低价提示+按钮「确认购买 ¥680.00」→payment-result | mode=buyout 全分支 |

## 3. mode=buyout 一口价直购（pages.json notes 的可点演示）

同一弹层组件复用：金额锁定禁改、隐藏快捷档/最低价提示；违约提示切换为支付时限文案【占位 24h】；确认后→payment-result（支付链路闭合，不走「出价」语义）。落地为 STATES 末位 `buyout` 演示帧：**STATES=pages.json 9 个 applicable 态 + buyout 追加帧（⊇ 门禁允许超集），状态板实际 4 板（pages.json board_parts=3 为声明值，第 4 板单帧 buyout）**。

## 4. 维度差异

- C：失焦校验=belowMin（<最低价）+overMax（>999999）computed，红字在 FormField error 槽（error 帧承载红字视觉证据）。
- 文案纪律（验收修复项）：success 帧移除「（原型帧停留供验收…）」元说明；guest 帧改用户视角「是否需实名以平台设置为准」；「上限 999999」改运行时 fmtMoney 格式。
- 触达（§0.7）：主按钮 lg=48px；快捷档胶囊 padding 9px（视觉高约 32px，热区扩展=交付语义）；submitting 帧快捷档禁用灰化增强。
- D：金额 tabular；与 P03 当前价同源（itemDetail）。
- E：lockMask=true；取消仅「×」/「取消」；buyout 确认→payment-result。
- F：出价成功触发订阅授权（拒绝→站内兜底）——交付语义，toast 说明。
- H：错误/警示红黄字对比度用语义色（--price-deep/--warn-ink）。
- I：POST /item/{id}/bid {amount}（服务端事务+乐观锁）、GET /deposit/balance（占位接口，仅语义）。

## 5. 资金纪律（红线）

- 金额一律 fmtMoney 两位小数到分；「确认出价/确认购买」均为**原型演示帧**，notify 明示「不接真实接口/不接真实支付」；无任何真实支付调用。
- nodeposit 的「去缴纳」：toast 占位（保证金缴纳流程不在本轮 35 单元）。

## 6. 占位与缺口

- 违约规则文案【占位规则】、支付时限【占位 24h】。
- 无图片缺口（缩略行用已登记 wulu-figure-banner，槽位=item-card-cover 语义）。
- derived 值更新：outbid 帧 refreshedCurrent=476、minBid=486（fixtures json 同步）。
