hn-hlw-service/upload.js
2026-07-27 11:28:33 +08:00

129 lines
4.1 KiB
JavaScript
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.

const multer = require("multer");
const path = require("path");
const express = require("express");
const fs = require("fs");
const api = require("./api");
const { safeSend, sendError } = require("./utils/response");
// 设置存储配置
const storage = multer.diskStorage({
destination: function (req, file, cb) {
// 获取当前日期,格式为 年/月/日
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
// 构建文件夹路径upload-imgs/年/月/日
const uploadDir = path.join(__dirname, "../upload-files", year.toString(), month, day);
// 确保目标目录存在(如果不存在则创建)
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
cb(null, uploadDir);
},
filename: function (req, file, cb) {
// 获取文件扩展名
const ext = path.extname(file.originalname).toLowerCase();
// 获取当前时间
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const milliseconds = String(now.getMilliseconds()).padStart(3, '0');
// 生成随机数
const randomNum = Math.floor(Math.random() * 10000);
// 生成文件名mmssSSS+随机数.原文件后缀
const fileName = `${hours}-${minutes}-${seconds}-${milliseconds}-${randomNum}${ext}`;
cb(null, fileName);
},
});
// 文件类型过滤(可选)
const fileFilter = (req, file, cb) => {
// 允许的文件类型
const allowedTypes = /jpeg|jpg|png|gif|mp4|avi|mov|pdf/;
// 检查文件扩展名是否匹配
const extname = allowedTypes.test(
path.extname(file.originalname).toLowerCase()
);
if (extname) {
return cb(null, true);
} else {
// 如果文件类型不符合要求,返回错误
cb(new Error("只允许上传图片和视频文件"));
}
};
// 创建multer实例并应用存储配置和文件过滤
const upload = multer({
storage: storage,
fileFilter: fileFilter,
limits: {
fileSize: 10 * 1024 * 1024, // 10MB 文件大小限制
}
});
exports.uploadFile = (app) => {
// 设置静态文件目录
app.use("/upload-files", express.static(path.join(__dirname, "../upload-files")));
// 创建上传路由
app.post("/upload", (req, res) => {
// 使用 multer 中间件处理文件上传
upload.single("file")(req, res, async (err) => {
// 检查是否已经发送响应
if (res.headersSent) {
return;
}
if (err) {
console.error("文件上传错误:", err);
if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') {
return sendError(res, "文件大小超过限制(最大10MB)", err.message, 400);
}
return sendError(res, "文件上传错误", err.message, 400);
}
return sendError(res, "文件上传失败", err.message, 500);
}
try {
const { file } = req;
if (!file) {
return sendError(res, "没有文件被上传", null, 400);
}
// 获取当前日期,格式为 年/月/日
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
// 文件存储路径:/upload-imgs/年/月/日/文件名
const filePath = path.join("/upload-files", year.toString(), month, day, file.filename);
const normalizedPath = filePath.replace(/\\/g, "/");
// 返回文件路径和成功消息
return safeSend(res, {
message: "文件上传成功",
filePath: normalizedPath,
success: true,
});
} catch (error) {
console.error("处理上传文件时出错:", error);
return sendError(res, "文件上传失败", error.message, 500);
}
});
});
};