1
This commit is contained in:
@@ -1414,4 +1414,73 @@ describe('Match3DResultView', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('背景音乐在非首个素材时仍显示并进入试玩 profile', async () => {
|
||||
const onStartTestRun = vi.fn();
|
||||
const generatedItemAssets = [
|
||||
createReadyGeneratedItemAsset(1),
|
||||
{
|
||||
...createReadyGeneratedItemAsset(2),
|
||||
backgroundMusicTitle: '漂浮船歌',
|
||||
backgroundMusicStyle: '轻快, 愉悦, 现代',
|
||||
backgroundMusicPrompt: '',
|
||||
backgroundMusic: {
|
||||
taskId: 'music-task-2',
|
||||
provider: 'vector-engine-suno',
|
||||
assetObjectId: 'asset-music-2',
|
||||
assetKind: 'match3d_background_music',
|
||||
audioSrc: '/generated-match3d-assets/audio/floating-song.mp3',
|
||||
prompt: '',
|
||||
title: '漂浮船歌',
|
||||
updatedAt: '2026-05-14T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
];
|
||||
const profile = createProfile({ generatedItemAssets });
|
||||
vi.mocked(match3dWorksService.updateMatch3DWork).mockResolvedValue({
|
||||
item: createProfile({ generatedItemAssets: [] }),
|
||||
});
|
||||
vi.mocked(
|
||||
match3dWorksService.updateMatch3DGeneratedItemAssets,
|
||||
).mockResolvedValue({
|
||||
item: createProfile({ generatedItemAssets }),
|
||||
});
|
||||
|
||||
render(
|
||||
<Match3DResultView
|
||||
profile={profile}
|
||||
onBack={() => {}}
|
||||
onStartTestRun={onStartTestRun}
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '素材配置' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '背景音乐' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByLabelText('抓大鹅背景音乐').getAttribute('src')).toBe(
|
||||
'https://signed.example.com/generated-match3d-assets/audio/floating-song.mp3',
|
||||
);
|
||||
});
|
||||
expect(screen.queryByText('暂无音乐')).toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '试玩' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onStartTestRun).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
generatedItemAssets: expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
itemId: 'match3d-item-1',
|
||||
backgroundMusic: expect.objectContaining({
|
||||
audioSrc:
|
||||
'/generated-match3d-assets/audio/floating-song.mp3',
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
expect.objectContaining({ itemTypeCountOverride: 2 }),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +49,8 @@ import {
|
||||
} from '../../services/match3d-works';
|
||||
import {
|
||||
getMatch3DGeneratedImageViewSources,
|
||||
mergeMatch3DGeneratedItemAssetsForRuntime,
|
||||
normalizeMatch3DGeneratedItemAssetsForRuntime,
|
||||
resolveMatch3DGeneratedImageAssetSource,
|
||||
resolveMatch3DGeneratedModelAssetSource,
|
||||
} from '../../services/match3dGeneratedModelCache';
|
||||
@@ -768,7 +770,7 @@ function createGeneratedAssetsFromDrafts(
|
||||
asset.backgroundMusicStyle ?? existing?.backgroundMusicStyle ?? null,
|
||||
backgroundMusicPrompt:
|
||||
asset.backgroundMusicPrompt ?? existing?.backgroundMusicPrompt ?? null,
|
||||
backgroundMusic: asset.backgroundMusic,
|
||||
backgroundMusic: asset.backgroundMusic ?? existing?.backgroundMusic ?? null,
|
||||
clickSound: asset.clickSound,
|
||||
backgroundAsset:
|
||||
asset.backgroundAsset ??
|
||||
@@ -1118,27 +1120,23 @@ function resolveMatch3DResultGeneratedItemAssets(
|
||||
const profileAssets = profile.generatedItemAssets ?? [];
|
||||
const draftAssets = draft?.generatedItemAssets ?? [];
|
||||
if (draftAssets.length <= 0) {
|
||||
return profileAssets;
|
||||
return normalizeMatch3DGeneratedItemAssetsForRuntime(profileAssets);
|
||||
}
|
||||
if (profileAssets.length <= 0) {
|
||||
return draftAssets;
|
||||
return normalizeMatch3DGeneratedItemAssetsForRuntime(draftAssets);
|
||||
}
|
||||
|
||||
const profileAssetsById = new Map(
|
||||
profileAssets.map((asset) => [asset.itemId, asset]),
|
||||
return mergeMatch3DGeneratedItemAssetsForRuntime(
|
||||
draftAssets.map((draftAsset) => {
|
||||
const profileAsset = profileAssets.find(
|
||||
(asset) => asset.itemId === draftAsset.itemId,
|
||||
);
|
||||
return profileAsset
|
||||
? mergeMatch3DGeneratedItemAsset(draftAsset, profileAsset)
|
||||
: draftAsset;
|
||||
}),
|
||||
profileAssets,
|
||||
);
|
||||
const mergedAssets = draftAssets.map((draftAsset) => {
|
||||
const profileAsset = profileAssetsById.get(draftAsset.itemId);
|
||||
return profileAsset
|
||||
? mergeMatch3DGeneratedItemAsset(draftAsset, profileAsset)
|
||||
: draftAsset;
|
||||
});
|
||||
for (const profileAsset of profileAssets) {
|
||||
if (!mergedAssets.some((asset) => asset.itemId === profileAsset.itemId)) {
|
||||
mergedAssets.push(profileAsset);
|
||||
}
|
||||
}
|
||||
return mergedAssets;
|
||||
}
|
||||
|
||||
function attachMatch3DGeneratedItemAssets(
|
||||
@@ -1152,7 +1150,8 @@ function attachMatch3DGeneratedItemAssets(
|
||||
// 中文注释:试玩入口依赖当前页面可见的生成素材;保存接口若返回旧快照,不能把素材从运行态入参里丢掉。
|
||||
return {
|
||||
...profile,
|
||||
generatedItemAssets: [...generatedItemAssets],
|
||||
generatedItemAssets:
|
||||
normalizeMatch3DGeneratedItemAssetsForRuntime(generatedItemAssets),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1177,10 +1176,12 @@ function buildPersistableGeneratedItemAssets(
|
||||
return [];
|
||||
}
|
||||
|
||||
return createGeneratedAssetsFromDrafts(
|
||||
assetDrafts,
|
||||
generatedItemAssets,
|
||||
).filter(hasPersistableMatch3DGeneratedItemAsset);
|
||||
return normalizeMatch3DGeneratedItemAssetsForRuntime(
|
||||
createGeneratedAssetsFromDrafts(
|
||||
assetDrafts,
|
||||
generatedItemAssets,
|
||||
).filter(hasPersistableMatch3DGeneratedItemAsset),
|
||||
);
|
||||
}
|
||||
|
||||
function Match3DResultHeader({
|
||||
|
||||
Reference in New Issue
Block a user