video-flow-toon/src/lib/initDB.ts

469 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Knex } from "knex";
import { v4 as uuid } from "uuid";
interface TableSchema {
name: string;
builder: (table: Knex.CreateTableBuilder) => void;
initData?: (knex: Knex) => Promise<void>;
}
export default async (knex: Knex, forceInit: boolean = false): Promise<void> => {
const tables: TableSchema[] = [
// 用户表
{
name: "o_user",
builder: (table) => {
table.integer("id").notNullable();
table.text("name");
table.text("password");
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => {
await knex("o_user").insert([{ id: 1, name: "admin", password: "admin123" }]);
},
},
//项目表
{
name: "o_project",
builder: (table) => {
table.integer("id");
table.string("projectType");
table.string("imageModel");
table.string("videoModel");
table.text("name");
table.text("intro");
table.text("type");
table.text("artStyle");
table.text("videoRatio");
table.integer("createTime");
table.integer("userId");
table.primary(["id"]);
},
},
//风格表
{
name: "o_artStyle",
builder: (table) => {
table.integer("id").notNullable();
table.string("name");
table.text("fileUrl");
table.text("label");
table.text("prompt");
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => {},
},
//Agent配置表
{
name: "o_agentDeploy",
builder: (table) => {
table.integer("id").notNullable();
table.string("model");
table.string("key");
table.string("modelName");
table.integer("vendorId");
table.string("desc");
table.string("name");
table.boolean("disabled").defaultTo(false);
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => {
await knex("o_agentDeploy").insert([
{
model: "",
modelName: "",
vendorId: null,
key: "scriptAgent",
name: "剧本Agent",
desc: "用于读取原文生成故事骨架、改编策略,建议使用具备强大文本理解和生成能力的模型",
disabled: false,
},
{
model: "",
modelName: "",
vendorId: null,
key: "productionAgent",
name: "生产Agent",
desc: "对工作流进行调度和管理,建议使用具备较强的逻辑推理和任务管理能力的模型",
disabled: false,
},
{
model: "",
modelName: "",
vendorId: null,
key: "universalAgent",
name: "通用Agent",
desc: "用于小说事件提取、资产提示词生成、台词提取等边缘功能,建议使用具备较强文本处理能力的模型",
disabled: false,
},
{
model: "",
modelName: "",
vendorId: null,
key: "ttsDubbing",
name: "TTS配音",
desc: "根据剧本内容生成角色配音,支持多种声音风格和情绪",
disabled: true,
},
]);
},
},
//设置表
{
name: "o_setting",
builder: (table) => {
table.text("key");
table.text("value");
table.primary(["key"]);
table.unique(["key"]);
},
initData: async (knex) => {
await knex("o_setting").insert([
{
key: "tokenKey",
value: uuid().slice(0, 8),
},
{
key: "messagesPerSummary",
value: 3,
},
{
key: "shortTermLimit",
value: 5,
},
{
key: "summaryMaxLength",
value: 500,
},
{
key: "summaryLimit",
value: 10,
},
{
key: "ragLimit",
value: 3,
},
{
key: "deepRetrieveSummaryLimit",
value: 5,
},
{
key: "modelOnnxFile",
value: '["all-MiniLM-L6-v2", "onnx", "model_fp16.onnx"]',
},
{
key: "modelDtype",
value: "fp16",
},
]);
},
},
//任务中心表
{
name: "o_tasks",
builder: (table) => {
table.integer("id").notNullable();
table.integer("projectId");
table.string("taskClass");
table.string("relatedObjects");
table.string("model");
table.text("describe");
table.string("state");
table.integer("startTime");
table.text("reason");
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => {},
},
//小说原文表
{
name: "o_novel",
builder: (table) => {
table.integer("id").notNullable();
table.integer("chapterIndex");
table.text("reel");
table.text("chapter");
table.text("chapterData");
table.integer("projectId");
table.integer("eventState");
table.text("event");
table.text("errorReason");
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//小说事件表
{
name: "o_event",
builder: (table) => {
table.integer("id").notNullable();
table.string("name");
table.string("detail");
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//事件-章节表
{
name: "o_eventChapter",
builder: (table) => {
table.integer("id").notNullable();
table.integer("eventId").unsigned().references("id").inTable("o_event");
table.integer("novelId").unsigned().references("id").inTable("o_novel");
table.primary(["id"]);
table.unique(["id"]);
},
},
//大纲表
{
name: "o_outline",
builder: (table) => {
table.integer("id").notNullable();
table.integer("episode");
table.text("data");
table.integer("projectId");
table.primary(["id"]);
table.unique(["id"]);
},
},
//大纲-原文表
{
name: "o_outlineNovel",
builder: (table) => {
table.integer("id").notNullable();
table.integer("outlineId").unsigned().references("id").inTable("o_outline");
table.integer("novelId").unsigned().references("id").inTable("o_novel");
table.primary(["id"]);
table.unique(["id"]);
},
},
//剧本
{
name: "o_script",
builder: (table) => {
table.integer("id").notNullable();
table.text("name");
table.text("content");
table.integer("projectId");
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//资产表
{
name: "o_assets",
builder: (table) => {
table.integer("id").notNullable();
table.text("name");
table.text("prompt");
table.text("remark");
table.text("type");
table.text("describe");
table.integer("scriptId"); //剧本id
table.integer("imageId").unsigned().references("id").inTable("o_image");
table.integer("assetsId");
table.integer("projectId");
table.integer("startTime");
table.primary(["id"]);
table.unique(["id"]);
},
initData: async (knex) => {},
},
//生成图片表
{
name: "o_image",
builder: (table) => {
table.integer("id").notNullable();
table.text("filePath");
table.text("type");
table.integer("assetsId");
table.text("model");
table.text("resolution");
table.text("state");
table.primary(["id"]);
table.unique(["id"]);
},
},
//分镜
{
name: "o_storyboard",
builder: (table) => {
table.integer("id").notNullable();
table.integer("scriptId");
table.text("title");
table.text("prompt");
table.text("description");
table.text("filePath");
table.text("model");
table.text("mode");
table.text("duration");
table.text("resolution");
table.text("frameMode");
table.text("camera");
table.text("sound");
table.text("lines");
table.text("state");
table.text("reason");
table.text("index");
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//flowData-剧本
{
name: "o_agentWorkData",
builder: (table) => {
table.integer("id").notNullable();
table.integer("projectId");
table.integer("episodesId");
table.string("key"); //用户其他方式索引
table.string("data");
table.integer("createTime");
table.integer("updateTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//视频
{
name: "o_video",
builder: (table) => {
table.integer("id").notNullable();
table.text("filePath");
table.text("errorReason");
table.integer("time");
table.text("state");
table.integer("scriptId");
table.integer("storyboardId");
table.primary(["id"]);
table.unique(["id"]);
},
},
{
name: "o_videoConfig",
builder: (table) => {
table.integer("id").notNullable();
table.integer("storyboardId");
table.integer("videoId");
table.integer("audio"); // 声音
table.text("model"); // 模型
table.text("mode"); // 模式:
table.text("data"); // 所选数据集图片 JSON
table.text("resolution"); // 分辨率
table.integer("duration"); // 时长
table.text("prompt"); // 提示词
table.integer("createTime"); // 创建时间
table.integer("updateTime"); // 更新时间
table.primary(["id"]);
table.unique(["id"]);
},
},
//供应商配置表
{
name: "o_vendorConfig",
builder: (table) => {
table.integer("id").notNullable();
table.text("name");
table.text("version");
table.text("icon");
table.text("inputs"); // 输入项配置 JSON
table.text("inputValues"); // 输入项值 JSON
table.text("models"); // 模型配置 JSON
table.text("code"); // 模型配置 JSON
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//供应商配置表
{
name: "o_vendorConfig",
builder: (table) => {
table.integer("id").notNullable();
table.text("name");
table.text("version");
table.text("icon");
table.text("inputs"); // 输入项配置 JSON
table.text("inputValues"); // 输入项值 JSON
table.text("models"); // 模型配置 JSON
table.text("code"); // 模型配置 JSON
table.integer("createTime");
table.primary(["id"]);
table.unique(["id"]);
},
},
//记忆表message=原始消息, summary=压缩摘要)
{
name: "memories",
builder: (table) => {
table.text("id").notNullable();
table.text("isolationKey").notNullable(); // 记忆隔离键
table.text("type").notNullable(); // 'message' | 'summary'
table.text("role"); // 'user' | 'assistant'
table.text("content").notNullable();
table.text("embedding"); // 向量嵌入 JSON
table.text("relatedMessageIds"); // summary关联的message id列表 JSON
table.integer("summarized").defaultTo(0); // message是否已被总结 0/1
table.integer("createTime").notNullable();
table.primary(["id"]);
table.index(["isolationKey", "type"]);
table.index(["isolationKey", "summarized"]);
},
},
//图片工作流表
{
name: "o_imageFlow",
builder: (table) => {
table.integer("id").notNullable();
table.text("flowData").notNullable();
table.integer("storyboardId");
table.integer("assetsId");
table.primary(["id"]);
table.unique(["id"]);
},
},
{
name: "o_assets2Storyboard",
builder: (table) => {
table.integer("storyboardId").notNullable();
table.integer("assetId").notNullable();
table.primary(["storyboardId", "assetId"]);
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) {
const tableExists = await knex.schema.hasTable(t.name);
if (!tableExists || forceInit) {
if (tableExists && forceInit) {
await knex.schema.dropTable(t.name);
console.log("[初始化数据库] 已存在表删除并重建:", t.name);
} else {
console.log("[初始化数据库] 创建数据表:", t.name);
}
await knex.schema.createTable(t.name, t.builder);
if (t.initData) {
await t.initData(knex);
console.log("[初始化数据库] 表数据初始化:", t.name);
}
}
}
};