fix: 修复多个运行时崩溃和功能bug,优化画布连接线和剧本评分

- 修复 EcommercePage generateEcommerceImage 调用不存在变量导致运行时崩溃
- 修复 DigitalHumanPage/ImageWorkbenchPage 变量名错误导致页面不可用
- 修复 ecommerceVideoService token 读取用错 key 导致请求 401
- 修复画布连接线在弹窗出现后仍跟随鼠标的问题
- 剧本评分 .docx 文件改为服务端 mammoth 解析(新增 /api/files/extract-text)
- ErrorBoundary 加 key 支持切换页面时自动重置
- Vite proxy 改为指向公网域名 omniai.net.cn
- 新增视频生成历史记录面板和删除确认弹窗

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 01:12:51 +08:00
parent 6bb71fcc19
commit 7c6129555b
12 changed files with 637 additions and 105 deletions
@@ -258,3 +258,73 @@ export function buildSceneTasks(
};
});
}
// ── Video History API ──────────────────────────────────
export interface VideoHistoryScene {
sceneId: number;
prompt: string;
imageUrl?: string | null;
videoUrl?: string | null;
}
export interface VideoHistoryItem {
id: number;
title: string;
config: Record<string, unknown>;
scenes: VideoHistoryScene[];
sourceImageUrls: string[];
createdAt: string;
}
export interface VideoHistoryListResponse {
items: VideoHistoryItem[];
total: number;
limit: number;
offset: number;
}
import { getStoredToken } from "../../api/serverConnection";
const API_BASE = "/api/ai/ecommerce/video-history";
function getAuthHeaders(): Record<string, string> {
const token = getStoredToken();
return token ? { Authorization: `Bearer ${token}` } : {};
}
export async function saveVideoHistory(payload: {
title: string;
config: Record<string, unknown>;
plan: Record<string, unknown>;
scenes: VideoHistoryScene[];
sourceImageUrls: string[];
}): Promise<{ id: number; createdAt: string }> {
const res = await fetch(API_BASE, {
method: "POST",
headers: { "Content-Type": "application/json", ...getAuthHeaders() },
body: JSON.stringify(payload),
});
if (!res.ok) throw new Error("保存历史记录失败");
return res.json();
}
export async function fetchVideoHistory(
limit = 20,
offset = 0,
): Promise<VideoHistoryListResponse> {
const res = await fetch(
`${API_BASE}?limit=${limit}&offset=${offset}`,
{ headers: getAuthHeaders() },
);
if (!res.ok) throw new Error("获取历史记录失败");
return res.json();
}
export async function deleteVideoHistory(id: number): Promise<void> {
const res = await fetch(`${API_BASE}/${id}`, {
method: "DELETE",
headers: getAuthHeaders(),
});
if (!res.ok) throw new Error("删除失败");
}