feat: 完成短剧项目空间与结构化资产创作闭环 (#38)
* feat(canvas): 短剧项目空间 - 建立项目章节与画布关联 MVP * feat(canvas): 短剧项目空间 - 完善项目资产、镜头与流程闭环 Refs #30 * fix(deploy): 本地部署 - 修复前端构建并忽略本地 PostgreSQL 配置 * feat(*): 短剧项目空间 - 完成项目、章节、资产、角色与画布创作闭环 Refs #30 --------- Co-authored-by: ddCat <ddcat666@88.com>
This commit is contained in:
1 parent
431b9e3294
commit
d2fbc413b3
208 files changed
+22655
-4234
No files matched your search
@@ -3,7 +3,7 @@ import { seedanceReferenceLabel } from "@/lib/seedance-video";
|
||||
import type { UpdreamSkill } from "@/services/api/skills";
|
||||
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData } from "@/types/canvas";
|
||||
|
||||
export type CanvasResourceKind = "image" | "video" | "audio" | "text" | "skill";
|
||||
export type CanvasResourceKind = "image" | "video" | "audio" | "text" | "skill" | "character";
|
||||
|
||||
export type CanvasResourceReference = {
|
||||
id: string;
|
||||
@@ -15,6 +15,7 @@ export type CanvasResourceReference = {
|
||||
storageKey?: string;
|
||||
text?: string;
|
||||
active: boolean;
|
||||
sourceType?: CanvasNodeType;
|
||||
skill?: UpdreamSkill;
|
||||
};
|
||||
|
||||
@@ -60,12 +61,13 @@ function getConnectedConfigResourceNodes(nodeId: string, nodes: CanvasNodeData[]
|
||||
}
|
||||
|
||||
function labelResourceNodes(nodes: CanvasNodeData[], active: boolean) {
|
||||
const counts: Record<CanvasResourceKind, number> = { image: 0, video: 0, audio: 0, text: 0, skill: 0 };
|
||||
const counts: Record<CanvasResourceKind, number> = { image: 0, video: 0, audio: 0, text: 0, skill: 0, character: 0 };
|
||||
let drawingCount = 0;
|
||||
return nodes.flatMap((node): CanvasResourceReference[] => {
|
||||
const kind = resourceKind(node);
|
||||
if (!kind) return [];
|
||||
const index = counts[kind]++;
|
||||
const label = labelForKind(kind, index);
|
||||
const index = node.type === CanvasNodeType.Drawing ? drawingCount++ : counts[kind]++;
|
||||
const label = node.type === CanvasNodeType.Drawing ? `绘图${index + 1}` : labelForKind(kind, index);
|
||||
return [
|
||||
{
|
||||
id: node.id,
|
||||
@@ -73,16 +75,18 @@ function labelResourceNodes(nodes: CanvasNodeData[], active: boolean) {
|
||||
kind,
|
||||
label,
|
||||
title: node.title || label,
|
||||
previewUrl: node.metadata?.content,
|
||||
previewUrl: node.metadata?.workflowKind === "character" ? node.metadata.characterCoverUrl : node.type === CanvasNodeType.Drawing ? node.metadata?.drawingPreviewUrl : node.metadata?.content,
|
||||
storageKey: node.metadata?.storageKey,
|
||||
text: node.type === CanvasNodeType.Text ? node.metadata?.content || node.metadata?.prompt : node.type === CanvasNodeType.Skill ? skillResourceText(node) : undefined,
|
||||
text: node.metadata?.workflowKind === "character" ? node.metadata.characterPrompt : node.type === CanvasNodeType.Text ? node.metadata?.content || node.metadata?.prompt : node.type === CanvasNodeType.Skill ? skillResourceText(node) : undefined,
|
||||
active,
|
||||
sourceType: node.type,
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
function labelForKind(kind: CanvasResourceKind, index: number) {
|
||||
if (kind === "character") return `角色${index + 1}`;
|
||||
if (kind === "image") return imageReferenceLabel(index);
|
||||
if (kind === "video") return seedanceReferenceLabel("video", index);
|
||||
if (kind === "audio") return seedanceReferenceLabel("audio", index);
|
||||
@@ -95,7 +99,9 @@ function isResourceNode(node: CanvasNodeData) {
|
||||
}
|
||||
|
||||
function resourceKind(node: CanvasNodeData): CanvasResourceKind | null {
|
||||
if (node.metadata?.workflowKind === "character" && node.metadata.characterAssetId) return "character";
|
||||
if (node.type === CanvasNodeType.Image && node.metadata?.content) return "image";
|
||||
if (node.type === CanvasNodeType.Drawing && node.metadata?.drawingId) return "image";
|
||||
if (node.type === CanvasNodeType.Video && node.metadata?.content) return "video";
|
||||
if (node.type === CanvasNodeType.Audio && node.metadata?.content) return "audio";
|
||||
if (node.type === CanvasNodeType.Text && (node.metadata?.content || node.metadata?.prompt)) return "text";
|
||||
|
||||
Reference in new issue
Block a user