Files
zhuomi-hui/server/lib/upload.js
T
Michelle ZanandCursor cd05113755 Add 卓米会 mini program and admin server.
Initial commit of the WeChat mini program, Express backend, and admin console.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 19:01:36 +08:00

53 lines
1.7 KiB
JavaScript

const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
const multer = require('multer')
const { ok, fail } = require('./http')
const uploadDir = process.env.UPLOAD_DIR
? path.resolve(process.env.UPLOAD_DIR)
: path.join(__dirname, '..', 'public', 'uploads')
const IMAGE_RE = /^image\/(png|jpe?g|webp)$/i
const VIDEO_RE = /^video\/(mp4|quicktime|webm)$/i
const storage = multer.diskStorage({
destination(req, file, cb) {
fs.mkdirSync(uploadDir, { recursive: true })
cb(null, uploadDir)
},
filename(req, file, cb) {
const ext = path.extname(file.originalname || '').toLowerCase() || '.bin'
cb(null, `${Date.now().toString(36)}${crypto.randomBytes(3).toString('hex')}${ext}`)
}
})
function uploader(options) {
const imagesOnly = !!(options && options.imagesOnly)
const middleware = multer({
storage,
limits: { fileSize: imagesOnly ? 5 * 1024 * 1024 : 80 * 1024 * 1024 },
fileFilter(req, file, cb) {
const mime = file.mimetype || ''
const allowed = IMAGE_RE.test(mime) || (!imagesOnly && VIDEO_RE.test(mime))
cb(null, allowed)
}
}).single('file')
return (req, res) => {
middleware(req, res, (error) => {
if (error) {
const tooLarge = error.code === 'LIMIT_FILE_SIZE'
return fail(res, 400, tooLarge ? (imagesOnly ? '图片需小于 5MB' : '文件需小于 80MB') : '上传失败')
}
if (!req.file) {
return fail(res, 400, imagesOnly ? '仅支持 png/jpg/webp 图片' : '仅支持 png/jpg/webp 图片或 mp4/mov/webm 视频')
}
const type = VIDEO_RE.test(req.file.mimetype) ? 'video' : 'image'
ok(res, { url: `/static/uploads/${req.file.filename}`, type })
})
}
}
module.exports = { uploader, uploadDir }