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 文件夹下所有图片文件路径列表 async function readAllImages(imagesDir: string) { try { const ossPath = u.getPath(["oss", imagesDir]); 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)); if (images.length) { return Promise.all(images.map(async (i) => await u.oss.getFileUrl(i))); } else { return []; } } 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 = await Promise.all( styleDirs.map(async (styleName) => { const styleDir = path.join(artPromptsDir, styleName); const images = await readAllImages(styleName); const readmePath = path.join(styleDir, "README.md"); const readmeContent = fs.readFileSync(readmePath, "utf-8"); const firstLine = readmeContent.split("\n")[0].replace(/--/g, ""); const stylePath = path.join("askills", "art_prompts", styleName); 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: firstLine, image: images, stylePath, data, }; }), ); res.status(200).send(success(result)); } catch (err) { res.status(500).send({ error: String(err) }); } });