修复bug

This commit is contained in:
zhishi 2026-04-04 18:34:07 +08:00
parent c7091fa90d
commit 8d8e24ec2c
2 changed files with 108 additions and 106 deletions

View File

@ -111,6 +111,7 @@ export default router.post(
.db("o_storyboard") .db("o_storyboard")
.where("id", item.id) .where("id", item.id)
.update({ .update({
filePath: "",
reason: u.error(e).message, reason: u.error(e).message,
state: "生成失败", state: "生成失败",
}); });

View File

@ -41,12 +41,16 @@ type GroupResult = {
} | null; } | null;
/** 将 scriptIds 数组按 groupSize 分组 */ /** 将 scriptIds 数组按 groupSize 分组 */
function chunkArray<T>(arr: T[], groupSize: number): T[][] { function chunkArray(arr: number[], groupSize: number): number[][][] {
const chunks: T[][] = []; const chunks: number[][] = [];
for (let i = 0; i < arr.length; i += groupSize) { for (let i = 0; i < arr.length; i += 5) {
chunks.push(arr.slice(i, i + groupSize)); chunks.push(arr.slice(i, i + 5));
} }
return chunks; const groupChunks = [];
for (let i = 0; i < chunks.length; i += groupSize) {
groupChunks.push(chunks.slice(i, i + groupSize));
}
return groupChunks;
} }
export default router.post( export default router.post(
@ -60,8 +64,10 @@ export default router.post(
const { scriptIds, projectId, groupSize = 5 } = req.body; const { scriptIds, projectId, groupSize = 5 } = req.body;
if (!scriptIds.length) return res.status(400).send(error("请先选择剧本")); if (!scriptIds.length) return res.status(400).send(error("请先选择剧本"));
console.log("%c Line:67 🍪 scriptIds", "background:#e41a6a", scriptIds);
const scripts = await u.db("o_script").whereIn("id", scriptIds); const scripts = await u.db("o_script").whereIn("id", scriptIds);
// 构建 scriptId -> script 内容的映射 // 构建 scriptId -> script 内容的映射
const scriptMap = new Map(scripts.map((s: o_script) => [s.id, s])); const scriptMap = new Map(scripts.map((s: o_script) => [s.id, s]));
@ -73,7 +79,8 @@ export default router.post(
let successCount = 0; let successCount = 0;
// 将 scriptIds 按 groupSize默认5分组每组一起发给 AI // 将 scriptIds 按 groupSize默认5分组每组一起发给 AI
const scriptGroups = chunkArray(scriptIds, groupSize); const scriptGroups = chunkArray(scriptIds as number[], groupSize);
console.log("%c Line:83 🍿 scriptGroups", "background:#f5ce50", scriptGroups);
/** 一组剧本提取完成后统一入库并建立关联 */ /** 一组剧本提取完成后统一入库并建立关联 */
async function persistGroupResult(result: GroupResult) { async function persistGroupResult(result: GroupResult) {
@ -139,11 +146,12 @@ export default router.post(
}); });
} }
res.send(success("开始提取资产")); res.send(success("开始提取资产"));
// 逐组处理(每组最多 groupSize 集剧本一起发给 AI
for (const group of scriptGroups) { function processGroup(group: number[][][]) {
// 过滤有效剧本 group.map(async (itemIds) => {
const validScripts: { id: number; script: o_script }[] = []; const validScripts: { id: number; script: o_script }[] = [];
for (const scriptId of group as number[]) { for (const scriptIds of itemIds as number[][]) {
for (const scriptId of scriptIds) {
const script = scriptMap.get(scriptId); const script = scriptMap.get(scriptId);
if (!script) { if (!script) {
errors.push({ scriptId, error: "未找到对应剧本" }); errors.push({ scriptId, error: "未找到对应剧本" });
@ -156,7 +164,10 @@ export default router.post(
} }
} }
} }
if (!validScripts.length) continue; }
console.log("%c Line:161 🥕 validScripts", "background:#42b983", validScripts);
if (!validScripts.length) return;
const validScriptIds = validScripts.map((v) => v.id); const validScriptIds = validScripts.map((v) => v.id);
// 修改状态为正在提取中 // 修改状态为正在提取中
await u.db("o_script").whereIn("id", validScriptIds).update({ await u.db("o_script").whereIn("id", validScriptIds).update({
@ -171,10 +182,9 @@ export default router.post(
.map(({ id, script }) => `===== 【剧本ID: ${id}${script.name || ""} =====\n${script.content}`) .map(({ id, script }) => `===== 【剧本ID: ${id}${script.name || ""} =====\n${script.content}`)
.join("\n\n"); .join("\n\n");
// 用闭包收集 AI 返回的资产
let collectedNew: NewAsset[] = []; let collectedNew: NewAsset[] = [];
let collectedExisting: ExistingAssetRef[] = []; let collectedExisting: ExistingAssetRef[] = [];
try {
const resultTool = tool({ const resultTool = tool({
description: "返回结果时必须调用这个工具", description: "返回结果时必须调用这个工具",
inputSchema: z.object({ inputSchema: z.object({
@ -192,13 +202,10 @@ export default router.post(
return "无需回复用户任何内容"; return "无需回复用户任何内容";
}, },
}); });
try {
const data = await u.db("o_prompt").where("type", "scriptAssetExtraction").first("data"); const data = await u.db("o_prompt").where("type", "scriptAssetExtraction").first("data");
const existingHint = existingAssetsList const existingHint = existingAssetsList
? `\n\n【已有资产列表】${existingAssetsList}\n对于已有资产如果在剧本中出现只需在 existingAssetRefs 中给出资产名称和对应的 scriptIds 数组即可,无需重复生成 desc/type。对于新发现的资产不在已有列表中请在 newAssets 中给出完整信息。` ? `\n\n【已有资产列表】${existingAssetsList}\n对于已有资产如果在剧本中出现只需在 existingAssetRefs 中给出资产名称和对应的 scriptIds 数组即可,无需重复生成 desc/type。对于新发现的资产不在已有列表中请在 newAssets 中给出完整信息。`
: ""; : "";
const output = await u.Ai.Text("universalAi").invoke({ const output = await u.Ai.Text("universalAi").invoke({
messages: [ messages: [
{ {
@ -215,11 +222,13 @@ export default router.post(
], ],
tools: { resultTool }, tools: { resultTool },
}); });
console.log("%c Line:extractAssets 🍧 output", "background:#f5ce50", output.text); await persistGroupResult({
} catch (e: any) { batchScriptIds: validScriptIds,
const msg = e?.message || String(e); newAssets: collectedNew,
const scriptNames = validScripts.map((v) => v.script.name).join(", "); existingRefs: collectedExisting,
console.error(`[extractAssets] group=[${validScriptIds.join(",")}] 提取失败:`, msg); });
} catch (e) {
console.error(`[extractAssets] group=[${validScriptIds.join(",")}] 提取失败:`, e);
for (const { id, script } of validScripts) { for (const { id, script } of validScripts) {
errors.push({ scriptId: id, error: (script.name || "") + ":" + u.error(e).message }); errors.push({ scriptId: id, error: (script.name || "") + ":" + u.error(e).message });
await u await u
@ -227,25 +236,17 @@ export default router.post(
.where("id", id) .where("id", id)
.update({ extractState: -1, errorReason: u.error(e).message }); .update({ extractState: -1, errorReason: u.error(e).message });
} }
continue; return;
} }
if (!collectedNew.length && !collectedExisting.length) { if (!collectedNew.length && !collectedExisting.length) {
for (const { id } of validScripts) { for (const { id } of validScripts) {
errors.push({ scriptId: id, error: "AI 未返回任何资产" }); errors.push({ scriptId: id, error: "AI 未返回任何资产" });
await u.db("o_script").where("id", id).update({ extractState: -1, errorReason: "AI 未返回任何资产" }); await u.db("o_script").where("id", id).update({ extractState: -1, errorReason: "AI 未返回任何资产" });
} }
continue; return;
} }
successCount += validScripts.length;
// 入库
await persistGroupResult({
batchScriptIds: validScriptIds,
newAssets: collectedNew,
existingRefs: collectedExisting,
}); });
} }
processGroup(scriptGroups);
}, },
); );