# Conflicts:
#	src/types/database.d.ts
This commit is contained in:
zhishi 2026-03-26 13:36:35 +08:00
commit a2aabd5aa5
7 changed files with 124 additions and 202 deletions

View File

@ -489,7 +489,6 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
return `错误检测到循环依赖涉及分镜id: ${cyclicIds.join(", ")}`;
}
console.log("%c Line:496 🌶", "background:#ea7e5c");
resTool.systemMessage(`图片生成调度计划:共 ${levels.length} 层,${images.length} 张图片`);
// --- 准备公共数据 ---

View File

@ -4,160 +4,129 @@ import { z } from "zod";
import { v4 as uuidv4 } from "uuid";
import { error, success } from "@/lib/responseFormat";
import { validateFields } from "@/middleware/middleware";
const router = express.Router();
// 生成资产图片
export default router.post(
"/",
validateFields({
id: z.number(),
type: z.enum(["role", "scene", "tool", "storyboard"]),
projectId: z.number(),
name: z.string(),
base64: z.string().optional().nullable(),
prompt: z.string(),
model: z.string(),
resolution: z.string(),
}),
async (req, res) => {
const { id, type, projectId, base64, prompt, name, model, resolution } = req.body;
//获取风格
const project = await u.db("o_project").where("id", projectId).select("artStyle", "type", "intro").first();
if (!project) return res.status(500).send(success({ message: "项目为空" }));
const role = (await u.getPrompts("role-generateImage")) ?? "";
const scene = (await u.getPrompts("scene-generateImage")) ?? "";
const tool = (await u.getPrompts("tool-generateImage")) ?? "";
let systemPrompt = "";
let userPrompt = "";
if (type == "role") {
systemPrompt = role;
userPrompt = `
type AssetType = "role" | "scene" | "tool";
****
- 画风风格: ${project?.artStyle || "未指定"}
interface AssetTypeConfig {
label: string;
taskClass: string;
dir: string;
promptTitle: string;
promptEnd: string;
}
****
- 名称:${name},
- 提示词:${prompt},
`;
}
if (type == "scene") {
systemPrompt = scene;
userPrompt = `
****
- 画风风格: ${project?.artStyle || "未指定"}
****
- 名称:${name},
- 提示词:${prompt},
`;
}
if (type == "tool") {
systemPrompt = tool;
userPrompt = `
****
- 画风风格: ${project?.artStyle || "未指定"}
****
- 名称:${name},
- 提示词:${prompt},
`;
}
const [imageId] = await u.db("o_image").insert({
type: type,
state: "生成中",
assetsId: id,
});
let taskClass = "";
if (type == "role") taskClass = "角色图生成";
if (type == "scene") taskClass = "场景图生成";
if (type == "tool") taskClass = "道具图生成";
try {
let imagePath;
let insertType;
let describe;
let relatedObjects = {};
if (type == "role") {
insertType = "role";
imagePath = `/${projectId}/role/${uuidv4()}.jpg`;
describe = `生成角色图,名称:${name},提示词:${prompt}`;
relatedObjects = {
id: id,
projectId,
type: "角色",
};
}
if (type == "scene") {
insertType = "scene";
imagePath = `/${projectId}/scene/${uuidv4()}.jpg`;
describe = `生成场景图,名称:${name},提示词:${prompt}`;
relatedObjects = {
id: id,
projectId,
type: "场景",
};
}
if (type == "tool") {
insertType = "tool";
imagePath = `/${projectId}/props/${uuidv4()}.jpg`;
describe = `生成道具图,名称:${name},提示词:${prompt}`;
relatedObjects = {
id: id,
projectId,
type: "道具",
};
}
const aiImage = u.Ai.Image(model);
await aiImage.run({
systemPrompt,
prompt: userPrompt,
imageBase64: base64 ? [base64] : [],
size: resolution,
aspectRatio: "16:9",
taskClass,
describe: describe ?? "", // 描述
projectId,
relatedObjects: JSON.stringify(relatedObjects), // 相关对象信息,便于后续分析和追踪
});
aiImage.save(imagePath!);
const imageData = await u.db("o_image").where("id", imageId).select("*").first();
const modelData = model.split(":")[1];
if (imageData) {
await u.db("o_image").where("id", imageId).update({
state: "生成成功",
filePath: imagePath,
type: insertType,
model: modelData,
resolution: resolution,
});
const path = await u.oss.getFileUrl(imagePath!);
await u.db("o_assets").where("id", id).update({
imageId: imageId,
});
return res.status(200).send(success({ path, assetsId: id }));
} else {
return res.status(500).send("资产已被删除");
}
} catch (e) {
await u.db("o_image").where("id", imageId).update({
state: "生成失败",
});
const msg = u.error(e).message || "图片生成失败";
return res.status(400).send(error(msg));
}
const assetTypeConfig: Record<AssetType, AssetTypeConfig> = {
role: {
label: "角色",
taskClass: "角色图生成",
dir: "role",
promptTitle: "角色标准四视图",
promptEnd: "人物角色四视图",
},
);
scene: {
label: "场景",
taskClass: "场景图生成",
dir: "scene",
promptTitle: "标准场景图",
promptEnd: "标准场景图",
},
tool: {
label: "道具",
taskClass: "道具图生成",
dir: "props",
promptTitle: "标准道具图",
promptEnd: "标准道具图",
},
};
// ─── 构建生成提示词 ──────────────────────────────────────────
function buildPrompt(cfg: AssetTypeConfig, artStyle: string, name: string, prompt: string): string {
return `
${cfg.promptTitle}
****
- 画风风格: ${artStyle || "未指定"}
**${cfg.label}**
- 名称:${name},
- 提示词:${prompt},
${cfg.promptEnd}
`;
}
// ─── 生成资产图片 ────────────────────────────────────────────
const requestSchema = {
id: z.number(),
type: z.enum(["role", "scene", "tool", "storyboard"]),
projectId: z.number(),
name: z.string(),
base64: z.string().optional().nullable(),
prompt: z.string(),
model: z.string(),
resolution: z.string(),
};
export default router.post("/", validateFields(requestSchema), async (req, res) => {
const { id, type, projectId, base64, prompt, name, model, resolution } = req.body;
// 1. 查询项目 & 获取类型配置
const project = await u.db("o_project").where("id", projectId).select("artStyle", "type", "intro").first();
if (!project) return res.status(500).send(success({ message: "项目为空" }));
const cfg = assetTypeConfig[type as AssetType];
if (!cfg) return res.status(400).send(error("不支持的类型"));
// 2. 创建图片占位记录
const [imageId] = await u.db("o_image").insert({
type,
state: "生成中",
assetsId: id,
});
// 3. 准备生成参数
const imagePath = `/${projectId}/${cfg.dir}/${uuidv4()}.jpg`;
const userPrompt = buildPrompt(cfg, project.artStyle!, name, prompt);
const describe = `生成${cfg.label}图,名称:${name},提示词:${prompt}`;
const relatedObjects = { id, projectId, type: cfg.label };
try {
// 4. 调用 AI 生成图片
const aiImage = u.Ai.Image(model);
await aiImage.run({
prompt: userPrompt,
imageBase64: base64 ? [base64] : [],
size: resolution,
aspectRatio: "16:9",
taskClass: cfg.taskClass,
describe,
projectId,
relatedObjects: JSON.stringify(relatedObjects),
});
aiImage.save(imagePath);
// 5. 更新记录 & 返回结果
const imageData = await u.db("o_image").where("id", imageId).select("*").first();
if (!imageData) return res.status(500).send("资产已被删除");
await u.db("o_image").where("id", imageId).update({
state: "生成成功",
filePath: imagePath,
type,
model: model.split(":")[1],
resolution,
});
const path = await u.oss.getFileUrl(imagePath);
await u.db("o_assets").where("id", id).update({ imageId });
return res.status(200).send(success({ path, assetsId: id }));
} catch (e) {
await u.db("o_image").where("id", imageId).update({ state: "生成失败" });
return res.status(400).send(error(u.error(e).message || "图片生成失败"));
}
});

View File

@ -1,25 +1,6 @@
// @db-hash ce28b6d566911952421c2661e14bfde5
// @db-hash f9f1fb9b0fc04331ecf65d34c1e4b6af
//该文件由脚本自动生成,请勿手动修改
export interface _o_storyboard_old_20260325 {
'camera'?: string | null;
'createTime'?: number | null;
'description'?: string | null;
'duration'?: string | null;
'filePath'?: string | null;
'frameMode'?: string | null;
'id'?: number;
'lines'?: string | null;
'mode'?: string | null;
'model'?: string | null;
'prompt'?: string | null;
'reason'?: string | null;
'resolution'?: string | null;
'scriptId'?: number | null;
'sound'?: string | null;
'state'?: string | null;
'title'?: string | null;
}
export interface memories {
'content': string;
'createTime': number;
@ -127,11 +108,13 @@ export interface o_project {
'artStyle'?: string | null;
'createTime'?: number | null;
'id'?: number | null;
'imageModel'?: string | null;
'intro'?: string | null;
'name'?: string | null;
'projectType'?: string | null;
'type'?: string | null;
'userId'?: number | null;
'videoModel'?: string | null;
'videoRatio'?: string | null;
}
export interface o_script {
@ -173,7 +156,6 @@ export interface o_storyboard {
'filePath'?: string | null;
'frameMode'?: string | null;
'id'?: number;
'index'?: string | null;
'lines'?: string | null;
'mode'?: string | null;
'model'?: string | null;
@ -237,7 +219,6 @@ export interface o_videoConfig {
}
export interface DB {
"_o_storyboard_old_20260325": _o_storyboard_old_20260325;
"memories": memories;
"o_agentDeploy": o_agentDeploy;
"o_agentWorkData": o_agentWorkData;

View File

@ -1,13 +1,11 @@
import db from "@/utils/db";
import oss from "@/utils/oss";
// import * as ai from "@/utils/ai";
import getConfig from "./utils/getConfig";
import { v4 as uuid } from "uuid";
import error from "@/utils/error";
import cleanNovel from "./utils/cleanNovel";
import getPath from "@/utils/getPath";
import vm from "@/utils/vm";
import { getPrompts } from "@/utils/getPrompts";
import task from "@/utils/taskRecord";
import Ai from "@/utils/ai";
@ -21,6 +19,5 @@ export default {
vm,
getPath,
Ai,
getPrompts,
task,
};

View File

@ -123,8 +123,6 @@ function createSkillTools(skill: SkillRecord, mainSkillName: string) {
.where("o_skillList.state", 1)
.andWhere("o_skillAttribution.attribution", mainSkillName);
console.log("%c Line:120 🌮 resources", "background:#b03734", resources);
activated.add(name);
console.log(`[Skill] 📖 已激活:${name}${body.length} 字符,${resources.length} 资源)`);
let content = "";
@ -144,7 +142,6 @@ function createSkillTools(skill: SkillRecord, mainSkillName: string) {
content += "- discover_skill_docs当上方资源不足以完成任务时使用关键词检索更多相关文档。传入与当前任务相关的关键词列表即可获取推荐。\n";
content += "</skill_tools_guide>\n";
content += "</skill_content>";
console.log("%c Line:133 🍊 content", "background:#2eafb0", content);
return { content };
},
}),

View File

@ -85,7 +85,6 @@ class AiText {
}
interface ImageConfig {
systemPrompt?: string; // 系统提示词
prompt: string; //图片提示词
imageBase64: string[]; //输入的图片提示词
size: "1K" | "2K" | "4K"; // 图片尺寸

View File

@ -1,20 +0,0 @@
export function getPrompts(type: string) {
if (type == "role-polish") {
return "帮我升深入描述一下这个角色,包括他的外貌、性格、背景故事等方面,要求生动有趣,能够让人印象深刻。"
}
if (type == "scene-polish") {
return "帮我升深入描述一下这个场景,包括它的环境、氛围、视觉效果等方面,要求生动有趣,能够让人印象深刻。"
}
if (type == "tool-polish") {
return "帮我升深入描述一下这个道具,包括它的外观、功能、使用方法等方面,要求生动有趣,能够让人印象深刻。"
}
if (type == "role-generateImage") {
return "你是一个资深的角色设计师,擅长根据提示词创作出符合要求的角色设计图。请根据用户提供的提示词,结合你的专业知识和创意,生成一套角色设计图,包括正面、侧面、背面和动态四视图。请确保设计图风格统一,细节丰富,能够清晰地展示角色的外貌特征、服装设计和个性特点。"
}
if (type == "scene-generateImage") {
return "你是一个资深的场景设计师,擅长根据提示词创作出符合要求的场景设计图。请根据用户提供的提示词,结合你的专业知识和创意,生成一套场景设计图,包括全景图、局部特写图和动态效果图。请确保设计图风格统一,细节丰富,能够清晰地展示场景的环境氛围、视觉效果和叙事功能。"
}
if (type == "tool-generateImage") {
return "你是一个资深的道具设计师,擅长根据提示词创作出符合要求的道具设计图。请根据用户提供的提示词,结合你的专业知识和创意,生成一套道具设计图,包括正面、侧面、背面和动态四视图。请确保设计图风格统一,细节丰富,能够清晰地展示道具的外观特征、功能设计和使用方法。"
}
}