127 lines
3.4 KiB
JavaScript
127 lines
3.4 KiB
JavaScript
const os = require('os')
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const formidable = require('formidable')
|
|
const { objForEach } = require('../util')
|
|
|
|
const { PROTOCOL, PORT, IP } = {
|
|
PROTOCOL: 'http',
|
|
PORT: '10007',
|
|
IP: '127.0.0.1',
|
|
}
|
|
|
|
const FILE_FOLDER = 'upload-files'
|
|
const isWindows = os.type().toLowerCase().indexOf('windows') >= 0
|
|
const TMP_FOLDER = 'upload-files-tmp'
|
|
|
|
const express = require('express')
|
|
const router = express.Router()
|
|
|
|
/**
|
|
* 获取随机数
|
|
*/
|
|
function getRandom() {
|
|
return Math.random().toString(36).slice(-3)
|
|
}
|
|
|
|
/**
|
|
* 给文件名加后缀,如 a.png 转换为 a-123123.png
|
|
* @param {string} fileName 文件名
|
|
*/
|
|
function genRandomFileName(fileName = '') {
|
|
// 如 fileName === 'a.123.png'
|
|
const r = getRandom()
|
|
if (!fileName) return r
|
|
|
|
const length = fileName.length // 9
|
|
const pointLastIndexOf = fileName.lastIndexOf('.') // 5
|
|
if (pointLastIndexOf < 0) return `${fileName}-${r}`
|
|
|
|
const fileNameWithOutExt = fileName.slice(0, pointLastIndexOf) // "a.123"
|
|
const ext = fileName.slice(pointLastIndexOf + 1, length) // "png"
|
|
return `${fileNameWithOutExt}-${r}.${ext}`
|
|
}
|
|
|
|
/**
|
|
* 保存上传的文件
|
|
* @param {Object} req request
|
|
* @param {number} time time 用于测试超时
|
|
*/
|
|
function saveFiles(req, time = 0) {
|
|
return new Promise((resolve, reject) => {
|
|
const imgLinks = []
|
|
const form = formidable({ multiples: true })
|
|
|
|
// windows 系统,处理 rename 报错
|
|
if (isWindows) {
|
|
const tmpPath = path.resolve(__dirname, '..', '..', TMP_FOLDER) // 在根目录下
|
|
if (!fs.existsSync(tmpPath)) {
|
|
fs.mkdirSync(tmpPath)
|
|
}
|
|
form.uploadDir = TMP_FOLDER
|
|
}
|
|
|
|
form.parse(req, function (err, fields, files) {
|
|
if (err) {
|
|
reject('formidable, form.parse err', err.stack)
|
|
}
|
|
// 存储图片的文件夹
|
|
const storePath = path.resolve(__dirname, '..', '..', FILE_FOLDER)
|
|
if (!fs.existsSync(storePath)) {
|
|
fs.mkdirSync(storePath)
|
|
}
|
|
|
|
console.log('fields......', fields)
|
|
|
|
// 遍历所有上传来的图片
|
|
objForEach(files, (name, file) => {
|
|
console.log('name...', name)
|
|
console.log('file.name...', file.name)
|
|
|
|
// 图片临时位置
|
|
const tempFilePath = file.path
|
|
// 图片名称和路径
|
|
const fileName = genRandomFileName(file.name || name) // 为文件名增加一个随机数,防止同名文件覆盖
|
|
console.log('fileName...', fileName)
|
|
const fullFileName = path.join(storePath, fileName)
|
|
console.log('fullFileName...', fullFileName)
|
|
// 将临时文件保存为正式文件
|
|
fs.renameSync(tempFilePath, fullFileName)
|
|
// 存储链接
|
|
const url = `${PROTOCOL}://${IP}:${PORT}/${FILE_FOLDER}/${fileName}`
|
|
imgLinks.push({ url, alt: fileName, href: url })
|
|
})
|
|
console.log('imgLinks...', imgLinks)
|
|
|
|
// 返回结果
|
|
let data
|
|
if (imgLinks.length === 1) {
|
|
data = imgLinks[0]
|
|
} else {
|
|
data = imgLinks
|
|
}
|
|
|
|
setTimeout(() => {
|
|
resolve({
|
|
errno: 0,
|
|
data: imgLinks,
|
|
})
|
|
}, time)
|
|
})
|
|
})
|
|
}
|
|
|
|
// 上传图片
|
|
router.post('/img', (req, res) => {
|
|
saveFiles(req)
|
|
.then((result) => {
|
|
res.json(result)
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error:', error)
|
|
res.status(500).json({ error: 'Internal Server Error' })
|
|
})
|
|
})
|
|
|
|
module.exports = router
|