fix: 全站页面保活机制、登录拦截优化、UI修复与功能完善
- 移除未登录全页面拦截,改为浏览自由 + 功能使用时弹窗 - 修复PageTransition退出动画卡死导致黑屏的bug - CanvasPage添加加载中状态避免首次访问黑屏假死 - 全站7个工具页添加页面保活机制,切页后台任务不中断 - 修复未登录时401误触发"用户已在别处登录"弹窗 - 删除MorePage模板板块、微信登录、EcommerceTemplates/SizeTemplate路由 - 剧本评分接入DashScope qwen3.7-max直连API - 电商视频生成重构为3阶段可视管线(策划→生成图片→生成视频) - 电商视频保活增强:异步函数直接写localStorage避免卸载丢失 - Workbench侧边栏移除mode过滤,三模式共用同一对话列表 - 首页更新轮播图/背景视频、按钮跳转修正、文案优化 - AppShell顶栏新增网站备案信息按钮 - 多个页面的terminate/cancel按钮覆盖、单镜头重试、批量保存下载 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import type {
|
||||
export interface PlanCallbacks {
|
||||
onStepStart: (step: PlanStep) => void;
|
||||
onStepDone: (step: PlanStep) => void;
|
||||
onImagesUploaded?: (urls: string[]) => void;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
@@ -46,7 +47,9 @@ export async function runVideoPlan(
|
||||
// skip images that fail to upload
|
||||
}
|
||||
}
|
||||
if (!imageUrls.length) throw new Error("图片上传失败,请检查图片格式或网络后重试");
|
||||
onStepDone("upload");
|
||||
callbacks.onImagesUploaded?.(imageUrls);
|
||||
|
||||
onStepStart("analyze");
|
||||
const imageDesc = await analyzeProductImages(imageUrls, signal);
|
||||
@@ -80,6 +83,45 @@ export async function runVideoPlan(
|
||||
return { imageUrls, summary, selling, creatives, storyboard, videoPrompts, compliance };
|
||||
}
|
||||
|
||||
export interface RenderSceneImageInput {
|
||||
sceneId: number;
|
||||
prompt: string;
|
||||
aspectRatio: string;
|
||||
}
|
||||
|
||||
export interface RenderImageCallbacks {
|
||||
onSceneImageSubmitted: (sceneId: number, taskId: string) => void;
|
||||
onSceneImageProgress: (sceneId: number, progress: number) => void;
|
||||
onSceneImageCompleted: (sceneId: number, resultUrl: string) => void;
|
||||
onSceneImageFailed: (sceneId: number, error: string) => void;
|
||||
}
|
||||
|
||||
export async function renderSceneImage(
|
||||
input: RenderSceneImageInput,
|
||||
callbacks: RenderImageCallbacks,
|
||||
abortRef: { current: boolean },
|
||||
): Promise<void> {
|
||||
const { taskId } = await aiGenerationClient.createImageTask({
|
||||
model: "gpt-image-2",
|
||||
prompt: input.prompt,
|
||||
ratio: input.aspectRatio,
|
||||
quality: "2K",
|
||||
});
|
||||
|
||||
callbacks.onSceneImageSubmitted(input.sceneId, taskId);
|
||||
|
||||
const resultUrl = await waitForTask(taskId, {
|
||||
abortRef,
|
||||
onProgress: (e) => callbacks.onSceneImageProgress(input.sceneId, e.progress),
|
||||
});
|
||||
|
||||
if (resultUrl) {
|
||||
callbacks.onSceneImageCompleted(input.sceneId, resultUrl);
|
||||
} else {
|
||||
callbacks.onSceneImageFailed(input.sceneId, "图片生成未返回结果");
|
||||
}
|
||||
}
|
||||
|
||||
export interface RenderSceneInput {
|
||||
sceneId: number;
|
||||
prompt: string;
|
||||
@@ -114,7 +156,7 @@ export async function renderScene(
|
||||
duration: input.durationSeconds,
|
||||
quality: input.resolution,
|
||||
resolution: input.resolution,
|
||||
imageUrl: input.imageUrl,
|
||||
frameMode: "start-end",
|
||||
referenceUrls: [input.imageUrl],
|
||||
hasReferenceVideo: false,
|
||||
});
|
||||
@@ -137,12 +179,12 @@ export function buildSceneTasks(
|
||||
plan: EcommerceVideoPlanResult,
|
||||
): EcommerceVideoSceneTask[] {
|
||||
return plan.storyboard.scenes.map((scene) => {
|
||||
const prompt = plan.videoPrompts.find((p) => p.scene_id === scene.scene_id);
|
||||
const matchedPrompt = plan.videoPrompts.find((p) => p.scene_id === scene.scene_id);
|
||||
return {
|
||||
sceneId: scene.scene_id,
|
||||
prompt: prompt?.positive_prompt || scene.visual_description,
|
||||
prompt: matchedPrompt?.positive_prompt || scene.visual_description,
|
||||
durationSeconds: Number.parseInt(scene.duration, 10) || 5,
|
||||
status: "idle",
|
||||
status: "idle" as const,
|
||||
progress: 0,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user