直接上代碼:
// app.js或者自己的路由文件
const fs = require("fs");
const path = require("path");
const koaBody = require("koa-body"); // npm i koa-body
const { format } = require("date-fns"); // npm i date-fns
// POST@/upload
router.post(
"/upload",
koaBody({
multipart: true, // 支持多文件上傳
encoding: "gzip", // 編碼格式
formidable: {
uploadDir: path.join(__dirname, "/public/upload/"), // 設(shè)置文件上傳目錄
keepExtensions: true, // 保持文件的后綴
maxFieldsSize: 10 * 1024 * 1024, // 文件上傳大小限制
onFileBegin: (name, file) => {
// 無(wú)論是多文件還是單文件上傳都會(huì)重復(fù)調(diào)用此函數(shù)
// 最終要保存到的文件夾目錄
const dirName = format(new Date(), "yyyyMMddhhmmss");
const dir = path.join(__dirname, `public/upload/${dirName}`);
// 檢查文件夾是否存在如果不存在則新建文件夾
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
// 文件名稱去掉特殊字符但保留原始文件名稱
const fileName = file.name
.replaceAll(" ", "_")
.replace(/[`~!@#$%^&*()|\-=?;:'",<>\{\}\\\/]/gi, "_");
file.name = fileName;
// 覆蓋文件存放的完整路徑(保留原始名稱)
file.path = `${dir}/${fileName}`;
},
onError: (error) => {
app.status = 400;
log4js.error(error);
// 這里可以定義自己的返回內(nèi)容
app.body = { code: 400, msg: "上傳失敗", data: {} };
return;
},
},
}),
async (ctx) => {
try {
// 獲取上傳文件
const files = ctx.request.files;
// 正則 替換掉文件原始路徑中不需要的部分
const reg = new RegExp(".*/upload/", "g");
for (const fileKey in files) {
ctx.uploadpaths = ctx.uploadpaths ? ctx.uploadpaths : [];
ctx.uploadpaths.push({
name: files[fileKey].name,
url: files[fileKey].path.replace(reg, ""),
});
}
ctx.body = { code: 200, msg: "", data:{ uploadpaths: ctx.uploadpaths }};
} catch (error) {
ctx.status = 400;
ctx.body = { code: 400, msg: "上傳失敗", data: {} };
}
}
);
主要是適配 Element Plus Upload 上傳器組件
需要注意的是 這個(gè)組件的多文件上傳其實(shí)是一個(gè)文件調(diào)用一次上傳接口钥星。
參考文章:
1看铆、koa-body 文件上傳自定義文件夾及文件名稱
2、NodeJs koa2實(shí)現(xiàn)文件上傳
參考的兩篇文章有部分代碼已不適用于最新情況雀摘,或者實(shí)現(xiàn)的業(yè)務(wù)邏輯與我自己的有沖突,所以我做了改動(dòng)苦掘,不過仍然非常感謝兩位作者的無(wú)私奉獻(xiàn)换帜。