63790e22ef
生成画板视频时截取首帧并上传为封面 将视频生成结果写入素材库并保留 thumbnailSrc 同步后端契约、SpacetimeDB 绑定、前端素材库和画布层映射 补充相关测试与文档说明
980 lines
28 KiB
TypeScript
980 lines
28 KiB
TypeScript
import { requestJson } from '../apiClient';
|
|
import type { ExternalGenerationJobStatusRecord } from '../../../packages/shared/src/contracts/externalGeneration';
|
|
import { EDITOR_REQUEST_RETRY_OPTIONS } from './editorRetryOptions';
|
|
|
|
const EDITOR_PROJECT_API_BASE = '/api/editor/projects';
|
|
const EDITOR_ASSET_API_BASE = '/api/editor/assets';
|
|
const EDITOR_SHOWCASE_RESOURCE_API = '/api/editor/showcase/resources';
|
|
const EDITOR_PROJECT_RESOURCE_API_BASE = '/api/editor/project-resources';
|
|
const EDITOR_IMAGE_GENERATION_API = '/api/editor/images/generations';
|
|
const EDITOR_IMAGE_EDIT_API = '/api/editor/images/edits';
|
|
const EDITOR_ICON_SPRITESHEET_GENERATION_API =
|
|
'/api/editor/icon-spritesheets/generations';
|
|
const EDITOR_UI_DESIGN_ASSET_EXTRACTION_API =
|
|
'/api/editor/ui-designs/assets/extractions';
|
|
const EDITOR_CHARACTER_ANIMATION_GENERATION_API =
|
|
'/api/editor/character-animations/generations';
|
|
const EDITOR_VIDEO_GENERATION_API = '/api/editor/videos/generations';
|
|
const EDITOR_SOUND_EFFECT_GENERATION_API =
|
|
'/api/editor/audios/sound-effects/generations';
|
|
const EDITOR_BACKGROUND_MUSIC_GENERATION_API =
|
|
'/api/editor/audios/background-music/generations';
|
|
const EDITOR_GENERATION_PRICING_API = '/api/editor/generation-pricing';
|
|
const EDITOR_IMAGE_MODEL_NANOBANANA2 = 'gemini-3.1-flash-image-preview';
|
|
const DEFAULT_PROJECT_TITLE = '未命名画布';
|
|
|
|
export type EditorCanvasViewport = {
|
|
x: number;
|
|
y: number;
|
|
scale: number;
|
|
};
|
|
|
|
export type EditorProjectLayerSnapshot = Record<string, unknown> & {
|
|
layerId: string;
|
|
resourceId: string;
|
|
};
|
|
|
|
export type EditorAssetGenerationInputField = {
|
|
title: string;
|
|
value: string;
|
|
};
|
|
|
|
export type EditorAssetGenerationInputReference = {
|
|
title: string;
|
|
label: string;
|
|
refType: 'project-resource' | 'asset';
|
|
refId: string;
|
|
};
|
|
|
|
export type EditorAssetGenerationInputs = {
|
|
fields: EditorAssetGenerationInputField[];
|
|
references: EditorAssetGenerationInputReference[];
|
|
};
|
|
|
|
export type EditorProjectResourceSourceType =
|
|
| 'uploaded'
|
|
| 'generated'
|
|
| 'mock_generated';
|
|
|
|
export type EditorProjectResourceSnapshot = {
|
|
resourceId: string;
|
|
projectId: string;
|
|
ownerUserId?: string | null;
|
|
authorDisplayName?: string | null;
|
|
authorPublicUserCode?: string | null;
|
|
imageSrc: string;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: EditorProjectResourceSourceType;
|
|
prompt?: string | null;
|
|
actualPrompt?: string | null;
|
|
model?: string | null;
|
|
provider?: string | null;
|
|
taskId?: string | null;
|
|
durationSeconds?: number | null;
|
|
sourceResourceId?: string | null;
|
|
assetKind?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
publicShowcaseEnabled?: boolean;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type EditorAssetFolderSnapshot = {
|
|
folderId: string;
|
|
label: string;
|
|
sortOrder: number;
|
|
collapsed: boolean;
|
|
systemDefault: boolean;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type EditorAssetSnapshot = {
|
|
assetId: string;
|
|
folderId: string;
|
|
label: string;
|
|
imageSrc: string;
|
|
thumbnailSrc?: string | null;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: EditorProjectResourceSourceType;
|
|
prompt?: string | null;
|
|
actualPrompt?: string | null;
|
|
model?: string | null;
|
|
provider?: string | null;
|
|
taskId?: string | null;
|
|
durationSeconds?: number | null;
|
|
sourceResourceId?: string | null;
|
|
assetKind?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
publicShowcaseEnabled?: boolean | null;
|
|
createdAt?: string;
|
|
updatedAt?: string;
|
|
};
|
|
|
|
export type EditorAssetLibrarySnapshot = {
|
|
folders: EditorAssetFolderSnapshot[];
|
|
assets: EditorAssetSnapshot[];
|
|
};
|
|
|
|
export type EditorImageGenerationInput = {
|
|
prompt: string;
|
|
size?: string;
|
|
kind?:
|
|
| 'spec'
|
|
| 'character'
|
|
| 'quick-edit'
|
|
| 'ui-design'
|
|
| 'publication-material';
|
|
model?: string;
|
|
aspectRatio?: string;
|
|
imageSize?: string;
|
|
referenceImageSrcs?: string[];
|
|
projectId?: string | null;
|
|
assetKind?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
assetFolderId?: string | null;
|
|
assetLabel?: string | null;
|
|
sourceResourceId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
};
|
|
|
|
export type EditorCanvasGenerationCompletionInput = {
|
|
dialogId?: string;
|
|
title: string;
|
|
placeholder: {
|
|
x: number;
|
|
y: number;
|
|
width: number;
|
|
height: number;
|
|
originalWidth: number;
|
|
originalHeight: number;
|
|
};
|
|
};
|
|
|
|
export type EditorIconSpritesheetGenerationInput = {
|
|
referenceImageSrc: string;
|
|
referenceImageSrcs?: string[];
|
|
iconDescriptions: string[];
|
|
model?: string;
|
|
aspectRatio?: string;
|
|
imageSize?: string;
|
|
projectId?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
assetFolderId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
};
|
|
|
|
export type EditorUiDesignAssetExtractionInput = {
|
|
sourceImageSrc: string;
|
|
model?: string;
|
|
referenceImageSrcs?: string[];
|
|
aspectRatio?: string;
|
|
imageSize?: string;
|
|
projectId?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
assetFolderId?: string | null;
|
|
spritesheetLabel?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
};
|
|
|
|
export type EditorImageEditInput = {
|
|
prompt: string;
|
|
sourceImageSrc: string;
|
|
size?: string;
|
|
model?: string;
|
|
projectId?: string | null;
|
|
assetKind?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
assetFolderId?: string | null;
|
|
assetLabel?: string | null;
|
|
sourceResourceId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
};
|
|
|
|
export type EditorImageGenerationResult = {
|
|
imageSrc: string;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: 'generated';
|
|
prompt: string;
|
|
actualPrompt?: string | null;
|
|
model: string;
|
|
provider: string;
|
|
taskId: string;
|
|
resource?: EditorProjectResourceSnapshot | null;
|
|
asset?: EditorAssetSnapshot | null;
|
|
project?: EditorProjectSnapshot | null;
|
|
queueState?: ExternalGenerationJobStatusRecord | null;
|
|
};
|
|
|
|
export type EditorIconSpritesheetIconResult = {
|
|
name: string;
|
|
imageSrc: string;
|
|
width: number;
|
|
height: number;
|
|
resource?: EditorProjectResourceSnapshot | null;
|
|
asset?: EditorAssetSnapshot | null;
|
|
};
|
|
|
|
export type EditorIconSpritesheetGenerationResult = {
|
|
spritesheetImageSrc: string;
|
|
spritesheetWidth: number;
|
|
spritesheetHeight: number;
|
|
iconImageSrcs: EditorIconSpritesheetIconResult[];
|
|
prompt: string;
|
|
actualPrompt?: string | null;
|
|
model: string;
|
|
provider: string;
|
|
taskId: string;
|
|
priceMudPoints: number;
|
|
spritesheetResource?: EditorProjectResourceSnapshot | null;
|
|
spritesheetAsset?: EditorAssetSnapshot | null;
|
|
project?: EditorProjectSnapshot | null;
|
|
queueState?: ExternalGenerationJobStatusRecord | null;
|
|
};
|
|
|
|
export type EditorCharacterAnimationResolution = '480p' | '720p';
|
|
|
|
export type EditorCharacterAnimationRatio =
|
|
| 'same'
|
|
| '1:1'
|
|
| '4:3'
|
|
| '16:9'
|
|
| '9:16'
|
|
| '3:4';
|
|
|
|
export type EditorCharacterAnimationFrameCount = 32 | 40 | 48;
|
|
|
|
export type EditorCharacterAnimationDurationSeconds = 4 | 5 | 6;
|
|
|
|
export type EditorCharacterAnimationGenerationInput = {
|
|
sourceLayerId: string;
|
|
sourceImageSrc: string;
|
|
sourceWidth: number;
|
|
sourceHeight: number;
|
|
promptText: string;
|
|
resolution: EditorCharacterAnimationResolution;
|
|
ratio: EditorCharacterAnimationRatio;
|
|
frameCount: EditorCharacterAnimationFrameCount;
|
|
durationSeconds: EditorCharacterAnimationDurationSeconds;
|
|
model: 'seedance2.0-fast';
|
|
projectId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
sourceResourceId?: string | null;
|
|
};
|
|
|
|
export type EditorCharacterAnimationFrameResult = {
|
|
frameIndex: number;
|
|
imageSrc: string;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
};
|
|
|
|
export type EditorCharacterAnimationGenerationResult = {
|
|
taskId: string;
|
|
model: 'seedance2.0-fast';
|
|
prompt: string;
|
|
previewVideoPath: string;
|
|
frames: EditorCharacterAnimationFrameResult[];
|
|
frameCount: number;
|
|
durationSeconds: number;
|
|
fps: number;
|
|
priceMudPoints: number;
|
|
project?: EditorProjectSnapshot | null;
|
|
queueState?: ExternalGenerationJobStatusRecord | null;
|
|
};
|
|
|
|
export type EditorVideoModel =
|
|
| 'seedance2.0'
|
|
| 'seedance2.0-fast'
|
|
| 'kling3.0'
|
|
| 'kling3.0-omni'
|
|
| 'veo3.1'
|
|
| 'veo3.1-fast';
|
|
|
|
export type EditorVideoResolution = '480p' | '720p' | '1080p';
|
|
export type EditorVideoSoundMode = 'on' | 'off';
|
|
export type EditorVideoAspectRatio =
|
|
| '16:9'
|
|
| '9:16'
|
|
| '1:1'
|
|
| '4:3'
|
|
| '3:4'
|
|
| '21:9';
|
|
|
|
export type EditorVideoGenerationInput = {
|
|
prompt: string;
|
|
model: EditorVideoModel;
|
|
aspectRatio: EditorVideoAspectRatio;
|
|
durationSeconds: number;
|
|
resolution: EditorVideoResolution;
|
|
mode: 'std';
|
|
sound: EditorVideoSoundMode;
|
|
webSearchEnabled?: boolean;
|
|
referenceImageSrcs?: string[];
|
|
referenceVideoSrcs?: string[];
|
|
referenceAudioSrcs?: string[];
|
|
projectId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
sourceResourceId?: string | null;
|
|
assetKind?: string | null;
|
|
assetFolderId?: string | null;
|
|
assetLabel?: string | null;
|
|
};
|
|
|
|
export type EditorVideoGenerationResult = {
|
|
videoSrc: string;
|
|
thumbnailSrc?: string | null;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: 'generated';
|
|
prompt: string;
|
|
actualPrompt?: string | null;
|
|
model: string;
|
|
provider: string;
|
|
taskId: string;
|
|
durationSeconds: number;
|
|
priceMudPoints?: number;
|
|
project?: EditorProjectSnapshot | null;
|
|
asset?: EditorAssetSnapshot | null;
|
|
queueState?: ExternalGenerationJobStatusRecord | null;
|
|
};
|
|
|
|
export type EditorSoundEffectGenerationInput = {
|
|
prompt: string;
|
|
model: 'audio1.0';
|
|
duration: number;
|
|
projectId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
};
|
|
|
|
export type EditorBackgroundMusicGenerationInput = {
|
|
gptDescriptionPrompt: string;
|
|
makeInstrumental: true;
|
|
projectId?: string | null;
|
|
canvasCompletion?: EditorCanvasGenerationCompletionInput | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
};
|
|
|
|
export type EditorAudioGenerationResult = {
|
|
audioSrc: string;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: 'generated';
|
|
prompt: string;
|
|
actualPrompt?: string | null;
|
|
model: string;
|
|
provider: string;
|
|
taskId: string;
|
|
priceMudPoints: number;
|
|
audioKind: 'sound-effect' | 'background-music';
|
|
durationSeconds?: number | null;
|
|
project?: EditorProjectSnapshot | null;
|
|
queueState?: ExternalGenerationJobStatusRecord | null;
|
|
};
|
|
|
|
export type EditorGenerationPricingUnit = 'perGeneration' | 'perSecond';
|
|
|
|
export type EditorGenerationModelPricing = {
|
|
unit: EditorGenerationPricingUnit;
|
|
price?: number;
|
|
prices?: Record<string, number>;
|
|
};
|
|
|
|
export type EditorGenerationPricingConfig = {
|
|
models: Record<string, EditorGenerationModelPricing>;
|
|
};
|
|
|
|
export type EditorProjectSnapshot = {
|
|
projectId: string;
|
|
title: string;
|
|
canvas?: EditorCanvasSnapshot;
|
|
viewport: EditorCanvasViewport;
|
|
layers: EditorProjectLayerSnapshot[];
|
|
resources: EditorProjectResourceSnapshot[];
|
|
updatedAt: string;
|
|
};
|
|
|
|
export type EditorCanvasSnapshot = {
|
|
canvasId: string;
|
|
projectId: string;
|
|
title: string;
|
|
viewport: EditorCanvasViewport;
|
|
layers: EditorProjectLayerSnapshot[];
|
|
createdAt?: string;
|
|
updatedAt: string;
|
|
};
|
|
|
|
export type EditorProjectCreateInput = {
|
|
title?: string;
|
|
};
|
|
|
|
export type EditorProjectLayoutSaveInput = {
|
|
viewport: EditorCanvasViewport;
|
|
layers: EditorProjectLayerSnapshot[];
|
|
};
|
|
|
|
export type EditorProjectLayoutSaveResult = {
|
|
projectId: string;
|
|
canvasId: string;
|
|
updatedAt: string;
|
|
};
|
|
|
|
export type EditorProjectResourceCreateInput = {
|
|
imageSrc: string;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: EditorProjectResourceSourceType;
|
|
prompt?: string | null;
|
|
actualPrompt?: string | null;
|
|
model?: string | null;
|
|
provider?: string | null;
|
|
taskId?: string | null;
|
|
durationSeconds?: number | null;
|
|
sourceResourceId?: string | null;
|
|
assetKind?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
};
|
|
|
|
export type EditorAssetCreateInput = {
|
|
folderId: string;
|
|
label: string;
|
|
imageSrc: string;
|
|
objectKey?: string | null;
|
|
assetObjectId?: string | null;
|
|
width: number;
|
|
height: number;
|
|
sourceType: EditorProjectResourceSourceType;
|
|
prompt?: string | null;
|
|
actualPrompt?: string | null;
|
|
model?: string | null;
|
|
provider?: string | null;
|
|
taskId?: string | null;
|
|
durationSeconds?: number | null;
|
|
assetKind?: string | null;
|
|
generationInputs?: EditorAssetGenerationInputs | null;
|
|
};
|
|
|
|
export type EditorAssetUpdateInput = {
|
|
label?: string;
|
|
folderId?: string;
|
|
};
|
|
|
|
type EditorProjectResponse = {
|
|
project: EditorProjectSnapshot;
|
|
};
|
|
|
|
type EditorProjectLayoutSaveResponse = EditorProjectLayoutSaveResult;
|
|
|
|
type EditorProjectRecentResponse = {
|
|
project: EditorProjectSnapshot | null;
|
|
};
|
|
|
|
type EditorProjectResourceResponse = {
|
|
resource: EditorProjectResourceSnapshot;
|
|
};
|
|
|
|
type EditorProjectResourceListResponse = {
|
|
resources: EditorProjectResourceSnapshot[];
|
|
};
|
|
|
|
type EditorAssetLibraryResponse = {
|
|
library: EditorAssetLibrarySnapshot;
|
|
};
|
|
|
|
type EditorAssetFolderResponse = {
|
|
folder: EditorAssetFolderSnapshot;
|
|
};
|
|
|
|
type EditorAssetFolderDeleteResponse = {
|
|
library: EditorAssetLibrarySnapshot;
|
|
};
|
|
|
|
type EditorAssetResponse = {
|
|
asset: EditorAssetSnapshot;
|
|
};
|
|
|
|
type EditorImageGenerationResponse = EditorImageGenerationResult;
|
|
type EditorIconSpritesheetGenerationResponse =
|
|
EditorIconSpritesheetGenerationResult;
|
|
type EditorVideoGenerationResponse = EditorVideoGenerationResult;
|
|
type EditorAudioGenerationResponse = EditorAudioGenerationResult;
|
|
|
|
function jsonRequest(method: 'POST' | 'PATCH', body: Record<string, unknown>) {
|
|
return {
|
|
method,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
};
|
|
}
|
|
|
|
export async function listEditorProjects() {
|
|
const response = await requestJson<{ projects: EditorProjectSnapshot[] }>(
|
|
EDITOR_PROJECT_API_BASE,
|
|
{ method: 'GET' },
|
|
'读取图片画布工程列表失败',
|
|
);
|
|
return response.projects;
|
|
}
|
|
|
|
export async function listPublicEditorProjectResources() {
|
|
const response = await requestJson<EditorProjectResourceListResponse>(
|
|
EDITOR_SHOWCASE_RESOURCE_API,
|
|
{ method: 'GET' },
|
|
'读取陶泥儿精选素材失败',
|
|
{
|
|
skipAuth: true,
|
|
skipRefresh: true,
|
|
notifyAuthStateChange: false,
|
|
clearAuthOnUnauthorized: false,
|
|
},
|
|
);
|
|
return response.resources;
|
|
}
|
|
|
|
export async function loadRecentEditorProject() {
|
|
return requestJson<EditorProjectRecentResponse>(
|
|
`${EDITOR_PROJECT_API_BASE}/recent`,
|
|
{ method: 'GET' },
|
|
'读取图片画布工程失败',
|
|
);
|
|
}
|
|
|
|
export async function createEditorProject(
|
|
input: EditorProjectCreateInput = {},
|
|
) {
|
|
const response = await requestJson<EditorProjectResponse>(
|
|
EDITOR_PROJECT_API_BASE,
|
|
jsonRequest('POST', {
|
|
title: input.title?.trim() || DEFAULT_PROJECT_TITLE,
|
|
}),
|
|
'创建图片画布工程失败',
|
|
);
|
|
return response.project;
|
|
}
|
|
|
|
export async function loadOrCreateRecentEditorProject() {
|
|
const response = await loadRecentEditorProject();
|
|
if (response.project) {
|
|
return response.project;
|
|
}
|
|
return createEditorProject({ title: DEFAULT_PROJECT_TITLE });
|
|
}
|
|
|
|
export async function loadEditorGenerationPricing() {
|
|
return requestJson<EditorGenerationPricingConfig>(
|
|
EDITOR_GENERATION_PRICING_API,
|
|
{ method: 'GET' },
|
|
'读取模型定价失败',
|
|
{
|
|
skipAuth: true,
|
|
skipRefresh: true,
|
|
notifyAuthStateChange: false,
|
|
clearAuthOnUnauthorized: false,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function loadEditorProject(projectId: string) {
|
|
const response = await requestJson<EditorProjectResponse>(
|
|
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}`,
|
|
{ method: 'GET' },
|
|
'读取图片画布工程失败',
|
|
);
|
|
return response.project;
|
|
}
|
|
|
|
export async function renameEditorProject(projectId: string, title: string) {
|
|
const response = await requestJson<EditorProjectResponse>(
|
|
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}/metadata`,
|
|
jsonRequest('PATCH', { title }),
|
|
'重命名图片画布工程失败',
|
|
);
|
|
return response.project;
|
|
}
|
|
|
|
export async function deleteEditorProject(projectId: string) {
|
|
const response = await requestJson<{ deletedProjectId: string }>(
|
|
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}`,
|
|
{ method: 'DELETE' },
|
|
'删除图片画布工程失败',
|
|
);
|
|
return response.deletedProjectId;
|
|
}
|
|
|
|
export async function saveEditorProjectLayout(
|
|
projectId: string,
|
|
input: EditorProjectLayoutSaveInput,
|
|
) {
|
|
return requestJson<EditorProjectLayoutSaveResponse>(
|
|
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}`,
|
|
jsonRequest('PATCH', {
|
|
viewport: input.viewport,
|
|
layers: input.layers,
|
|
}),
|
|
'保存图片画布工程失败',
|
|
);
|
|
}
|
|
|
|
export async function createEditorProjectResource(
|
|
projectId: string,
|
|
input: EditorProjectResourceCreateInput,
|
|
) {
|
|
const response = await requestJson<EditorProjectResourceResponse>(
|
|
`${EDITOR_PROJECT_API_BASE}/${encodeURIComponent(projectId)}/resources`,
|
|
jsonRequest('POST', { ...input }),
|
|
'创建图片画布资源失败',
|
|
);
|
|
return response.resource;
|
|
}
|
|
|
|
export async function updateEditorProjectResourceShowcase(
|
|
resourceId: string,
|
|
publicShowcaseEnabled: boolean,
|
|
) {
|
|
const response = await requestJson<EditorProjectResourceResponse>(
|
|
`${EDITOR_PROJECT_RESOURCE_API_BASE}/${encodeURIComponent(resourceId)}/showcase`,
|
|
jsonRequest('PATCH', { publicShowcaseEnabled }),
|
|
'更新素材公开展示状态失败',
|
|
);
|
|
return response.resource;
|
|
}
|
|
|
|
export async function loadEditorAssetLibrary() {
|
|
const response = await requestJson<EditorAssetLibraryResponse>(
|
|
`${EDITOR_ASSET_API_BASE}/library`,
|
|
{ method: 'GET' },
|
|
'读取图片画布素材库失败',
|
|
);
|
|
return response.library;
|
|
}
|
|
|
|
export async function createEditorAssetFolder(
|
|
label: string,
|
|
sortOrder?: number,
|
|
) {
|
|
const response = await requestJson<EditorAssetFolderResponse>(
|
|
`${EDITOR_ASSET_API_BASE}/folders`,
|
|
jsonRequest('POST', { label, sortOrder }),
|
|
'创建图片画布素材文件夹失败',
|
|
);
|
|
return response.folder;
|
|
}
|
|
|
|
export async function updateEditorAssetFolder(
|
|
folderId: string,
|
|
input: { label?: string; collapsed?: boolean },
|
|
) {
|
|
const response = await requestJson<EditorAssetFolderResponse>(
|
|
`${EDITOR_ASSET_API_BASE}/folders/${encodeURIComponent(folderId)}`,
|
|
jsonRequest('PATCH', input),
|
|
'更新图片画布素材文件夹失败',
|
|
);
|
|
return response.folder;
|
|
}
|
|
|
|
export async function deleteEditorAssetFolder(folderId: string) {
|
|
const response = await requestJson<EditorAssetFolderDeleteResponse>(
|
|
`${EDITOR_ASSET_API_BASE}/folders/${encodeURIComponent(folderId)}`,
|
|
{ method: 'DELETE' },
|
|
'删除图片画布素材文件夹失败',
|
|
);
|
|
return response.library;
|
|
}
|
|
|
|
export async function createEditorAsset(input: EditorAssetCreateInput) {
|
|
const response = await requestJson<EditorAssetResponse>(
|
|
EDITOR_ASSET_API_BASE,
|
|
jsonRequest('POST', input),
|
|
'创建图片画布素材失败',
|
|
);
|
|
return response.asset;
|
|
}
|
|
|
|
export async function updateEditorAsset(
|
|
assetId: string,
|
|
input: EditorAssetUpdateInput,
|
|
) {
|
|
const response = await requestJson<EditorAssetResponse>(
|
|
`${EDITOR_ASSET_API_BASE}/${encodeURIComponent(assetId)}`,
|
|
jsonRequest('PATCH', input),
|
|
'更新图片画布素材失败',
|
|
);
|
|
return response.asset;
|
|
}
|
|
|
|
export async function deleteEditorAsset(assetId: string) {
|
|
const response = await requestJson<EditorAssetResponse>(
|
|
`${EDITOR_ASSET_API_BASE}/${encodeURIComponent(assetId)}`,
|
|
{ method: 'DELETE' },
|
|
'删除图片画布素材失败',
|
|
);
|
|
return response.asset;
|
|
}
|
|
|
|
export async function generateEditorImage(input: EditorImageGenerationInput) {
|
|
return requestJson<EditorImageGenerationResponse>(
|
|
EDITOR_IMAGE_GENERATION_API,
|
|
jsonRequest('POST', {
|
|
prompt: input.prompt,
|
|
...(input.size ? { size: input.size } : {}),
|
|
...(input.kind ? { kind: input.kind } : {}),
|
|
...(input.model ? { model: input.model } : {}),
|
|
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
|
|
...(input.imageSize ? { imageSize: input.imageSize } : {}),
|
|
...(input.referenceImageSrcs?.length
|
|
? { referenceImageSrcs: input.referenceImageSrcs }
|
|
: {}),
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.assetKind ? { assetKind: input.assetKind } : {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
|
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
|
|
...(input.sourceResourceId
|
|
? { sourceResourceId: input.sourceResourceId }
|
|
: {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
}),
|
|
'生成图片失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function generateEditorIconSpritesheet(
|
|
input: EditorIconSpritesheetGenerationInput,
|
|
) {
|
|
return requestJson<EditorIconSpritesheetGenerationResponse>(
|
|
EDITOR_ICON_SPRITESHEET_GENERATION_API,
|
|
jsonRequest('POST', {
|
|
referenceImageSrc: input.referenceImageSrc,
|
|
...(input.referenceImageSrcs?.length
|
|
? { referenceImageSrcs: input.referenceImageSrcs }
|
|
: {}),
|
|
iconDescriptions: input.iconDescriptions,
|
|
model: input.model?.trim() || EDITOR_IMAGE_MODEL_NANOBANANA2,
|
|
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
|
|
...(input.imageSize ? { imageSize: input.imageSize } : {}),
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
}),
|
|
'生成图标素材失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function extractEditorUiDesignAssets(
|
|
input: EditorUiDesignAssetExtractionInput,
|
|
) {
|
|
return requestJson<EditorIconSpritesheetGenerationResponse>(
|
|
EDITOR_UI_DESIGN_ASSET_EXTRACTION_API,
|
|
jsonRequest('POST', {
|
|
sourceImageSrc: input.sourceImageSrc,
|
|
...(input.model ? { model: input.model } : {}),
|
|
...(input.referenceImageSrcs?.length
|
|
? { referenceImageSrcs: input.referenceImageSrcs }
|
|
: {}),
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
|
...(input.spritesheetLabel
|
|
? { spritesheetLabel: input.spritesheetLabel }
|
|
: {}),
|
|
...(input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}),
|
|
...(input.imageSize ? { imageSize: input.imageSize } : {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
}),
|
|
'提取UI设计图素材失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function editEditorImage(input: EditorImageEditInput) {
|
|
return requestJson<EditorImageGenerationResponse>(
|
|
EDITOR_IMAGE_EDIT_API,
|
|
jsonRequest('POST', {
|
|
prompt: input.prompt,
|
|
sourceImageSrc: input.sourceImageSrc,
|
|
...(input.size ? { size: input.size } : {}),
|
|
...(input.model ? { model: input.model } : {}),
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.assetKind ? { assetKind: input.assetKind } : {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
|
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
|
|
...(input.sourceResourceId
|
|
? { sourceResourceId: input.sourceResourceId }
|
|
: {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
}),
|
|
'修改图片失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function generateEditorCharacterAnimation(
|
|
input: EditorCharacterAnimationGenerationInput,
|
|
) {
|
|
return requestJson<EditorCharacterAnimationGenerationResult>(
|
|
EDITOR_CHARACTER_ANIMATION_GENERATION_API,
|
|
jsonRequest('POST', {
|
|
...input,
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
...(input.sourceResourceId
|
|
? { sourceResourceId: input.sourceResourceId }
|
|
: {}),
|
|
}),
|
|
'生成角色动画失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function generateEditorVideo(input: EditorVideoGenerationInput) {
|
|
return requestJson<EditorVideoGenerationResponse>(
|
|
EDITOR_VIDEO_GENERATION_API,
|
|
jsonRequest('POST', {
|
|
prompt: input.prompt,
|
|
model: input.model,
|
|
aspectRatio: input.aspectRatio,
|
|
durationSeconds: input.durationSeconds,
|
|
resolution: input.resolution,
|
|
mode: input.mode,
|
|
sound: input.sound,
|
|
webSearchEnabled: input.webSearchEnabled ?? true,
|
|
...(input.referenceImageSrcs?.length
|
|
? { referenceImageSrcs: input.referenceImageSrcs }
|
|
: {}),
|
|
...(input.referenceVideoSrcs?.length
|
|
? { referenceVideoSrcs: input.referenceVideoSrcs }
|
|
: {}),
|
|
...(input.referenceAudioSrcs?.length
|
|
? { referenceAudioSrcs: input.referenceAudioSrcs }
|
|
: {}),
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
...(input.sourceResourceId
|
|
? { sourceResourceId: input.sourceResourceId }
|
|
: {}),
|
|
...(input.assetKind ? { assetKind: input.assetKind } : {}),
|
|
...(input.assetFolderId ? { assetFolderId: input.assetFolderId } : {}),
|
|
...(input.assetLabel ? { assetLabel: input.assetLabel } : {}),
|
|
}),
|
|
'生成视频失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function generateEditorSoundEffect(
|
|
input: EditorSoundEffectGenerationInput,
|
|
) {
|
|
return requestJson<EditorAudioGenerationResponse>(
|
|
EDITOR_SOUND_EFFECT_GENERATION_API,
|
|
jsonRequest('POST', {
|
|
prompt: input.prompt,
|
|
model: input.model,
|
|
duration: input.duration,
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
}),
|
|
'生成游戏音效失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|
|
|
|
export async function generateEditorBackgroundMusic(
|
|
input: EditorBackgroundMusicGenerationInput,
|
|
) {
|
|
return requestJson<EditorAudioGenerationResponse>(
|
|
EDITOR_BACKGROUND_MUSIC_GENERATION_API,
|
|
jsonRequest('POST', {
|
|
gptDescriptionPrompt: input.gptDescriptionPrompt,
|
|
makeInstrumental: input.makeInstrumental,
|
|
...(input.projectId ? { projectId: input.projectId } : {}),
|
|
...(input.canvasCompletion
|
|
? { canvasCompletion: input.canvasCompletion }
|
|
: {}),
|
|
...(input.generationInputs
|
|
? { generationInputs: input.generationInputs }
|
|
: {}),
|
|
}),
|
|
'生成游戏背景音乐失败',
|
|
{
|
|
timeoutMs: 1_200_000,
|
|
retry: EDITOR_REQUEST_RETRY_OPTIONS,
|
|
},
|
|
);
|
|
}
|