修复拼图结果页图片预览层级

关卡缩略图改为完整显示,避免生成图被裁切

关卡详情内主图预览支持提高层级,避免被详情弹窗遮挡

补充拼图结果页聚焦测试与 Hermes 踩坑记录
This commit is contained in:
2026-06-13 16:15:38 +08:00
parent 38babc592d
commit 5a1c1c88dd
4 changed files with 16 additions and 1 deletions

View File

@@ -240,6 +240,14 @@
- 验证:浏览器触发 `/creation/puzzle``/creation/match3d` 的泥点确认弹窗,检查 overlay 最近主题 class 存在、`--platform-modal-fill` 有值且面板为实底;聚焦测试覆盖默认 overlay / panel class。 - 验证:浏览器触发 `/creation/puzzle``/creation/match3d` 的泥点确认弹窗,检查 overlay 最近主题 class 存在、`--platform-modal-fill` 有值且面板为实底;聚焦测试覆盖默认 overlay / panel class。
- 关联:`src/components/common/PlatformMudPointConfirmDialog.tsx``src/components/common/PlatformStatusDialog.tsx``src/components/unified-creation/workspaces/PuzzleCreationWorkspace.tsx``src/components/unified-creation/workspaces/Match3DCreationWorkspace.tsx` - 关联:`src/components/common/PlatformMudPointConfirmDialog.tsx``src/components/common/PlatformStatusDialog.tsx``src/components/unified-creation/workspaces/PuzzleCreationWorkspace.tsx``src/components/unified-creation/workspaces/Match3DCreationWorkspace.tsx`
## 拼图结果页关卡图不要裁切,嵌套图片预览要高于详情弹窗
- 现象:拼图结果页“拼图关卡”列表里的关卡图底部被裁掉;进入关卡详情后点击画面图,看起来没有打开全屏预览。
- 原因:关卡列表复用 `PlatformMediaFrame aspect="standard"` 默认 `object-cover`,方图或竖向生成图会在 4:3 框内被裁切;关卡详情弹窗自身层级高于 `CreativeImageInputPanel` 默认图片预览层级,预览实际打开但被压在详情弹窗后面。
- 处理:结果页关卡缩略图显式传 `imageClassName="h-full w-full object-contain"` 保留完整画面;`CreativeImageInputPanel` 提供 `mainImagePreviewZIndexClassName`,嵌套在高层级弹窗内时由调用方传更高层级。
- 验证:聚焦测试断言关卡缩略图使用 `object-contain` 且没有 `object-cover`,并断言关卡详情内主图预览 overlay 层级高于详情弹窗;浏览器里检查列表完整显示图片,详情内点击画面图能打开可见预览。
- 关联:`src/components/puzzle-result/PuzzleResultView.tsx``src/components/common/CreativeImageInputPanel.tsx``src/components/puzzle-result/PuzzleResultView.test.tsx`
## 玩法入口分类字段缺失要前端兜底 ## 玩法入口分类字段缺失要前端兜底
- 现象:平台创作入口初始化时,`platformEntryCreationTypes.ts` 直接对 `creationTypes[].categoryId` / `categoryLabel``trim()`,一旦后端旧数据、局部 mock 或异常返回里缺字段,整个创作页会在 `derivePlatformCreationTypes(...)` 里直接炸掉。 - 现象:平台创作入口初始化时,`platformEntryCreationTypes.ts` 直接对 `creationTypes[].categoryId` / `categoryLabel``trim()`,一旦后端旧数据、局部 mock 或异常返回里缺字段,整个创作页会在 `derivePlatformCreationTypes(...)` 里直接炸掉。

View File

@@ -52,6 +52,7 @@ export type CreativeImageInputPanelProps = {
uploadedImageSrc: string; uploadedImageSrc: string;
uploadedImageAlt: string; uploadedImageAlt: string;
uploadedImageRefreshKey?: string | number | null; uploadedImageRefreshKey?: string | number | null;
mainImagePreviewZIndexClassName?: string;
mainImageMeta?: ReactNode; mainImageMeta?: ReactNode;
mainImageInputId: string; mainImageInputId: string;
mainImageAccept?: string; mainImageAccept?: string;
@@ -100,6 +101,7 @@ export function CreativeImageInputPanel({
uploadedImageSrc, uploadedImageSrc,
uploadedImageAlt, uploadedImageAlt,
uploadedImageRefreshKey = null, uploadedImageRefreshKey = null,
mainImagePreviewZIndexClassName = 'z-[82]',
mainImageMeta = null, mainImageMeta = null,
mainImageInputId, mainImageInputId,
mainImageAccept = DEFAULT_IMAGE_ACCEPT, mainImageAccept = DEFAULT_IMAGE_ACCEPT,
@@ -524,7 +526,7 @@ export function CreativeImageInputPanel({
} }
closeVariant="profileCompact" closeVariant="profileCompact"
size="xl" size="xl"
zIndexClassName="z-[82]" zIndexClassName={mainImagePreviewZIndexClassName}
overlayClassName="px-4 py-6" overlayClassName="px-4 py-6"
panelClassName="platform-remap-surface rounded-[1.35rem] p-3 shadow-[0_24px_70px_rgba(15,23,42,0.22)]" panelClassName="platform-remap-surface rounded-[1.35rem] p-3 shadow-[0_24px_70px_rgba(15,23,42,0.22)]"
headerClassName="mb-3 items-center border-b-0 px-1 py-0" headerClassName="mb-3 items-center border-b-0 px-1 py-0"

View File

@@ -274,6 +274,8 @@ describe('PuzzleResultView', () => {
const levelImage = screen.getByRole('img', { name: '雨夜猫街' }); const levelImage = screen.getByRole('img', { name: '雨夜猫街' });
const mediaFrame = levelImage.closest('div.relative'); const mediaFrame = levelImage.closest('div.relative');
expect(mediaFrame?.className).toContain('aspect-[4/3]'); expect(mediaFrame?.className).toContain('aspect-[4/3]');
expect(levelImage.className).toContain('object-contain');
expect(levelImage.className).not.toContain('object-cover');
expect(mediaFrame?.className).not.toContain( expect(mediaFrame?.className).not.toContain(
'bg-[var(--platform-subpanel-fill)]', 'bg-[var(--platform-subpanel-fill)]',
); );
@@ -552,6 +554,7 @@ describe('PuzzleResultView', () => {
const imagePreviewDialog = screen.getByRole('dialog', { const imagePreviewDialog = screen.getByRole('dialog', {
name: '查看关卡图片', name: '查看关卡图片',
}); });
expect(imagePreviewDialog.parentElement?.className).toContain('z-[150]');
expect(within(imagePreviewDialog).getByAltText('暖灯猫街')).toBeTruthy(); expect(within(imagePreviewDialog).getByAltText('暖灯猫街')).toBeTruthy();
fireEvent.click( fireEvent.click(
within(imagePreviewDialog).getByRole('button', { within(imagePreviewDialog).getByRole('button', {

View File

@@ -724,6 +724,7 @@ function PuzzleLevelDetailDialog({
promptReferenceImages={promptReferenceImages} promptReferenceImages={promptReferenceImages}
promptReferenceLimit={PUZZLE_LEVEL_PROMPT_REFERENCE_LIMIT} promptReferenceLimit={PUZZLE_LEVEL_PROMPT_REFERENCE_LIMIT}
imageLimitHint="图片≤6MB" imageLimitHint="图片≤6MB"
mainImagePreviewZIndexClassName="z-[150]"
imageModelPicker={ imageModelPicker={
<PuzzleImageModelPicker <PuzzleImageModelPicker
value={imageModel} value={imageModel}
@@ -1069,6 +1070,7 @@ function PuzzleLevelListTab({
fallbackLabel="暂无正式图" fallbackLabel="暂无正式图"
aspect="standard" aspect="standard"
surface="none" surface="none"
imageClassName="h-full w-full object-contain"
className="rounded-none" className="rounded-none"
fallbackClassName="tracking-normal text-[var(--platform-text-soft)]" fallbackClassName="tracking-normal text-[var(--platform-text-soft)]"
previewOverlay={ previewOverlay={