From 547e771f75b9b29892202aa257e4d50f250381e9 Mon Sep 17 00:00:00 2001 From: kdletters Date: Wed, 10 Jun 2026 20:36:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B6=E5=8F=A3=E5=A4=A7=E9=B1=BC=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E9=A1=B5=E5=A4=B1=E8=B4=A5=E7=8A=B6=E6=80=81=E5=BC=B9?= =?UTF-8?q?=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 扩展 PlatformStatusDialog 支持自定义图标标签与动作按钮透传 BigFishResultView 改用共享状态弹窗承接发布失败提示 更新 PlatformUiKit 收口文档与团队决策记录 --- .hermes/shared-memory/decision-log.md | 1 + ...】PlatformUiKit弹窗组件收口计划-2026-06-08.md | 1 + .../big-fish-result/BigFishResultView.tsx | 37 ++++++++----------- .../common/PlatformStatusDialog.test.tsx | 31 ++++++++++++++++ .../common/PlatformStatusDialog.tsx | 27 +++++++++++--- 5 files changed, 70 insertions(+), 27 deletions(-) diff --git a/.hermes/shared-memory/decision-log.md b/.hermes/shared-memory/decision-log.md index 586ebef8..f8734426 100644 --- a/.hermes/shared-memory/decision-log.md +++ b/.hermes/shared-memory/decision-log.md @@ -45,6 +45,7 @@ - 2026-06-10 追加:RPG 首页个人中心的账户充值弹层统一抽到 `src/components/platform-entry/PlatformProfileRechargeModal.tsx`;充值 tab、套餐卡片、Native 二维码生成和确认支付入口不再内联在 `RpgEntryHomeView`,后续 profile 侧充值入口优先复用同一个组件。 - 2026-06-10 追加:RPG 首页个人中心的泥点账单、每日任务和兑换码弹层统一抽到 `src/components/platform-entry/PlatformProfileWalletLedgerModal.tsx`、`src/components/platform-entry/PlatformProfileTaskCenterModal.tsx` 与 `src/components/platform-entry/PlatformProfileRewardCodeRedeemModal.tsx`;`RpgEntryHomeView` 只保留打开条件和数据流,标准 profile 弹层内容以后优先沉到 `platform-entry` 独立组件,不在首页继续堆叠。 - 2026-06-10 追加:个人中心支付结果提示与支付确认遮罩统一抽到 `src/components/common/PlatformStatusDialog.tsx`,扫码面板统一抽到 `src/components/platform-entry/PlatformProfileQrScannerModal.tsx`;`RpgEntryHomeView` 只保留支付结果 kind 到 `success / loading / cancel / error` 的映射、确认遮罩开关和扫码结果写回,不再内联 profile 状态弹层壳层、二维码摄像头启动或 `BarcodeDetector` 轮询。后续 profile 侧同类“状态图标 + 标题正文 + 可选主动作”弹层优先复用 `PlatformStatusDialog`,扫码类弹层优先复用 `PlatformProfileQrScannerModal`。 +- 2026-06-10 追加:`PlatformStatusDialog` 支持自定义图标、图标可访问标签以及动作按钮 surface / size / className 透传,用来承接玩法结果页里保留品牌视觉但语义仍是“状态结果弹层”的场景;大鱼吃小鱼结果页的发布失败弹层已迁移到这套组件,业务页不再保留 `UnifiedConfirmDialog + PlatformIconBadge` 的专用组合。 - 2026-06-09 追加:通用输入 Composer 的上传参考图、发送和移除参考图已迁移到 `PlatformIconButton`;图标上传仍使用 `asChild="label"` 保留 label + file input 语义,公共组件会自动写入隐藏文本,确保内嵌 file input 继承可访问名称。 - 2026-06-10 追加:creation-agent composer 的上传文档 / 上传参考图入口使用 `PlatformIconButton` 默认 `platformIcon`;工作台只保留动态 label、title、busy 状态和 picker 回调,发送按钮继续保留主题色动作布局。验证命令:`npm run test -- src/components/creation-agent/CreationAgentWorkspace.test.tsx src/components/common/PlatformIconButton.test.tsx`。 - 2026-06-10 追加:作品详情顶部返回 / 分享和封面轮播上一张 / 下一张入口使用 `PlatformIconButton variant="platformIcon"`;详情页保留原 `platform-work-detail__*` 局部 class 控制位置和尺寸,点赞、复制三态等专用动作暂不迁移。验证命令:`npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformIconButton.test.tsx`。 diff --git a/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md b/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md index ba453282..0b444064 100644 --- a/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md +++ b/docs/technical/【前端架构】PlatformUiKit弹窗组件收口计划-2026-06-08.md @@ -243,6 +243,7 @@ 19.3.19. RPG 首页个人中心的支付结果提示、支付确认遮罩与扫码面板继续向共享组件收口:支付结果 / 确认中弹层统一抽到 `src/components/common/PlatformStatusDialog.tsx`,扫码面板统一抽到 `src/components/platform-entry/PlatformProfileQrScannerModal.tsx`;`RpgEntryHomeView` 仅保留支付状态映射、扫码打开关闭和结果写回,不再内联 `RechargePaymentResultModal`、`RechargePaymentConfirmationMask`、`ProfileQrScannerModal`、`BarcodeDetector` 启动逻辑和 profile 弹层壳层参数。组件级验证新增 `src/components/common/PlatformStatusDialog.test.tsx` 与 `src/components/platform-entry/PlatformProfileQrScannerModal.test.tsx`,首页继续复用 `RpgEntryHomeView.recharge.test.tsx` 的支付 / 扫码入口断言。验证命令:`npm run test -- src/components/common/PlatformStatusDialog.test.tsx`、`npm run test -- src/components/platform-entry/PlatformProfileQrScannerModal.test.tsx`、`npm run test -- src/components/rpg-entry/RpgEntryHomeView.recharge.test.tsx -t "profile recharge modal jumps to h5 payment on mobile web by default|profile recharge modal posts mini program payment request and reacts to success hash result|profile recharge modal releases submitting state and shows virtual payment failure detail|profile recharge modal eventually shows error text even when hashchange is not dispatched|profile recharge modal resumes virtual payment confirmation when pageshow returns with paid order|profile recharge modal blocks tab navigation while virtual payment confirmation is pending|profile scan action opens camera scanner instead of recharge panel"`、`npm run typecheck`。 19.3. creative-agent 首页的侧边栏菜单、账号入口、开启新对话、我的创作、首页激励 CTA 和 prompt suggestion 按钮迁移到 `PlatformIconButton` / `PlatformActionButton`;首页继续保留 `creative-agent-home__*` 本地 class 承接透明顶栏、抽屉和品牌化胶囊视觉,不把视觉回收和语义收口绑成一次大改。`Beta` 徽标和历史记录纯文本行暂保留本地实现,等出现更多同构轻量列表行后再评估是否抽新的共享 row primitive。 19.4. 大鱼吃小鱼结果页 hero 的返回入口迁移到 `PlatformIconButton variant="darkMini"`,测试 / 发布动作迁移到 `PlatformActionButton surface="editorDark"`;结果页只保留测试运行、发布提交和文案状态语义,不再手写 hero 顶栏按钮壳。 +19.4.1. 大鱼吃小鱼结果页的发布失败弹层迁移到 `src/components/common/PlatformStatusDialog.tsx`;`PlatformStatusDialog` 补充自定义图标、可访问标签和动作按钮样式透传后,`BigFishResultView` 不再保留 `BigFishResultErrorModal` 内联的 `UnifiedConfirmDialog + PlatformIconBadge` 组合。结果页只保留失败文案和关闭回调,发布失败的状态图标、遮罩、白底面板和“知道了”主动作统一由共享状态弹层承接。验证命令:`npm run test -- src/components/common/PlatformStatusDialog.test.tsx src/components/big-fish-result/BigFishResultView.test.tsx`、`npm run typecheck`。 20. 平台方形上传入口和紧凑虚线新增入口迁移到 `PlatformUploadTile`,上传后的图片预览迁移到 `PlatformUploadPreviewCard`;反馈页上传凭证入口 / 预览、敲木鱼工作台新增功德词条入口、通用创作图片面板的提示词参考图缩略图、抓大鹅封面编辑参考图缩略图、通用输入 Composer 已选参考图条、creation-agent 已选参考图条和拼图结果页关卡引用图横条已先迁移。方形缩略图使用默认 `layout="square"`,横向“已选择参考图 / 文件名 / 素材名 / 移除”条使用 `layout="inline"`;只读引用图条不传 `onRemove`,避免公共组件额外渲染删除入口。后续继续收口结果页素材上传、工作台参考图上传、紧凑虚线新增入口等上传 / 动作块时,业务页只保留文件选择、预览数组、预览回调、删除回调、校验逻辑或新增回调,上传方块外观、主副文案、缩略图壳、预览按钮、标题行、横向已选条、移除按钮和禁用态统一由 Module 承接;工具栏中的小图标上传仍继续使用 `PlatformIconButton asChild="label"`。 21. 图片编辑面板中的白底胶囊开关迁移到 `PlatformPillSwitch`;通用创作图片面板和抓大鹅封面编辑的 `AI重绘` 已先迁移。后续同类开关只保留受控布尔值和状态变更回调,switch 输入语义、轨道、圆点、白底浮层和禁用态统一由 Module 承接。 22. 设置面板、结果页运行配置和工作台白底配置项中的整行开关迁移到 `PlatformToggleRow`;视觉小说结果页、runtime 设置面板和拼消消创作工作台 AI 生成底图开关已先迁移。后续整行配置项只保留字段写回和可选点击动作,不再重复开关行 chrome、checkbox class 或状态 pill。 diff --git a/src/components/big-fish-result/BigFishResultView.tsx b/src/components/big-fish-result/BigFishResultView.tsx index 8c7b5342..6921a9d6 100644 --- a/src/components/big-fish-result/BigFishResultView.tsx +++ b/src/components/big-fish-result/BigFishResultView.tsx @@ -23,9 +23,9 @@ import { PlatformIconBadge } from '../common/PlatformIconBadge'; import { PlatformIconButton } from '../common/PlatformIconButton'; import { PlatformMediaFrame } from '../common/PlatformMediaFrame'; import { PlatformPillBadge } from '../common/PlatformPillBadge'; +import { PlatformStatusDialog } from '../common/PlatformStatusDialog'; import { PlatformStatusMessage } from '../common/PlatformStatusMessage'; import { PlatformSubpanel } from '../common/PlatformSubpanel'; -import { UnifiedConfirmDialog } from '../common/UnifiedConfirmDialog'; type BigFishAssetStudioTarget = | { @@ -619,32 +619,25 @@ function BigFishResultErrorModal({ onClose: () => void; }) { return ( - } + iconLabel="发布失败提示" + iconClassName="mt-0.5 bg-[var(--platform-button-danger-fill)] text-[var(--platform-button-danger-text)]" + action={{ + label: '知道了', + onClick: onClose, + surface: 'platform', + className: 'border-slate-950 bg-slate-950 text-white', + }} zIndexClassName="z-[160]" overlayClassName="bg-slate-950/58" panelClassName="border-red-100/80 bg-white text-slate-950 shadow-2xl" - footerClassName="border-t-0 px-5 pb-5 pt-0" - > -
- } - label="发布失败提示" - tone="danger" - className="mt-0.5" - /> -
- {message} -
-
-
+ bodyClassName="px-5 pb-5 pt-6 text-center" + /> ); } diff --git a/src/components/common/PlatformStatusDialog.test.tsx b/src/components/common/PlatformStatusDialog.test.tsx index cebb330d..2c380864 100644 --- a/src/components/common/PlatformStatusDialog.test.tsx +++ b/src/components/common/PlatformStatusDialog.test.tsx @@ -1,5 +1,6 @@ /* @vitest-environment jsdom */ +import { Waves } from 'lucide-react'; import { fireEvent, render, screen } from '@testing-library/react'; import { expect, test, vi } from 'vitest'; @@ -65,3 +66,33 @@ test('supports blocking confirming state without close action', () => { expect(onClose).not.toHaveBeenCalled(); }); + +test('supports custom badge icon label and action button styling', () => { + render( + } + iconLabel="发布失败提示" + iconClassName="bg-[var(--platform-button-danger-fill)] text-[var(--platform-button-danger-text)]" + action={{ + label: '知道了', + onClick: vi.fn(), + surface: 'platform', + className: 'border-slate-950 bg-slate-950 text-white', + }} + />, + ); + + const badge = screen.getByLabelText('发布失败提示'); + const action = screen.getByRole('button', { name: '知道了' }); + + expect(badge.className).toContain('bg-[var(--platform-button-danger-fill)]'); + expect(badge.className).toContain( + 'text-[var(--platform-button-danger-text)]', + ); + expect(action.className).toContain('border-slate-950'); + expect(action.className).toContain('bg-slate-950'); +}); diff --git a/src/components/common/PlatformStatusDialog.tsx b/src/components/common/PlatformStatusDialog.tsx index 0352a29e..144b0072 100644 --- a/src/components/common/PlatformStatusDialog.tsx +++ b/src/components/common/PlatformStatusDialog.tsx @@ -10,6 +10,11 @@ import { import { PlatformActionButton } from './PlatformActionButton'; import { PlatformIconBadge } from './PlatformIconBadge'; import { UnifiedModal } from './UnifiedModal'; +import type { + PlatformActionButtonSize, + PlatformActionButtonSurface, + PlatformActionButtonTone, +} from './platformActionButtonModel'; export type PlatformStatusDialogStatus = | 'success' @@ -22,6 +27,11 @@ type PlatformStatusDialogAction = { label: string; onClick: () => void; disabled?: boolean; + tone?: PlatformActionButtonTone; + surface?: PlatformActionButtonSurface; + size?: PlatformActionButtonSize; + fullWidth?: boolean; + className?: string; }; type PlatformStatusDialogProps = { @@ -37,6 +47,8 @@ type PlatformStatusDialogProps = { panelClassName?: string; bodyClassName?: string; iconClassName?: string; + icon?: ReactNode; + iconLabel?: string; }; type PlatformStatusVisualConfig = { @@ -97,8 +109,11 @@ export function PlatformStatusDialog({ panelClassName = DEFAULT_PANEL_CLASS, bodyClassName = DEFAULT_BODY_CLASS, iconClassName, + icon, + iconLabel, }: PlatformStatusDialogProps) { const visualConfig = getStatusVisualConfig(status); + const badgeIcon = icon ?? visualConfig.icon; return (