# Conflicts:
#	src/types/database.d.ts
This commit is contained in:
zhishi 2026-04-02 01:40:56 +08:00
commit 6027908367
18 changed files with 274 additions and 194 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

View File

@ -12,6 +12,7 @@ import fs from "fs";
import u from "@/utils"; import u from "@/utils";
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import socketInit from "@/socket/index"; import socketInit from "@/socket/index";
import path from "path";
const app = express(); const app = express();
const server = http.createServer(app); const server = http.createServer(app);
@ -29,14 +30,28 @@ export default async function startServe(randomPort: Boolean = false) {
app.use(express.json({ limit: "100mb" })); app.use(express.json({ limit: "100mb" }));
app.use(express.urlencoded({ extended: true, limit: "100mb" })); app.use(express.urlencoded({ extended: true, limit: "100mb" }));
// oss 静态资源 // oss 静态资源
const rootDir = u.getPath("oss"); const ossDir = u.getPath("oss");
if (!fs.existsSync(rootDir)) { if (!fs.existsSync(ossDir)) {
fs.mkdirSync(rootDir, { recursive: true }); fs.mkdirSync(ossDir, { recursive: true });
} }
console.log("文件目录:", rootDir); console.log("文件目录:", ossDir);
app.use(express.static(rootDir)); app.use("/oss", express.static(ossDir));
// skills 静态资源
const skillsDir = u.getPath("skills");
if (!fs.existsSync(skillsDir)) {
fs.mkdirSync(skillsDir, { recursive: true });
}
console.log("文件目录:", skillsDir);
// 只允许图片文件访问
app.use(
"/skills",
(req, res, next) => {
/\.(jpe?g|png|gif|webp|svg|ico|bmp)$/i.test(req.path) ? next() : res.status(403).end();
},
express.static(skillsDir),
);
// data/web 静态网站 // data/web 静态网站
const webDir = u.getPath("web"); const webDir = u.getPath("web");

View File

@ -3,8 +3,8 @@ import path from "path";
// 默认环境变量(当 env 文件不存在时自动创建) // 默认环境变量(当 env 文件不存在时自动创建)
const defaultEnvValues: Record<string, string> = { const defaultEnvValues: Record<string, string> = {
dev: `NODE_ENV=dev\nPORT=10588\nOSSURL=http://127.0.0.1:10588/`, dev: `NODE_ENV=dev\nPORT=10588\nOSSURL=http://127.0.0.1:10588/oss/`,
prod: `NODE_ENV=prod\nPORT=10588\nOSSURL=http://127.0.0.1:10588/`, prod: `NODE_ENV=prod\nPORT=10588\nOSSURL=http://127.0.0.1:10588/oss/`,
}; };
// 判断是否为打包后的 Electron 环境 // 判断是否为打包后的 Electron 环境

View File

@ -1,4 +1,4 @@
// @routes-hash 3d1d48934f908135efd71196a7205556 // @routes-hash 6b77c26005a9993d80cda7ab95d26702
import { Express } from "express"; import { Express } from "express";
import route1 from "./routes/agents/clearMemory"; import route1 from "./routes/agents/clearMemory";
@ -70,66 +70,67 @@ import route66 from "./routes/production/storyboard/previewImage";
import route67 from "./routes/production/storyboard/removeFrame"; import route67 from "./routes/production/storyboard/removeFrame";
import route68 from "./routes/production/storyboard/updateStoryboardUrl"; import route68 from "./routes/production/storyboard/updateStoryboardUrl";
import route69 from "./routes/production/workbench/addTrack"; import route69 from "./routes/production/workbench/addTrack";
import route70 from "./routes/production/workbench/delVideo"; import route70 from "./routes/production/workbench/deleteTrack";
import route71 from "./routes/production/workbench/generateVideo"; import route71 from "./routes/production/workbench/delVideo";
import route72 from "./routes/production/workbench/generateVideoPrompt"; import route72 from "./routes/production/workbench/generateVideo";
import route73 from "./routes/production/workbench/getGenerateData"; import route73 from "./routes/production/workbench/generateVideoPrompt";
import route74 from "./routes/production/workbench/getVideoList"; import route74 from "./routes/production/workbench/getGenerateData";
import route75 from "./routes/production/workbench/getVideoModelDetail"; import route75 from "./routes/production/workbench/getVideoList";
import route76 from "./routes/production/workbench/selectVideo"; import route76 from "./routes/production/workbench/getVideoModelDetail";
import route77 from "./routes/project/addProject"; import route77 from "./routes/production/workbench/selectVideo";
import route78 from "./routes/project/addVisual"; import route78 from "./routes/project/addProject";
import route79 from "./routes/project/addVisualManual"; import route79 from "./routes/project/addVisual";
import route80 from "./routes/project/deleteVisualManual"; import route80 from "./routes/project/addVisualManual";
import route81 from "./routes/project/delProject"; import route81 from "./routes/project/deleteVisualManual";
import route82 from "./routes/project/editProject"; import route82 from "./routes/project/delProject";
import route83 from "./routes/project/editVisualManual"; import route83 from "./routes/project/editProject";
import route84 from "./routes/project/getProject"; import route84 from "./routes/project/editVisualManual";
import route85 from "./routes/project/getVisualManual"; import route85 from "./routes/project/getProject";
import route86 from "./routes/project/visualManual"; import route86 from "./routes/project/getVisualManual";
import route87 from "./routes/script/addScript"; import route87 from "./routes/project/visualManual";
import route88 from "./routes/script/delScript"; import route88 from "./routes/script/addScript";
import route89 from "./routes/script/exportScript"; import route89 from "./routes/script/delScript";
import route90 from "./routes/script/extractAssets"; import route90 from "./routes/script/exportScript";
import route91 from "./routes/script/getScrptApi"; import route91 from "./routes/script/extractAssets";
import route92 from "./routes/script/pollScriptAssets"; import route92 from "./routes/script/getScrptApi";
import route93 from "./routes/script/updateScript"; import route93 from "./routes/script/pollScriptAssets";
import route94 from "./routes/scriptAgent/getPlanData"; import route94 from "./routes/script/updateScript";
import route95 from "./routes/scriptAgent/setPlanData"; import route95 from "./routes/scriptAgent/getPlanData";
import route96 from "./routes/scriptAgent/updateData"; import route96 from "./routes/scriptAgent/setPlanData";
import route97 from "./routes/setting/about/checkUpdate"; import route97 from "./routes/scriptAgent/updateData";
import route98 from "./routes/setting/about/downloadApp"; import route98 from "./routes/setting/about/checkUpdate";
import route99 from "./routes/setting/agentDeploy/agentSetKey"; import route99 from "./routes/setting/about/downloadApp";
import route100 from "./routes/setting/agentDeploy/deployAgentModel"; import route100 from "./routes/setting/agentDeploy/agentSetKey";
import route101 from "./routes/setting/agentDeploy/getAgentDeploy"; import route101 from "./routes/setting/agentDeploy/deployAgentModel";
import route102 from "./routes/setting/dbConfig/clearData"; import route102 from "./routes/setting/agentDeploy/getAgentDeploy";
import route103 from "./routes/setting/dev/getSwitchAiDevTool"; import route103 from "./routes/setting/dbConfig/clearData";
import route104 from "./routes/setting/dev/updateSwitchAiDevTool"; import route104 from "./routes/setting/dev/getSwitchAiDevTool";
import route105 from "./routes/setting/fileManagement/openFolder"; import route105 from "./routes/setting/dev/updateSwitchAiDevTool";
import route106 from "./routes/setting/getTextModel"; import route106 from "./routes/setting/fileManagement/openFolder";
import route107 from "./routes/setting/loginConfig/getUser"; import route107 from "./routes/setting/getTextModel";
import route108 from "./routes/setting/loginConfig/updateUserPwd"; import route108 from "./routes/setting/loginConfig/getUser";
import route109 from "./routes/setting/memoryConfig/delAllMemory"; import route109 from "./routes/setting/loginConfig/updateUserPwd";
import route110 from "./routes/setting/memoryConfig/getMemory"; import route110 from "./routes/setting/memoryConfig/delAllMemory";
import route111 from "./routes/setting/memoryConfig/sureMemory"; import route111 from "./routes/setting/memoryConfig/getMemory";
import route112 from "./routes/setting/promptManage/getPrompt"; import route112 from "./routes/setting/memoryConfig/sureMemory";
import route113 from "./routes/setting/promptManage/updatePrompt"; import route113 from "./routes/setting/promptManage/getPrompt";
import route114 from "./routes/setting/skillManagement/getSkillContent"; import route114 from "./routes/setting/promptManage/updatePrompt";
import route115 from "./routes/setting/skillManagement/getSkillList"; import route115 from "./routes/setting/skillManagement/getSkillContent";
import route116 from "./routes/setting/skillManagement/saveSkillContent"; import route116 from "./routes/setting/skillManagement/getSkillList";
import route117 from "./routes/setting/vendorConfig/addVendor"; import route117 from "./routes/setting/skillManagement/saveSkillContent";
import route118 from "./routes/setting/vendorConfig/deleteVendor"; import route118 from "./routes/setting/vendorConfig/addVendor";
import route119 from "./routes/setting/vendorConfig/enableEnglishVendor"; import route119 from "./routes/setting/vendorConfig/deleteVendor";
import route120 from "./routes/setting/vendorConfig/getCodeByLink"; import route120 from "./routes/setting/vendorConfig/enableEnglishVendor";
import route121 from "./routes/setting/vendorConfig/getVendorList"; import route121 from "./routes/setting/vendorConfig/getCodeByLink";
import route122 from "./routes/setting/vendorConfig/modelTest"; import route122 from "./routes/setting/vendorConfig/getVendorList";
import route123 from "./routes/setting/vendorConfig/updateCode"; import route123 from "./routes/setting/vendorConfig/modelTest";
import route124 from "./routes/setting/vendorConfig/updateVendor"; import route124 from "./routes/setting/vendorConfig/updateCode";
import route125 from "./routes/task/getProject"; import route125 from "./routes/setting/vendorConfig/updateVendor";
import route126 from "./routes/task/getTaskApi"; import route126 from "./routes/task/getProject";
import route127 from "./routes/task/getTaskCategories"; import route127 from "./routes/task/getTaskApi";
import route128 from "./routes/task/taskDetails"; import route128 from "./routes/task/getTaskCategories";
import route129 from "./routes/test/test"; import route129 from "./routes/task/taskDetails";
import route130 from "./routes/test/test";
export default async (app: Express) => { export default async (app: Express) => {
app.use("/api/agents/clearMemory", route1); app.use("/api/agents/clearMemory", route1);
@ -201,64 +202,65 @@ export default async (app: Express) => {
app.use("/api/production/storyboard/removeFrame", route67); app.use("/api/production/storyboard/removeFrame", route67);
app.use("/api/production/storyboard/updateStoryboardUrl", route68); app.use("/api/production/storyboard/updateStoryboardUrl", route68);
app.use("/api/production/workbench/addTrack", route69); app.use("/api/production/workbench/addTrack", route69);
app.use("/api/production/workbench/delVideo", route70); app.use("/api/production/workbench/deleteTrack", route70);
app.use("/api/production/workbench/generateVideo", route71); app.use("/api/production/workbench/delVideo", route71);
app.use("/api/production/workbench/generateVideoPrompt", route72); app.use("/api/production/workbench/generateVideo", route72);
app.use("/api/production/workbench/getGenerateData", route73); app.use("/api/production/workbench/generateVideoPrompt", route73);
app.use("/api/production/workbench/getVideoList", route74); app.use("/api/production/workbench/getGenerateData", route74);
app.use("/api/production/workbench/getVideoModelDetail", route75); app.use("/api/production/workbench/getVideoList", route75);
app.use("/api/production/workbench/selectVideo", route76); app.use("/api/production/workbench/getVideoModelDetail", route76);
app.use("/api/project/addProject", route77); app.use("/api/production/workbench/selectVideo", route77);
app.use("/api/project/addVisual", route78); app.use("/api/project/addProject", route78);
app.use("/api/project/addVisualManual", route79); app.use("/api/project/addVisual", route79);
app.use("/api/project/deleteVisualManual", route80); app.use("/api/project/addVisualManual", route80);
app.use("/api/project/delProject", route81); app.use("/api/project/deleteVisualManual", route81);
app.use("/api/project/editProject", route82); app.use("/api/project/delProject", route82);
app.use("/api/project/editVisualManual", route83); app.use("/api/project/editProject", route83);
app.use("/api/project/getProject", route84); app.use("/api/project/editVisualManual", route84);
app.use("/api/project/getVisualManual", route85); app.use("/api/project/getProject", route85);
app.use("/api/project/visualManual", route86); app.use("/api/project/getVisualManual", route86);
app.use("/api/script/addScript", route87); app.use("/api/project/visualManual", route87);
app.use("/api/script/delScript", route88); app.use("/api/script/addScript", route88);
app.use("/api/script/exportScript", route89); app.use("/api/script/delScript", route89);
app.use("/api/script/extractAssets", route90); app.use("/api/script/exportScript", route90);
app.use("/api/script/getScrptApi", route91); app.use("/api/script/extractAssets", route91);
app.use("/api/script/pollScriptAssets", route92); app.use("/api/script/getScrptApi", route92);
app.use("/api/script/updateScript", route93); app.use("/api/script/pollScriptAssets", route93);
app.use("/api/scriptAgent/getPlanData", route94); app.use("/api/script/updateScript", route94);
app.use("/api/scriptAgent/setPlanData", route95); app.use("/api/scriptAgent/getPlanData", route95);
app.use("/api/scriptAgent/updateData", route96); app.use("/api/scriptAgent/setPlanData", route96);
app.use("/api/setting/about/checkUpdate", route97); app.use("/api/scriptAgent/updateData", route97);
app.use("/api/setting/about/downloadApp", route98); app.use("/api/setting/about/checkUpdate", route98);
app.use("/api/setting/agentDeploy/agentSetKey", route99); app.use("/api/setting/about/downloadApp", route99);
app.use("/api/setting/agentDeploy/deployAgentModel", route100); app.use("/api/setting/agentDeploy/agentSetKey", route100);
app.use("/api/setting/agentDeploy/getAgentDeploy", route101); app.use("/api/setting/agentDeploy/deployAgentModel", route101);
app.use("/api/setting/dbConfig/clearData", route102); app.use("/api/setting/agentDeploy/getAgentDeploy", route102);
app.use("/api/setting/dev/getSwitchAiDevTool", route103); app.use("/api/setting/dbConfig/clearData", route103);
app.use("/api/setting/dev/updateSwitchAiDevTool", route104); app.use("/api/setting/dev/getSwitchAiDevTool", route104);
app.use("/api/setting/fileManagement/openFolder", route105); app.use("/api/setting/dev/updateSwitchAiDevTool", route105);
app.use("/api/setting/getTextModel", route106); app.use("/api/setting/fileManagement/openFolder", route106);
app.use("/api/setting/loginConfig/getUser", route107); app.use("/api/setting/getTextModel", route107);
app.use("/api/setting/loginConfig/updateUserPwd", route108); app.use("/api/setting/loginConfig/getUser", route108);
app.use("/api/setting/memoryConfig/delAllMemory", route109); app.use("/api/setting/loginConfig/updateUserPwd", route109);
app.use("/api/setting/memoryConfig/getMemory", route110); app.use("/api/setting/memoryConfig/delAllMemory", route110);
app.use("/api/setting/memoryConfig/sureMemory", route111); app.use("/api/setting/memoryConfig/getMemory", route111);
app.use("/api/setting/promptManage/getPrompt", route112); app.use("/api/setting/memoryConfig/sureMemory", route112);
app.use("/api/setting/promptManage/updatePrompt", route113); app.use("/api/setting/promptManage/getPrompt", route113);
app.use("/api/setting/skillManagement/getSkillContent", route114); app.use("/api/setting/promptManage/updatePrompt", route114);
app.use("/api/setting/skillManagement/getSkillList", route115); app.use("/api/setting/skillManagement/getSkillContent", route115);
app.use("/api/setting/skillManagement/saveSkillContent", route116); app.use("/api/setting/skillManagement/getSkillList", route116);
app.use("/api/setting/vendorConfig/addVendor", route117); app.use("/api/setting/skillManagement/saveSkillContent", route117);
app.use("/api/setting/vendorConfig/deleteVendor", route118); app.use("/api/setting/vendorConfig/addVendor", route118);
app.use("/api/setting/vendorConfig/enableEnglishVendor", route119); app.use("/api/setting/vendorConfig/deleteVendor", route119);
app.use("/api/setting/vendorConfig/getCodeByLink", route120); app.use("/api/setting/vendorConfig/enableEnglishVendor", route120);
app.use("/api/setting/vendorConfig/getVendorList", route121); app.use("/api/setting/vendorConfig/getCodeByLink", route121);
app.use("/api/setting/vendorConfig/modelTest", route122); app.use("/api/setting/vendorConfig/getVendorList", route122);
app.use("/api/setting/vendorConfig/updateCode", route123); app.use("/api/setting/vendorConfig/modelTest", route123);
app.use("/api/setting/vendorConfig/updateVendor", route124); app.use("/api/setting/vendorConfig/updateCode", route124);
app.use("/api/task/getProject", route125); app.use("/api/setting/vendorConfig/updateVendor", route125);
app.use("/api/task/getTaskApi", route126); app.use("/api/task/getProject", route126);
app.use("/api/task/getTaskCategories", route127); app.use("/api/task/getTaskApi", route127);
app.use("/api/task/taskDetails", route128); app.use("/api/task/getTaskCategories", route128);
app.use("/api/test/test", route129); app.use("/api/task/taskDetails", route129);
app.use("/api/test/test", route130);
} }

View File

@ -83,21 +83,47 @@ export default router.post(
}); });
}); });
const result: ResultItem[] = Object.values(itemMap); const result: ResultItem[] = Object.values(itemMap);
const typeConfig: Record<string, { promptKey: string; itemType: ItemType; label: string; nameLabel: string; visualManual: string }> = {
role: { promptKey: "role-polish", itemType: "characters", label: "角色标准四视图", nameLabel: "角色", visualManual: "art_character" },
scene: { promptKey: "scene-polish", itemType: "scenes", label: "场景图", nameLabel: "场景", visualManual: "art_scene" },
tool: { promptKey: "tool-polish", itemType: "props", label: "道具图", nameLabel: "道具", visualManual: "art_prop" },
};
// 批量更新所有 item 状态为生成中 // 批量更新所有 item 状态为生成中
const assetsIds = items.map((item: { assetsId: number }) => item.assetsId); const assetsIds = items.map((item: { assetsId: number }) => item.assetsId);
await u.db("o_assets").whereIn("id", assetsIds).update({ promptState: "生成中" }); await u.db("o_assets").whereIn("id", assetsIds).update({ promptState: "生成中" });
//查询所有资产,用于判断每个资产是否是衍生资产
const assetsDataList = await u.db("o_assets").whereIn("id", assetsIds).select("id", "assetsId");
if (!assetsDataList || assetsDataList.length === 0) return res.status(500).send(error("资产不存在"));
const assetsDataMap = new Map(assetsDataList.map((a: any) => [a.id, a]));
const getTypeConfig = (
isDerivative: boolean,
): Record<string, { promptKey: string; itemType: ItemType; label: string; nameLabel: string; visualManual: string }> => ({
role: {
promptKey: "role-polish",
itemType: "characters",
label: "角色标准四视图",
nameLabel: "角色",
visualManual: isDerivative ? "art_character_derivative" : "art_character",
},
scene: {
promptKey: "scene-polish",
itemType: "scenes",
label: "场景图",
nameLabel: "场景",
visualManual: isDerivative ? "art_scene_derivative" : "art_scene",
},
tool: {
promptKey: "tool-polish",
itemType: "props",
label: "道具图",
nameLabel: "道具",
visualManual: isDerivative ? "art_prop_derivative" : "art_prop",
},
});
// 后台异步并发生成,不阻塞响应 // 后台异步并发生成,不阻塞响应
const limit = pLimit(concurrentCount ?? 1); const limit = pLimit(concurrentCount ?? 1);
const tasks = items.map((item: { assetsId: number; type: string; name: string; describe: string }) => const tasks = items.map((item: { assetsId: number; type: string; name: string; describe: string }) =>
limit(async () => { limit(async () => {
const assetData = assetsDataMap.get(item.assetsId);
if (!assetData) return;
const typeConfig = getTypeConfig(!!assetData.assetsId);
const config = typeConfig[item.type]; const config = typeConfig[item.type];
if (!config) return; if (!config) return;
//获取到视觉手册 //获取到视觉手册

View File

@ -76,11 +76,31 @@ export default router.post(
}); });
const result: ResultItem[] = Object.values(itemMap); const result: ResultItem[] = Object.values(itemMap);
//查询资产是否是衍生资产
const assetsData = await u.db("o_assets").where("id", assetsId).select("assetsId").first();
if (!assetsData) return { code: 500, message: "资产不存在" };
const typeConfig: Record<string, { promptKey: string; itemType: ItemType; label: string; nameLabel: string; visualManual: string }> = { const typeConfig: Record<string, { promptKey: string; itemType: ItemType; label: string; nameLabel: string; visualManual: string }> = {
role: { promptKey: "role-polish", itemType: "characters", label: "角色标准四视图", nameLabel: "角色", visualManual: "art_character" }, role: {
scene: { promptKey: "scene-polish", itemType: "scenes", label: "场景图", nameLabel: "场景", visualManual: "art_scene" }, promptKey: "role-polish",
tool: { promptKey: "tool-polish", itemType: "props", label: "道具图", nameLabel: "道具", visualManual: "art_prop" }, itemType: "characters",
label: "角色标准四视图",
nameLabel: "角色",
visualManual: assetsData.assetsId ? "art_character_derivative" : "art_character",
},
scene: {
promptKey: "scene-polish",
itemType: "scenes",
label: "场景图",
nameLabel: "场景",
visualManual: assetsData.assetsId ? "art_scene_derivative" : "art_scene",
},
tool: {
promptKey: "tool-polish",
itemType: "props",
label: "道具图",
nameLabel: "道具",
visualManual: assetsData.assetsId ? "art_prop_derivative" : "art_prop",
},
}; };
const config = typeConfig[type]; const config = typeConfig[type];

View File

@ -8,12 +8,11 @@ const router = express.Router();
export default router.post( export default router.post(
"/", "/",
validateFields({ validateFields({
videoId: z.number(), id: z.number(),
}), }),
async (req, res) => { async (req, res) => {
const { videoId } = req.body; const { id } = req.body;
await u.db("o_video").where("id", videoId).delete(); await u.db("o_video").where("id", id).delete();
await u.db("o_videoConfig").where("videoId", videoId).update({ videoId: null, updateTime: Date.now() });
res.status(200).send(success({ message: "视频删除成功" })); res.status(200).send(success({ message: "视频删除成功" }));
}, },
); );

View File

@ -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_videoTrack").where("id", id).delete();
await u.db("o_storyboard").where("trackId", id).delete();
res.status(200).send(success({ message: "视频段删除成功" }));
},
);

View File

@ -23,6 +23,7 @@ interface TrackItem {
prompt: string; prompt: string;
state: "未生成" | "生成中" | "已完成" | "生成失败"; state: "未生成" | "生成中" | "已完成" | "生成失败";
reason?: string; reason?: string;
duration?: number;
selectVideoId?: number; selectVideoId?: number;
medias: TrackMedia[]; medias: TrackMedia[];
videoList: VideoItem[]; videoList: VideoItem[];
@ -53,6 +54,7 @@ export default router.post(
const item = trackData.find((t) => t.id === trackId); const item = trackData.find((t) => t.id === trackId);
trackList.push({ trackList.push({
id: trackId, id: trackId,
duration: item?.duration ?? 0,
prompt: item?.prompt || "", prompt: item?.prompt || "",
state: (item?.state as "未生成" | "生成中" | "已完成" | "生成失败") ?? "未生成", state: (item?.state as "未生成" | "生成中" | "已完成" | "生成失败") ?? "未生成",
reason: item?.reason ?? "", reason: item?.reason ?? "",

View File

@ -76,11 +76,11 @@ export default router.post(
} }
fs.writeFileSync(filePath, item.data, "utf-8"); fs.writeFileSync(filePath, item.data, "utf-8");
} }
const ossImagesDir = u.getPath(["oss", stylePath]); const imagesDir = path.join(mainPath, "images");
let existingFiles: string[] = []; let existingFiles: string[] = [];
try { try {
const allFiles = fs.readdirSync(ossImagesDir); const allFiles = fs.readdirSync(imagesDir);
existingFiles = allFiles.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f)); existingFiles = allFiles.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f));
} catch {} } catch {}
@ -88,12 +88,22 @@ export default router.post(
for (const file of existingFiles) { for (const file of existingFiles) {
if (!retainedFileNames.has(file)) { if (!retainedFileNames.has(file)) {
await u.oss.deleteFile(`${stylePath}/${file}`); const filePath = path.join(imagesDir, file);
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
} }
} }
if (!fs.existsSync(imagesDir)) {
fs.mkdirSync(imagesDir, { recursive: true });
}
for (const item of images) { for (const item of images) {
if (!item.startsWith("http")) await u.oss.writeFile(`${stylePath}/${u.uuid()}.jpg`, item); if (!item.startsWith("http")) {
const fileName = `${u.uuid()}.jpg`;
const targetPath = path.join(imagesDir, fileName);
const buffer = Buffer.from(item.replace(/^data:[^;]+;base64,/, ""), "base64");
fs.writeFileSync(targetPath, buffer);
}
} }
res.status(200).send(success()); res.status(200).send(success());

View File

@ -33,14 +33,6 @@ export default router.post(
} catch (e) { } catch (e) {
console.error("[删除视觉手册] 删除失败:", artPromptsDir, e); console.error("[删除视觉手册] 删除失败:", artPromptsDir, e);
} }
// 2. 删除 oss 下的同名文件夹(存放图片),独立于 art_prompts 目录
try {
await u.oss.deleteDirectory(name);
} catch (e) {
console.warn("[删除视觉手册] oss 目录删除失败:", name, e);
}
res.status(200).send(success({ message: "删除成功" })); res.status(200).send(success({ message: "删除成功" }));
} catch (err) { } catch (err) {
res.status(500).send(error(u.error(err).message || "删除失败")); res.status(500).send(error(u.error(err).message || "删除失败"));

View File

@ -77,11 +77,11 @@ export default router.post(
const content = item.value === "README" ? `${name}\n${item.data}` : item.data; const content = item.value === "README" ? `${name}\n${item.data}` : item.data;
fs.writeFileSync(filePath, content, "utf-8"); fs.writeFileSync(filePath, content, "utf-8");
} }
const ossImagesDir = u.getPath(["oss", stylePath]); const imagesDir = path.join(mainPath, "images");
let existingFiles: string[] = []; let existingFiles: string[] = [];
try { try {
const allFiles = fs.readdirSync(ossImagesDir); const allFiles = fs.readdirSync(imagesDir);
existingFiles = allFiles.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f)); existingFiles = allFiles.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f));
} catch {} } catch {}
@ -89,12 +89,22 @@ export default router.post(
for (const file of existingFiles) { for (const file of existingFiles) {
if (!retainedFileNames.has(file)) { if (!retainedFileNames.has(file)) {
await u.oss.deleteFile(`${stylePath}/${file}`); const filePath = path.join(imagesDir, file);
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
} }
} }
if (!fs.existsSync(imagesDir)) {
fs.mkdirSync(imagesDir, { recursive: true });
}
for (const item of images) { for (const item of images) {
if (!item.startsWith("http")) await u.oss.writeFile(`${stylePath}/${u.uuid()}.jpg`, item); if (!item.startsWith("http")) {
const fileName = `${u.uuid()}.jpg`;
const targetPath = path.join(imagesDir, fileName);
const buffer = Buffer.from(item.replace(/^data:[^;]+;base64,/, ""), "base64");
fs.writeFileSync(targetPath, buffer);
}
} }
res.status(200).send(success()); res.status(200).send(success());

View File

@ -33,11 +33,11 @@ function readMd(filePath: string): string {
// 获取 images 文件夹下所有图片文件路径列表 // 获取 images 文件夹下所有图片文件路径列表
async function readAllImages(imagesDir: string) { async function readAllImages(imagesDir: string) {
try { try {
const ossPath = u.getPath(["oss", imagesDir]); const ossPath = u.getPath(path.join("skills", "art_prompts", imagesDir, "images"));
const files = fs.readdirSync(ossPath); const files = fs.readdirSync(ossPath);
const images = files.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f)).map((f) => path.join(imagesDir, f)); const images = files.filter((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f)).map((f) => path.join("art_prompts", imagesDir, "images", f));
if (images.length) { if (images.length) {
return Promise.all(images.map(async (i) => await u.oss.getFileUrl(i))); return Promise.all(images.map(async (i) => await u.oss.getFileUrl(i, "skills")));
} else { } else {
return []; return [];
} }
@ -60,7 +60,6 @@ export default router.post("/", async (req, res) => {
const result = await Promise.all( const result = await Promise.all(
styleDirs.map(async (styleName) => { styleDirs.map(async (styleName) => {
const styleDir = path.join(artPromptsDir, styleName); const styleDir = path.join(artPromptsDir, styleName);
const images = await readAllImages(styleName); const images = await readAllImages(styleName);
const readmePath = path.join(styleDir, "README.md"); const readmePath = path.join(styleDir, "README.md");
const readmeContent = fs.readFileSync(readmePath, "utf-8"); const readmeContent = fs.readFileSync(readmePath, "utf-8");

View File

@ -1,26 +1,11 @@
// @db-hash 147d0f569132c3ba4fedb17a1039d15f // @db-hash a6017ee44d67db4a339664cfe7bacb76
//该文件由脚本自动生成,请勿手动修改 //该文件由脚本自动生成,请勿手动修改
export interface _o_storyboard_old_20260402 {
'createTime'?: number | null;
'duration'?: string | null;
'filePath'?: string | null;
'flowId'?: number | null;
'id'?: number;
'index'?: number | null;
'projectId'?: number | null;
'prompt'?: string | null;
'reason'?: string | null;
'scriptId'?: number | null;
'state'?: string | null;
'trackId'?: number | null;
}
export interface _o_vendorConfig_old_20260401 { export interface _o_vendorConfig_old_20260401 {
'author'?: string | null; 'author'?: string | null;
'code'?: string | null; 'code'?: string | null;
'createTime'?: number | null; 'createTime'?: number | null;
'description'?: string | null; 'description'?: string | null;
'enableEnglish'?: number | null;
'icon'?: string | null; 'icon'?: string | null;
'id'?: string; 'id'?: string;
'inputs'?: string | null; 'inputs'?: string | null;
@ -28,7 +13,13 @@ export interface _o_vendorConfig_old_20260401 {
'models'?: string | null; 'models'?: string | null;
'name'?: string | null; 'name'?: string | null;
} }
export interface _o_videoTrack_old_20260402 { export interface _o_videoTrack_old_20260401 {
'id'?: number;
'projectId'?: number | null;
'scriptId'?: number | null;
'videoId'?: number | null;
}
export interface _o_videoTrack_old_20260401_1 {
'id'?: number; 'id'?: number;
'projectId'?: number | null; 'projectId'?: number | null;
'prompt'?: string | null; 'prompt'?: string | null;
@ -210,11 +201,8 @@ export interface o_storyboard {
'prompt'?: string | null; 'prompt'?: string | null;
'reason'?: string | null; 'reason'?: string | null;
'scriptId'?: number | null; 'scriptId'?: number | null;
'shouldGenerateImage'?: number | null;
'state'?: string | null; 'state'?: string | null;
'track'?: string | null;
'trackId'?: number | null; 'trackId'?: number | null;
'videoPrompt'?: string | null;
} }
export interface o_tasks { export interface o_tasks {
'describe'?: string | null; 'describe'?: string | null;
@ -237,7 +225,6 @@ export interface o_vendorConfig {
'code'?: string | null; 'code'?: string | null;
'createTime'?: number | null; 'createTime'?: number | null;
'description'?: string | null; 'description'?: string | null;
'enable'?: number | null;
'enableEnglish'?: number | null; 'enableEnglish'?: number | null;
'icon'?: string | null; 'icon'?: string | null;
'id'?: string; 'id'?: string;
@ -263,14 +250,15 @@ export interface o_videoTrack {
'prompt'?: string | null; 'prompt'?: string | null;
'reason'?: string | null; 'reason'?: string | null;
'scriptId'?: number | null; 'scriptId'?: number | null;
'selectVideoId'?: number | null;
'state'?: string | null; 'state'?: string | null;
'videoId'?: number | null; 'videoId'?: number | null;
} }
export interface DB { export interface DB {
"_o_storyboard_old_20260402": _o_storyboard_old_20260402;
"_o_vendorConfig_old_20260401": _o_vendorConfig_old_20260401; "_o_vendorConfig_old_20260401": _o_vendorConfig_old_20260401;
"_o_videoTrack_old_20260402": _o_videoTrack_old_20260402; "_o_videoTrack_old_20260401": _o_videoTrack_old_20260401;
"_o_videoTrack_old_20260401_1": _o_videoTrack_old_20260401_1;
"memories": memories; "memories": memories;
"o_agentDeploy": o_agentDeploy; "o_agentDeploy": o_agentDeploy;
"o_agentWorkData": o_agentWorkData; "o_agentWorkData": o_agentWorkData;

View File

@ -45,12 +45,13 @@ class OSS {
* @param userRelPath 使 / * @param userRelPath 使 /
* @returns http * @returns http
*/ */
async getFileUrl(userRelPath: string): Promise<string> { async getFileUrl(userRelPath: string, prefix?: string): Promise<string> {
if (!prefix) prefix = "oss";
await this.ensureInit(); await this.ensureInit();
const safePath = normalizeUserPath(userRelPath); const safePath = normalizeUserPath(userRelPath);
// URL 始终使用 /,所以这里需要将系统分隔符转回 / // URL 始终使用 /,所以这里需要将系统分隔符转回 /
let url = process.env.OSSURL || `http://127.0.0.1:10588/`; let url = `${process.env.OSSURL}${prefix}/` || `http://127.0.0.1:10588/${prefix}/`;
if (isEletron()) url = `http://localhost:${process.env.PORT}/`; if (isEletron()) url = `http://localhost:${process.env.PORT}/${prefix}/`;
return `${url}${safePath.split(path.sep).join("/")}`; return `${url}${safePath.split(path.sep).join("/")}`;
} }
@ -146,10 +147,7 @@ class OSS {
await fs.mkdir(path.dirname(absPath), { recursive: true }); await fs.mkdir(path.dirname(absPath), { recursive: true });
// 如果 data 是 string则视为 base64 编码,先解码再写入 // 如果 data 是 string则视为 base64 编码,先解码再写入
// 自动去除可能存在的 Data URL 前缀(如 "data:image/png;base64," // 自动去除可能存在的 Data URL 前缀(如 "data:image/png;base64,"
const buffer = const buffer = typeof data === "string" ? Buffer.from(data.replace(/^data:[^;]+;base64,/, ""), "base64") : data;
typeof data === "string"
? Buffer.from(data.replace(/^data:[^;]+;base64,/, ""), "base64")
: data;
await fs.writeFile(absPath, buffer); await fs.writeFile(absPath, buffer);
} }