mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 08:09:19 +00:00

在 utils/file.js 中添加了 MIME 类型常量、通用错误处理函数以及对文件操作函数的改进。 - 添加了常量对象用于文件类型和 MIME 类型的映射 - 增加了错误处理函数 handleError 用于统一错误处理 - 修改了 checkAndRemoveFile、mkdirIfNotExists、deleteFolderRecursive 等函数,使用 handleError 处理异常 - 优化了 readCurrentDir 函数的参数和返回值类型注释 - 增加了 copyFiles 函数的参数类型注释和返回值类型 - 增加了 toBase64 函数的参数类型注释和返回值类型 - 修改了 getMimeType 函数,使用 path.extname 获取文件扩展名 - 增加了 getMediaFilesAndOthers 函数,用于区分图片、视频和其他
191 lines
5.3 KiB
JavaScript
191 lines
5.3 KiB
JavaScript
import fs from "node:fs";
|
||
import path from "path";
|
||
|
||
// 常量提取
|
||
const mimeTypes = {
|
||
'.jpg': 'image/jpeg',
|
||
'.jpeg': 'image/jpeg',
|
||
'.png': 'image/png',
|
||
'.gif': 'image/gif',
|
||
'.pdf': 'application/pdf',
|
||
'.txt': 'text/plain',
|
||
// 添加其他文件类型和MIME类型的映射
|
||
};
|
||
|
||
// 通用错误处理函数
|
||
function handleError(err) {
|
||
logger.error(err);
|
||
throw err;
|
||
}
|
||
|
||
/**
|
||
* 检查文件是否存在并且删除
|
||
* @param {string} file - 文件路径
|
||
* @returns {Promise<void>}
|
||
*/
|
||
export async function checkAndRemoveFile(file) {
|
||
try {
|
||
await fs.promises.access(file);
|
||
await fs.promises.unlink(file);
|
||
} catch (err) {
|
||
if (err.code !== 'ENOENT') {
|
||
handleError(err);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 创建文件夹,如果不存在
|
||
* @param {string} dir - 文件夹路径
|
||
* @returns {Promise<void>}
|
||
*/
|
||
export async function mkdirIfNotExists(dir) {
|
||
try {
|
||
await fs.promises.access(dir);
|
||
} catch (err) {
|
||
if (err.code === 'ENOENT') {
|
||
await fs.promises.mkdir(dir, { recursive: true });
|
||
} else {
|
||
handleError(err);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除文件夹下所有文件
|
||
* @param {string} folderPath - 文件夹路径
|
||
* @returns {Promise<number>}
|
||
*/
|
||
export async function deleteFolderRecursive(folderPath) {
|
||
try {
|
||
const files = await readCurrentDir(folderPath);
|
||
const actions = files.map(async (file) => {
|
||
const curPath = path.join(folderPath, file);
|
||
|
||
const stat = await fs.promises.lstat(curPath);
|
||
if (stat.isDirectory()) {
|
||
// recurse
|
||
return deleteFolderRecursive(curPath);
|
||
} else {
|
||
// delete file
|
||
return fs.promises.unlink(curPath);
|
||
}
|
||
});
|
||
|
||
await Promise.allSettled(actions);
|
||
return files.length;
|
||
} catch (error) {
|
||
handleError(error);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 读取当前文件夹的所有文件和文件夹
|
||
* @param {string} dirPath - 路径
|
||
* @returns {Promise<string[]>} 返回一个包含文件名的数组
|
||
*/
|
||
export async function readCurrentDir(dirPath) {
|
||
try {
|
||
return await fs.promises.readdir(dirPath);
|
||
} catch (err) {
|
||
handleError(err);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 拷贝文件
|
||
* @param {string} srcDir - 源文件目录
|
||
* @param {string} destDir - 目标文件目录
|
||
* @param {string[]} [specificFiles=[]] - 过滤文件,不填写就拷贝全部
|
||
* @returns {Promise<string[]>} 拷贝的文件列表
|
||
*/
|
||
export async function copyFiles(srcDir, destDir, specificFiles = []) {
|
||
try {
|
||
await mkdirIfNotExists(destDir);
|
||
const files = await readCurrentDir(srcDir);
|
||
|
||
// 如果 specificFiles 数组为空,拷贝全部文件;否则只拷贝指定文件
|
||
const filesToCopy = specificFiles.length > 0
|
||
? files.filter(file => specificFiles.includes(file))
|
||
: files;
|
||
|
||
logger.info(logger.yellow(`[R插件][拷贝文件] 正在将 ${srcDir} 的文件拷贝到 ${destDir} 中`));
|
||
|
||
// 用于保存拷贝了哪些文件
|
||
const copiedFiles = [];
|
||
|
||
for (const file of filesToCopy) {
|
||
const srcFile = path.join(srcDir, file);
|
||
const destFile = path.join(destDir, file);
|
||
await fs.promises.copyFile(srcFile, destFile);
|
||
copiedFiles.push(file);
|
||
}
|
||
|
||
logger.info(logger.yellow(`[R插件][拷贝文件] 拷贝完成`));
|
||
|
||
return copiedFiles
|
||
} catch (error) {
|
||
handleError(error);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 转换路径图片为base64格式
|
||
* @param {string} filePath - 图片路径
|
||
* @returns {Promise<string>} Base64字符串
|
||
*/
|
||
export async function toBase64(filePath) {
|
||
try {
|
||
const fileData = await fs.promises.readFile(filePath);
|
||
const base64Data = fileData.toString('base64');
|
||
// 返回Base64字符串
|
||
return `data:${getMimeType(filePath)};base64,${base64Data}`;
|
||
} catch (error) {
|
||
handleError(error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 辅助函数:根据文件扩展名获取MIME类型
|
||
* @param {string} filePath - 文件路径
|
||
* @returns {string} MIME类型
|
||
*/
|
||
function getMimeType(filePath) {
|
||
const ext = path.extname(filePath).toLowerCase();
|
||
return mimeTypes[ext] || 'application/octet-stream';
|
||
}
|
||
|
||
/**
|
||
* 获取文件夹中的图片和视频文件
|
||
* @param {string} folderPath - 要检测的文件夹路径
|
||
* @returns {Promise<Object>} 包含图片和视频文件名的对象
|
||
*/
|
||
export async function getMediaFilesAndOthers(folderPath) {
|
||
try {
|
||
const files = await fs.promises.readdir(folderPath);
|
||
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'];
|
||
const videoExtensions = ['.mp4', '.mkv', '.avi', '.mov', '.wmv', '.flv', '.webm'];
|
||
|
||
// 初始化存储图片和视频的数组
|
||
const images = [];
|
||
const videos = [];
|
||
const others = [];
|
||
|
||
files.forEach(file => {
|
||
const ext = path.extname(file).toLowerCase();
|
||
if (imageExtensions.includes(ext)) {
|
||
images.push(file);
|
||
} else if (videoExtensions.includes(ext)) {
|
||
videos.push(file);
|
||
} else {
|
||
others.push(file);
|
||
}
|
||
});
|
||
|
||
return { images, videos, others };
|
||
} catch (err) {
|
||
handleError(err);
|
||
}
|
||
} |