Merge branch 'develop' of https://github.com/HBAI-Ltd/Toonflow-app into develop
This commit is contained in:
commit
78c869805f
@ -111,6 +111,7 @@ export default router.post(
|
||||
.db("o_storyboard")
|
||||
.where("id", item.id)
|
||||
.update({
|
||||
filePath: "",
|
||||
reason: u.error(e).message,
|
||||
state: "生成失败",
|
||||
});
|
||||
|
||||
@ -41,12 +41,16 @@ type GroupResult = {
|
||||
} | null;
|
||||
|
||||
/** 将 scriptIds 数组按 groupSize 分组 */
|
||||
function chunkArray<T>(arr: T[], groupSize: number): T[][] {
|
||||
const chunks: T[][] = [];
|
||||
for (let i = 0; i < arr.length; i += groupSize) {
|
||||
chunks.push(arr.slice(i, i + groupSize));
|
||||
function chunkArray(arr: number[], groupSize: number): number[][][] {
|
||||
const chunks: number[][] = [];
|
||||
for (let i = 0; i < arr.length; i += 5) {
|
||||
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(
|
||||
@ -60,8 +64,10 @@ export default router.post(
|
||||
const { scriptIds, projectId, groupSize = 5 } = req.body;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
// 构建 scriptId -> script 内容的映射
|
||||
const scriptMap = new Map(scripts.map((s: o_script) => [s.id, s]));
|
||||
|
||||
@ -73,7 +79,8 @@ export default router.post(
|
||||
let successCount = 0;
|
||||
|
||||
// 将 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) {
|
||||
@ -139,11 +146,12 @@ export default router.post(
|
||||
});
|
||||
}
|
||||
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 }[] = [];
|
||||
for (const scriptId of group as number[]) {
|
||||
for (const scriptIds of itemIds as number[][]) {
|
||||
for (const scriptId of scriptIds) {
|
||||
const script = scriptMap.get(scriptId);
|
||||
if (!script) {
|
||||
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);
|
||||
// 修改状态为正在提取中
|
||||
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}`)
|
||||
.join("\n\n");
|
||||
|
||||
// 用闭包收集 AI 返回的资产
|
||||
let collectedNew: NewAsset[] = [];
|
||||
let collectedExisting: ExistingAssetRef[] = [];
|
||||
|
||||
try {
|
||||
const resultTool = tool({
|
||||
description: "返回结果时必须调用这个工具",
|
||||
inputSchema: z.object({
|
||||
@ -192,13 +202,10 @@ export default router.post(
|
||||
return "无需回复用户任何内容";
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const data = await u.db("o_prompt").where("type", "scriptAssetExtraction").first("data");
|
||||
const existingHint = existingAssetsList
|
||||
? `\n\n【已有资产列表】:${existingAssetsList}\n对于已有资产,如果在剧本中出现,只需在 existingAssetRefs 中给出资产名称和对应的 scriptIds 数组即可,无需重复生成 desc/type。对于新发现的资产(不在已有列表中),请在 newAssets 中给出完整信息。`
|
||||
: "";
|
||||
|
||||
const output = await u.Ai.Text("universalAi").invoke({
|
||||
messages: [
|
||||
{
|
||||
@ -215,11 +222,13 @@ export default router.post(
|
||||
],
|
||||
tools: { resultTool },
|
||||
});
|
||||
console.log("%c Line:extractAssets 🍧 output", "background:#f5ce50", output.text);
|
||||
} catch (e: any) {
|
||||
const msg = e?.message || String(e);
|
||||
const scriptNames = validScripts.map((v) => v.script.name).join(", ");
|
||||
console.error(`[extractAssets] group=[${validScriptIds.join(",")}] 提取失败:`, msg);
|
||||
await persistGroupResult({
|
||||
batchScriptIds: validScriptIds,
|
||||
newAssets: collectedNew,
|
||||
existingRefs: collectedExisting,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`[extractAssets] group=[${validScriptIds.join(",")}] 提取失败:`, e);
|
||||
for (const { id, script } of validScripts) {
|
||||
errors.push({ scriptId: id, error: (script.name || "") + ":" + u.error(e).message });
|
||||
await u
|
||||
@ -227,25 +236,17 @@ export default router.post(
|
||||
.where("id", id)
|
||||
.update({ extractState: -1, errorReason: u.error(e).message });
|
||||
}
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!collectedNew.length && !collectedExisting.length) {
|
||||
for (const { id } of validScripts) {
|
||||
errors.push({ scriptId: id, error: "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);
|
||||
},
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user