From 551728061dea14447336f0a81dc4ef722e898517 Mon Sep 17 00:00:00 2001 From: zhishi <1951671751@qq.com> Date: Mon, 23 Mar 2026 22:58:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=EF=BC=8C=E6=9B=B4=E6=96=B0=E5=89=A7=E6=9C=AC=E5=85=B3=E8=81=94?= =?UTF-8?q?=E8=B5=84=E4=BA=A7=EF=BC=8C=E6=8F=90=E5=8F=96=E5=8F=B0=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/initDB.ts | 9 ++ src/router.ts | 120 +++++++++--------- .../production/workbench/getChatLines.ts | 49 +++++++ src/routes/script/addScript.ts | 42 +++--- src/routes/script/getScrptApi.ts | 53 ++++++-- src/routes/script/updateScript.ts | 38 ++++-- src/types/database.d.ts | 7 +- 7 files changed, 214 insertions(+), 104 deletions(-) create mode 100644 src/routes/production/workbench/getChatLines.ts diff --git a/src/lib/initDB.ts b/src/lib/initDB.ts index 334ed68..a17ae71 100644 --- a/src/lib/initDB.ts +++ b/src/lib/initDB.ts @@ -448,6 +448,15 @@ export default async (knex: Knex, forceInit: boolean = false): Promise => table.unique(["storyboardId", "assetId"]); }, }, + { + name: "o_scriptAssets", + builder: (table) => { + table.integer("scriptId").notNullable(); + table.integer("assetId").notNullable(); + table.primary(["scriptId", "assetId"]); + table.unique(["scriptId", "assetId"]); + }, + }, ]; for (const t of tables) { diff --git a/src/router.ts b/src/router.ts index 3841909..71fd85a 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,4 +1,4 @@ -// @routes-hash cd0c360844a1f493a1cf5deb6ab906b0 +// @routes-hash 61bac5fab20be7b63f8e2cda7f6945b6 import { Express } from "express"; import route1 from "./routes/agents/clearMemory"; @@ -49,35 +49,36 @@ import route45 from "./routes/production/saveFlowData"; import route46 from "./routes/production/workbench/confirmSelection"; import route47 from "./routes/production/workbench/delVideo"; import route48 from "./routes/production/workbench/generateVideo"; -import route49 from "./routes/production/workbench/getVideoModelDetail"; -import route50 from "./routes/production/workbench/videoPolling"; -import route51 from "./routes/project/addProject"; -import route52 from "./routes/project/delProject"; -import route53 from "./routes/project/editProject"; -import route54 from "./routes/project/getProject"; -import route55 from "./routes/script/addScript"; -import route56 from "./routes/script/delScript"; -import route57 from "./routes/script/exportScript"; -import route58 from "./routes/script/getScrptApi"; -import route59 from "./routes/script/updateScript"; -import route60 from "./routes/setting/agentDeploy/deployAgentModel"; -import route61 from "./routes/setting/agentDeploy/getAgentDeploy"; -import route62 from "./routes/setting/agentDeploy/updateKey"; -import route63 from "./routes/setting/dbConfig/clearData"; -import route64 from "./routes/setting/getTextModel"; -import route65 from "./routes/setting/loginConfig/getUser"; -import route66 from "./routes/setting/loginConfig/updateUserPwd"; -import route67 from "./routes/setting/memoryConfig/getMemory"; -import route68 from "./routes/setting/memoryConfig/sureMemory"; -import route69 from "./routes/setting/vendorConfig/addVendor"; -import route70 from "./routes/setting/vendorConfig/deleteVendor"; -import route71 from "./routes/setting/vendorConfig/getVendorList"; -import route72 from "./routes/setting/vendorConfig/modelTest"; -import route73 from "./routes/setting/vendorConfig/updateVendor"; -import route74 from "./routes/task/getTaskApi"; -import route75 from "./routes/task/getTaskCategories"; -import route76 from "./routes/task/taskDetails"; -import route77 from "./routes/test/test"; +import route49 from "./routes/production/workbench/getChatLines"; +import route50 from "./routes/production/workbench/getVideoModelDetail"; +import route51 from "./routes/production/workbench/videoPolling"; +import route52 from "./routes/project/addProject"; +import route53 from "./routes/project/delProject"; +import route54 from "./routes/project/editProject"; +import route55 from "./routes/project/getProject"; +import route56 from "./routes/script/addScript"; +import route57 from "./routes/script/delScript"; +import route58 from "./routes/script/exportScript"; +import route59 from "./routes/script/getScrptApi"; +import route60 from "./routes/script/updateScript"; +import route61 from "./routes/setting/agentDeploy/deployAgentModel"; +import route62 from "./routes/setting/agentDeploy/getAgentDeploy"; +import route63 from "./routes/setting/agentDeploy/updateKey"; +import route64 from "./routes/setting/dbConfig/clearData"; +import route65 from "./routes/setting/getTextModel"; +import route66 from "./routes/setting/loginConfig/getUser"; +import route67 from "./routes/setting/loginConfig/updateUserPwd"; +import route68 from "./routes/setting/memoryConfig/getMemory"; +import route69 from "./routes/setting/memoryConfig/sureMemory"; +import route70 from "./routes/setting/vendorConfig/addVendor"; +import route71 from "./routes/setting/vendorConfig/deleteVendor"; +import route72 from "./routes/setting/vendorConfig/getVendorList"; +import route73 from "./routes/setting/vendorConfig/modelTest"; +import route74 from "./routes/setting/vendorConfig/updateVendor"; +import route75 from "./routes/task/getTaskApi"; +import route76 from "./routes/task/getTaskCategories"; +import route77 from "./routes/task/taskDetails"; +import route78 from "./routes/test/test"; export default async (app: Express) => { app.use("/api/agents/clearMemory", route1); @@ -128,33 +129,34 @@ export default async (app: Express) => { app.use("/api/production/workbench/confirmSelection", route46); app.use("/api/production/workbench/delVideo", route47); app.use("/api/production/workbench/generateVideo", route48); - app.use("/api/production/workbench/getVideoModelDetail", route49); - app.use("/api/production/workbench/videoPolling", route50); - app.use("/api/project/addProject", route51); - app.use("/api/project/delProject", route52); - app.use("/api/project/editProject", route53); - app.use("/api/project/getProject", route54); - app.use("/api/script/addScript", route55); - app.use("/api/script/delScript", route56); - app.use("/api/script/exportScript", route57); - app.use("/api/script/getScrptApi", route58); - app.use("/api/script/updateScript", route59); - app.use("/api/setting/agentDeploy/deployAgentModel", route60); - app.use("/api/setting/agentDeploy/getAgentDeploy", route61); - app.use("/api/setting/agentDeploy/updateKey", route62); - app.use("/api/setting/dbConfig/clearData", route63); - app.use("/api/setting/getTextModel", route64); - app.use("/api/setting/loginConfig/getUser", route65); - app.use("/api/setting/loginConfig/updateUserPwd", route66); - app.use("/api/setting/memoryConfig/getMemory", route67); - app.use("/api/setting/memoryConfig/sureMemory", route68); - app.use("/api/setting/vendorConfig/addVendor", route69); - app.use("/api/setting/vendorConfig/deleteVendor", route70); - app.use("/api/setting/vendorConfig/getVendorList", route71); - app.use("/api/setting/vendorConfig/modelTest", route72); - app.use("/api/setting/vendorConfig/updateVendor", route73); - app.use("/api/task/getTaskApi", route74); - app.use("/api/task/getTaskCategories", route75); - app.use("/api/task/taskDetails", route76); - app.use("/api/test/test", route77); + app.use("/api/production/workbench/getChatLines", route49); + app.use("/api/production/workbench/getVideoModelDetail", route50); + app.use("/api/production/workbench/videoPolling", route51); + app.use("/api/project/addProject", route52); + app.use("/api/project/delProject", route53); + app.use("/api/project/editProject", route54); + app.use("/api/project/getProject", route55); + app.use("/api/script/addScript", route56); + app.use("/api/script/delScript", route57); + app.use("/api/script/exportScript", route58); + app.use("/api/script/getScrptApi", route59); + app.use("/api/script/updateScript", route60); + app.use("/api/setting/agentDeploy/deployAgentModel", route61); + app.use("/api/setting/agentDeploy/getAgentDeploy", route62); + app.use("/api/setting/agentDeploy/updateKey", route63); + app.use("/api/setting/dbConfig/clearData", route64); + app.use("/api/setting/getTextModel", route65); + app.use("/api/setting/loginConfig/getUser", route66); + app.use("/api/setting/loginConfig/updateUserPwd", route67); + app.use("/api/setting/memoryConfig/getMemory", route68); + app.use("/api/setting/memoryConfig/sureMemory", route69); + app.use("/api/setting/vendorConfig/addVendor", route70); + app.use("/api/setting/vendorConfig/deleteVendor", route71); + app.use("/api/setting/vendorConfig/getVendorList", route72); + app.use("/api/setting/vendorConfig/modelTest", route73); + app.use("/api/setting/vendorConfig/updateVendor", route74); + app.use("/api/task/getTaskApi", route75); + app.use("/api/task/getTaskCategories", route76); + app.use("/api/task/taskDetails", route77); + app.use("/api/test/test", route78); } diff --git a/src/routes/production/workbench/getChatLines.ts b/src/routes/production/workbench/getChatLines.ts new file mode 100644 index 0000000..3e2b98a --- /dev/null +++ b/src/routes/production/workbench/getChatLines.ts @@ -0,0 +1,49 @@ +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 { Output } from "ai"; +const router = express.Router(); + +export default router.post("/", validateFields({}), async (req, res) => { + const {} = req.body; +}); + +async function getLines() { + const resText = await u.Ai.Text("eventExtractAgent").invoke({ + messages: [ + { + role: "system", + content: ` +你是一个专业的文本分析助手,请从以下文本中提取所有台词(对话内容)。 +## 提取规则: +1. 提取所有人物说话的内容,包括: + - 引号内的对话("..."、'...'、「...」、『...』) + - 旁白式独白 +2. 忽略说话者、叙述性文字、动作描写 +3. 保留台词的原始语气和标点 +4. 忽略非对话的叙述性文字 +5. 直接以 JSON 数组格式输出,不要任何额外说明 +示例输出格式: +["台词1", "台词2", "台词3"] + `, + }, + { + role: "user", + content: ` + + `, + }, + ], + output: Output.array({ + element: z.object({ + lines: z.string().describe("台词内容"), + }), + }), + }); + const parseLines = JSON.parse(resText.text); + const chatLines = parseLines.elements.map((i) => i.lines); + return chatLines; +} diff --git a/src/routes/script/addScript.ts b/src/routes/script/addScript.ts index a3ef01d..6753ffc 100644 --- a/src/routes/script/addScript.ts +++ b/src/routes/script/addScript.ts @@ -7,20 +7,30 @@ const router = express.Router(); // 新增剧本 export default router.post( - "/", - validateFields({ - name: z.string(), - content: z.string(), - projectId: z.number(), - }), - async (req, res) => { - const { name, content, projectId } = req.body; - await u.db("o_script").insert({ - name, - content, - projectId, - createTime: Date.now(), - }); - res.status(200).send(success({ message: "添加剧本成功" })); - }, + "/", + validateFields({ + name: z.string(), + content: z.string(), + projectId: z.number(), + assets: z.array(z.number()), + }), + async (req, res) => { + const { name, content, projectId, assets } = req.body; + const [scriptId] = await u.db("o_script").insert({ + name, + content, + projectId, + createTime: Date.now(), + }); + const assetsData = await u.db("o_assets").whereIn("id", assets).select(); + const assetsIds = assetsData.map((item) => item.id); + const insertData = assetsIds.map((i) => { + return { + scriptId, + assetsId: i, + }; + }); + await u.db("o_scriptAssets").insert(insertData); + res.status(200).send(success({ message: "添加剧本成功" })); + }, ); diff --git a/src/routes/script/getScrptApi.ts b/src/routes/script/getScrptApi.ts index 75d169b..0fb7f8e 100644 --- a/src/routes/script/getScrptApi.ts +++ b/src/routes/script/getScrptApi.ts @@ -6,18 +6,43 @@ import { validateFields } from "@/middleware/middleware"; const router = express.Router(); export default router.post( - "/", - validateFields({ - projectId: z.number(), - name: z.string().optional(), - }), - async (req, res) => { - const { projectId, name } = req.body; - let query = u.db("o_script").where("projectId", projectId).select("*"); - if (name) { - query = query.andWhere("name", "like", `%${name}%`); - } - const data = await query; - res.status(200).send(success(data)); - }, + "/", + validateFields({ + projectId: z.number(), + name: z.string().optional(), + }), + async (req, res) => { + const { projectId, name } = req.body; + let query = u.db("o_script").where("projectId", projectId).select("*"); + if (name) { + query = query.andWhere("name", "like", `%${name}%`); + } + + const data = await query; + const assetsData = await u + .db("o_assets") + .leftJoin("o_scriptAssets", "o_assets.id", "o_scriptAssets.assetsId") + .whereIn( + "o_scriptAssets.scriptId", + data.map((i) => i.id), + ) + .select("o_assets.id", "o_assets.name", "o_scriptAssets.scriptId"); + console.log("%c Line:23 🍷 assetsData", "background:#ffdd4d", assetsData); + const scriptAssetsMap: Record = {}; + assetsData.forEach((i) => { + if (scriptAssetsMap[i.scriptId]) { + scriptAssetsMap[i.scriptId].push({ id: i.id, name: i.name }); + } else { + scriptAssetsMap[i.scriptId] = [{ id: i.id, name: i.name }]; + } + }); + const returnData = data.map((i) => ({ + id: i.id, + name: i.name, + content: i.content, + createTime: i.createTime, + assets: scriptAssetsMap[i.id!] || [], + })); + res.status(200).send(success(returnData)); + }, ); diff --git a/src/routes/script/updateScript.ts b/src/routes/script/updateScript.ts index 2a4cbfe..51db2a3 100644 --- a/src/routes/script/updateScript.ts +++ b/src/routes/script/updateScript.ts @@ -7,18 +7,28 @@ const router = express.Router(); // 编辑剧本 export default router.post( - "/", - validateFields({ - id: z.number(), - name: z.string(), - content: z.string(), - }), - async (req, res) => { - const { id, name, content } = req.body; - await u.db("o_script").where({ id }).update({ - name, - content, - }); - res.status(200).send(success({ message: "编辑剧本成功" })); - }, + "/", + validateFields({ + id: z.number(), + name: z.string(), + content: z.string(), + assets: z.array(z.number()), + }), + async (req, res) => { + const { id, name, content, assets } = req.body; + await u.db("o_script").where({ id }).update({ + name, + content, + }); + const assetsData = await u.db("o_assets").whereIn("id", assets).select(); + await u.db("o_scriptAssets").where({ scriptId: id }).delete(); + const insertData = assetsData.map((item) => { + return { + scriptId: id, + assetsId: item.id, + }; + }); + await u.db("o_scriptAssets").insert(insertData); + res.status(200).send(success({ message: "编辑剧本成功" })); + }, ); diff --git a/src/types/database.d.ts b/src/types/database.d.ts index 66a078c..4cf9a82 100644 --- a/src/types/database.d.ts +++ b/src/types/database.d.ts @@ -1,4 +1,4 @@ -// @db-hash cb0c490907acc0c671f064a309397e4e +// @db-hash 2e39d6c2e0f11467eb8a669c22a4f771 //该文件由脚本自动生成,请勿手动修改 export interface _o_novel_old_20260323 { @@ -126,6 +126,10 @@ export interface o_script { 'name'?: string | null; 'projectId'?: number | null; } +export interface o_scriptAssets { + 'assetsId'?: number; + 'scriptId'?: number; +} export interface o_setting { 'key'?: string | null; 'value'?: string | null; @@ -218,6 +222,7 @@ export interface DB { "o_outlineNovel": o_outlineNovel; "o_project": o_project; "o_script": o_script; + "o_scriptAssets": o_scriptAssets; "o_setting": o_setting; "o_storyboard": o_storyboard; "o_storyboardFlow": o_storyboardFlow;