181 lines
4.3 KiB
JavaScript
181 lines
4.3 KiB
JavaScript
const express = require('express');
|
|
const multer = require('multer');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const dbConnector = require('../utils/dbConnector');
|
|
const { asyncHandler } = require('../middlewares/errorHandler');
|
|
|
|
const router = express.Router();
|
|
|
|
// 配置multer用于文件上传
|
|
const storage = multer.diskStorage({
|
|
destination: (req, file, cb) => {
|
|
const uploadType = req.body.type || 'common';
|
|
const uploadDir = path.join(__dirname, `../uploads/${uploadType}`);
|
|
|
|
// 确保上传目录存在
|
|
if (!fs.existsSync(uploadDir)) {
|
|
fs.mkdirSync(uploadDir, { recursive: true });
|
|
}
|
|
|
|
cb(null, uploadDir);
|
|
},
|
|
filename: (req, file, cb) => {
|
|
const uploadType = req.body.type || 'common';
|
|
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
|
const ext = path.extname(file.originalname);
|
|
const filename = `${uploadType}_${uniqueSuffix}${ext}`;
|
|
cb(null, filename);
|
|
}
|
|
});
|
|
|
|
const upload = multer({
|
|
storage: storage,
|
|
limits: {
|
|
fileSize: 10 * 1024 * 1024, // 10MB限制
|
|
},
|
|
fileFilter: (req, file, cb) => {
|
|
// 允许所有文件类型
|
|
cb(null, true);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* 文件上传接口
|
|
* POST /api/v1/upload
|
|
*/
|
|
router.post('/', upload.single('file'), asyncHandler(async (req, res) => {
|
|
if (!req.file) {
|
|
return res.status(400).json({
|
|
code: 400,
|
|
message: '请选择要上传的文件'
|
|
});
|
|
}
|
|
|
|
const uploadType = req.body.type || 'common';
|
|
const userId = req.user?.id;
|
|
|
|
// 构建文件访问URL
|
|
const fileUrl = `/uploads/${uploadType}/${req.file.filename}`;
|
|
|
|
// 保存文件记录到数据库(可选)
|
|
if (userId) {
|
|
try {
|
|
await dbConnector.query(
|
|
`INSERT INTO uploads
|
|
(user_id, filename, original_name, file_type, file_size, file_url, upload_type, created_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())`,
|
|
[
|
|
userId,
|
|
req.file.filename,
|
|
req.file.originalname,
|
|
req.file.mimetype,
|
|
req.file.size,
|
|
fileUrl,
|
|
uploadType
|
|
]
|
|
);
|
|
} catch (error) {
|
|
console.warn('保存文件记录失败:', error);
|
|
// 不中断上传流程,仅记录警告
|
|
}
|
|
}
|
|
|
|
res.json({
|
|
code: 200,
|
|
message: '上传成功',
|
|
data: {
|
|
url: fileUrl,
|
|
filename: req.file.filename,
|
|
original_name: req.file.originalname,
|
|
size: req.file.size,
|
|
mime_type: req.file.mimetype,
|
|
upload_type: uploadType
|
|
}
|
|
});
|
|
}));
|
|
|
|
/**
|
|
* 获取上传文件列表
|
|
* GET /api/v1/upload
|
|
*/
|
|
router.get('/', asyncHandler(async (req, res) => {
|
|
const userId = req.user.id;
|
|
const { page = 1, limit = 10, type } = req.query;
|
|
const offset = (page - 1) * limit;
|
|
|
|
let query = 'SELECT * FROM uploads WHERE user_id = ?';
|
|
let queryParams = [userId];
|
|
|
|
if (type) {
|
|
query += ' AND upload_type = ?';
|
|
queryParams.push(type);
|
|
}
|
|
|
|
query += ' ORDER BY created_at DESC LIMIT ? OFFSET ?';
|
|
queryParams.push(parseInt(limit), parseInt(offset));
|
|
|
|
const files = await dbConnector.query(query, queryParams);
|
|
|
|
const countResult = await dbConnector.query(
|
|
'SELECT COUNT(*) as count FROM uploads WHERE user_id = ?' + (type ? ' AND upload_type = ?' : ''),
|
|
type ? [userId, type] : [userId]
|
|
);
|
|
|
|
const total = countResult[0].count;
|
|
|
|
res.json({
|
|
code: 200,
|
|
message: '获取成功',
|
|
data: {
|
|
files: files,
|
|
pagination: {
|
|
page: parseInt(page),
|
|
limit: parseInt(limit),
|
|
total: total,
|
|
pages: Math.ceil(total / limit)
|
|
}
|
|
}
|
|
});
|
|
}));
|
|
|
|
/**
|
|
* 删除上传文件
|
|
* DELETE /api/v1/upload/:id
|
|
*/
|
|
router.delete('/:id', asyncHandler(async (req, res) => {
|
|
const { id } = req.params;
|
|
const userId = req.user.id;
|
|
|
|
// 查询文件信息
|
|
const file = await dbConnector.query(
|
|
'SELECT * FROM uploads WHERE id = ? AND user_id = ?',
|
|
[id, userId]
|
|
);
|
|
|
|
if (file.length === 0) {
|
|
return res.status(404).json({
|
|
code: 404,
|
|
message: '文件不存在'
|
|
});
|
|
}
|
|
|
|
// 删除物理文件
|
|
const filePath = path.join(__dirname, `../${file[0].file_url}`);
|
|
if (fs.existsSync(filePath)) {
|
|
fs.unlinkSync(filePath);
|
|
}
|
|
|
|
// 删除数据库记录
|
|
await dbConnector.query(
|
|
'DELETE FROM uploads WHERE id = ? AND user_id = ?',
|
|
[id, userId]
|
|
);
|
|
|
|
res.json({
|
|
code: 200,
|
|
message: '删除成功'
|
|
});
|
|
}));
|
|
|
|
module.exports = router; |