diff --git a/README.md b/README.md index e862983..0ab7531 100644 --- a/README.md +++ b/README.md @@ -123,42 +123,14 @@ https://www.bilibili.com/video/BV1na6wB6Ea2 ### 前置条件 - 已安装 [Docker](https://docs.docker.com/get-docker/)(版本 20.10+) -- 已安装 [Docker Compose](https://docs.docker.com/compose/install/)(版本 2.0+) -### 方式一:在线部署(推荐) +### 方式一:在线部署 -从 GitHub / Gitee 自动拉取源码并构建镜像: - -```shell -docker-compose -f docker/docker-compose.yml up -d --build -``` - -**支持的构建参数:** - -| 参数 | 说明 | 默认值 | 示例 | -| -------- | ------------ | -------- | ------------------ | -| `GIT` | 代码仓库源 | `github` | `github` / `gitee` | -| `TAG` | 指定版本标签 | 最新 tag | `v1.0.6` | -| `BRANCH` | 指定分支 | 默认分支 | `main` / `dev` | - -**版本选择优先级**:指定 TAG > 指定 BRANCH > 自动获取最新 tag > 默认分支 - -**指定参数示例:** - -```shell -# 使用 Gitee 源(国内推荐,速度更快) -GIT=gitee docker-compose -f docker/docker-compose.yml up -d --build - -# 指定版本标签 -TAG=v1.0.6 docker-compose -f docker/docker-compose.yml up -d --build - -# 指定分支 + Gitee 源 -GIT=gitee BRANCH=dev docker-compose -f docker/docker-compose.yml up -d --build -``` +待完善,暂时使用本地构建。 ### 方式二:本地构建 -使用本地已有的源码直接构建,适合开发者或已克隆仓库的用户: +使用本地已有的源码直接构建,适合开发者或已克隆仓库的用户,这需要你在本地安装git: ```shell # 先克隆项目(如已有则跳过) @@ -166,50 +138,45 @@ git clone https://github.com/HBAI-Ltd/Toonflow-app.git cd Toonflow-app # 使用本地源码构建 -docker-compose -f docker/docker-compose.local.yml up -d --build +chmod +x ./build-docker.sh && ./build-docker.sh + +docker run -d -p <本地端口>:10588 -v <本地数据路径>:/app/data toonflow + +# 此时在相应端口的 /web/index.html 路径即可访问页面。docker版本暂时处于测试状态,容器内会以dev模式运行,这可能会导致响应速度略微受限 +# 例如 http://localhost:10588/web/index.html ``` ### 服务端口说明 -| 端口 | 用途 | 在线部署映射 | 本地构建映射 | -| ------- | -------------- | ------------- | ------------- | -| `80` | Nginx 前端页面 | 随机端口 | `8080:80` | -| `10588` | 后端 API 服务 | `10588:10588` | `10588:10588` | +| 端口 | 用途 | 部署映射 +| ------- | -------------- | ------------- +| `10588` | 软件界面 | `10588:10588` -### 数据持久化 -默认日志目录会挂载到宿主机 `./logs` 目录。如需持久化上传文件或数据库,可在 `docker-compose.yml` 中添加 volumes: +**环境变量说明:** -```yaml -volumes: - - ./logs:/var/log - - ./uploads:/app/uploads # 持久化上传文件 - - ./data:/app/data # 持久化数据库(如有) -``` +| 变量 | 说明 | +| ---------- | ---------------------------------- | +| `NODE_ENV` | 运行环境,`prod` 表示生产环境 | -### 常用操作命令 +--- -```shell -# 查看容器状态 -docker-compose -f docker/docker-compose.yml ps - -# 查看实时日志 -docker-compose -f docker/docker-compose.yml logs -f - -# 停止服务 -docker-compose -f docker/docker-compose.yml down - -# 重新构建并启动(更新版本时使用) -docker-compose -f docker/docker-compose.yml up -d --build - -# 进入容器调试 -docker exec -it toonflow sh -``` > ⚠️ **首次登录** > 账号:`admin` > 密码:`admin123` +#### 6. 部署前端网站 + +如需单独部署或定制前端界面,请参考前端仓库: + +- **GitHub**:[Toonflow-web](https://github.com/HBAI-Ltd/Toonflow-web) +- **Gitee**:[Toonflow-web](https://gitee.com/HBAI-Ltd/Toonflow-web) + +> 💡 **说明**:本仓库已内置编译好的前端资源,普通用户无需单独部署前端。前端仓库仅供需要二次开发的开发者使用。 + +--- + ## 云端部署 ### 一、服务器环境要求 @@ -260,7 +227,7 @@ yarn build ```json { "name": "toonflow-app", - "script": "build/app.js", + "script": "data/serve/app.js", "instances": "max", "exec_mode": "cluster", "env": { diff --git a/src/router.ts b/src/router.ts index efdce9e..6d36176 100644 --- a/src/router.ts +++ b/src/router.ts @@ -1,4 +1,4 @@ -// @routes-hash fc02af7340ae26f567792eda4cde50a6 +// @routes-hash 01a3e214a845cf74065af521bc0794cc import { Express } from "express"; import route1 from "./routes/agents/clearMemory"; @@ -57,69 +57,73 @@ import route53 from "./routes/production/getFlowData"; import route54 from "./routes/production/getProductionData"; import route55 from "./routes/production/getStoryboardData"; import route56 from "./routes/production/saveFlowData"; -import route57 from "./routes/production/storyboard/batchGenerateImage"; -import route58 from "./routes/production/storyboard/downPreviewImage"; -import route59 from "./routes/production/storyboard/getStoryboardData"; -import route60 from "./routes/production/storyboard/pollingImage"; -import route61 from "./routes/production/storyboard/previewImage"; -import route62 from "./routes/production/workbench/confirmSelection"; -import route63 from "./routes/production/workbench/delVideo"; -import route64 from "./routes/production/workbench/generateVideo"; -import route65 from "./routes/production/workbench/generateVideoPrompt"; -import route66 from "./routes/production/workbench/getChatLines"; -import route67 from "./routes/production/workbench/getVideoModelDetail"; -import route68 from "./routes/production/workbench/videoPolling"; -import route69 from "./routes/project/addProject"; -import route70 from "./routes/project/addVisual"; -import route71 from "./routes/project/addVisualManual"; -import route72 from "./routes/project/deleteVisualManual"; -import route73 from "./routes/project/delProject"; -import route74 from "./routes/project/editProject"; -import route75 from "./routes/project/editVisualManual"; -import route76 from "./routes/project/getProject"; -import route77 from "./routes/project/getVisualManual"; -import route78 from "./routes/project/visualManual"; -import route79 from "./routes/script/addScript"; -import route80 from "./routes/script/delScript"; -import route81 from "./routes/script/exportScript"; -import route82 from "./routes/script/extractAssets"; -import route83 from "./routes/script/getScrptApi"; -import route84 from "./routes/script/pollScriptAssets"; -import route85 from "./routes/script/updateScript"; -import route86 from "./routes/scriptAgent/getPlanData"; -import route87 from "./routes/scriptAgent/setPlanData"; -import route88 from "./routes/scriptAgent/updateData"; -import route89 from "./routes/setting/about/checkUpdate"; -import route90 from "./routes/setting/about/downloadApp"; -import route91 from "./routes/setting/agentDeploy/agentSetKey"; -import route92 from "./routes/setting/agentDeploy/deployAgentModel"; -import route93 from "./routes/setting/agentDeploy/getAgentDeploy"; -import route94 from "./routes/setting/dbConfig/clearData"; -import route95 from "./routes/setting/dev/getSwitchAiDevTool"; -import route96 from "./routes/setting/dev/updateSwitchAiDevTool"; -import route97 from "./routes/setting/fileManagement/openFolder"; -import route98 from "./routes/setting/getTextModel"; -import route99 from "./routes/setting/loginConfig/getUser"; -import route100 from "./routes/setting/loginConfig/updateUserPwd"; -import route101 from "./routes/setting/memoryConfig/delAllMemory"; -import route102 from "./routes/setting/memoryConfig/getMemory"; -import route103 from "./routes/setting/memoryConfig/sureMemory"; -import route104 from "./routes/setting/promptManage/getPrompt"; -import route105 from "./routes/setting/promptManage/updatePrompt"; -import route106 from "./routes/setting/skillManagement/getSkillContent"; -import route107 from "./routes/setting/skillManagement/getSkillList"; -import route108 from "./routes/setting/skillManagement/saveSkillContent"; -import route109 from "./routes/setting/vendorConfig/addVendor"; -import route110 from "./routes/setting/vendorConfig/deleteVendor"; -import route111 from "./routes/setting/vendorConfig/getVendorList"; -import route112 from "./routes/setting/vendorConfig/modelTest"; -import route113 from "./routes/setting/vendorConfig/updateCode"; -import route114 from "./routes/setting/vendorConfig/updateVendor"; -import route115 from "./routes/task/getProject"; -import route116 from "./routes/task/getTaskApi"; -import route117 from "./routes/task/getTaskCategories"; -import route118 from "./routes/task/taskDetails"; -import route119 from "./routes/test/test"; +import route57 from "./routes/production/storyboard/batchAddStoryboardInfo"; +import route58 from "./routes/production/storyboard/batchGenerateImage"; +import route59 from "./routes/production/storyboard/downPreviewImage"; +import route60 from "./routes/production/storyboard/editStoryboardInfo"; +import route61 from "./routes/production/storyboard/getStoryboardData"; +import route62 from "./routes/production/storyboard/pollingImage"; +import route63 from "./routes/production/storyboard/previewImage"; +import route64 from "./routes/production/storyboard/removeFrame"; +import route65 from "./routes/production/storyboard/updateStoryboardInfo"; +import route66 from "./routes/production/workbench/confirmSelection"; +import route67 from "./routes/production/workbench/delVideo"; +import route68 from "./routes/production/workbench/generateVideo"; +import route69 from "./routes/production/workbench/generateVideoPrompt"; +import route70 from "./routes/production/workbench/getChatLines"; +import route71 from "./routes/production/workbench/getVideoModelDetail"; +import route72 from "./routes/production/workbench/videoPolling"; +import route73 from "./routes/project/addProject"; +import route74 from "./routes/project/addVisual"; +import route75 from "./routes/project/addVisualManual"; +import route76 from "./routes/project/deleteVisualManual"; +import route77 from "./routes/project/delProject"; +import route78 from "./routes/project/editProject"; +import route79 from "./routes/project/editVisualManual"; +import route80 from "./routes/project/getProject"; +import route81 from "./routes/project/getVisualManual"; +import route82 from "./routes/project/visualManual"; +import route83 from "./routes/script/addScript"; +import route84 from "./routes/script/delScript"; +import route85 from "./routes/script/exportScript"; +import route86 from "./routes/script/extractAssets"; +import route87 from "./routes/script/getScrptApi"; +import route88 from "./routes/script/pollScriptAssets"; +import route89 from "./routes/script/updateScript"; +import route90 from "./routes/scriptAgent/getPlanData"; +import route91 from "./routes/scriptAgent/setPlanData"; +import route92 from "./routes/scriptAgent/updateData"; +import route93 from "./routes/setting/about/checkUpdate"; +import route94 from "./routes/setting/about/downloadApp"; +import route95 from "./routes/setting/agentDeploy/agentSetKey"; +import route96 from "./routes/setting/agentDeploy/deployAgentModel"; +import route97 from "./routes/setting/agentDeploy/getAgentDeploy"; +import route98 from "./routes/setting/dbConfig/clearData"; +import route99 from "./routes/setting/dev/getSwitchAiDevTool"; +import route100 from "./routes/setting/dev/updateSwitchAiDevTool"; +import route101 from "./routes/setting/fileManagement/openFolder"; +import route102 from "./routes/setting/getTextModel"; +import route103 from "./routes/setting/loginConfig/getUser"; +import route104 from "./routes/setting/loginConfig/updateUserPwd"; +import route105 from "./routes/setting/memoryConfig/delAllMemory"; +import route106 from "./routes/setting/memoryConfig/getMemory"; +import route107 from "./routes/setting/memoryConfig/sureMemory"; +import route108 from "./routes/setting/promptManage/getPrompt"; +import route109 from "./routes/setting/promptManage/updatePrompt"; +import route110 from "./routes/setting/skillManagement/getSkillContent"; +import route111 from "./routes/setting/skillManagement/getSkillList"; +import route112 from "./routes/setting/skillManagement/saveSkillContent"; +import route113 from "./routes/setting/vendorConfig/addVendor"; +import route114 from "./routes/setting/vendorConfig/deleteVendor"; +import route115 from "./routes/setting/vendorConfig/getVendorList"; +import route116 from "./routes/setting/vendorConfig/modelTest"; +import route117 from "./routes/setting/vendorConfig/updateCode"; +import route118 from "./routes/setting/vendorConfig/updateVendor"; +import route119 from "./routes/task/getProject"; +import route120 from "./routes/task/getTaskApi"; +import route121 from "./routes/task/getTaskCategories"; +import route122 from "./routes/task/taskDetails"; +import route123 from "./routes/test/test"; export default async (app: Express) => { app.use("/api/agents/clearMemory", route1); @@ -178,67 +182,71 @@ export default async (app: Express) => { app.use("/api/production/getProductionData", route54); app.use("/api/production/getStoryboardData", route55); app.use("/api/production/saveFlowData", route56); - app.use("/api/production/storyboard/batchGenerateImage", route57); - app.use("/api/production/storyboard/downPreviewImage", route58); - app.use("/api/production/storyboard/getStoryboardData", route59); - app.use("/api/production/storyboard/pollingImage", route60); - app.use("/api/production/storyboard/previewImage", route61); - app.use("/api/production/workbench/confirmSelection", route62); - app.use("/api/production/workbench/delVideo", route63); - app.use("/api/production/workbench/generateVideo", route64); - app.use("/api/production/workbench/generateVideoPrompt", route65); - app.use("/api/production/workbench/getChatLines", route66); - app.use("/api/production/workbench/getVideoModelDetail", route67); - app.use("/api/production/workbench/videoPolling", route68); - app.use("/api/project/addProject", route69); - app.use("/api/project/addVisual", route70); - app.use("/api/project/addVisualManual", route71); - app.use("/api/project/deleteVisualManual", route72); - app.use("/api/project/delProject", route73); - app.use("/api/project/editProject", route74); - app.use("/api/project/editVisualManual", route75); - app.use("/api/project/getProject", route76); - app.use("/api/project/getVisualManual", route77); - app.use("/api/project/visualManual", route78); - app.use("/api/script/addScript", route79); - app.use("/api/script/delScript", route80); - app.use("/api/script/exportScript", route81); - app.use("/api/script/extractAssets", route82); - app.use("/api/script/getScrptApi", route83); - app.use("/api/script/pollScriptAssets", route84); - app.use("/api/script/updateScript", route85); - app.use("/api/scriptAgent/getPlanData", route86); - app.use("/api/scriptAgent/setPlanData", route87); - app.use("/api/scriptAgent/updateData", route88); - app.use("/api/setting/about/checkUpdate", route89); - app.use("/api/setting/about/downloadApp", route90); - app.use("/api/setting/agentDeploy/agentSetKey", route91); - app.use("/api/setting/agentDeploy/deployAgentModel", route92); - app.use("/api/setting/agentDeploy/getAgentDeploy", route93); - app.use("/api/setting/dbConfig/clearData", route94); - app.use("/api/setting/dev/getSwitchAiDevTool", route95); - app.use("/api/setting/dev/updateSwitchAiDevTool", route96); - app.use("/api/setting/fileManagement/openFolder", route97); - app.use("/api/setting/getTextModel", route98); - app.use("/api/setting/loginConfig/getUser", route99); - app.use("/api/setting/loginConfig/updateUserPwd", route100); - app.use("/api/setting/memoryConfig/delAllMemory", route101); - app.use("/api/setting/memoryConfig/getMemory", route102); - app.use("/api/setting/memoryConfig/sureMemory", route103); - app.use("/api/setting/promptManage/getPrompt", route104); - app.use("/api/setting/promptManage/updatePrompt", route105); - app.use("/api/setting/skillManagement/getSkillContent", route106); - app.use("/api/setting/skillManagement/getSkillList", route107); - app.use("/api/setting/skillManagement/saveSkillContent", route108); - app.use("/api/setting/vendorConfig/addVendor", route109); - app.use("/api/setting/vendorConfig/deleteVendor", route110); - app.use("/api/setting/vendorConfig/getVendorList", route111); - app.use("/api/setting/vendorConfig/modelTest", route112); - app.use("/api/setting/vendorConfig/updateCode", route113); - app.use("/api/setting/vendorConfig/updateVendor", route114); - app.use("/api/task/getProject", route115); - app.use("/api/task/getTaskApi", route116); - app.use("/api/task/getTaskCategories", route117); - app.use("/api/task/taskDetails", route118); - app.use("/api/test/test", route119); + app.use("/api/production/storyboard/batchAddStoryboardInfo", route57); + app.use("/api/production/storyboard/batchGenerateImage", route58); + app.use("/api/production/storyboard/downPreviewImage", route59); + app.use("/api/production/storyboard/editStoryboardInfo", route60); + app.use("/api/production/storyboard/getStoryboardData", route61); + app.use("/api/production/storyboard/pollingImage", route62); + app.use("/api/production/storyboard/previewImage", route63); + app.use("/api/production/storyboard/removeFrame", route64); + app.use("/api/production/storyboard/updateStoryboardInfo", route65); + app.use("/api/production/workbench/confirmSelection", route66); + app.use("/api/production/workbench/delVideo", route67); + app.use("/api/production/workbench/generateVideo", route68); + app.use("/api/production/workbench/generateVideoPrompt", route69); + app.use("/api/production/workbench/getChatLines", route70); + app.use("/api/production/workbench/getVideoModelDetail", route71); + app.use("/api/production/workbench/videoPolling", route72); + app.use("/api/project/addProject", route73); + app.use("/api/project/addVisual", route74); + app.use("/api/project/addVisualManual", route75); + app.use("/api/project/deleteVisualManual", route76); + app.use("/api/project/delProject", route77); + app.use("/api/project/editProject", route78); + app.use("/api/project/editVisualManual", route79); + app.use("/api/project/getProject", route80); + app.use("/api/project/getVisualManual", route81); + app.use("/api/project/visualManual", route82); + app.use("/api/script/addScript", route83); + app.use("/api/script/delScript", route84); + app.use("/api/script/exportScript", route85); + app.use("/api/script/extractAssets", route86); + app.use("/api/script/getScrptApi", route87); + app.use("/api/script/pollScriptAssets", route88); + app.use("/api/script/updateScript", route89); + app.use("/api/scriptAgent/getPlanData", route90); + app.use("/api/scriptAgent/setPlanData", route91); + app.use("/api/scriptAgent/updateData", route92); + app.use("/api/setting/about/checkUpdate", route93); + app.use("/api/setting/about/downloadApp", route94); + app.use("/api/setting/agentDeploy/agentSetKey", route95); + app.use("/api/setting/agentDeploy/deployAgentModel", route96); + app.use("/api/setting/agentDeploy/getAgentDeploy", route97); + app.use("/api/setting/dbConfig/clearData", route98); + app.use("/api/setting/dev/getSwitchAiDevTool", route99); + app.use("/api/setting/dev/updateSwitchAiDevTool", route100); + app.use("/api/setting/fileManagement/openFolder", route101); + app.use("/api/setting/getTextModel", route102); + app.use("/api/setting/loginConfig/getUser", route103); + app.use("/api/setting/loginConfig/updateUserPwd", route104); + app.use("/api/setting/memoryConfig/delAllMemory", route105); + app.use("/api/setting/memoryConfig/getMemory", route106); + app.use("/api/setting/memoryConfig/sureMemory", route107); + app.use("/api/setting/promptManage/getPrompt", route108); + app.use("/api/setting/promptManage/updatePrompt", route109); + app.use("/api/setting/skillManagement/getSkillContent", route110); + app.use("/api/setting/skillManagement/getSkillList", route111); + app.use("/api/setting/skillManagement/saveSkillContent", route112); + app.use("/api/setting/vendorConfig/addVendor", route113); + app.use("/api/setting/vendorConfig/deleteVendor", route114); + app.use("/api/setting/vendorConfig/getVendorList", route115); + app.use("/api/setting/vendorConfig/modelTest", route116); + app.use("/api/setting/vendorConfig/updateCode", route117); + app.use("/api/setting/vendorConfig/updateVendor", route118); + app.use("/api/task/getProject", route119); + app.use("/api/task/getTaskApi", route120); + app.use("/api/task/getTaskCategories", route121); + app.use("/api/task/taskDetails", route122); + app.use("/api/test/test", route123); } diff --git a/src/routes/production/assets/batchGenerateAssetsImage.ts b/src/routes/production/assets/batchGenerateAssetsImage.ts index ea1cbad..1841709 100644 --- a/src/routes/production/assets/batchGenerateAssetsImage.ts +++ b/src/routes/production/assets/batchGenerateAssetsImage.ts @@ -51,12 +51,14 @@ export default router.post( tool: { prompt: toolPrompt, label: "道具衍生资产", - focus: "注重道具的材质质感、光影效果、结构细节与功能特征,保持与原始道具设计的一致性(如形状、配色、标志性元素),清晰展示道具在不同状态或角度下的视觉表现。", + focus: + "注重道具的材质质感、光影效果、结构细节与功能特征,保持与原始道具设计的一致性(如形状、配色、标志性元素),清晰展示道具在不同状态或角度下的视觉表现。", }, scene: { prompt: scenePrompt, label: "场景衍生资产", - focus: "注重场景的空间层次、光影氛围、环境细节与情绪渲染,保持与原始场景设计的一致性(如建筑风格、色调、标志性地标),体现不同时间段或天气条件下的视觉变化。", + focus: + "注重场景的空间层次、光影氛围、环境细节与情绪渲染,保持与原始场景设计的一致性(如建筑风格、色调、标志性地标),体现不同时间段或天气条件下的视觉变化。", }, }; const imageData = []; @@ -72,7 +74,6 @@ export default router.post( ## 输出要求 - 直接输出最终提示词,不要包含任何解释、标题或标记 -- 提示词应为具体的视觉描述,包含主体、构图、光影、色调、氛围等要素 - ${typeConfig.focus} ${hasRefImage ? "- 当前资产有参考图作为风格锚点,提示词应侧重描述衍生变化部分,避免重复参考图已有的基础特征" : "- 当前资产无参考图,提示词需要完整描述视觉特征"} @@ -86,11 +87,6 @@ ${typeConfig.prompt || "(未指定特定美术风格,请根据资产描述 ], }); - const repeloadObj = { - prompt: text, - size: projectSettingData?.imageQuality as "1K" | "2K" | "4K", - aspectRatio: "16:9", - }; const [imageId] = await u.db("o_image").insert({ assetsId: item.id, type: item.type, @@ -100,16 +96,23 @@ ${typeConfig.prompt || "(未指定特定美术风格,请根据资产描述 }); const imageBase64 = imageUrlRecord[item.assetsId!] ? await urlToBase64(imageUrlRecord[item.assetsId!]) : null; try { - const imageCls = await u.Ai.Image(projectSettingData?.imageModel as `${string}:${string}`).run({ + const repeloadObj = { prompt: text, - imageBase64: imageBase64 ? [imageBase64] : [], size: projectSettingData?.imageQuality as "1K" | "2K" | "4K", - aspectRatio: "16:9", - taskClass: "生成图片", - describe: "资产图片生成", - relatedObjects: JSON.stringify(repeloadObj), - projectId: projectId, - }); + aspectRatio: "16:9" as `${number}:${number}`, + }; + const imageCls = await u.Ai.Image(projectSettingData?.imageModel as `${string}:${string}`).run( + { + imageBase64: imageBase64 ? [imageBase64] : [], + ...repeloadObj, + }, + { + taskClass: "生成图片", + describe: "资产图片生成", + relatedObjects: JSON.stringify(repeloadObj), + projectId: projectId, + }, + ); const savePath = `/${projectId}/assets/${scriptId}/${u.uuid()}.jpg`; await imageCls.save(savePath); // 更新对应数据库 @@ -121,7 +124,6 @@ ${typeConfig.prompt || "(未指定特定美术风格,请根据资产描述 src: await u.oss.getFileUrl(savePath), }); } catch (e) { - console.log("%c Line:95 🥛 e", "background:#fca650", e); await u .db("o_image") .where({ id: imageId }) diff --git a/src/routes/production/saveFlowData.ts b/src/routes/production/saveFlowData.ts index 92ad364..c429a74 100644 --- a/src/routes/production/saveFlowData.ts +++ b/src/routes/production/saveFlowData.ts @@ -24,17 +24,17 @@ export default router.post( episodesId: number; } = req.body; const sqlData = await u.db("o_agentWorkData").where("projectId", String(projectId)).andWhere("episodesId", String(episodesId)).first(); - if (data.storyboard && data.storyboard.length) - await Promise.all( - data.storyboard.map(async (i, index) => { - await u - .db("o_storyboard") - .where("id", i.id) - .update({ - index: index + 1, - }); - }), - ); + // if (data.storyboard && data.storyboard.length) + // await Promise.all( + // data.storyboard.map(async (i, index) => { + // await u + // .db("o_storyboard") + // .where("id", i.id) + // .update({ + // index: index + 1, + // }); + // }), + // ); if (!sqlData) { await u.db("o_agentWorkData").insert({ projectId, diff --git a/src/routes/production/storyboard/batchAddStoryboardInfo.ts b/src/routes/production/storyboard/batchAddStoryboardInfo.ts new file mode 100644 index 0000000..dbcc417 --- /dev/null +++ b/src/routes/production/storyboard/batchAddStoryboardInfo.ts @@ -0,0 +1,31 @@ +import express from "express"; +import u from "@/utils"; +import { z } from "zod"; +import { success } from "@/lib/responseFormat"; +import { validateFields } from "@/middleware/middleware"; +const router = express.Router(); + +export default router.post( + "/", + validateFields({ + data: z.array( + z.object({ + prompt: z.string(), + }), + ), + scriptId: z.number(), + }), + async (req, res) => { + const { data, scriptId } = req.body; + if (!data.length) return res.status(400).send({ success: false, message: "数据不能为空" }); + await u.db("o_storyboard").insert( + data.map((i: { prompt: string }) => ({ + ...i, + scriptId, + createTime: Date.now(), + state: "未生成", + })), + ); + return res.status(200).send(success()); + }, +); diff --git a/src/routes/production/storyboard/batchGenerateImage.ts b/src/routes/production/storyboard/batchGenerateImage.ts index 7a3f715..77da460 100644 --- a/src/routes/production/storyboard/batchGenerateImage.ts +++ b/src/routes/production/storyboard/batchGenerateImage.ts @@ -169,23 +169,25 @@ ${sceneArkPrompt || "(未指定特定美术风格,请根据分镜内容选 const repeloadObj = { prompt: text, size: projectSettingData?.imageQuality as "1K" | "2K" | "4K", - aspectRatio: "16:9", + aspectRatio: "16:9" as `${number}:${number}`, }; await u.db("o_storyboard").where("id", item.id).update({ prompt: text, state: "生成中", }); u.Ai.Image(projectSettingData?.imageModel as `${string}:${string}`) - .run({ - prompt: text, - imageBase64: await getAssetsImageBase64(assetRecord[item.id!] || []), - size: projectSettingData?.imageQuality as "1K" | "2K" | "4K", - aspectRatio: "16:9", - taskClass: "生成图片", - describe: "资产图片生成", - relatedObjects: JSON.stringify(repeloadObj), - projectId: projectId, - }) + .run( + { + imageBase64: await getAssetsImageBase64(assetRecord[item.id!] || []), + ...repeloadObj, + }, + { + taskClass: "生成分镜图片", + describe: "分镜图片生成", + relatedObjects: JSON.stringify(repeloadObj), + projectId: projectId, + }, + ) .then(async (imageCls) => { const savePath = `/${projectId}/assets/${scriptId}/${u.uuid()}.jpg`; await imageCls.save(savePath); diff --git a/src/routes/production/storyboard/editStoryboardInfo.ts b/src/routes/production/storyboard/editStoryboardInfo.ts new file mode 100644 index 0000000..4640c62 --- /dev/null +++ b/src/routes/production/storyboard/editStoryboardInfo.ts @@ -0,0 +1,22 @@ +import express from "express"; +import u from "@/utils"; +import { z } from "zod"; +import { success } from "@/lib/responseFormat"; +import { validateFields } from "@/middleware/middleware"; +import { id } from "zod/locales"; +const router = express.Router(); + +export default router.post( + "/", + validateFields({ + id: z.number(), + prompt: z.string(), + }), + async (req, res) => { + const { id, prompt } = req.body; + await u.db("o_storyboard").where({ id }).update({ + prompt, + }); + res.status(200).send(success({ message: "更新提示词成功" })); + }, +); diff --git a/src/routes/production/storyboard/removeFrame.ts b/src/routes/production/storyboard/removeFrame.ts new file mode 100644 index 0000000..55d4483 --- /dev/null +++ b/src/routes/production/storyboard/removeFrame.ts @@ -0,0 +1,19 @@ +import express from "express"; +import u from "@/utils"; +import { z } from "zod"; +import { success } from "@/lib/responseFormat"; +import { validateFields } from "@/middleware/middleware"; +const router = express.Router(); + +export default router.post( + "/", + validateFields({ + id: z.number(), + }), + async (req, res) => { + const { id } = req.body; + await u.db("o_storyboard").where("id", id).delete(); + await u.db("o_assets2Storyboard").where("storyboardId", id).delete(); + res.status(200).send(success({ message: "视频删除成功" })); + }, +); diff --git a/src/routes/production/storyboard/updateStoryboardInfo.ts b/src/routes/production/storyboard/updateStoryboardInfo.ts new file mode 100644 index 0000000..4640c62 --- /dev/null +++ b/src/routes/production/storyboard/updateStoryboardInfo.ts @@ -0,0 +1,22 @@ +import express from "express"; +import u from "@/utils"; +import { z } from "zod"; +import { success } from "@/lib/responseFormat"; +import { validateFields } from "@/middleware/middleware"; +import { id } from "zod/locales"; +const router = express.Router(); + +export default router.post( + "/", + validateFields({ + id: z.number(), + prompt: z.string(), + }), + async (req, res) => { + const { id, prompt } = req.body; + await u.db("o_storyboard").where({ id }).update({ + prompt, + }); + res.status(200).send(success({ message: "更新提示词成功" })); + }, +); diff --git a/src/types/database.d.ts b/src/types/database.d.ts index 2a3bc57..533ce4d 100644 --- a/src/types/database.d.ts +++ b/src/types/database.d.ts @@ -1,6 +1,17 @@ +<<<<<<< HEAD // @db-hash 93b2462070c45c2b449e9a18c4e88763 +======= +// @db-hash f7bc2fdb80756d5536929eb47155578b +>>>>>>> 7f36f15fd76d7990ba6e4af584cbb5f1408c0cf6 //该文件由脚本自动生成,请勿手动修改 +export interface _o_script_old_20260327 { + 'content'?: string | null; + 'createTime'?: number | null; + 'id'?: number; + 'name'?: string | null; + 'projectId'?: number | null; +} export interface memories { 'content': string; 'createTime': number; @@ -21,7 +32,7 @@ export interface o_agentDeploy { 'model'?: string | null; 'modelName'?: string | null; 'name'?: string | null; - 'vendorId'?: string | null; + 'vendorId'?: number | null; } export interface o_agentWorkData { 'createTime'?: number | null; @@ -47,7 +58,6 @@ export interface o_assets { 'name'?: string | null; 'projectId'?: number | null; 'prompt'?: string | null; - 'promptState'?: string | null; 'remark'?: string | null; 'scriptId'?: number | null; 'startTime'?: number | null; @@ -167,7 +177,7 @@ export interface o_storyboard { 'filePath'?: string | null; 'frameMode'?: string | null; 'id'?: number; - 'index'?: number | null; + 'index'?: string | null; 'lines'?: string | null; 'mode'?: string | null; 'model'?: string | null; @@ -232,6 +242,7 @@ export interface o_videoConfig { } export interface DB { + "_o_script_old_20260327": _o_script_old_20260327; "memories": memories; "o_agentDeploy": o_agentDeploy; "o_agentWorkData": o_agentWorkData;