增加宫格图片下载
This commit is contained in:
parent
558e9b95e3
commit
110f2b03d8
@ -284,6 +284,7 @@ export default (resTool: ResTool, toolsNames?: string[]) => {
|
|||||||
lines: item.lines,
|
lines: item.lines,
|
||||||
state: "未生成",
|
state: "未生成",
|
||||||
scriptId: resTool.data.scriptId,
|
scriptId: resTool.data.scriptId,
|
||||||
|
createTime: Date.now(),
|
||||||
});
|
});
|
||||||
if (item.associateAssetsIds.length) {
|
if (item.associateAssetsIds.length) {
|
||||||
await u.db("o_assets2Storyboard").insert(item.associateAssetsIds.map((i) => ({ storyboardId: insertedId, assetId: i })));
|
await u.db("o_assets2Storyboard").insert(item.associateAssetsIds.map((i) => ({ storyboardId: insertedId, assetId: i })));
|
||||||
|
|||||||
154
src/router.ts
154
src/router.ts
@ -1,4 +1,4 @@
|
|||||||
// @routes-hash f5f78866e59979bf30af031c9ea0de82
|
// @routes-hash ced882fe9cc49f6e16ade49cf276b583
|
||||||
import { Express } from "express";
|
import { Express } from "express";
|
||||||
|
|
||||||
import route1 from "./routes/agents/clearMemory";
|
import route1 from "./routes/agents/clearMemory";
|
||||||
@ -49,43 +49,45 @@ import route45 from "./routes/production/getFlowData";
|
|||||||
import route46 from "./routes/production/getProductionData";
|
import route46 from "./routes/production/getProductionData";
|
||||||
import route47 from "./routes/production/getStoryboardData";
|
import route47 from "./routes/production/getStoryboardData";
|
||||||
import route48 from "./routes/production/saveFlowData";
|
import route48 from "./routes/production/saveFlowData";
|
||||||
import route49 from "./routes/production/storyboard/previewImage";
|
import route49 from "./routes/production/storyboard/downPreviewImage";
|
||||||
import route50 from "./routes/production/workbench/confirmSelection";
|
import route50 from "./routes/production/storyboard/getStoryboardData";
|
||||||
import route51 from "./routes/production/workbench/delVideo";
|
import route51 from "./routes/production/storyboard/previewImage";
|
||||||
import route52 from "./routes/production/workbench/generateVideo";
|
import route52 from "./routes/production/workbench/confirmSelection";
|
||||||
import route53 from "./routes/production/workbench/getChatLines";
|
import route53 from "./routes/production/workbench/delVideo";
|
||||||
import route54 from "./routes/production/workbench/getVideoModelDetail";
|
import route54 from "./routes/production/workbench/generateVideo";
|
||||||
import route55 from "./routes/production/workbench/videoPolling";
|
import route55 from "./routes/production/workbench/getChatLines";
|
||||||
import route56 from "./routes/project/addProject";
|
import route56 from "./routes/production/workbench/getVideoModelDetail";
|
||||||
import route57 from "./routes/project/delProject";
|
import route57 from "./routes/production/workbench/videoPolling";
|
||||||
import route58 from "./routes/project/editProject";
|
import route58 from "./routes/project/addProject";
|
||||||
import route59 from "./routes/project/getProject";
|
import route59 from "./routes/project/delProject";
|
||||||
import route60 from "./routes/script/addScript";
|
import route60 from "./routes/project/editProject";
|
||||||
import route61 from "./routes/script/delScript";
|
import route61 from "./routes/project/getProject";
|
||||||
import route62 from "./routes/script/exportScript";
|
import route62 from "./routes/script/addScript";
|
||||||
import route63 from "./routes/script/getScrptApi";
|
import route63 from "./routes/script/delScript";
|
||||||
import route64 from "./routes/script/updateScript";
|
import route64 from "./routes/script/exportScript";
|
||||||
import route65 from "./routes/scriptAgent/getPlanData";
|
import route65 from "./routes/script/getScrptApi";
|
||||||
import route66 from "./routes/scriptAgent/setPlanData";
|
import route66 from "./routes/script/updateScript";
|
||||||
import route67 from "./routes/setting/agentDeploy/agentSetKey";
|
import route67 from "./routes/scriptAgent/getPlanData";
|
||||||
import route68 from "./routes/setting/agentDeploy/deployAgentModel";
|
import route68 from "./routes/scriptAgent/setPlanData";
|
||||||
import route69 from "./routes/setting/agentDeploy/getAgentDeploy";
|
import route69 from "./routes/setting/agentDeploy/agentSetKey";
|
||||||
import route70 from "./routes/setting/dbConfig/clearData";
|
import route70 from "./routes/setting/agentDeploy/deployAgentModel";
|
||||||
import route71 from "./routes/setting/fileManagement/openFolder";
|
import route71 from "./routes/setting/agentDeploy/getAgentDeploy";
|
||||||
import route72 from "./routes/setting/getTextModel";
|
import route72 from "./routes/setting/dbConfig/clearData";
|
||||||
import route73 from "./routes/setting/loginConfig/getUser";
|
import route73 from "./routes/setting/fileManagement/openFolder";
|
||||||
import route74 from "./routes/setting/loginConfig/updateUserPwd";
|
import route74 from "./routes/setting/getTextModel";
|
||||||
import route75 from "./routes/setting/memoryConfig/getMemory";
|
import route75 from "./routes/setting/loginConfig/getUser";
|
||||||
import route76 from "./routes/setting/memoryConfig/sureMemory";
|
import route76 from "./routes/setting/loginConfig/updateUserPwd";
|
||||||
import route77 from "./routes/setting/vendorConfig/addVendor";
|
import route77 from "./routes/setting/memoryConfig/getMemory";
|
||||||
import route78 from "./routes/setting/vendorConfig/deleteVendor";
|
import route78 from "./routes/setting/memoryConfig/sureMemory";
|
||||||
import route79 from "./routes/setting/vendorConfig/getVendorList";
|
import route79 from "./routes/setting/vendorConfig/addVendor";
|
||||||
import route80 from "./routes/setting/vendorConfig/modelTest";
|
import route80 from "./routes/setting/vendorConfig/deleteVendor";
|
||||||
import route81 from "./routes/setting/vendorConfig/updateVendor";
|
import route81 from "./routes/setting/vendorConfig/getVendorList";
|
||||||
import route82 from "./routes/task/getTaskApi";
|
import route82 from "./routes/setting/vendorConfig/modelTest";
|
||||||
import route83 from "./routes/task/getTaskCategories";
|
import route83 from "./routes/setting/vendorConfig/updateVendor";
|
||||||
import route84 from "./routes/task/taskDetails";
|
import route84 from "./routes/task/getTaskApi";
|
||||||
import route85 from "./routes/test/test";
|
import route85 from "./routes/task/getTaskCategories";
|
||||||
|
import route86 from "./routes/task/taskDetails";
|
||||||
|
import route87 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);
|
||||||
@ -136,41 +138,43 @@ export default async (app: Express) => {
|
|||||||
app.use("/api/production/getProductionData", route46);
|
app.use("/api/production/getProductionData", route46);
|
||||||
app.use("/api/production/getStoryboardData", route47);
|
app.use("/api/production/getStoryboardData", route47);
|
||||||
app.use("/api/production/saveFlowData", route48);
|
app.use("/api/production/saveFlowData", route48);
|
||||||
app.use("/api/production/storyboard/previewImage", route49);
|
app.use("/api/production/storyboard/downPreviewImage", route49);
|
||||||
app.use("/api/production/workbench/confirmSelection", route50);
|
app.use("/api/production/storyboard/getStoryboardData", route50);
|
||||||
app.use("/api/production/workbench/delVideo", route51);
|
app.use("/api/production/storyboard/previewImage", route51);
|
||||||
app.use("/api/production/workbench/generateVideo", route52);
|
app.use("/api/production/workbench/confirmSelection", route52);
|
||||||
app.use("/api/production/workbench/getChatLines", route53);
|
app.use("/api/production/workbench/delVideo", route53);
|
||||||
app.use("/api/production/workbench/getVideoModelDetail", route54);
|
app.use("/api/production/workbench/generateVideo", route54);
|
||||||
app.use("/api/production/workbench/videoPolling", route55);
|
app.use("/api/production/workbench/getChatLines", route55);
|
||||||
app.use("/api/project/addProject", route56);
|
app.use("/api/production/workbench/getVideoModelDetail", route56);
|
||||||
app.use("/api/project/delProject", route57);
|
app.use("/api/production/workbench/videoPolling", route57);
|
||||||
app.use("/api/project/editProject", route58);
|
app.use("/api/project/addProject", route58);
|
||||||
app.use("/api/project/getProject", route59);
|
app.use("/api/project/delProject", route59);
|
||||||
app.use("/api/script/addScript", route60);
|
app.use("/api/project/editProject", route60);
|
||||||
app.use("/api/script/delScript", route61);
|
app.use("/api/project/getProject", route61);
|
||||||
app.use("/api/script/exportScript", route62);
|
app.use("/api/script/addScript", route62);
|
||||||
app.use("/api/script/getScrptApi", route63);
|
app.use("/api/script/delScript", route63);
|
||||||
app.use("/api/script/updateScript", route64);
|
app.use("/api/script/exportScript", route64);
|
||||||
app.use("/api/scriptAgent/getPlanData", route65);
|
app.use("/api/script/getScrptApi", route65);
|
||||||
app.use("/api/scriptAgent/setPlanData", route66);
|
app.use("/api/script/updateScript", route66);
|
||||||
app.use("/api/setting/agentDeploy/agentSetKey", route67);
|
app.use("/api/scriptAgent/getPlanData", route67);
|
||||||
app.use("/api/setting/agentDeploy/deployAgentModel", route68);
|
app.use("/api/scriptAgent/setPlanData", route68);
|
||||||
app.use("/api/setting/agentDeploy/getAgentDeploy", route69);
|
app.use("/api/setting/agentDeploy/agentSetKey", route69);
|
||||||
app.use("/api/setting/dbConfig/clearData", route70);
|
app.use("/api/setting/agentDeploy/deployAgentModel", route70);
|
||||||
app.use("/api/setting/fileManagement/openFolder", route71);
|
app.use("/api/setting/agentDeploy/getAgentDeploy", route71);
|
||||||
app.use("/api/setting/getTextModel", route72);
|
app.use("/api/setting/dbConfig/clearData", route72);
|
||||||
app.use("/api/setting/loginConfig/getUser", route73);
|
app.use("/api/setting/fileManagement/openFolder", route73);
|
||||||
app.use("/api/setting/loginConfig/updateUserPwd", route74);
|
app.use("/api/setting/getTextModel", route74);
|
||||||
app.use("/api/setting/memoryConfig/getMemory", route75);
|
app.use("/api/setting/loginConfig/getUser", route75);
|
||||||
app.use("/api/setting/memoryConfig/sureMemory", route76);
|
app.use("/api/setting/loginConfig/updateUserPwd", route76);
|
||||||
app.use("/api/setting/vendorConfig/addVendor", route77);
|
app.use("/api/setting/memoryConfig/getMemory", route77);
|
||||||
app.use("/api/setting/vendorConfig/deleteVendor", route78);
|
app.use("/api/setting/memoryConfig/sureMemory", route78);
|
||||||
app.use("/api/setting/vendorConfig/getVendorList", route79);
|
app.use("/api/setting/vendorConfig/addVendor", route79);
|
||||||
app.use("/api/setting/vendorConfig/modelTest", route80);
|
app.use("/api/setting/vendorConfig/deleteVendor", route80);
|
||||||
app.use("/api/setting/vendorConfig/updateVendor", route81);
|
app.use("/api/setting/vendorConfig/getVendorList", route81);
|
||||||
app.use("/api/task/getTaskApi", route82);
|
app.use("/api/setting/vendorConfig/modelTest", route82);
|
||||||
app.use("/api/task/getTaskCategories", route83);
|
app.use("/api/setting/vendorConfig/updateVendor", route83);
|
||||||
app.use("/api/task/taskDetails", route84);
|
app.use("/api/task/getTaskApi", route84);
|
||||||
app.use("/api/test/test", route85);
|
app.use("/api/task/getTaskCategories", route85);
|
||||||
|
app.use("/api/task/taskDetails", route86);
|
||||||
|
app.use("/api/test/test", route87);
|
||||||
}
|
}
|
||||||
|
|||||||
116
src/routes/production/storyboard/downPreviewImage.ts
Normal file
116
src/routes/production/storyboard/downPreviewImage.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import express from "express";
|
||||||
|
import u from "@/utils";
|
||||||
|
import { z } from "zod";
|
||||||
|
import sharp from "sharp";
|
||||||
|
import { validateFields } from "@/middleware/middleware";
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
export default router.post(
|
||||||
|
"/",
|
||||||
|
validateFields({
|
||||||
|
storyboardIds: z.array(z.number()),
|
||||||
|
}),
|
||||||
|
async (req, res) => {
|
||||||
|
const { storyboardIds } = req.body;
|
||||||
|
const storyboardImage = await u.db("o_storyboard").whereIn("id", storyboardIds).select("id", "filePath");
|
||||||
|
|
||||||
|
// 按 storyboardIds 顺序构建 filePath 映射
|
||||||
|
const filePathMap: Record<number, string> = {};
|
||||||
|
storyboardImage.forEach((i) => {
|
||||||
|
filePathMap[i.id!] = i.filePath || "";
|
||||||
|
});
|
||||||
|
const orderedFilePaths = storyboardIds.map((id: number) => filePathMap[id]);
|
||||||
|
|
||||||
|
// 读取所有图片 buffer 并获取元数据
|
||||||
|
// sharp 底层 libvips 在 composite 时会将所有 input 解码为内存像素再合成,无需预转格式
|
||||||
|
const loaded = await Promise.all(
|
||||||
|
orderedFilePaths.map(async (filePath: string) => {
|
||||||
|
if (!filePath) return null;
|
||||||
|
const buffer = await u.oss.getFile(filePath);
|
||||||
|
const metadata = await sharp(buffer).metadata();
|
||||||
|
return { buffer, width: metadata.width || 0, height: metadata.height || 0 };
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 过滤掉无效图片
|
||||||
|
const validImages = loaded.filter((img): img is NonNullable<typeof img> => img !== null && img.width > 0 && img.height > 0);
|
||||||
|
if (validImages.length === 0) {
|
||||||
|
res.status(204).end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算网格布局
|
||||||
|
const cols = Math.min(5, validImages.length);
|
||||||
|
const rows = Math.ceil(validImages.length / cols);
|
||||||
|
|
||||||
|
const colWidths: number[] = Array(cols).fill(0);
|
||||||
|
const rowHeights: number[] = Array(rows).fill(0);
|
||||||
|
validImages.forEach((img, idx) => {
|
||||||
|
const c = idx % cols;
|
||||||
|
const r = Math.floor(idx / cols);
|
||||||
|
colWidths[c] = Math.max(colWidths[c], img.width);
|
||||||
|
rowHeights[r] = Math.max(rowHeights[r], img.height);
|
||||||
|
});
|
||||||
|
|
||||||
|
const canvasWidth = colWidths.reduce((a, b) => a + b, 0);
|
||||||
|
const canvasHeight = rowHeights.reduce((a, b) => a + b, 0);
|
||||||
|
|
||||||
|
// 为每张图片生成带标号的合成层
|
||||||
|
const compositeInputs: sharp.OverlayOptions[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < validImages.length; i++) {
|
||||||
|
const img = validImages[i];
|
||||||
|
const c = i % cols;
|
||||||
|
const r = Math.floor(i / cols);
|
||||||
|
const x = colWidths.slice(0, c).reduce((a, b) => a + b, 0);
|
||||||
|
const y = rowHeights.slice(0, r).reduce((a, b) => a + b, 0);
|
||||||
|
|
||||||
|
// 添加图片层
|
||||||
|
compositeInputs.push({
|
||||||
|
input: img.buffer,
|
||||||
|
left: x,
|
||||||
|
top: y,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 生成标号标签 SVG
|
||||||
|
const label = `S${String(i + 1).padStart(2, "0")}`;
|
||||||
|
const fontSize = Math.max(14, Math.min(img.width, img.height) * 0.06);
|
||||||
|
const padding = Math.round(fontSize * 0.4);
|
||||||
|
const textWidth = Math.round(label.length * fontSize * 0.65);
|
||||||
|
const bgW = textWidth + padding * 2;
|
||||||
|
const bgH = Math.round(fontSize) + padding * 2;
|
||||||
|
|
||||||
|
const labelSvg = Buffer.from(
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${bgW}" height="${bgH}">
|
||||||
|
<rect x="0" y="0" width="${bgW}" height="${bgH}" rx="4" ry="4" fill="rgba(0,0,0,0.55)"/>
|
||||||
|
<text x="${padding}" y="${padding + fontSize * 0.85}" font-family="Arial, sans-serif" font-weight="bold" font-size="${fontSize}" fill="#fff">${label}</text>
|
||||||
|
</svg>`,
|
||||||
|
);
|
||||||
|
|
||||||
|
compositeInputs.push({
|
||||||
|
input: labelSvg,
|
||||||
|
left: x + 4,
|
||||||
|
top: y + 4,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 sharp 创建画布并合成,输出 PNG 无损格式避免压缩损耗
|
||||||
|
const resultBuffer = await sharp({
|
||||||
|
create: {
|
||||||
|
width: canvasWidth,
|
||||||
|
height: canvasHeight,
|
||||||
|
channels: 4,
|
||||||
|
background: { r: 255, g: 255, b: 255, alpha: 1 },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.composite(compositeInputs)
|
||||||
|
.png({ compressionLevel: 3 })
|
||||||
|
.toBuffer();
|
||||||
|
|
||||||
|
// 以文件下载形式返回
|
||||||
|
res.setHeader("Content-Type", "image/png");
|
||||||
|
res.setHeader("Content-Disposition", "attachment; filename=storyboard-preview.png");
|
||||||
|
res.setHeader("Content-Length", resultBuffer.length);
|
||||||
|
res.status(200).send(resultBuffer);
|
||||||
|
},
|
||||||
|
);
|
||||||
58
src/routes/production/storyboard/getStoryboardData.ts
Normal file
58
src/routes/production/storyboard/getStoryboardData.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
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({
|
||||||
|
scriptId: z.number(),
|
||||||
|
page: z.number(),
|
||||||
|
limit: z.number(),
|
||||||
|
name: z.string().optional().nullable(),
|
||||||
|
}),
|
||||||
|
async (req, res) => {
|
||||||
|
const { scriptId, page, limit, name } = req.body;
|
||||||
|
const offset = (page - 1) * limit;
|
||||||
|
|
||||||
|
const storyboardData = await u
|
||||||
|
.db("o_storyboard")
|
||||||
|
.where({ scriptId })
|
||||||
|
.modify((qb) => {
|
||||||
|
if (name) {
|
||||||
|
qb.andWhere("title", "like", `%${name}%`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.offset(offset)
|
||||||
|
.limit(limit);
|
||||||
|
const data = await Promise.all(
|
||||||
|
storyboardData.map(async (i: any) => {
|
||||||
|
return {
|
||||||
|
id: i.id,
|
||||||
|
title: i.title,
|
||||||
|
prompt: i.prompt,
|
||||||
|
description: i.description,
|
||||||
|
camera: i.camera,
|
||||||
|
lines: i.lines,
|
||||||
|
sound: i.sound,
|
||||||
|
state: i.state,
|
||||||
|
src: i.filePath ? await u.oss.getFileUrl(i.filePath!) : "",
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const totalQuery = (await u
|
||||||
|
.db("o_storyboard")
|
||||||
|
.where({ scriptId })
|
||||||
|
.modify((qb) => {
|
||||||
|
if (name) {
|
||||||
|
qb.andWhere("title", "like", `%${name}%`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.count("* as total")
|
||||||
|
.first()) as any;
|
||||||
|
|
||||||
|
res.status(200).send(success({ data: data, total: totalQuery?.total }));
|
||||||
|
},
|
||||||
|
);
|
||||||
@ -38,13 +38,28 @@ export default router.post(
|
|||||||
return res.status(200).send(success(null));
|
return res.status(200).send(success(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将每张图片缩放到合理尺寸,单张最大宽度 512px
|
||||||
|
const maxThumbWidth = 512;
|
||||||
|
const resizedImages = await Promise.all(
|
||||||
|
validImages.map(async (img) => {
|
||||||
|
if (img.width <= maxThumbWidth) {
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
const scale = maxThumbWidth / img.width;
|
||||||
|
const newWidth = maxThumbWidth;
|
||||||
|
const newHeight = Math.round(img.height * scale);
|
||||||
|
const buffer = await sharp(img.buffer).resize(newWidth, newHeight).toBuffer();
|
||||||
|
return { buffer, width: newWidth, height: newHeight };
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// 计算网格布局
|
// 计算网格布局
|
||||||
const cols = Math.min(5, validImages.length);
|
const cols = Math.min(5, resizedImages.length);
|
||||||
const rows = Math.ceil(validImages.length / cols);
|
const rows = Math.ceil(resizedImages.length / cols);
|
||||||
|
|
||||||
const colWidths: number[] = Array(cols).fill(0);
|
const colWidths: number[] = Array(cols).fill(0);
|
||||||
const rowHeights: number[] = Array(rows).fill(0);
|
const rowHeights: number[] = Array(rows).fill(0);
|
||||||
validImages.forEach((img, idx) => {
|
resizedImages.forEach((img, idx) => {
|
||||||
const c = idx % cols;
|
const c = idx % cols;
|
||||||
const r = Math.floor(idx / cols);
|
const r = Math.floor(idx / cols);
|
||||||
colWidths[c] = Math.max(colWidths[c], img.width);
|
colWidths[c] = Math.max(colWidths[c], img.width);
|
||||||
@ -57,8 +72,8 @@ export default router.post(
|
|||||||
// 为每张图片生成带标号的合成层
|
// 为每张图片生成带标号的合成层
|
||||||
const compositeInputs: sharp.OverlayOptions[] = [];
|
const compositeInputs: sharp.OverlayOptions[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < validImages.length; i++) {
|
for (let i = 0; i < resizedImages.length; i++) {
|
||||||
const img = validImages[i];
|
const img = resizedImages[i];
|
||||||
const c = i % cols;
|
const c = i % cols;
|
||||||
const r = Math.floor(i / cols);
|
const r = Math.floor(i / cols);
|
||||||
const x = colWidths.slice(0, c).reduce((a, b) => a + b, 0);
|
const x = colWidths.slice(0, c).reduce((a, b) => a + b, 0);
|
||||||
@ -104,11 +119,11 @@ export default router.post(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.composite(compositeInputs)
|
.composite(compositeInputs)
|
||||||
.png()
|
.jpeg({ quality: 80 })
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
const base64 = resultBuffer.toString("base64");
|
const base64 = resultBuffer.toString("base64");
|
||||||
const dataUrl = `data:image/png;base64,${base64}`;
|
const dataUrl = `data:image/jpeg;base64,${base64}`;
|
||||||
|
|
||||||
return res.status(200).send(success(dataUrl));
|
return res.status(200).send(success(dataUrl));
|
||||||
},
|
},
|
||||||
|
|||||||
23
src/types/database.d.ts
vendored
23
src/types/database.d.ts
vendored
@ -1,6 +1,25 @@
|
|||||||
// @db-hash a3673cf3a1d1c9cbf22ae3cfff196a71
|
// @db-hash 71b2e55243e59382321a140a8d9a64ff
|
||||||
//该文件由脚本自动生成,请勿手动修改
|
//该文件由脚本自动生成,请勿手动修改
|
||||||
|
|
||||||
|
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 {
|
export interface memories {
|
||||||
'content': string;
|
'content': string;
|
||||||
'createTime': number;
|
'createTime': number;
|
||||||
@ -138,6 +157,7 @@ export interface o_storyboard {
|
|||||||
'filePath'?: string | null;
|
'filePath'?: string | null;
|
||||||
'frameMode'?: string | null;
|
'frameMode'?: string | null;
|
||||||
'id'?: number;
|
'id'?: number;
|
||||||
|
'index'?: string | null;
|
||||||
'lines'?: string | null;
|
'lines'?: string | null;
|
||||||
'mode'?: string | null;
|
'mode'?: string | null;
|
||||||
'model'?: string | null;
|
'model'?: string | null;
|
||||||
@ -201,6 +221,7 @@ export interface o_videoConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DB {
|
export interface DB {
|
||||||
|
"_o_storyboard_old_20260325": _o_storyboard_old_20260325;
|
||||||
"memories": memories;
|
"memories": memories;
|
||||||
"o_agentDeploy": o_agentDeploy;
|
"o_agentDeploy": o_agentDeploy;
|
||||||
"o_agentWorkData": o_agentWorkData;
|
"o_agentWorkData": o_agentWorkData;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user