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:
30
web/src/lib/canvas/canvas-context-summary.ts
Normal file
30
web/src/lib/canvas/canvas-context-summary.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { ProjectUnit } from "@/services/api/projects";
|
||||
import type { CanvasNodeData } from "@/types/canvas";
|
||||
|
||||
export type CanvasContextSummary = {
|
||||
nodeCount: number;
|
||||
selectedCount: number;
|
||||
chapterLabel: string;
|
||||
shotLabel: string;
|
||||
};
|
||||
|
||||
export function summarizeCanvasContext(nodes: CanvasNodeData[], selectedNodeIds: Set<string>, units: ProjectUnit[] = []): CanvasContextSummary {
|
||||
const selectedNodes = nodes.filter((node) => selectedNodeIds.has(node.id));
|
||||
const unitTitleById = new Map(units.map((unit) => [unit.id, unit.title]));
|
||||
const chapterTitles = unique(selectedNodes.flatMap((node) => {
|
||||
const chapterTitle = node.metadata?.chapterTitle || (node.metadata?.chapterId ? unitTitleById.get(node.metadata.chapterId) : "");
|
||||
return chapterTitle ? [chapterTitle] : [];
|
||||
}));
|
||||
const shotIndexes = unique(selectedNodes.flatMap((node) => typeof node.metadata?.shotIndex === "number" ? [node.metadata.shotIndex] : []));
|
||||
|
||||
return {
|
||||
nodeCount: nodes.length,
|
||||
selectedCount: selectedNodes.length,
|
||||
chapterLabel: chapterTitles.length === 1 ? chapterTitles[0] : chapterTitles.length > 1 ? `${chapterTitles.length} 个章节` : "",
|
||||
shotLabel: shotIndexes.length === 1 ? `镜头 ${shotIndexes[0] + 1}` : shotIndexes.length > 1 ? `${shotIndexes.length} 个镜头` : "",
|
||||
};
|
||||
}
|
||||
|
||||
function unique<T>(values: T[]) {
|
||||
return Array.from(new Set(values));
|
||||
}
|
||||
Reference in New Issue
Block a user