发版前准备

This commit is contained in:
ACT丶流星雨 2026-04-08 20:01:04 +08:00
commit 6adcd82c60
10 changed files with 108 additions and 115 deletions

View File

@ -1 +1 @@
1.1.1
1.1.2

View File

@ -1,6 +1,6 @@
{
"name": "toonflow",
"version": "1.1.1",
"version": "1.1.2",
"description": "Toonflow 是一款 AI 短剧漫剧工具,能够利用 AI 技术将小说自动转化为剧本,并结合 AI 生成的图片和视频,实现高效的短剧创作。",
"author": "HBAI-Ltd <ltlctools@outlook.com>",
"license": "Apache-2.0",
@ -97,7 +97,6 @@
"overrides": {
"@rmp135/sql-ts": {
"better-sqlite3": "^12.8.0"
},
"sqlite3": "^6.0.1"
}
}
}

View File

@ -1,4 +1,4 @@
// @routes-hash a06e43d398afaba14e067c04a027c18a
// @routes-hash 5f94013d5d29facaed754713858ed40b
import { Express } from "express";
import route1 from "./routes/agents/clearMemory";
@ -58,30 +58,30 @@ import route54 from "./routes/production/editImage/getImageFlow";
import route55 from "./routes/production/editImage/saveImageFlow";
import route56 from "./routes/production/editImage/updateImageFlow";
import route57 from "./routes/production/editImage/uploadImage";
import route58 from "./routes/production/exportImage";
import route59 from "./routes/production/getFlowData";
import route60 from "./routes/production/getProductionData";
import route61 from "./routes/production/getStoryboardData";
import route62 from "./routes/production/saveFlowData";
import route63 from "./routes/production/storyboard/addStoryboard";
import route64 from "./routes/production/storyboard/batchAddStoryboardInfo";
import route65 from "./routes/production/storyboard/batchGenerateImage";
import route66 from "./routes/production/storyboard/downPreviewImage";
import route67 from "./routes/production/storyboard/editStoryboardInfo";
import route68 from "./routes/production/storyboard/getStoryboardData";
import route69 from "./routes/production/storyboard/pollingImage";
import route70 from "./routes/production/storyboard/previewImage";
import route71 from "./routes/production/storyboard/removeFrame";
import route72 from "./routes/production/storyboard/updateStoryboardUrl";
import route73 from "./routes/production/workbench/addTrack";
import route74 from "./routes/production/workbench/deleteTrack";
import route75 from "./routes/production/workbench/delVideo";
import route76 from "./routes/production/workbench/generateVideo";
import route77 from "./routes/production/workbench/generateVideoPrompt";
import route78 from "./routes/production/workbench/getGenerateData";
import route79 from "./routes/production/workbench/getVideoList";
import route80 from "./routes/production/workbench/getVideoModelDetail";
import route81 from "./routes/production/workbench/selectVideo";
import route58 from "./routes/production/getFlowData";
import route59 from "./routes/production/getProductionData";
import route60 from "./routes/production/getStoryboardData";
import route61 from "./routes/production/saveFlowData";
import route62 from "./routes/production/storyboard/addStoryboard";
import route63 from "./routes/production/storyboard/batchAddStoryboardInfo";
import route64 from "./routes/production/storyboard/batchGenerateImage";
import route65 from "./routes/production/storyboard/downPreviewImage";
import route66 from "./routes/production/storyboard/editStoryboardInfo";
import route67 from "./routes/production/storyboard/getStoryboardData";
import route68 from "./routes/production/storyboard/pollingImage";
import route69 from "./routes/production/storyboard/previewImage";
import route70 from "./routes/production/storyboard/removeFrame";
import route71 from "./routes/production/storyboard/updateStoryboardUrl";
import route72 from "./routes/production/workbench/addTrack";
import route73 from "./routes/production/workbench/deleteTrack";
import route74 from "./routes/production/workbench/delVideo";
import route75 from "./routes/production/workbench/generateVideo";
import route76 from "./routes/production/workbench/generateVideoPrompt";
import route77 from "./routes/production/workbench/getGenerateData";
import route78 from "./routes/production/workbench/getVideoList";
import route79 from "./routes/production/workbench/getVideoModelDetail";
import route80 from "./routes/production/workbench/selectVideo";
import route81 from "./routes/production/workbench/updateVideoPrompt";
import route82 from "./routes/project/addDirectorManual";
import route83 from "./routes/project/addProject";
import route84 from "./routes/project/addVisualManual";
@ -198,30 +198,30 @@ export default async (app: Express) => {
app.use("/api/production/editImage/saveImageFlow", route55);
app.use("/api/production/editImage/updateImageFlow", route56);
app.use("/api/production/editImage/uploadImage", route57);
app.use("/api/production/exportImage", route58);
app.use("/api/production/getFlowData", route59);
app.use("/api/production/getProductionData", route60);
app.use("/api/production/getStoryboardData", route61);
app.use("/api/production/saveFlowData", route62);
app.use("/api/production/storyboard/addStoryboard", route63);
app.use("/api/production/storyboard/batchAddStoryboardInfo", route64);
app.use("/api/production/storyboard/batchGenerateImage", route65);
app.use("/api/production/storyboard/downPreviewImage", route66);
app.use("/api/production/storyboard/editStoryboardInfo", route67);
app.use("/api/production/storyboard/getStoryboardData", route68);
app.use("/api/production/storyboard/pollingImage", route69);
app.use("/api/production/storyboard/previewImage", route70);
app.use("/api/production/storyboard/removeFrame", route71);
app.use("/api/production/storyboard/updateStoryboardUrl", route72);
app.use("/api/production/workbench/addTrack", route73);
app.use("/api/production/workbench/deleteTrack", route74);
app.use("/api/production/workbench/delVideo", route75);
app.use("/api/production/workbench/generateVideo", route76);
app.use("/api/production/workbench/generateVideoPrompt", route77);
app.use("/api/production/workbench/getGenerateData", route78);
app.use("/api/production/workbench/getVideoList", route79);
app.use("/api/production/workbench/getVideoModelDetail", route80);
app.use("/api/production/workbench/selectVideo", route81);
app.use("/api/production/getFlowData", route58);
app.use("/api/production/getProductionData", route59);
app.use("/api/production/getStoryboardData", route60);
app.use("/api/production/saveFlowData", route61);
app.use("/api/production/storyboard/addStoryboard", route62);
app.use("/api/production/storyboard/batchAddStoryboardInfo", route63);
app.use("/api/production/storyboard/batchGenerateImage", route64);
app.use("/api/production/storyboard/downPreviewImage", route65);
app.use("/api/production/storyboard/editStoryboardInfo", route66);
app.use("/api/production/storyboard/getStoryboardData", route67);
app.use("/api/production/storyboard/pollingImage", route68);
app.use("/api/production/storyboard/previewImage", route69);
app.use("/api/production/storyboard/removeFrame", route70);
app.use("/api/production/storyboard/updateStoryboardUrl", route71);
app.use("/api/production/workbench/addTrack", route72);
app.use("/api/production/workbench/deleteTrack", route73);
app.use("/api/production/workbench/delVideo", route74);
app.use("/api/production/workbench/generateVideo", route75);
app.use("/api/production/workbench/generateVideoPrompt", route76);
app.use("/api/production/workbench/getGenerateData", route77);
app.use("/api/production/workbench/getVideoList", route78);
app.use("/api/production/workbench/getVideoModelDetail", route79);
app.use("/api/production/workbench/selectVideo", route80);
app.use("/api/production/workbench/updateVideoPrompt", route81);
app.use("/api/project/addDirectorManual", route82);
app.use("/api/project/addProject", route83);
app.use("/api/project/addVisualManual", route84);

View File

@ -13,7 +13,7 @@ export default router.post(
describe: z.string(),
type: z.string(),
projectId: z.number(),
remark: z.string(),
remark: z.string().optional().nullable(),
prompt: z.string().optional().nullable(),
}),
async (req, res) => {

View File

@ -8,22 +8,22 @@ const router = express.Router();
// 更新资产
export default router.post(
"/",
validateFields({
id: z.number(),
name: z.string(),
describe: z.string(),
remark: z.string(),
prompt: z.string().optional().nullable(),
}),
async (req, res) => {
const { id, name, describe, remark, prompt } = req.body;
await u.db("o_assets").where({ id }).update({
name,
describe,
remark,
prompt,
});
res.status(200).send(success({ message: "更新资产成功" }));
},
"/",
validateFields({
id: z.number(),
name: z.string(),
describe: z.string(),
remark: z.string().optional().nullable(),
prompt: z.string().optional().nullable(),
}),
async (req, res) => {
const { id, name, describe, remark, prompt } = req.body;
await u.db("o_assets").where({ id }).update({
name,
describe,
remark,
prompt,
});
res.status(200).send(success({ message: "更新资产成功" }));
},
);

View File

@ -1,40 +0,0 @@
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();
import compressing from "compressing";
import path from "path";
import getPath from "@/utils/getPath";
export default router.post(
"/",
validateFields({
shotId: z.array(
z.object({
id: z.string(),
}),
),
}),
async (req, res) => {
const { shotId } = req.body;
const id = shotId.map((item: { id: string }) => item.id);
const data = await u.db("o_storyboard").whereIn("id", id);
const result = await Promise.all(
data.map(async (item) => {
const url = await u.oss.getFileUrl(item.filePath!);
return { ...item, url };
}),
);
const zipStream = new compressing.zip.Stream();
result.forEach((item, index) => {
const ext = (item.filePath?.split(".").pop() || "png").toLowerCase();
const absPath = path.join(getPath("oss"), item.filePath!);
zipStream.addEntry(absPath, { relativePath: `${index}.${ext}` });
});
res.setHeader("Content-Type", "application/zip");
res.setHeader("Content-Disposition", "attachment; filename=export.zip");
zipStream.pipe(res);
},
);

View File

@ -9,12 +9,14 @@ export default router.post(
validateFields({
projectId: z.number(),
scriptId: z.number(),
duration: z.number().optional(),
}),
async (req, res) => {
const { projectId, scriptId } = req.body;
const { projectId, scriptId, duration } = req.body;
const [id] = await u.db("o_videoTrack").insert({
projectId,
scriptId,
duration,
});
res.status(200).send(success(id));
},

View File

@ -38,6 +38,13 @@ export default router.post(
}),
async (req, res) => {
const { scriptId, projectId, prompt, uploadData, model, duration, resolution, audio, mode, trackId } = 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();
const videoPath = `/${projectId}/video/${uuidv4()}.mp4`; //视频保存路径
@ -89,7 +96,7 @@ export default router.post(
{
prompt,
imageBase64: base64.filter((item) => item !== null) as string[],
mode,
mode: modeData.length > 0 ? modeData : mode,
duration,
aspectRatio: (ratio?.videoRatio as `${number}:${number}`) || "16:9",
resolution,

View File

@ -38,6 +38,9 @@ export default router.post(
async (req, res) => {
const { projectId, scriptId } = req.body;
const projectData = await u.db("o_project").where("id", projectId).select("id", "videoModel").first();
if (!projectData?.videoModel) {
return res.status(400).json(success("项目未配置视频模型"));
}
const [videoId, videoModelName] = projectData.videoModel.split(":");
const vendorData = await u.db("o_vendorConfig").where("id", videoId).select("models").first();
const models = JSON.parse(vendorData!.models!);
@ -135,7 +138,7 @@ export default router.post(
.map(async (v) => ({
id: v.id!,
src: v.filePath ? await u.oss.getFileUrl(v.filePath) : "",
state: v.state === "done" ? "已完成" : v.state === "generating" ? "生成中" : v.state === "error" ? "生成失败" : "未生成",
state: v.state === "已完成" ? "已完成" : v.state === "生成中" ? "生成中" : v.state === "生成失败" ? "生成失败" : "未生成",
})),
),
});

View File

@ -0,0 +1,22 @@
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({
id: z.number(),
prompt: z.string().optional(),
duration: z.number().optional(),
}),
async (req, res) => {
const { id, prompt, duration } = req.body;
await u.db("o_videoTrack").where("id", id).update({
prompt,
duration,
});
res.status(200).send(success("更新成功"));
},
);