收口公开编号搜索结果弹层

平台入口公开编号搜索结果弹层改用 UnifiedModal 承接公共模态外壳
未命中提示与命中用户卡分别复用 PlatformStatusMessage 和 PlatformSubpanel
补充公开编号搜索结果弹层交互测试与收口文档记录
This commit is contained in:
2026-06-10 15:26:22 +08:00
parent fface53745
commit 1e6ecf2ea9
4 changed files with 85 additions and 34 deletions

View File

@@ -237,6 +237,7 @@
- 2026-06-10 验证补充:作品详情底部启动 / 改造动作收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx` - 2026-06-10 验证补充:作品详情底部启动 / 改造动作收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx`
- 2026-06-10 验证补充:作品详情点赞按钮收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx src/components/common/platformActionButtonModel.test.ts` - 2026-06-10 验证补充:作品详情点赞按钮收口补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformActionButton.test.tsx src/components/common/platformActionButtonModel.test.ts`
- 2026-06-10 验证补充creative-agent 模板确认弹层“关卡数”行内标题收口到 `PlatformFieldLabel variant="inlineForm"` 后,补跑 `npm run test -- src/components/creative-agent/CreativeAgentTemplateConfirmPanel.test.tsx src/components/common/PlatformFieldLabel.test.tsx` - 2026-06-10 验证补充creative-agent 模板确认弹层“关卡数”行内标题收口到 `PlatformFieldLabel variant="inlineForm"` 后,补跑 `npm run test -- src/components/creative-agent/CreativeAgentTemplateConfirmPanel.test.tsx src/components/common/PlatformFieldLabel.test.tsx`
- 2026-06-10 验证补充:平台入口公开编号搜索结果弹层收口到 `UnifiedModal``PlatformStatusMessage``PlatformSubpanel` 后,补跑 `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "public code search"`
- 2026-06-10 验证补充:平台作品详情主题标签和作品号复制 chip 收口后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformPillBadge.test.tsx src/components/common/CopyCodeButton.test.tsx` - 2026-06-10 验证补充:平台作品详情主题标签和作品号复制 chip 收口后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformPillBadge.test.tsx src/components/common/CopyCodeButton.test.tsx`
- 2026-06-10 验证补充:平台作品详情分享复制反馈按状态映射到 `PlatformStatusMessage surface="platform"` 后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformStatusMessage.test.tsx` - 2026-06-10 验证补充:平台作品详情分享复制反馈按状态映射到 `PlatformStatusMessage surface="platform"` 后,补跑 `npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/common/PlatformStatusMessage.test.tsx`
- 2026-06-10 验证补充:大鱼吃小鱼结果页缺草稿空态收口补跑 `npm run test -- src/components/big-fish-result/BigFishResultView.test.tsx src/components/common/PlatformEmptyState.test.tsx` - 2026-06-10 验证补充:大鱼吃小鱼结果页缺草稿空态收口补跑 `npm run test -- src/components/big-fish-result/BigFishResultView.test.tsx src/components/common/PlatformEmptyState.test.tsx`

View File

@@ -44,6 +44,7 @@
- 弹窗标题、列表项和小卡片里的非交互中性图标槽优先使用 `PlatformIconBadge`,业务页只传 icon、尺寸和形状不再重复拼 `grid h-* w-* place-items-center bg-[var(--platform-neutral-bg)] text-[var(--platform-neutral-text)]` - 弹窗标题、列表项和小卡片里的非交互中性图标槽优先使用 `PlatformIconBadge`,业务页只传 icon、尺寸和形状不再重复拼 `grid h-* w-* place-items-center bg-[var(--platform-neutral-bg)] text-[var(--platform-neutral-text)]`
- 平台表单和结果页中的方形上传入口、紧凑虚线新增入口优先使用 `PlatformUploadTile`,业务页只传 `label``hint`、可选 `icon``size``showLabel``disabled``asChild="label"` 或点击回调,不再重复手写虚线边框、图标、提示文案和 hover / 禁用态 class。上传后的方形图片预览优先使用 `PlatformUploadPreviewCard`,业务页只保留文件读取、预览数组和删除回调,不再重复手写缩略图壳、`object-cover` 图片和右上角移除按钮。 - 平台表单和结果页中的方形上传入口、紧凑虚线新增入口优先使用 `PlatformUploadTile`,业务页只传 `label``hint`、可选 `icon``size``showLabel``disabled``asChild="label"` 或点击回调,不再重复手写虚线边框、图标、提示文案和 hover / 禁用态 class。上传后的方形图片预览优先使用 `PlatformUploadPreviewCard`,业务页只保留文件读取、预览数组和删除回调,不再重复手写缩略图壳、`object-cover` 图片和右上角移除按钮。
- 特殊内容弹窗仍可直接使用 `UnifiedModal`,但只有在正文需要复杂网格、媒体预览、渠道按钮或运行态专属布局时才保留自定义 footer。 - 特殊内容弹窗仍可直接使用 `UnifiedModal`,但只有在正文需要复杂网格、媒体预览、渠道按钮或运行态专属布局时才保留自定义 footer。
- `UnifiedModal` 补充:平台入口公开编号搜索结果弹层使用 `size="sm"``closeLabel="关闭搜索结果"``closeOnBackdrop={false}`;壳层只保留搜索状态机、命中 / 未命中分支和关闭时清空结果状态,不再手写 overlay、header 和平台 close button 布局。
## 当前接口 ## 当前接口
@@ -68,6 +69,7 @@
- `PlatformStatusMessage` 补充:拼图首访 onboarding 的输入错误和登录保存错误使用 `surface="editorDark"`onboarding 只保留错误文案和条件渲染,不再手写暗色红色错误条。 - `PlatformStatusMessage` 补充:拼图首访 onboarding 的输入错误和登录保存错误使用 `surface="editorDark"`onboarding 只保留错误文案和条件渲染,不再手写暗色红色错误条。
- `PlatformStatusMessage` 补充:平台作品详情页分享复制反馈使用 `surface="platform"` 并按 `shareState` 映射 `success / error`;详情页只保留复制状态机和文案,不再为失败态复用成功 toast chrome。 - `PlatformStatusMessage` 补充:平台作品详情页分享复制反馈使用 `surface="platform"` 并按 `shareState` 映射 `success / error`;详情页只保留复制状态机和文案,不再为失败态复用成功 toast chrome。
- `PlatformStatusMessage` 补充creative-agent 首页错误提示使用 `tone="error" surface="platform" size="md"`;首页只保留宽度对齐布局 class 和错误文案,不再手写 danger panel chrome。 - `PlatformStatusMessage` 补充creative-agent 首页错误提示使用 `tone="error" surface="platform" size="md"`;首页只保留宽度对齐布局 class 和错误文案,不再手写 danger panel chrome。
- `PlatformStatusMessage` 补充:平台入口公开编号搜索未命中结果使用 `tone="neutral" surface="platform" size="md"`;壳层只保留搜索错误文案,不再手写普通文本提示块。
- `PlatformRuntimeStatusToast`:接收 `tone="error" | "success" | "info" | "warning" | "neutral"``surface="light" | "dark" | "solid"``size="xs" | "sm" | "md"``shape="pill" | "rounded"``children``className`;根节点固定带 `platform-runtime-status-toast` 稳定类名,默认按 `tone` 写入 `role="alert/status"``aria-live`。它只承接运行态 HUD 中短错误、成功和反馈 chip 的圆角、字号、阴影、色值和可访问语义,具体浮层位置、玩法资产按钮、计分牌、蓄力提示、强品牌 primary 按钮仍由玩法 runtime 控制。跳一跳、拼图、敲木鱼、方洞和宝贝爱画运行态的短错误 / 成功 / 投放反馈已先迁移;后续同类短 toast 不再手写 `rounded-full bg-white/* text-*`、暗色 `border-rose/emerald bg-*/text-*` 或单玩法 `*-runtime-error-chip` - `PlatformRuntimeStatusToast`:接收 `tone="error" | "success" | "info" | "warning" | "neutral"``surface="light" | "dark" | "solid"``size="xs" | "sm" | "md"``shape="pill" | "rounded"``children``className`;根节点固定带 `platform-runtime-status-toast` 稳定类名,默认按 `tone` 写入 `role="alert/status"``aria-live`。它只承接运行态 HUD 中短错误、成功和反馈 chip 的圆角、字号、阴影、色值和可访问语义,具体浮层位置、玩法资产按钮、计分牌、蓄力提示、强品牌 primary 按钮仍由玩法 runtime 控制。跳一跳、拼图、敲木鱼、方洞和宝贝爱画运行态的短错误 / 成功 / 投放反馈已先迁移;后续同类短 toast 不再手写 `rounded-full bg-white/* text-*`、暗色 `border-rose/emerald bg-*/text-*` 或单玩法 `*-runtime-error-chip`
- `PlatformDarkOptionCard`:接收 `selected``tone="emerald" | "sky" | "rose" | "amber"``radius="sm" | "md" | "lg"``padding="sm" | "md" | "lg"``children``className` 和原生 button props根节点固定带 `platform-dark-option-card` 稳定类名,统一承接 RPG 暗色弹窗 / 面板中的 selected / idle / hover / disabled 可选项卡按钮外观。NPC 交易模式、交易物品行、赠礼候选、招募替换候选、角色素材工作室动作预览格、营地编组替换位按钮和角色聊天建议按钮已先迁移;业务页只保留选中判断、点击回调和内容布局,不再重复手写 `rounded-* border px-3 py-*``border-*-400/* bg-*-500/10``border-white/* bg-black/20 hover:border-white/15` - `PlatformDarkOptionCard`:接收 `selected``tone="emerald" | "sky" | "rose" | "amber"``radius="sm" | "md" | "lg"``padding="sm" | "md" | "lg"``children``className` 和原生 button props根节点固定带 `platform-dark-option-card` 稳定类名,统一承接 RPG 暗色弹窗 / 面板中的 selected / idle / hover / disabled 可选项卡按钮外观。NPC 交易模式、交易物品行、赠礼候选、招募替换候选、角色素材工作室动作预览格、营地编组替换位按钮和角色聊天建议按钮已先迁移;业务页只保留选中判断、点击回调和内容布局,不再重复手写 `rounded-* border px-3 py-*``border-*-400/* bg-*-500/10``border-white/* bg-black/20 hover:border-white/15`
- `PlatformEmptyState`:接收 `surface="soft" | "dashed" | "subpanel" | "editorDark"``size="compact" | "panel" | "inline"``tone="base" | "soft"``children``className`;根节点固定带 `platform-empty-state` 稳定类名,业务测试可断言公共空态接入。`soft + compact` 用于公开广场、排行和作品架内的轻量空态,`soft + panel` 用于创作中心作品架整块空态,`dashed + panel` 用于素材选择、历史资源等弹窗的大面积空态或读取态,`subpanel + inline` 用于视觉小说 runtime、个人中心充值 / 任务等白底子面板内的无操作空态,`editorDark + compact/inline` 用于 RPG 大编辑器、实体详情弹窗、营地编组、角色聊天和运行态设置弹窗等暗色面板里的纯展示空态 / 禁用提示。组件只承接外观,不内置业务文案。 - `PlatformEmptyState`:接收 `surface="soft" | "dashed" | "subpanel" | "editorDark"``size="compact" | "panel" | "inline"``tone="base" | "soft"``children``className`;根节点固定带 `platform-empty-state` 稳定类名,业务测试可断言公共空态接入。`soft + compact` 用于公开广场、排行和作品架内的轻量空态,`soft + panel` 用于创作中心作品架整块空态,`dashed + panel` 用于素材选择、历史资源等弹窗的大面积空态或读取态,`subpanel + inline` 用于视觉小说 runtime、个人中心充值 / 任务等白底子面板内的无操作空态,`editorDark + compact/inline` 用于 RPG 大编辑器、实体详情弹窗、营地编组、角色聊天和运行态设置弹窗等暗色面板里的纯展示空态 / 禁用提示。组件只承接外观,不内置业务文案。
@@ -98,6 +100,7 @@
- `PlatformSubpanel`:接收 `as="section" | "div" | "article" | "aside" | "button"``title``titleVariant="section" | "strong"``actions``interactive``padding="tight" | "row" | "xs" | "sm" | "md" | "lg" | "none"``radius="xs" | "sm" | "md" | "lg" | "xl"``surface="platform" | "flat" | "soft" | "dark" | "darkSky" | "darkEmerald" | "darkAmber" | "darkRose" | "danger"``className``headerClassName``titleClassName``actionsClassName``bodyClassName``children`;静态 element 透传 `aria-*``data-*` 等原生属性,`as="button"` 时透传普通 button 属性并默认 `type="button"`。Module 统一承接平台结果页 / 工作台 / 个人中心子面板外壳、`PlatformFieldLabel variant="section"` 标题、强标题、右侧动作区、内容容器和普通白底列表卡片的 hover / focus / disabled 交互态。`surface="platform"` 复用 `platform-subpanel` token`surface="soft" + padding="tight"` 用于标签编辑新增输入行等白底柔和紧凑行,`surface="soft" + padding="row"` 用于上传预览横向已选素材条等白底柔和横向行;`surface="danger"` 用于整卡危险选中态;`radius="xl" + padding="lg"` 用于方洞等更大圆角的标准结果页面板;`surface="platform" + radius="xl" + padding="none"` 用于只需要公共边框 / 背景 / 大圆角且内部自带固定比例内容的静态封面壳,`surface="platform" + radius="xl" + padding="sm"` 可用局部 `sm:p-5` 保留物品详情类响应式内容面板;`surface="flat" + radius="sm" + padding="sm"` 用于素材 / 音频 / 排行榜 / 选项编辑 / 局部进度状态等小型白底卡片,`surface="flat" + radius="sm" + padding="none"` 仅用于只包已有图片、图集、角色或路径预览且不需要 fallback / overlay 的白底壳需要图片源、fallback、固定比例或 overlay 时优先使用 `PlatformMediaFrame`。需要整卡点击或缩略图点击时组合 `as="button" interactive`。拼图结果页作品名称 / 描述 / 标签编辑 / 智能修订条 / 关卡卡片、拼图图库详情页封面轮播壳 / 题材标签 / 关卡摘要、敲木鱼结果页主预览面板 / 作品标题 / 简介 / 主题标签 / 飘字 / 音效、敲木鱼工作台功德词条面板、跳一跳结果页预览 / 操作面板 / 排行榜 / 轻量媒体壳、拼消消创作工作台左侧表单面板、拼消消结果页预览 / 统计 / 操作面板 / 轻量媒体壳、方洞结果页封面 / 主信息 / 形状 / 洞口标准面板、方洞形状 / 洞口选项卡与缩略图按钮、RPG 结果页开发资产诊断摘要 / 条目 / 空态、RPG 个人中心未登录提示、通用音频输入面板、视觉小说创作工作台画风选择面板、视觉小说结果页素材 / 音频小面板、视觉小说结果页作品 / 开场 / 运行配置 / 世界观标准编辑面板、视觉小说 runtime 历史条目 / 存档列表、抓大鹅创作工作台难度小面板、抓大鹅结果页作品 / 难度 / 统计 / UI素材预览标准面板 / 当前难度摘要小卡 / 物品详情五视角面板 / 物品图集分组卡 / 批量素材生成进度卡、汪汪声浪结果页草稿摘要 / 素材槽 / 预览卡、平台反馈页问题描述 / 上传凭证 / 联系方式区块、自定义世界实体目录世界基调 / 角色维度 / 基本设定条目 / 场景幕级缩略图 / 目录卡片媒体壳 / 目录卡片整卡壳、创作中心作品架加载骨架卡,以及 creative-agent 工作台目录 / 目标就绪 / 空消息 / 过程 / 关卡计划 / 关卡计划小卡 / 模板确认理由面板已先迁移;`PlatformTagEditor` 内部新增输入行使用 `surface="soft" padding="tight"``PlatformUploadPreviewCard layout="inline"` 内部横向已选素材条使用 `surface="soft" padding="row"`。后续同类白底面板、白底轻量媒体壳或白底交互列表卡片只传标题、动作、内容、可访问属性和点击回调,不再重复写 `platform-subpanel rounded-[1.25rem] p-4``rounded-[1.35rem] p-4 sm:p-5``platform-subpanel rounded-[1.5rem] p-4 sm:p-5``rounded-[1.5rem] border border-[var(--platform-subpanel-border)] bg-[var(--platform-subpanel-fill)]``rounded-[1rem] border ... bg-white/72 p-3``rounded-[1rem] border ... bg-white/68 p-2``rounded-[1rem] border ... bg-white/68 px-3 py-2``rounded-[1.1rem] border ... bg-white/58 p-3``rounded-[1rem] border ... bg-white/80``hover:bg-white disabled:cursor-not-allowed disabled:opacity-55`、标题行 flex 和 `text-xs font-bold tracking-[0.18em]` - `PlatformSubpanel`:接收 `as="section" | "div" | "article" | "aside" | "button"``title``titleVariant="section" | "strong"``actions``interactive``padding="tight" | "row" | "xs" | "sm" | "md" | "lg" | "none"``radius="xs" | "sm" | "md" | "lg" | "xl"``surface="platform" | "flat" | "soft" | "dark" | "darkSky" | "darkEmerald" | "darkAmber" | "darkRose" | "danger"``className``headerClassName``titleClassName``actionsClassName``bodyClassName``children`;静态 element 透传 `aria-*``data-*` 等原生属性,`as="button"` 时透传普通 button 属性并默认 `type="button"`。Module 统一承接平台结果页 / 工作台 / 个人中心子面板外壳、`PlatformFieldLabel variant="section"` 标题、强标题、右侧动作区、内容容器和普通白底列表卡片的 hover / focus / disabled 交互态。`surface="platform"` 复用 `platform-subpanel` token`surface="soft" + padding="tight"` 用于标签编辑新增输入行等白底柔和紧凑行,`surface="soft" + padding="row"` 用于上传预览横向已选素材条等白底柔和横向行;`surface="danger"` 用于整卡危险选中态;`radius="xl" + padding="lg"` 用于方洞等更大圆角的标准结果页面板;`surface="platform" + radius="xl" + padding="none"` 用于只需要公共边框 / 背景 / 大圆角且内部自带固定比例内容的静态封面壳,`surface="platform" + radius="xl" + padding="sm"` 可用局部 `sm:p-5` 保留物品详情类响应式内容面板;`surface="flat" + radius="sm" + padding="sm"` 用于素材 / 音频 / 排行榜 / 选项编辑 / 局部进度状态等小型白底卡片,`surface="flat" + radius="sm" + padding="none"` 仅用于只包已有图片、图集、角色或路径预览且不需要 fallback / overlay 的白底壳需要图片源、fallback、固定比例或 overlay 时优先使用 `PlatformMediaFrame`。需要整卡点击或缩略图点击时组合 `as="button" interactive`。拼图结果页作品名称 / 描述 / 标签编辑 / 智能修订条 / 关卡卡片、拼图图库详情页封面轮播壳 / 题材标签 / 关卡摘要、敲木鱼结果页主预览面板 / 作品标题 / 简介 / 主题标签 / 飘字 / 音效、敲木鱼工作台功德词条面板、跳一跳结果页预览 / 操作面板 / 排行榜 / 轻量媒体壳、拼消消创作工作台左侧表单面板、拼消消结果页预览 / 统计 / 操作面板 / 轻量媒体壳、方洞结果页封面 / 主信息 / 形状 / 洞口标准面板、方洞形状 / 洞口选项卡与缩略图按钮、RPG 结果页开发资产诊断摘要 / 条目 / 空态、RPG 个人中心未登录提示、通用音频输入面板、视觉小说创作工作台画风选择面板、视觉小说结果页素材 / 音频小面板、视觉小说结果页作品 / 开场 / 运行配置 / 世界观标准编辑面板、视觉小说 runtime 历史条目 / 存档列表、抓大鹅创作工作台难度小面板、抓大鹅结果页作品 / 难度 / 统计 / UI素材预览标准面板 / 当前难度摘要小卡 / 物品详情五视角面板 / 物品图集分组卡 / 批量素材生成进度卡、汪汪声浪结果页草稿摘要 / 素材槽 / 预览卡、平台反馈页问题描述 / 上传凭证 / 联系方式区块、自定义世界实体目录世界基调 / 角色维度 / 基本设定条目 / 场景幕级缩略图 / 目录卡片媒体壳 / 目录卡片整卡壳、创作中心作品架加载骨架卡,以及 creative-agent 工作台目录 / 目标就绪 / 空消息 / 过程 / 关卡计划 / 关卡计划小卡 / 模板确认理由面板已先迁移;`PlatformTagEditor` 内部新增输入行使用 `surface="soft" padding="tight"``PlatformUploadPreviewCard layout="inline"` 内部横向已选素材条使用 `surface="soft" padding="row"`。后续同类白底面板、白底轻量媒体壳或白底交互列表卡片只传标题、动作、内容、可访问属性和点击回调,不再重复写 `platform-subpanel rounded-[1.25rem] p-4``rounded-[1.35rem] p-4 sm:p-5``platform-subpanel rounded-[1.5rem] p-4 sm:p-5``rounded-[1.5rem] border border-[var(--platform-subpanel-border)] bg-[var(--platform-subpanel-fill)]``rounded-[1rem] border ... bg-white/72 p-3``rounded-[1rem] border ... bg-white/68 p-2``rounded-[1rem] border ... bg-white/68 px-3 py-2``rounded-[1.1rem] border ... bg-white/58 p-3``rounded-[1rem] border ... bg-white/80``hover:bg-white disabled:cursor-not-allowed disabled:opacity-55`、标题行 flex 和 `text-xs font-bold tracking-[0.18em]`
- `PlatformSubpanel` 补充:个人中心玩过弹窗里的已玩作品按钮卡使用 `as="button" surface="flat" radius="sm" padding="md" interactive`,业务组件只保留作品标题 / 副标题 / 类型胶囊 / 作品号 / 最近游玩 / 时长内容和粉色 hover 边框,不再手写白底按钮卡 chrome。 - `PlatformSubpanel` 补充:个人中心玩过弹窗里的已玩作品按钮卡使用 `as="button" surface="flat" radius="sm" padding="md" interactive`,业务组件只保留作品标题 / 副标题 / 类型胶囊 / 作品号 / 最近游玩 / 时长内容和粉色 hover 边框,不再手写白底按钮卡 chrome。
- `PlatformSubpanel` 补充:平台入口壳纯 Suspense fallback、作品详情读取 / 错误提示和 Agent 工作区恢复提示使用 `radius="sm" padding="none"` 承接原 `platform-subpanel` 外壳,业务层只保留居中布局、提示文案和局部内边距;生成结果恢复面板使用 `radius="xl" padding="none"` 保留恢复动作与固定内容间距。玩法 runtime overlay 仍保留专用层级语义,后续单独评估。 - `PlatformSubpanel` 补充:平台入口壳纯 Suspense fallback、作品详情读取 / 错误提示和 Agent 工作区恢复提示使用 `radius="sm" padding="none"` 承接原 `platform-subpanel` 外壳,业务层只保留居中布局、提示文案和局部内边距;生成结果恢复面板使用 `radius="xl" padding="none"` 保留恢复动作与固定内容间距。玩法 runtime overlay 仍保留专用层级语义,后续单独评估。
- `PlatformSubpanel` 补充:平台入口公开编号搜索命中用户卡使用 `surface="flat" radius="sm" padding="md"``titleVariant="strong"`;壳层只保留用户摘要字段和关闭分支,不再手写白底 bordered 搜索结果卡。
- `PlatformSubpanel` 补充RPG runtime 主阶段路由里的平台首页、角色选择和冒险面板懒加载提示使用 `radius="sm" padding="none"` 承接原 `platform-subpanel` 外壳;路由器只保留 Suspense 分流和提示文案,运行态 HUD / overlay 继续保留专用层级语义。 - `PlatformSubpanel` 补充RPG runtime 主阶段路由里的平台首页、角色选择和冒险面板懒加载提示使用 `radius="sm" padding="none"` 承接原 `platform-subpanel` 外壳;路由器只保留 Suspense 分流和提示文案,运行态 HUD / overlay 继续保留专用层级语义。
- `PlatformSubpanel` 补充:个人中心钱包账单行使用 `as="div" surface="flat" radius="xs" padding="none"`,业务组件只保留来源、时间、收入 / 支出色值、余额右对齐和局部 `px-3 py-3 shadow-sm`;后续同类白底数据行优先从该组合扩展。 - `PlatformSubpanel` 补充:个人中心钱包账单行使用 `as="div" surface="flat" radius="xs" padding="none"`,业务组件只保留来源、时间、收入 / 支出色值、余额右对齐和局部 `px-3 py-3 shadow-sm`;后续同类白底数据行优先从该组合扩展。
- `PlatformSubpanel` 补充:个人中心邀请弹窗里的社区二维码卡、邀请码展示卡、成功邀请容器和邀请用户行使用 `surface="flat" | "soft"` 的白底子面板;复制按钮、奖励说明卡和弹窗状态机不并入本轮。 - `PlatformSubpanel` 补充:个人中心邀请弹窗里的社区二维码卡、邀请码展示卡、成功邀请容器和邀请用户行使用 `surface="flat" | "soft"` 的白底子面板;复制按钮、奖励说明卡和弹窗状态机不并入本轮。

View File

@@ -364,11 +364,13 @@ import {
import type { CustomWorldProfile } from '../../types'; import type { CustomWorldProfile } from '../../types';
import { useAuthUi } from '../auth/AuthUiContext'; import { useAuthUi } from '../auth/AuthUiContext';
import { PlatformActionButton } from '../common/PlatformActionButton'; import { PlatformActionButton } from '../common/PlatformActionButton';
import { PlatformModalCloseButton } from '../common/PlatformModalCloseButton'; import { PlatformFieldLabel } from '../common/PlatformFieldLabel';
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
import { PlatformSubpanel } from '../common/PlatformSubpanel'; import { PlatformSubpanel } from '../common/PlatformSubpanel';
import { PublishShareModal } from '../common/PublishShareModal'; import { PublishShareModal } from '../common/PublishShareModal';
import type { PublishShareModalPayload } from '../common/publishShareModalModel'; import type { PublishShareModalPayload } from '../common/publishShareModalModel';
import { UnifiedConfirmDialog } from '../common/UnifiedConfirmDialog'; import { UnifiedConfirmDialog } from '../common/UnifiedConfirmDialog';
import { UnifiedModal } from '../common/UnifiedModal';
import { resolveCreativeAgentTargetSelectionStage } from '../creative-agent/creativeAgentViewModel'; import { resolveCreativeAgentTargetSelectionStage } from '../creative-agent/creativeAgentViewModel';
import { import {
buildCreationWorkShelfItems, buildCreationWorkShelfItems,
@@ -13942,6 +13944,11 @@ export function PlatformEntryFlowShellImpl({
], ],
); );
const closePublicSearchResult = useCallback(() => {
setSearchedPublicUser(null);
setPublicSearchError(null);
}, []);
const openProfilePlayedWorks = useCallback(() => { const openProfilePlayedWorks = useCallback(() => {
setIsProfilePlayStatsOpen(true); setIsProfilePlayStatsOpen(true);
setIsProfilePlayStatsLoading(true); setIsProfilePlayStatsLoading(true);
@@ -17054,49 +17061,47 @@ export function PlatformEntryFlowShellImpl({
{pendingDeleteCreationWork?.detail} {pendingDeleteCreationWork?.detail}
</UnifiedConfirmDialog> </UnifiedConfirmDialog>
<AnimatePresence> <AnimatePresence>
{(searchedPublicUser || publicSearchError) && ( {searchedPublicUser || publicSearchError ? (
<motion.div <motion.div
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
exit={{ opacity: 0 }} exit={{ opacity: 0 }}
className="fixed inset-0 z-50 flex items-center justify-center bg-black/45 p-4"
> >
<div className="platform-surface w-full max-w-md rounded-[1.6rem] p-5"> <UnifiedModal
<div className="flex items-start justify-between gap-4"> open
<div> title={publicSearchError ? '未找到结果' : '命中用户'}
<div className="text-sm font-semibold text-[var(--platform-text-soft)]"> description="公开编号搜索"
onClose={closePublicSearchResult}
</div> closeOnBackdrop={false}
<div className="mt-1 text-xl font-black text-[var(--platform-text-strong)]"> closeLabel="关闭搜索结果"
{publicSearchError ? '未找到结果' : '命中用户'} portal={false}
</div> size="sm"
</div> overlayClassName={`platform-theme ${platformThemeClass} !items-center bg-black/45 !p-4`}
<PlatformModalCloseButton panelClassName="platform-remap-surface rounded-[1.6rem]"
onClick={() => { >
setSearchedPublicUser(null);
setPublicSearchError(null);
}}
label="关闭搜索结果"
variant="platformIcon"
/>
</div>
{publicSearchError ? ( {publicSearchError ? (
<div className="mt-4 text-sm leading-6 text-[var(--platform-text-soft)]"> <PlatformStatusMessage tone="neutral" surface="platform" size="md">
{publicSearchError} {publicSearchError}
</div> </PlatformStatusMessage>
) : searchedPublicUser ? ( ) : searchedPublicUser ? (
<div className="mt-4 rounded-[1.2rem] border border-[var(--platform-line-soft)] p-4"> <PlatformSubpanel
<div className="text-lg font-bold text-[var(--platform-text-strong)]"> as="section"
{searchedPublicUser.displayName} surface="flat"
</div> radius="sm"
<div className="mt-2 text-sm text-[var(--platform-text-soft)]"> padding="md"
{searchedPublicUser.publicUserCode} title={searchedPublicUser.displayName}
</div> titleVariant="strong"
bodyClassName="mt-3"
>
<PlatformFieldLabel></PlatformFieldLabel>
<div className="mt-1 text-sm font-semibold text-[var(--platform-text-base)]">
{searchedPublicUser.publicUserCode}
</div> </div>
</PlatformSubpanel>
) : null} ) : null}
</div> </UnifiedModal>
</motion.div> </motion.div>
)} ) : null}
</AnimatePresence> </AnimatePresence>
</> </>
); );

View File

@@ -7334,11 +7334,53 @@ test('public code search blocks edutainment work when entry switch is disabled',
await user.type(searchInput, 'PZ-TMENT1'); await user.type(searchInput, 'PZ-TMENT1');
await user.click(screen.getByRole('button', { name: '搜索' })); await user.click(screen.getByRole('button', { name: '搜索' }));
expect(await screen.findByText('未找到结果')).toBeTruthy(); const dialog = await screen.findByRole('dialog', { name: '未找到结果' });
expect(within(dialog).getByText('公开编号搜索')).toBeTruthy();
expect(within(dialog).getByText('未找到拼图作品。')).toBeTruthy();
await user.click(
within(dialog).getByRole('button', { name: '关闭搜索结果' }),
);
await waitFor(() => {
expect(screen.queryByRole('dialog', { name: '未找到结果' })).toBeNull();
});
expect(screen.queryByText('儿童动作热身 Demo')).toBeNull(); expect(screen.queryByText('儿童动作热身 Demo')).toBeNull();
expect(getPuzzleGalleryDetail).not.toHaveBeenCalled(); expect(getPuzzleGalleryDetail).not.toHaveBeenCalled();
}); });
test('public code search shows public user summary in shared search result modal and clears it on close', async () => {
const user = userEvent.setup();
vi.mocked(authServiceMocks.getPublicAuthUserByCode).mockResolvedValue({
id: 'public-user-yjsh',
publicUserCode: 'SY-00000001',
username: 'author_user',
displayName: '公开作者',
avatarUrl: null,
});
render(<TestWrapper withAuth />);
await openDiscoverHub(user);
const searchInput =
await screen.findByPlaceholderText('搜索作品号、名称、作者、描述');
await user.type(searchInput, '月井守望');
await user.click(screen.getByRole('button', { name: '搜索' }));
const dialog = await screen.findByRole('dialog', { name: '命中用户' });
expect(within(dialog).getByText('公开编号搜索')).toBeTruthy();
expect(within(dialog).getByText('公开作者')).toBeTruthy();
expect(within(dialog).getByText('陶泥号')).toBeTruthy();
expect(within(dialog).getByText('SY-00000001')).toBeTruthy();
await user.click(
within(dialog).getByRole('button', { name: '关闭搜索结果' }),
);
await waitFor(() => {
expect(screen.queryByRole('dialog', { name: '命中用户' })).toBeNull();
});
});
test('creation hub clears all private work shelves immediately after logout state', async () => { test('creation hub clears all private work shelves immediately after logout state', async () => {
const user = userEvent.setup(); const user = userEvent.setup();
const loggedInAuth = createAuthValue(); const loggedInAuth = createAuthValue();