修复bug:直接下载图片导致小图 修复,优化批量生成视频卡顿,改为一次性全部发送,后端分批发送任务,。 增加音色绑定,修复塑角造景生成图片失败导致分辨率丢失问题;增加批量删除分镜图

This commit is contained in:
DESKTOP-TR7ALU6\zcb 2026-04-29 18:14:27 +08:00
parent 8197cfcdec
commit 5a4c2319fd
23 changed files with 784 additions and 317 deletions

View File

@ -61,10 +61,9 @@ export async function runDecisionAI(ctx: AgentContext) {
videoMode = projectInfo.mode ?? "";
}
const isRef = Array.isArray(videoMode) ? true : false;
// console.log("%c Line:64 🍯 isRef", "background:#b03734", isRef);
// const findData = models.find((i: any) => i.modelName == videoModelName);
// const isRef = findData.mode.every((i: any) => Array.isArray(i));
console.log("%c Line:67 🍪 isRef", "background:#fca650", isRef);
const modelInfo = `项目使用的模型如下:\n图像模型${imageModelName}\n视频模型${videoModelName}\n多参${isRef ? "是" : "否"}`;
const mem = buildMemPrompt(await memory.get(text));
@ -153,7 +152,7 @@ async function createSubAgent(parentCtx: AgentContext) {
const models = await u.vendor.getModelList(id);
if (!models.length) throw new Error(`项目使用的模型不存在ID: ${projectInfo.videoModel}`);
// const findData = models.find((i: any) => i.modelName == videoModelName);
// console.log("%c Line:153 🍿 findData.mode", "background:#93c0a4", findData.mode);
//
let videoMode = "";
try {
videoMode = JSON.parse(projectInfo.mode ?? "");
@ -161,7 +160,7 @@ async function createSubAgent(parentCtx: AgentContext) {
videoMode = projectInfo.mode ?? "";
}
const isRef = Array.isArray(videoMode) ? true : false;
console.log("%c Line:153 🥤 isRef", "background:#42b983", isRef);
const modelInfo = `项目使用的模型如下:\n图像模型${imageModelName}\n视频模型${videoModelName}\n多参${isRef ? "是" : "否"}`;
// const run_sub_agent_execution = tool({

View File

@ -65,6 +65,7 @@ export default async (knex: Knex): Promise<void> => {
await addColumn("o_agentDeploy", "temperature", "integer");
// 添加新字段
await addColumn("o_agentDeploy", "maxOutputTokens", "integer");
await addColumn("o_assets", "audioBindState", "integer");
//添加数据高级配置
const advancedAgentList = [

View File

@ -58,7 +58,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => { },
initData: async (knex) => {},
},
//Agent配置表
{
@ -258,7 +258,6 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
maxOutputTokens: 0,
disabled: false,
},
]);
},
},
@ -332,7 +331,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => { },
initData: async (knex) => {},
},
//提示词表
{
@ -377,7 +376,7 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => { },
initData: async (knex) => {},
},
//小说原文表
{
@ -452,11 +451,12 @@ export default async (knex: Knex, forceInit: boolean = false): Promise<void> =>
table.integer("flowId"); //工作流id
table.integer("startTime");
table.string("promptState");
table.integer("audioBindState");
table.text("promptErrorReason");
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => { },
initData: async (knex) => {},
},
//生成图片表
{

View File

@ -1,4 +1,4 @@
// @routes-hash 8fa7db9525fe2ff96ba91e9bd6c22b65
// @routes-hash 902e3917f4bdb484fea4ea9219071a06
import { Express } from "express";
import route1 from "./routes/agents/clearMemory";
@ -30,130 +30,134 @@ import route26 from "./routes/assetsGenerate/polishAssetsPrompt";
import route27 from "./routes/common/getBigImage";
import route28 from "./routes/cornerScape/batchBindAudio";
import route29 from "./routes/cornerScape/getAllAssets";
import route30 from "./routes/cornerScape/updateAssetsAudio";
import route31 from "./routes/general/generalStatistics";
import route32 from "./routes/general/getSingleProject";
import route33 from "./routes/general/updateProject";
import route34 from "./routes/login/login";
import route35 from "./routes/modelSelect/getModelDetail";
import route36 from "./routes/modelSelect/getModelList";
import route37 from "./routes/novel/addNovel";
import route38 from "./routes/novel/batchDeleteNovel";
import route39 from "./routes/novel/delNovel";
import route40 from "./routes/novel/event/batchDeleteEvent";
import route41 from "./routes/novel/event/deletEvent";
import route42 from "./routes/novel/event/generateEvents";
import route43 from "./routes/novel/event/getEvent";
import route44 from "./routes/novel/getNovel";
import route45 from "./routes/novel/getNovelData";
import route46 from "./routes/novel/getNovelEventState";
import route47 from "./routes/novel/getNovelIndex";
import route48 from "./routes/novel/updateNovel";
import route49 from "./routes/other/deleteAllData";
import route50 from "./routes/other/getVersion";
import route51 from "./routes/production/assets/batchGenerateAssetsImage";
import route52 from "./routes/production/assets/deleteAssetsDireve";
import route53 from "./routes/production/assets/pollingImage";
import route54 from "./routes/production/assets/updateAssetsUrl";
import route55 from "./routes/production/editImage/generateFlowImage";
import route56 from "./routes/production/editImage/getImageDefaultModle";
import route57 from "./routes/production/editImage/getImageFlow";
import route58 from "./routes/production/editImage/saveImageFlow";
import route59 from "./routes/production/editImage/updateImageFlow";
import route60 from "./routes/production/editImage/uploadImage";
import route61 from "./routes/production/getFlowData";
import route62 from "./routes/production/getStoryboardData";
import route63 from "./routes/production/saveFlowData";
import route64 from "./routes/production/storyboard/addStoryboard";
import route65 from "./routes/production/storyboard/batchAddStoryboardInfo";
import route66 from "./routes/production/storyboard/batchGenerateImage";
import route67 from "./routes/production/storyboard/downPreviewImage";
import route68 from "./routes/production/storyboard/editStoryboardInfo";
import route69 from "./routes/production/storyboard/getStoryboardData";
import route70 from "./routes/production/storyboard/pollingImage";
import route71 from "./routes/production/storyboard/previewImage";
import route72 from "./routes/production/storyboard/removeFrame";
import route73 from "./routes/production/storyboard/updateStoryboardUrl";
import route74 from "./routes/production/workbench/addTrack";
import route75 from "./routes/production/workbench/checkVideoStateList";
import route76 from "./routes/production/workbench/deleteTrack";
import route77 from "./routes/production/workbench/delVideo";
import route78 from "./routes/production/workbench/generateVideo";
import route79 from "./routes/production/workbench/generateVideoPrompt";
import route80 from "./routes/production/workbench/getFileUrl";
import route81 from "./routes/production/workbench/getGenerateData";
import route82 from "./routes/production/workbench/getVideoList";
import route83 from "./routes/production/workbench/selectVideo";
import route84 from "./routes/production/workbench/updateVideoDuration";
import route85 from "./routes/production/workbench/updateVideoPrompt";
import route86 from "./routes/project/addDirectorManual";
import route87 from "./routes/project/addProject";
import route88 from "./routes/project/addVisualManual";
import route89 from "./routes/project/deleteDirectorManual";
import route90 from "./routes/project/deleteVisualManual";
import route91 from "./routes/project/delProject";
import route92 from "./routes/project/editDirectorlManual";
import route93 from "./routes/project/editProject";
import route94 from "./routes/project/editVisualManual";
import route95 from "./routes/project/getModelDetails";
import route96 from "./routes/project/getProject";
import route97 from "./routes/project/getVisualManual";
import route98 from "./routes/project/queryDirectorManual";
import route99 from "./routes/project/visualManual";
import route100 from "./routes/script/addScript";
import route101 from "./routes/script/batchAddScript";
import route102 from "./routes/script/delScript";
import route103 from "./routes/script/exportScript";
import route104 from "./routes/script/extractAssets";
import route105 from "./routes/script/getAiRegex";
import route106 from "./routes/script/getScrptApi";
import route107 from "./routes/script/pollScriptAssets";
import route108 from "./routes/script/updateScript";
import route109 from "./routes/scriptAgent/getPlanData";
import route110 from "./routes/scriptAgent/setPlanData";
import route111 from "./routes/scriptAgent/updateData";
import route112 from "./routes/setting/about/checkUpdate";
import route113 from "./routes/setting/about/downloadApp";
import route114 from "./routes/setting/agentDeploy/agentSetKey";
import route115 from "./routes/setting/agentDeploy/deployAgentModel";
import route116 from "./routes/setting/agentDeploy/getAgentDeploy";
import route117 from "./routes/setting/dbConfig/clearData";
import route118 from "./routes/setting/dbConfig/clearTable";
import route119 from "./routes/setting/dbConfig/dbInfo";
import route120 from "./routes/setting/dbConfig/exportData";
import route121 from "./routes/setting/dbConfig/importData";
import route122 from "./routes/setting/dev/getSwitchAiDevTool";
import route123 from "./routes/setting/dev/updateSwitchAiDevTool";
import route124 from "./routes/setting/fileManagement/openFolder";
import route125 from "./routes/setting/getTextModel";
import route126 from "./routes/setting/loginConfig/getUser";
import route127 from "./routes/setting/loginConfig/updateUserPwd";
import route128 from "./routes/setting/memoryConfig/delAllMemory";
import route129 from "./routes/setting/memoryConfig/getMemory";
import route130 from "./routes/setting/memoryConfig/sureMemory";
import route131 from "./routes/setting/modelMap/bindingPrompt";
import route132 from "./routes/setting/modelMap/getImageAndVideoModel";
import route133 from "./routes/setting/promptManage/getPrompt";
import route134 from "./routes/setting/promptManage/updatePrompt";
import route135 from "./routes/setting/skillManagement/getSkillContent";
import route136 from "./routes/setting/skillManagement/getSkillList";
import route137 from "./routes/setting/skillManagement/saveSkillContent";
import route138 from "./routes/setting/vendorConfig/addVendor";
import route139 from "./routes/setting/vendorConfig/addVendorModel";
import route140 from "./routes/setting/vendorConfig/deleteVendor";
import route141 from "./routes/setting/vendorConfig/delVendorModel";
import route142 from "./routes/setting/vendorConfig/enableVendor";
import route143 from "./routes/setting/vendorConfig/getCodeByLink";
import route144 from "./routes/setting/vendorConfig/getVendorList";
import route145 from "./routes/setting/vendorConfig/modelTest";
import route146 from "./routes/setting/vendorConfig/updateCode";
import route147 from "./routes/setting/vendorConfig/updateVendorInputs";
import route148 from "./routes/setting/vendorConfig/upVendorModel";
import route149 from "./routes/task/getProject";
import route150 from "./routes/task/getTaskApi";
import route151 from "./routes/task/getTaskCategories";
import route152 from "./routes/task/taskDetails";
import route153 from "./routes/test/test";
import route30 from "./routes/cornerScape/pollingAudio";
import route31 from "./routes/cornerScape/updateAssetsAudio";
import route32 from "./routes/general/generalStatistics";
import route33 from "./routes/general/getSingleProject";
import route34 from "./routes/general/updateProject";
import route35 from "./routes/login/login";
import route36 from "./routes/modelSelect/getModelDetail";
import route37 from "./routes/modelSelect/getModelList";
import route38 from "./routes/novel/addNovel";
import route39 from "./routes/novel/batchDeleteNovel";
import route40 from "./routes/novel/delNovel";
import route41 from "./routes/novel/event/batchDeleteEvent";
import route42 from "./routes/novel/event/deletEvent";
import route43 from "./routes/novel/event/generateEvents";
import route44 from "./routes/novel/event/getEvent";
import route45 from "./routes/novel/getNovel";
import route46 from "./routes/novel/getNovelData";
import route47 from "./routes/novel/getNovelEventState";
import route48 from "./routes/novel/getNovelIndex";
import route49 from "./routes/novel/updateNovel";
import route50 from "./routes/other/deleteAllData";
import route51 from "./routes/other/getVersion";
import route52 from "./routes/production/assets/batchGenerateAssetsImage";
import route53 from "./routes/production/assets/deleteAssetsDireve";
import route54 from "./routes/production/assets/pollingImage";
import route55 from "./routes/production/assets/updateAssetsUrl";
import route56 from "./routes/production/editImage/generateFlowImage";
import route57 from "./routes/production/editImage/getImageDefaultModle";
import route58 from "./routes/production/editImage/getImageFlow";
import route59 from "./routes/production/editImage/saveImageFlow";
import route60 from "./routes/production/editImage/updateImageFlow";
import route61 from "./routes/production/editImage/uploadImage";
import route62 from "./routes/production/getFlowData";
import route63 from "./routes/production/getStoryboardData";
import route64 from "./routes/production/saveFlowData";
import route65 from "./routes/production/storyboard/addStoryboard";
import route66 from "./routes/production/storyboard/batchAddStoryboardInfo";
import route67 from "./routes/production/storyboard/batchDelete";
import route68 from "./routes/production/storyboard/batchGenerateImage";
import route69 from "./routes/production/storyboard/downPreviewImage";
import route70 from "./routes/production/storyboard/editStoryboardInfo";
import route71 from "./routes/production/storyboard/getStoryboardData";
import route72 from "./routes/production/storyboard/pollingImage";
import route73 from "./routes/production/storyboard/previewImage";
import route74 from "./routes/production/storyboard/removeFrame";
import route75 from "./routes/production/storyboard/updateStoryboardUrl";
import route76 from "./routes/production/workbench/addTrack";
import route77 from "./routes/production/workbench/batchGeneratePrompt";
import route78 from "./routes/production/workbench/batchGenerateVideo";
import route79 from "./routes/production/workbench/checkVideoStateList";
import route80 from "./routes/production/workbench/deleteTrack";
import route81 from "./routes/production/workbench/delVideo";
import route82 from "./routes/production/workbench/generateVideo";
import route83 from "./routes/production/workbench/generateVideoPrompt";
import route84 from "./routes/production/workbench/getFileUrl";
import route85 from "./routes/production/workbench/getGenerateData";
import route86 from "./routes/production/workbench/getVideoList";
import route87 from "./routes/production/workbench/selectVideo";
import route88 from "./routes/production/workbench/updateVideoDuration";
import route89 from "./routes/production/workbench/updateVideoPrompt";
import route90 from "./routes/project/addDirectorManual";
import route91 from "./routes/project/addProject";
import route92 from "./routes/project/addVisualManual";
import route93 from "./routes/project/deleteDirectorManual";
import route94 from "./routes/project/deleteVisualManual";
import route95 from "./routes/project/delProject";
import route96 from "./routes/project/editDirectorlManual";
import route97 from "./routes/project/editProject";
import route98 from "./routes/project/editVisualManual";
import route99 from "./routes/project/getModelDetails";
import route100 from "./routes/project/getProject";
import route101 from "./routes/project/getVisualManual";
import route102 from "./routes/project/queryDirectorManual";
import route103 from "./routes/project/visualManual";
import route104 from "./routes/script/addScript";
import route105 from "./routes/script/batchAddScript";
import route106 from "./routes/script/delScript";
import route107 from "./routes/script/exportScript";
import route108 from "./routes/script/extractAssets";
import route109 from "./routes/script/getAiRegex";
import route110 from "./routes/script/getScrptApi";
import route111 from "./routes/script/pollScriptAssets";
import route112 from "./routes/script/updateScript";
import route113 from "./routes/scriptAgent/getPlanData";
import route114 from "./routes/scriptAgent/setPlanData";
import route115 from "./routes/scriptAgent/updateData";
import route116 from "./routes/setting/about/checkUpdate";
import route117 from "./routes/setting/about/downloadApp";
import route118 from "./routes/setting/agentDeploy/agentSetKey";
import route119 from "./routes/setting/agentDeploy/deployAgentModel";
import route120 from "./routes/setting/agentDeploy/getAgentDeploy";
import route121 from "./routes/setting/dbConfig/clearData";
import route122 from "./routes/setting/dbConfig/clearTable";
import route123 from "./routes/setting/dbConfig/dbInfo";
import route124 from "./routes/setting/dbConfig/exportData";
import route125 from "./routes/setting/dbConfig/importData";
import route126 from "./routes/setting/dev/getSwitchAiDevTool";
import route127 from "./routes/setting/dev/updateSwitchAiDevTool";
import route128 from "./routes/setting/fileManagement/openFolder";
import route129 from "./routes/setting/getTextModel";
import route130 from "./routes/setting/loginConfig/getUser";
import route131 from "./routes/setting/loginConfig/updateUserPwd";
import route132 from "./routes/setting/memoryConfig/delAllMemory";
import route133 from "./routes/setting/memoryConfig/getMemory";
import route134 from "./routes/setting/memoryConfig/sureMemory";
import route135 from "./routes/setting/modelMap/bindingPrompt";
import route136 from "./routes/setting/modelMap/getImageAndVideoModel";
import route137 from "./routes/setting/promptManage/getPrompt";
import route138 from "./routes/setting/promptManage/updatePrompt";
import route139 from "./routes/setting/skillManagement/getSkillContent";
import route140 from "./routes/setting/skillManagement/getSkillList";
import route141 from "./routes/setting/skillManagement/saveSkillContent";
import route142 from "./routes/setting/vendorConfig/addVendor";
import route143 from "./routes/setting/vendorConfig/addVendorModel";
import route144 from "./routes/setting/vendorConfig/deleteVendor";
import route145 from "./routes/setting/vendorConfig/delVendorModel";
import route146 from "./routes/setting/vendorConfig/enableVendor";
import route147 from "./routes/setting/vendorConfig/getCodeByLink";
import route148 from "./routes/setting/vendorConfig/getVendorList";
import route149 from "./routes/setting/vendorConfig/modelTest";
import route150 from "./routes/setting/vendorConfig/updateCode";
import route151 from "./routes/setting/vendorConfig/updateVendorInputs";
import route152 from "./routes/setting/vendorConfig/upVendorModel";
import route153 from "./routes/task/getProject";
import route154 from "./routes/task/getTaskApi";
import route155 from "./routes/task/getTaskCategories";
import route156 from "./routes/task/taskDetails";
import route157 from "./routes/test/test";
export default async (app: Express) => {
app.use("/api/agents/clearMemory", route1);
@ -185,128 +189,132 @@ export default async (app: Express) => {
app.use("/api/common/getBigImage", route27);
app.use("/api/cornerScape/batchBindAudio", route28);
app.use("/api/cornerScape/getAllAssets", route29);
app.use("/api/cornerScape/updateAssetsAudio", route30);
app.use("/api/general/generalStatistics", route31);
app.use("/api/general/getSingleProject", route32);
app.use("/api/general/updateProject", route33);
app.use("/api/login/login", route34);
app.use("/api/modelSelect/getModelDetail", route35);
app.use("/api/modelSelect/getModelList", route36);
app.use("/api/novel/addNovel", route37);
app.use("/api/novel/batchDeleteNovel", route38);
app.use("/api/novel/delNovel", route39);
app.use("/api/novel/event/batchDeleteEvent", route40);
app.use("/api/novel/event/deletEvent", route41);
app.use("/api/novel/event/generateEvents", route42);
app.use("/api/novel/event/getEvent", route43);
app.use("/api/novel/getNovel", route44);
app.use("/api/novel/getNovelData", route45);
app.use("/api/novel/getNovelEventState", route46);
app.use("/api/novel/getNovelIndex", route47);
app.use("/api/novel/updateNovel", route48);
app.use("/api/other/deleteAllData", route49);
app.use("/api/other/getVersion", route50);
app.use("/api/production/assets/batchGenerateAssetsImage", route51);
app.use("/api/production/assets/deleteAssetsDireve", route52);
app.use("/api/production/assets/pollingImage", route53);
app.use("/api/production/assets/updateAssetsUrl", route54);
app.use("/api/production/editImage/generateFlowImage", route55);
app.use("/api/production/editImage/getImageDefaultModle", route56);
app.use("/api/production/editImage/getImageFlow", route57);
app.use("/api/production/editImage/saveImageFlow", route58);
app.use("/api/production/editImage/updateImageFlow", route59);
app.use("/api/production/editImage/uploadImage", route60);
app.use("/api/production/getFlowData", route61);
app.use("/api/production/getStoryboardData", route62);
app.use("/api/production/saveFlowData", route63);
app.use("/api/production/storyboard/addStoryboard", route64);
app.use("/api/production/storyboard/batchAddStoryboardInfo", route65);
app.use("/api/production/storyboard/batchGenerateImage", route66);
app.use("/api/production/storyboard/downPreviewImage", route67);
app.use("/api/production/storyboard/editStoryboardInfo", route68);
app.use("/api/production/storyboard/getStoryboardData", route69);
app.use("/api/production/storyboard/pollingImage", route70);
app.use("/api/production/storyboard/previewImage", route71);
app.use("/api/production/storyboard/removeFrame", route72);
app.use("/api/production/storyboard/updateStoryboardUrl", route73);
app.use("/api/production/workbench/addTrack", route74);
app.use("/api/production/workbench/checkVideoStateList", route75);
app.use("/api/production/workbench/deleteTrack", route76);
app.use("/api/production/workbench/delVideo", route77);
app.use("/api/production/workbench/generateVideo", route78);
app.use("/api/production/workbench/generateVideoPrompt", route79);
app.use("/api/production/workbench/getFileUrl", route80);
app.use("/api/production/workbench/getGenerateData", route81);
app.use("/api/production/workbench/getVideoList", route82);
app.use("/api/production/workbench/selectVideo", route83);
app.use("/api/production/workbench/updateVideoDuration", route84);
app.use("/api/production/workbench/updateVideoPrompt", route85);
app.use("/api/project/addDirectorManual", route86);
app.use("/api/project/addProject", route87);
app.use("/api/project/addVisualManual", route88);
app.use("/api/project/deleteDirectorManual", route89);
app.use("/api/project/deleteVisualManual", route90);
app.use("/api/project/delProject", route91);
app.use("/api/project/editDirectorlManual", route92);
app.use("/api/project/editProject", route93);
app.use("/api/project/editVisualManual", route94);
app.use("/api/project/getModelDetails", route95);
app.use("/api/project/getProject", route96);
app.use("/api/project/getVisualManual", route97);
app.use("/api/project/queryDirectorManual", route98);
app.use("/api/project/visualManual", route99);
app.use("/api/script/addScript", route100);
app.use("/api/script/batchAddScript", route101);
app.use("/api/script/delScript", route102);
app.use("/api/script/exportScript", route103);
app.use("/api/script/extractAssets", route104);
app.use("/api/script/getAiRegex", route105);
app.use("/api/script/getScrptApi", route106);
app.use("/api/script/pollScriptAssets", route107);
app.use("/api/script/updateScript", route108);
app.use("/api/scriptAgent/getPlanData", route109);
app.use("/api/scriptAgent/setPlanData", route110);
app.use("/api/scriptAgent/updateData", route111);
app.use("/api/setting/about/checkUpdate", route112);
app.use("/api/setting/about/downloadApp", route113);
app.use("/api/setting/agentDeploy/agentSetKey", route114);
app.use("/api/setting/agentDeploy/deployAgentModel", route115);
app.use("/api/setting/agentDeploy/getAgentDeploy", route116);
app.use("/api/setting/dbConfig/clearData", route117);
app.use("/api/setting/dbConfig/clearTable", route118);
app.use("/api/setting/dbConfig/dbInfo", route119);
app.use("/api/setting/dbConfig/exportData", route120);
app.use("/api/setting/dbConfig/importData", route121);
app.use("/api/setting/dev/getSwitchAiDevTool", route122);
app.use("/api/setting/dev/updateSwitchAiDevTool", route123);
app.use("/api/setting/fileManagement/openFolder", route124);
app.use("/api/setting/getTextModel", route125);
app.use("/api/setting/loginConfig/getUser", route126);
app.use("/api/setting/loginConfig/updateUserPwd", route127);
app.use("/api/setting/memoryConfig/delAllMemory", route128);
app.use("/api/setting/memoryConfig/getMemory", route129);
app.use("/api/setting/memoryConfig/sureMemory", route130);
app.use("/api/setting/modelMap/bindingPrompt", route131);
app.use("/api/setting/modelMap/getImageAndVideoModel", route132);
app.use("/api/setting/promptManage/getPrompt", route133);
app.use("/api/setting/promptManage/updatePrompt", route134);
app.use("/api/setting/skillManagement/getSkillContent", route135);
app.use("/api/setting/skillManagement/getSkillList", route136);
app.use("/api/setting/skillManagement/saveSkillContent", route137);
app.use("/api/setting/vendorConfig/addVendor", route138);
app.use("/api/setting/vendorConfig/addVendorModel", route139);
app.use("/api/setting/vendorConfig/deleteVendor", route140);
app.use("/api/setting/vendorConfig/delVendorModel", route141);
app.use("/api/setting/vendorConfig/enableVendor", route142);
app.use("/api/setting/vendorConfig/getCodeByLink", route143);
app.use("/api/setting/vendorConfig/getVendorList", route144);
app.use("/api/setting/vendorConfig/modelTest", route145);
app.use("/api/setting/vendorConfig/updateCode", route146);
app.use("/api/setting/vendorConfig/updateVendorInputs", route147);
app.use("/api/setting/vendorConfig/upVendorModel", route148);
app.use("/api/task/getProject", route149);
app.use("/api/task/getTaskApi", route150);
app.use("/api/task/getTaskCategories", route151);
app.use("/api/task/taskDetails", route152);
app.use("/api/test/test", route153);
app.use("/api/cornerScape/pollingAudio", route30);
app.use("/api/cornerScape/updateAssetsAudio", route31);
app.use("/api/general/generalStatistics", route32);
app.use("/api/general/getSingleProject", route33);
app.use("/api/general/updateProject", route34);
app.use("/api/login/login", route35);
app.use("/api/modelSelect/getModelDetail", route36);
app.use("/api/modelSelect/getModelList", route37);
app.use("/api/novel/addNovel", route38);
app.use("/api/novel/batchDeleteNovel", route39);
app.use("/api/novel/delNovel", route40);
app.use("/api/novel/event/batchDeleteEvent", route41);
app.use("/api/novel/event/deletEvent", route42);
app.use("/api/novel/event/generateEvents", route43);
app.use("/api/novel/event/getEvent", route44);
app.use("/api/novel/getNovel", route45);
app.use("/api/novel/getNovelData", route46);
app.use("/api/novel/getNovelEventState", route47);
app.use("/api/novel/getNovelIndex", route48);
app.use("/api/novel/updateNovel", route49);
app.use("/api/other/deleteAllData", route50);
app.use("/api/other/getVersion", route51);
app.use("/api/production/assets/batchGenerateAssetsImage", route52);
app.use("/api/production/assets/deleteAssetsDireve", route53);
app.use("/api/production/assets/pollingImage", route54);
app.use("/api/production/assets/updateAssetsUrl", route55);
app.use("/api/production/editImage/generateFlowImage", route56);
app.use("/api/production/editImage/getImageDefaultModle", route57);
app.use("/api/production/editImage/getImageFlow", route58);
app.use("/api/production/editImage/saveImageFlow", route59);
app.use("/api/production/editImage/updateImageFlow", route60);
app.use("/api/production/editImage/uploadImage", route61);
app.use("/api/production/getFlowData", route62);
app.use("/api/production/getStoryboardData", route63);
app.use("/api/production/saveFlowData", route64);
app.use("/api/production/storyboard/addStoryboard", route65);
app.use("/api/production/storyboard/batchAddStoryboardInfo", route66);
app.use("/api/production/storyboard/batchDelete", route67);
app.use("/api/production/storyboard/batchGenerateImage", route68);
app.use("/api/production/storyboard/downPreviewImage", route69);
app.use("/api/production/storyboard/editStoryboardInfo", route70);
app.use("/api/production/storyboard/getStoryboardData", route71);
app.use("/api/production/storyboard/pollingImage", route72);
app.use("/api/production/storyboard/previewImage", route73);
app.use("/api/production/storyboard/removeFrame", route74);
app.use("/api/production/storyboard/updateStoryboardUrl", route75);
app.use("/api/production/workbench/addTrack", route76);
app.use("/api/production/workbench/batchGeneratePrompt", route77);
app.use("/api/production/workbench/batchGenerateVideo", route78);
app.use("/api/production/workbench/checkVideoStateList", route79);
app.use("/api/production/workbench/deleteTrack", route80);
app.use("/api/production/workbench/delVideo", route81);
app.use("/api/production/workbench/generateVideo", route82);
app.use("/api/production/workbench/generateVideoPrompt", route83);
app.use("/api/production/workbench/getFileUrl", route84);
app.use("/api/production/workbench/getGenerateData", route85);
app.use("/api/production/workbench/getVideoList", route86);
app.use("/api/production/workbench/selectVideo", route87);
app.use("/api/production/workbench/updateVideoDuration", route88);
app.use("/api/production/workbench/updateVideoPrompt", route89);
app.use("/api/project/addDirectorManual", route90);
app.use("/api/project/addProject", route91);
app.use("/api/project/addVisualManual", route92);
app.use("/api/project/deleteDirectorManual", route93);
app.use("/api/project/deleteVisualManual", route94);
app.use("/api/project/delProject", route95);
app.use("/api/project/editDirectorlManual", route96);
app.use("/api/project/editProject", route97);
app.use("/api/project/editVisualManual", route98);
app.use("/api/project/getModelDetails", route99);
app.use("/api/project/getProject", route100);
app.use("/api/project/getVisualManual", route101);
app.use("/api/project/queryDirectorManual", route102);
app.use("/api/project/visualManual", route103);
app.use("/api/script/addScript", route104);
app.use("/api/script/batchAddScript", route105);
app.use("/api/script/delScript", route106);
app.use("/api/script/exportScript", route107);
app.use("/api/script/extractAssets", route108);
app.use("/api/script/getAiRegex", route109);
app.use("/api/script/getScrptApi", route110);
app.use("/api/script/pollScriptAssets", route111);
app.use("/api/script/updateScript", route112);
app.use("/api/scriptAgent/getPlanData", route113);
app.use("/api/scriptAgent/setPlanData", route114);
app.use("/api/scriptAgent/updateData", route115);
app.use("/api/setting/about/checkUpdate", route116);
app.use("/api/setting/about/downloadApp", route117);
app.use("/api/setting/agentDeploy/agentSetKey", route118);
app.use("/api/setting/agentDeploy/deployAgentModel", route119);
app.use("/api/setting/agentDeploy/getAgentDeploy", route120);
app.use("/api/setting/dbConfig/clearData", route121);
app.use("/api/setting/dbConfig/clearTable", route122);
app.use("/api/setting/dbConfig/dbInfo", route123);
app.use("/api/setting/dbConfig/exportData", route124);
app.use("/api/setting/dbConfig/importData", route125);
app.use("/api/setting/dev/getSwitchAiDevTool", route126);
app.use("/api/setting/dev/updateSwitchAiDevTool", route127);
app.use("/api/setting/fileManagement/openFolder", route128);
app.use("/api/setting/getTextModel", route129);
app.use("/api/setting/loginConfig/getUser", route130);
app.use("/api/setting/loginConfig/updateUserPwd", route131);
app.use("/api/setting/memoryConfig/delAllMemory", route132);
app.use("/api/setting/memoryConfig/getMemory", route133);
app.use("/api/setting/memoryConfig/sureMemory", route134);
app.use("/api/setting/modelMap/bindingPrompt", route135);
app.use("/api/setting/modelMap/getImageAndVideoModel", route136);
app.use("/api/setting/promptManage/getPrompt", route137);
app.use("/api/setting/promptManage/updatePrompt", route138);
app.use("/api/setting/skillManagement/getSkillContent", route139);
app.use("/api/setting/skillManagement/getSkillList", route140);
app.use("/api/setting/skillManagement/saveSkillContent", route141);
app.use("/api/setting/vendorConfig/addVendor", route142);
app.use("/api/setting/vendorConfig/addVendorModel", route143);
app.use("/api/setting/vendorConfig/deleteVendor", route144);
app.use("/api/setting/vendorConfig/delVendorModel", route145);
app.use("/api/setting/vendorConfig/enableVendor", route146);
app.use("/api/setting/vendorConfig/getCodeByLink", route147);
app.use("/api/setting/vendorConfig/getVendorList", route148);
app.use("/api/setting/vendorConfig/modelTest", route149);
app.use("/api/setting/vendorConfig/updateCode", route150);
app.use("/api/setting/vendorConfig/updateVendorInputs", route151);
app.use("/api/setting/vendorConfig/upVendorModel", route152);
app.use("/api/task/getProject", route153);
app.use("/api/task/getTaskApi", route154);
app.use("/api/task/getTaskCategories", route155);
app.use("/api/task/taskDetails", route156);
app.use("/api/test/test", route157);
}

View File

@ -26,8 +26,19 @@ export default router.post(
await Promise.all(
assetsItem.map(async (i: { src?: string; base64: string; prompt: string }) => {
if (i.base64) {
const savePath = `/${projectId}/assets/audio/${u.uuid()}.mp4`;
await u.oss.writeFile(savePath, i.base64);
const mimeMatch = i.base64.match(/^data:audio\/([^;]+);base64,/);
const mimeExt = mimeMatch ? mimeMatch[1] : "mp3";
const mimeToExt: Record<string, string> = {
mpeg: "mp3",
"x-wav": "wav",
"x-aiff": "aiff",
"x-m4a": "m4a",
"x-flac": "flac",
};
const ext = mimeToExt[mimeExt] ?? mimeExt;
const savePath = `/${projectId}/assets/audio/${u.uuid()}.${ext}`;
const base64Data = i.base64.replace(/^data:[^;]+;base64,/, "");
await u.oss.writeFile(savePath, base64Data);
i.src = savePath;
}
}),

View File

@ -32,8 +32,19 @@ export default router.post(
i.src = u.replaceUrl(i.src);
}
if (i.base64) {
const savePath = `/${projectId}/assets/audio/${u.uuid()}.mp4`;
await u.oss.writeFile(savePath, i.base64);
const mimeMatch = i.base64.match(/^data:audio\/([^;]+);base64,/);
const mimeExt = mimeMatch ? mimeMatch[1] : "mp3";
const mimeToExt: Record<string, string> = {
mpeg: "mp3",
"x-wav": "wav",
"x-aiff": "aiff",
"x-m4a": "m4a",
"x-flac": "flac",
};
const ext = mimeToExt[mimeExt] ?? mimeExt;
const savePath = `/${projectId}/assets/audio/${u.uuid()}.${ext}`;
const base64Data = i.base64.replace(/^data:[^;]+;base64,/, "");
await u.oss.writeFile(savePath, base64Data);
i.src = savePath;
}
}),

View File

@ -130,7 +130,6 @@ export default router.post("/", validateFields(requestSchema), async (req, res)
aiImage.save(imagePath);
const imageData = await u.db("o_image").where("id", imageId).select("*").first();
console.log("%c Line:133 🥒 imageData", "background:#465975", imageData);
if (!imageData) return res.status(500).send("资产已被删除");
if (!imageData) return;
if (imageData.state === "生成失败") return;

View File

@ -13,7 +13,6 @@ export default router.post(
}),
async (req, res) => {
const { id } = req.body;
console.log("%c Line:16 🌭 id", "background:#2eafb0", id);
await u.db("o_image").where("id", id).update({
state: "生成失败",
});

View File

@ -86,6 +86,8 @@ export default router.post("/", validateFields(requestSchema), async (req, res)
type,
state: "生成中",
assetsId: id,
model: model.split(/:(.+)/)[1],
resolution,
});
await u.db("o_assets").where("id", id).update({ imageId });

View File

@ -1,7 +1,7 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success } from "@/lib/responseFormat";
import { error, success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
import { tool, jsonSchema } from "ai";
const router = express.Router();
@ -16,12 +16,7 @@ export default router.post(
}),
async (req, res) => {
const { projectId, assetsIds, concurrentCount } = req.body;
const assetsData = await u
.db("o_assets")
.where("type", "audio")
.whereIn("id", assetsIds)
.andWhere("projectId", projectId)
.select("id", "name", "describe");
const assetsData = await u.db("o_assets").whereIn("id", assetsIds).andWhere("projectId", projectId).select("id", "name", "describe");
const audioData = await u
.db("o_assets")
@ -29,57 +24,81 @@ export default router.post(
.whereNull("assetsId")
.andWhere("projectId", projectId)
.select("id", "name", "describe");
async function processGroup() {
if (!audioData.length) return res.status(400).send(error("暂无设置音频,请先前往资产中心上传音频"));
const batchSize = concurrentCount ?? 1;
async function processAsset(asset: (typeof assetsData)[number]) {
try {
const resultTool = tool({
description: "返回结果时必须调用这个工具",
inputSchema: jsonSchema<{ result: { id: number; audioIds: number[] }[] }>(
description: "匹配完成后必须调用此工具提交结果",
inputSchema: jsonSchema<{ id: number; audioId: number }>(
z
.object({
result: z
.array(
z.object({
id: z.number(),
audioIds: z.array(z.number()).describe("适配的音频id 无适配内容可以为 空数组"),
}),
)
.describe("适配的音色列表id为资产idaudioIds为适配的音频id 无适配内容可以为 空数组"),
id: z.number().describe("资产ID"),
audioId: z.number().nullable().optional().describe("与该资产匹配的音频ID列表若无合适匹配则返回空数组"),
})
.toJSONSchema(),
),
execute: async ({ result }) => {
console.log("[tools] extractAssets result", result);
for (const item of result) {
await u.db("o_assetsRole2Audio").where("assetsRoleId", item.id).delete();
if (item.audioIds.length)
await u.db("o_assetsRole2Audio").insert(item.audioIds.map((i) => ({ assetsRoleId: item.id, assetsAudioId: i })));
}
execute: async (result) => {
await u.db("o_assetsRole2Audio").where("assetsRoleId", asset.id).delete();
if (result?.audioId) await u.db("o_assetsRole2Audio").insert({ assetsRoleId: asset.id, assetsAudioId: result.audioId });
await u.db("o_assets").where("id", asset.id).update("audioBindState", "已完成");
return "无需回复用户任何内容";
},
});
const audioList = audioData.map((i) => `- ID:${i.id} | 名称:${i.name} | 描述:${i.describe ?? "无"}`).join("\n");
const { text } = await u.Ai.Text("universalAi").invoke({
messages: [
{
role: "system",
content: `请根据提供的资产内容描述 与 提供的音色 进行匹配,返回适配的音色,结果必须调用 resultTool 工具返回, 调用工具之后你无需回复用户任何内容。`,
content: `
1.
2.
3.
4. resultTool
`,
},
{
role: "user",
content: `音频内容:${audioData.map((i) => `Id:${i.id},音色名称:${i.name},描述:${i.describe}`).join("\n")}\n\n
${assetsData.map((i) => `ID:${i.id},名称:${i.name},描述:${i.describe}`).join("\n")}\n\n
`,
content: `
##
${audioList}
##
- ID:${asset.id} | 名称:${asset.name} | 描述:${asset.describe ?? "无"}
resultTool
`,
},
],
tools: { resultTool },
});
console.log("%c Line:44 🍞 text", "background:#f5ce50", text);
} catch (e) {
console.error(`提取失败:`, e);
return;
await u.db("o_assets").where("id", asset.id).update("audioBindState", "生成失败");
console.error(`[bindAudio] 资产 ${asset.id} 处理失败:`, e);
}
}
await processGroup();
async function runWithConcurrency() {
for (let i = 0; i < assetsData.length; i += batchSize) {
const batch = assetsData.slice(i, i + batchSize);
await Promise.all(batch.map((asset) => processAsset(asset)));
}
}
await u
.db("o_assets")
.whereIn(
"id",
assetsData.map((i) => i.id),
)
.update("audioBindState", "生成中");
runWithConcurrency();
res.status(200).send(success());
},
);

View File

@ -0,0 +1,18 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
const router = express.Router();
export default router.post(
"/",
validateFields({
ids: z.array(z.number()),
}),
async (req, res) => {
const { ids } = req.body;
const data = await u.db("o_assets").whereIn("id", ids).whereNot("audioBindState", "生成中").select("*");
res.status(200).send(success(data));
},
);

View File

@ -1,7 +1,7 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success } from "@/lib/responseFormat";
import { error, success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
const router = express.Router();
@ -10,13 +10,14 @@ export default router.post(
"/",
validateFields({
assetsId: z.number(),
audioIds: z.array(z.number()),
audioIds: z.array(z.number()).optional(),
}),
async (req, res) => {
const { assetsId, audioIds } = req.body;
if (audioIds && audioIds.length > 1) return res.status(400).send(error("仅可绑定一个音色"));
await u.db("o_assetsRole2Audio").where("assetsRoleId", assetsId).delete();
if (audioIds.length) {
await u.db("o_assetsRole2Audio").insert(audioIds.map((i: number) => ({ assetsRoleId: assetsId, assetsAudioId: i })));
if (audioIds && audioIds.length) {
await u.db("o_assetsRole2Audio").insert({ assetsRoleId: assetsId, assetsAudioId: audioIds[0] });
}
res.status(200).send(success({ message: "更新音频成功" }));
},

View File

@ -14,7 +14,6 @@ export default router.post(
async (req, res) => {
const { edges, nodes } = req.body;
nodes.forEach((node: any) => {
console.log("%c Line:17 🌮 node", "background:#465975", node);
if (node.type == "upload") {
node.data.image = node.data.image ? u.replaceUrl(node.data.image) : "";
}

View File

@ -0,0 +1,31 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { error, success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
const router = express.Router();
export default router.post(
"/",
validateFields({
ids: z.array(z.number()),
projectId: z.number(),
}),
async (req, res) => {
const { ids, projectId } = req.body;
if (!ids.length) return res.status(400).send(error("请先选择分镜"));
const storyboardDataList = await u.db("o_storyboard").whereIn("id", ids).where("projectId", projectId).select("id", "track", "trackId", "flowId");
if (!storyboardDataList.length) return res.status(400).send(error("当前选择分镜不存在"));
const flowIds = storyboardDataList.map((i) => i.flowId);
const storyBoardIds = storyboardDataList.map((i) => i.id);
if (flowIds.length)
await u
.db("o_imageFlow")
.whereIn("id", flowIds as number[])
.delete();
await u.db("o_storyboard").whereIn("id", storyBoardIds).delete();
await u.db("o_assets2Storyboard").whereIn("storyboardId", storyBoardIds).delete();
res.status(200).send(success({ message: "视频删除成功" }));
},
);

View File

@ -0,0 +1,133 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { success, error } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
import { info } from "node:console";
const router = express.Router();
export default router.post(
"/",
validateFields({
projectId: z.number(),
trackData: z.array(
z.object({
trackId: 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).orderBy("rowid").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")
.leftJoin("o_image", "o_image.id", "o_assets.imageId")
.where("o_assets.id", item.id)
.select("o_assets.id", "o_assets.type", "o_assets.name", "o_image.filePath")
.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,
filePath: item.filePath,
});
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();
let videoPromptGeneration = "" as string | undefined;
if (videoPrompt && videoPrompt.useData) {
videoPromptGeneration = videoPrompt.useData;
} else {
videoPromptGeneration = videoPrompt?.data ?? undefined;
}
const artStyle = projectData?.artStyle || "无";
const visualManual = u.getArtPrompt(artStyle, "art_skills", "art_storyboard_video");
const content = `
****${modelData},
****):${assets
.filter((i) => i.filePath)
.map((i) => `[${i.id},${i.type},${i.name}]`)
.join("")},
****${storyboard.map(
(i) => `<storyboardItem
videoDesc='${i.videoDesc}'
duration='${i.duration}'
></storyboardItem>`,
)},
`;
try {
const { text } = await u.Ai.Text("universalAi").invoke({
system: videoPromptGeneration,
messages: [
{
role: "assistant",
content: `${visualManual}`,
},
{
role: "user",
content: content,
},
],
});
await u.db("o_videoTrack").where({ id: trackId }).update({
prompt: text,
});
res.status(200).send(success(text));
} catch (e) {
res.status(400).send(error(u.error(e).message));
}
},
);

View File

@ -0,0 +1,148 @@
import express from "express";
import u from "@/utils";
import { z } from "zod";
import { v4 as uuidv4 } from "uuid";
import { success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
import { ReferenceList } from "@/utils/ai";
const router = express.Router();
type Type = "imageReference" | "startImage" | "endImage" | "videoReference" | "audioReference";
interface UploadItem {
fileType: "image" | "video" | "audio";
type: Type;
sources?: "assets" | "storyboard";
id?: number;
src?: string;
label?: string;
prompt?: string;
}
export default router.post(
"/",
validateFields({
projectId: z.number(),
scriptId: z.number(),
trackData: z.array(
z.object({
uploadData: z.array(
z.object({
id: z.number(),
sources: z.string(),
}),
),
trackId: z.number(),
prompt: z.string(),
duration: z.number(),
}),
),
model: z.string(),
mode: z.string(),
resolution: z.string(),
audio: z.boolean().optional(),
}),
async (req, res) => {
const { scriptId, projectId, trackData, model, resolution, audio, mode } = req.body;
let modeData = [];
if (Array.isArray(mode)) {
} else if (typeof mode === "string" && mode.startsWith('["') && mode.endsWith('"]')) {
try {
modeData = JSON.parse(mode);
} catch (e) {}
}
// 获取生成视频比例
const ratio = await u.db("o_project").select("videoRatio").where("id", projectId).first();
// 为每个 track 预处理数据并插入数据库,返回任务列表
const tasks = await Promise.all(
(trackData as { uploadData: { id: number; sources: string }[]; trackId: number; prompt: string; duration: number }[]).map(async (track) => {
const { uploadData, trackId, prompt, duration } = track;
// 查询出图片数据
const images = await Promise.all(
uploadData.map(async (item) => {
if (item.sources === "storyboard") {
const filePath = await u.db("o_storyboard").where("id", item.id).select("filePath").first();
return { path: filePath?.filePath, sources: "storyBoard" };
}
if (item.sources === "assets") {
const filePath = await u
.db("o_assets")
.where("o_assets.id", item.id)
.leftJoin("o_image", "o_assets.imageId", "o_image.id")
.select("o_image.filePath", "o_image.type")
.first();
return { path: filePath?.filePath, sources: filePath.type };
}
}),
);
const videoPath = `/${projectId}/video/${uuidv4()}.mp4`;
const [videoId] = await u.db("o_video").insert({
filePath: videoPath,
time: Date.now(),
state: "生成中",
scriptId,
projectId,
videoTrackId: trackId,
});
return { videoId, videoPath, prompt, duration, images, trackId };
}),
);
res.status(200).send(success(tasks.map((t) => ({ videoId: t.videoId, trackId: t.trackId }))));
// 分批执行3个一批
(async () => {
const batchSize = 3;
for (let i = 0; i < tasks.length; i += batchSize) {
const batch = tasks.slice(i, i + batchSize);
await Promise.all(
batch.map(async ({ videoId, videoPath, prompt, duration, images }) => {
// 调用时再转 base64
const base64 = await Promise.all(
images.map(async (item) => {
if (!item) return null;
return { base64: await u.oss.getImageBase64(item.path), type: item.sources == "audio" ? "audio" : "image" };
}),
);
const relatedObjects = { projectId, videoId, scriptId, type: "视频" };
const aiVideo = u.Ai.Video(model);
return aiVideo
.run(
{
prompt,
referenceList: base64.filter(Boolean) as ReferenceList[],
mode: modeData.length > 0 ? modeData : mode,
duration,
aspectRatio: (ratio?.videoRatio as "16:9" | "9:16") || "16:9",
resolution,
audio,
},
{
projectId,
taskClass: "视频生成",
describe: "根据提示词生成视频",
relatedObjects: JSON.stringify(relatedObjects),
},
)
.then(() => aiVideo.save(videoPath))
.then(() => u.db("o_video").where("id", videoId).update({ state: "生成成功" }))
.catch(async (error: any) => {
await u
.db("o_video")
.where("id", videoId)
.update({
state: "生成失败",
errorReason: u.error(error).message,
});
});
}),
);
}
})();
},
);

View File

@ -4,6 +4,7 @@ import { z } from "zod";
import { v4 as uuidv4 } from "uuid";
import { success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
import { ReferenceList } from "@/utils/ai";
const router = express.Router();
type Type = "imageReference" | "startImage" | "endImage" | "videoReference" | "audioReference";
@ -43,7 +44,7 @@ export default router.post(
} else if (typeof mode === "string" && mode.startsWith('["') && mode.endsWith('"]')) {
try {
modeData = JSON.parse(mode);
} catch (e) { }
} catch (e) {}
}
//获取生成视频比例
const ratio = await u.db("o_project").select("videoRatio").where("id", projectId).first();
@ -53,16 +54,16 @@ export default router.post(
uploadData.map(async (item: UploadItem) => {
if (item.sources === "storyboard") {
const filePath = await u.db("o_storyboard").where("id", item.id).select("filePath").first();
return filePath?.filePath;
return { path: filePath?.filePath, sources: "storyBoard" };
}
if (item.sources === "assets") {
const filePath = await u
.db("o_assets")
.where("o_assets.id", item.id)
.leftJoin("o_image", "o_assets.imageId", "o_image.id")
.select("o_image.filePath")
.select("o_image.filePath", "o_image.type")
.first();
return filePath?.filePath;
return { path: filePath?.filePath, sources: filePath.type };
}
}),
);
@ -70,7 +71,7 @@ export default router.post(
const base64 = await Promise.all(
images.map(async (item) => {
if (!item) return null;
return await u.oss.getImageBase64(item);
return { base64: await u.oss.getImageBase64(item.path), type: item.sources == "audio" ? "audio" : "image" };
}),
);
//新增
@ -95,7 +96,7 @@ export default router.post(
await aiVideo.run(
{
prompt,
referenceList: base64.filter((item) => item !== null).map((item) => ({ type: "image" as const, base64: item! })),
referenceList: base64.filter(Boolean) as ReferenceList[],
mode: modeData.length > 0 ? modeData : mode,
duration,
aspectRatio: (ratio?.videoRatio as "16:9" | "9:16") || "16:9",

View File

@ -78,6 +78,7 @@ export default router.post(
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();
@ -91,7 +92,7 @@ export default router.post(
const visualManual = u.getArtPrompt(artStyle, "art_skills", "art_storyboard_video");
const content = `
****${modelData},
****):${assets
****):${assets
.filter((i) => i.filePath)
.map((i) => `[${i.id},${i.type},${i.name}]`)
.join("")},

View File

@ -82,8 +82,17 @@ export default router.post(
});
// 按 storyboardId 分组的资产数据key 为 storyboardId
const otherDataMap: Record<number, any[]> = {};
// 解析 videoMode 中 audioReference 的数量,例如 'audioReference:3' => 3
const audioReferenceCount = (() => {
if (!Array.isArray(videoMode)) return 0;
const item = (videoMode as string[]).find((v) => v.toLowerCase().startsWith("audioreference:"));
if (!item) return 0;
const num = parseInt(item.split(":")[1], 10);
return isNaN(num) ? 0 : num;
})();
if (isRef) {
const storyIds = storyboardList.map((s) => s.id);
const assetDatas = await u
.db("o_assets2Storyboard")
.leftJoin("o_assets", "o_assets2Storyboard.assetId", "o_assets.id")
@ -91,6 +100,38 @@ export default router.post(
.whereIn("o_assets2Storyboard.storyboardId", storyIds as number[])
.select("o_assets.*", "o_image.filePath", "o_assets2Storyboard.storyboardId");
const queryAudioIds = [...assetDatas.map((i) => i.id!), ...assetDatas.map((i) => i.assetsId!)].filter(Boolean);
const assets2AudioData = await u
.db("o_assetsRole2Audio")
.leftJoin("o_assets", "o_assets.assetsId", "o_assetsRole2Audio.assetsAudioId")
.leftJoin("o_image", "o_image.id", "o_assets.imageId")
.whereIn("o_assetsRole2Audio.assetsRoleId", queryAudioIds)
.select(
"o_assets.id",
"o_assets.name",
"o_assetsRole2Audio.assetsRoleId",
"o_assets.describe",
"o_assets.type",
"o_assets.prompt",
"o_image.filePath",
);
const audioRecord: Record<string, any> = {};
await Promise.all(
assets2AudioData.map(async (i) => {
if (!audioRecord[i.assetsRoleId]) audioRecord[i.assetsRoleId] = [];
audioRecord[i.assetsRoleId].push({
id: i.id,
name: i.name,
describe: i.describe,
type: i.type,
fileType: "audio" as const,
sources: "assets",
prompt: i.prompt,
src: i.filePath ? await u.oss.getFileUrl(i.filePath) : "",
});
}),
);
await Promise.all(
assetDatas.map(async (i) => {
const item = {
@ -105,6 +146,8 @@ export default router.post(
const sid = i.storyboardId as number;
if (!otherDataMap[sid]) otherDataMap[sid] = [];
otherDataMap[sid].push(item);
if (audioRecord[i.id]) otherDataMap[sid].push(...audioRecord[i.id]);
if (audioRecord[i.assetsId]) otherDataMap[sid].push(...audioRecord[i.assetsId]);
}),
);
}
@ -128,14 +171,27 @@ export default router.post(
medias: (() => {
const storyboardMedias = storyboardTrackRecord[trackId] ?? [];
const assetMedias = storyboardMedias.flatMap((s) => otherDataMap[s.id] ?? []);
const seenAssetIds = new Set<number>();
const uniqueAssets = assetMedias.filter((a) => {
if (seenAssetIds.has(a.id)) return false;
seenAssetIds.add(a.id);
return true;
});
const hasImageAssetData = uniqueAssets.filter((i) => i.src);
const notHasImageAssetData = uniqueAssets.filter((i) => !i.src);
// 有 audioReference 时,按数量截取 audio 类型资产
const audioCountMap: Record<string, number> = {};
const filteredAssets = uniqueAssets.filter((a) => {
if (a.fileType !== "audio" || audioReferenceCount === 0) return true;
const key = String(a.id);
audioCountMap[key] = (audioCountMap[key] ?? 0) + 1;
// 统计当前 track 内 audio 总数,超过上限则过滤
const totalAudio = Object.values(audioCountMap).reduce((s, n) => s + n, 0);
return totalAudio <= audioReferenceCount;
});
const hasImageAssetData = filteredAssets.filter((i) => i.src);
const notHasImageAssetData = filteredAssets.filter((i) => !i.src);
return [...hasImageAssetData, ...storyboardMedias, ...notHasImageAssetData];
})(),

View File

@ -20,7 +20,6 @@ export default router.post(
const { path: folderPath } = req.body;
const platform = process.platform;
const target = u.getPath(folderPath);
console.log("%c Line:23 🎂 target", "background:#fca650", target);
const cmd = platform === "win32" ? `explorer "${target}"` : platform === "darwin" ? `open "${target}"` : `xdg-open "${target}"`;
exec(cmd, (err) => {
if (err) {

View File

@ -1,6 +1,22 @@
// @db-hash 5364c2db0bf42b520761b813ce040489
// @db-hash ef0c3cdd7111f4f5d87b82df06bdd72a
//该文件由脚本自动生成,请勿手动修改
export interface _o_assets_old_20260428 {
'assetsId'?: number | null;
'describe'?: string | null;
'flowId'?: number | null;
'id'?: number;
'imageId'?: number | null;
'name'?: string | null;
'projectId'?: number | null;
'prompt'?: string | null;
'promptErrorReason'?: string | null;
'promptState'?: string | null;
'remark'?: string | null;
'scriptId'?: number | null;
'startTime'?: number | null;
'type'?: string | null;
}
export interface memories {
'content': string;
'createTime': number;
@ -23,7 +39,6 @@ export interface o_agentDeploy {
'modelName'?: string | null;
'name'?: string | null;
'temperature'?: number | null;
'topP'?: number | null;
'type'?: string | null;
'vendorId'?: string | null;
}
@ -45,6 +60,7 @@ export interface o_artStyle {
}
export interface o_assets {
'assetsId'?: number | null;
'audioBindState'?: number | null;
'describe'?: string | null;
'flowId'?: number | null;
'id'?: number;
@ -211,6 +227,7 @@ export interface o_user {
'password'?: string | null;
}
export interface o_vendorConfig {
'code'?: string | null;
'enable'?: number | null;
'id'?: string;
'inputValues'?: string | null;
@ -239,6 +256,7 @@ export interface o_videoTrack {
}
export interface DB {
"_o_assets_old_20260428": _o_assets_old_20260428;
"memories": memories;
"o_agentDeploy": o_agentDeploy;
"o_agentWorkData": o_agentWorkData;

View File

@ -189,7 +189,7 @@ function referenceList2imageBase642(id: string, input: any) {
return input;
}
type ReferenceList = { type: "image"; base64: string } | { type: "audio"; base64: string } | { type: "video"; base64: string };
export type ReferenceList = { type: "image"; base64: string } | { type: "audio"; base64: string } | { type: "video"; base64: string };
interface ImageConfig {
prompt: string;

View File

@ -1,3 +1,5 @@
import path from "node:path";
export default function replaceUrl(url: string): string {
if (typeof url !== 'string' || !url.trim()) return '';
let cleanedPath = '';
@ -5,8 +7,19 @@ export default function replaceUrl(url: string): string {
const pathname = new URL(url).pathname;
cleanedPath = pathname.replace(/^\/oss/, '').replace(/^\/smallImage/, '');
} catch (e) {
// 如果不是有效的URL则直接返回原字符串
// 如果不是有效的URL则直接使用原字符串
cleanedPath = url;
}
return cleanedPath;
// 防止路径穿越:对路径进行规范化后,确保不含上溯分量
// 使用 posix 规范化(保持 / 分隔符),去除所有 .. 和 .
const normalized = path.posix.normalize(cleanedPath);
// 规范化后若路径以 ../ 开头或等于 .. 则说明发生了路径穿越,拒绝并返回空字符串
if (normalized.startsWith('../') || normalized === '..') {
return '';
}
// 去除前导斜杠,保证返回的是相对路径
return normalized.replace(/^\/+/, '');
}