video-flow-toon/src/routes/production/workbench/generateVideoPrompt.ts
2026-04-02 20:09:44 +08:00

101 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
import { info } from "node:console";
const router = express.Router();
export default router.post(
"/",
validateFields({
trackId: z.number(),
projectId: z.number(),
info: z.array(
z.object({
id: z.number(),
sources: z.string(),
}),
),
model: z.string(),
}),
async (req, res) => {
const { trackId, projectId, info, model } = req.body;
//查询参数
const images = await Promise.all(
info.map(async (item: { id: number; sources: string }) => {
if (item.sources === "storyboard") {
// 查询分镜主信息
const storyboard = await u
.db("o_storyboard")
.where("o_storyboard.id", item.id)
.select("videoDesc", "prompt", "track", "duration", "shouldGenerateImage")
.first();
// 查询分镜关联的资产ID
const assetRows = await u.db("o_assets2Storyboard").where("storyboardId", item.id).select("assetId");
const associateAssetsIds = assetRows.map((row: any) => row.assetId);
return {
...storyboard,
associateAssetsIds,
_type: "storyboard", // 标记类型,便于后续区分
};
}
if (item.sources === "assets") {
// 查询素材
const assetsData = await u.db("o_assets").where("o_assets.id", item.id).select("id", "type", "name").first();
return {
...assetsData,
_type: "assets", // 标记类型
};
}
}),
);
// 拆分 assets 和 storyboard
const assets: any[] = [];
const storyboard: any[] = [];
for (const item of images) {
if (!item) continue; // 忽略空
if (item._type === "assets")
assets.push({
id: item.id,
type: item.type,
name: item.name,
});
if (item._type === "storyboard")
storyboard.push({
videoDesc: item.videoDesc,
prompt: item.prompt,
track: item.track,
duration: item.duration,
associateAssetsIds: item.associateAssetsIds,
shouldGenerateImage: item.shouldGenerateImage,
});
}
const [id, modelData] = model.split(":");
const projectData = await u.db("o_project").select("*").where({ id: projectId }).first();
const videoPrompt = await u.db("o_prompt").where("type", "videoPromptGeneration").first();
const artStyle = projectData?.artStyle || "无";
const data = projectData?.directorManual || "无";
const visualManual = u.getArtPrompt(artStyle, "art_skills", "art_storyboard_video");
const directorManual = u.getArtPrompt(data, "story_skills", "narrative_sweet_romance");
const { text } = await u.Ai.Text("universalAi").invoke({
system: `${videoPrompt?.data}\n${visualManual}\n${directorManual}`,
messages: [
{
role: "user",
content: `
**模型名称**${modelData},
**资产信息**(角色、场景、道具):${JSON.stringify(assets)},
**分镜信息**${JSON.stringify(storyboard)},
`,
},
],
});
await u.db("o_videoTrack").where({ id: trackId }).update({
prompt: text,
});
res.status(200).send(success(text));
},
);