video-flow-toon/src/routes/project/getVisualManual.ts
2026-03-29 00:03:41 +08:00

91 lines
3.0 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 express from "express";
import u from "@/utils";
import { success } from "@/lib/responseFormat";
import fs from "fs";
import path from "path";
const router = express.Router();
// 字段映射表
const DATA_MAP: { label: string; value: string; subDir?: string }[] = [
{ label: "README", value: "README" },
{ label: "前缀", value: "prefix" },
{ label: "角色", value: "art_character", subDir: "art_prompt" },
{ label: "角色衍生", value: "art_character_derivative", subDir: "art_prompt" },
{ label: "道具", value: "art_prop", subDir: "art_prompt" },
{ label: "道具衍生", value: "art_prop_derivative", subDir: "art_prompt" },
{ label: "场景", value: "art_scene", subDir: "art_prompt" },
{ label: "场景衍生", value: "art_scene_derivative", subDir: "art_prompt" },
{ label: "分镜", value: "art_storyboard", subDir: "art_prompt" },
{ label: "分镜视频", value: "art_storyboard_video", subDir: "art_prompt" },
{ label: "技法-导演规划", value: "director_planning", subDir: "driector_skills" },
{ label: "技法-分镜表设计", value: "director_storyboard_table", subDir: "driector_skills" },
];
// 读取 md 文件内容,文件不存在时返回空字符串
function readMd(filePath: string): string {
try {
return fs.readFileSync(filePath, "utf-8");
} catch {
return "";
}
}
// 获取 images 文件夹第一张图片的 base64无图片返回空字符串
function readFirstImage(imagesDir: string): string {
try {
const files = fs.readdirSync(imagesDir);
const imgFile = files.find((f) => /\.(png|jpe?g|gif|webp|svg)$/i.test(f));
if (!imgFile) return "";
const imgPath = path.join(imagesDir, imgFile);
const ext = path.extname(imgFile).slice(1).toLowerCase();
const mimeType = ext === "jpg" ? "jpeg" : ext;
const base64 = fs.readFileSync(imgPath).toString("base64");
return `data:image/${mimeType};base64,${base64}`;
} catch {
return "";
}
}
// 获取视觉手册
export default router.post("/", async (req, res) => {
try {
const artPromptsDir = u.getPath(["skills", "art_prompts"]);
// 读取所有风格文件夹
const styleDirs = fs
.readdirSync(artPromptsDir, { withFileTypes: true })
.filter((d) => d.isDirectory())
.map((d) => d.name);
const result = styleDirs.map((styleName) => {
const styleDir = path.join(artPromptsDir, styleName);
const imagesDir = path.join(styleDir, "images");
const image = readFirstImage(imagesDir);
const data = DATA_MAP.map(({ label, value, subDir }) => {
let mdPath: string;
if (subDir) {
mdPath = path.join(styleDir, subDir, `${value}.md`);
} else {
mdPath = path.join(styleDir, `${value}.md`);
}
return {
label,
value,
data: readMd(mdPath),
};
});
return {
name: styleName,
image,
data,
};
});
res.status(200).send(success(result));
} catch (err) {
res.status(500).send({ error: String(err) });
}
});