import multer from 'multer' import path from 'path' import crypto from 'crypto' import fs from 'fs' const UPLOAD_DIR = process.env.UPLOAD_DIR || './uploads' /** 创建指定子目录的 multer 配置 */ export function createUploadConfig(subDir: string, maxFileSize = 5 * 1024 * 1024) { const targetDir = path.resolve(UPLOAD_DIR, subDir) // 确保目录存在 if (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true }) } const storage = multer.diskStorage({ destination: (_req, _file, cb) => { // 运行时再次确认(可能被手动删除) if (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true }) } cb(null, targetDir) }, filename: (_req, file, cb) => { const ext = path.extname(file.originalname).toLowerCase() || '.jpg' const prefix = subDir === 'avatars' ? '' : 'notif_' cb(null, `${prefix}${Date.now()}_${crypto.randomInt(1000, 9999)}${ext}`) } }) return multer({ storage, limits: { fileSize: maxFileSize }, fileFilter: (_req, file, cb) => { const allowed = ['.jpg', '.jpeg', '.png', '.webp'] const ext = path.extname(file.originalname).toLowerCase() if (allowed.includes(ext)) { cb(null, true) } else { cb(new Error('仅支持 JPEG、PNG、WebP 格式')) } } }) }