完成图片编辑器宣发素材生成

新增宣发素材入口、工作流模型、画布生成卡片和参考图选择能力。

接入宣发素材真实生图请求,隐藏 Prompt 摘要和约束预览,并将约束作为内部 Prompt 使用。

支持游戏首图、详情五图、运营海报尺寸,其中详情五图一次生成五张 720x1280 竖图。

后端仅对 publication-material 生图扣 5 泥点,并沿用现有失败退款逻辑。

补充前后端测试和宣发素材设计文档。
This commit is contained in:
Codex
2026-06-18 00:05:25 +08:00
parent 7dec8b7a66
commit 0ebf6242bb
34 changed files with 1883 additions and 86 deletions
@@ -698,6 +698,49 @@ describe('editorProjectClient', () => {
);
});
it('passes publication material generation kind and size to the backend BFF', async () => {
requestJsonMock.mockResolvedValueOnce({
imageSrc: 'data:image/png;base64,publication',
width: 720,
height: 1280,
sourceType: 'generated',
prompt: '宣发素材 prompt',
actualPrompt: '宣发素材 prompt',
model: 'gpt-image-2',
provider: 'VectorEngine',
taskId: 'vector-publication-1',
});
const result = await generateEditorImage({
prompt: '宣发素材 prompt',
size: '720x1280',
kind: 'publication-material',
candidateCount: 5,
referenceImageSrcs: ['data:image/png;base64,ref'],
});
expect(result.height).toBe(1280);
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/editor/images/generations',
expect.objectContaining({
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: '宣发素材 prompt',
size: '720x1280',
kind: 'publication-material',
candidateCount: 5,
referenceImageSrcs: ['data:image/png;base64,ref'],
}),
}),
'生成图片失败',
expect.objectContaining({
timeoutMs: 1_200_000,
retry: { maxRetries: 0 },
}),
);
});
it('generates editor character animations through the backend BFF', async () => {
requestJsonMock.mockResolvedValueOnce({
taskId: 'character-animation-1',
@@ -83,10 +83,11 @@ export type EditorAssetLibrarySnapshot = {
export type EditorImageGenerationInput = {
prompt: string;
size?: string;
kind?: 'spec' | 'character' | 'quick-edit';
kind?: 'spec' | 'character' | 'quick-edit' | 'publication-material';
model?: string;
aspectRatio?: string;
imageSize?: string;
candidateCount?: number;
referenceImageSrcs?: string[];
};
@@ -105,7 +106,7 @@ export type EditorImageEditInput = {
model?: string;
};
export type EditorImageGenerationResult = {
export type EditorImageGenerationItemResult = {
imageSrc: string;
objectKey?: string | null;
assetObjectId?: string | null;
@@ -119,6 +120,10 @@ export type EditorImageGenerationResult = {
taskId: string;
};
export type EditorImageGenerationResult = EditorImageGenerationItemResult & {
images?: EditorImageGenerationItemResult[];
};
export type EditorIconSpritesheetIconResult = {
name: string;
imageSrc: string;
@@ -464,6 +469,7 @@ export async function generateEditorImage(input: EditorImageGenerationInput) {
...(input.model ? { model: input.model } : {}),
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
...(input.imageSize ? { imageSize: input.imageSize } : {}),
...(input.candidateCount ? { candidateCount: input.candidateCount } : {}),
...(input.referenceImageSrcs?.length
? { referenceImageSrcs: input.referenceImageSrcs }
: {}),