upload.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { Router, Request, Response, NextFunction } from 'express';
  2. import { uploadVideo, uploadImage, uploadCover } from '../middleware/upload.js';
  3. import { authenticate } from '../middleware/auth.js';
  4. import { asyncHandler, AppError } from '../middleware/error.js';
  5. import { ERROR_CODES, HTTP_STATUS } from '@media-manager/shared';
  6. const router = Router();
  7. router.use(authenticate);
  8. // 包装 multer 错误处理
  9. const handleMulterError = (
  10. uploadFn: (req: Request, res: Response, next: NextFunction) => void
  11. ) => {
  12. return (req: Request, res: Response, next: NextFunction) => {
  13. uploadFn(req, res, (err: unknown) => {
  14. if (err) {
  15. if ((err as { code?: string }).code === 'LIMIT_FILE_SIZE') {
  16. return next(new AppError('文件大小超出限制', HTTP_STATUS.BAD_REQUEST, ERROR_CODES.VIDEO_TOO_LARGE));
  17. }
  18. return next(err);
  19. }
  20. next();
  21. });
  22. };
  23. };
  24. // 上传视频
  25. router.post(
  26. '/video',
  27. handleMulterError(uploadVideo),
  28. asyncHandler(async (req, res) => {
  29. if (!req.file) {
  30. throw new AppError('未上传文件', HTTP_STATUS.BAD_REQUEST, ERROR_CODES.VALIDATION);
  31. }
  32. res.json({
  33. success: true,
  34. data: {
  35. filename: req.file.filename,
  36. originalname: req.file.originalname,
  37. path: `/uploads/videos/${req.file.filename}`,
  38. size: req.file.size,
  39. mimetype: req.file.mimetype,
  40. },
  41. });
  42. })
  43. );
  44. // 上传图片
  45. router.post(
  46. '/image',
  47. handleMulterError(uploadImage),
  48. asyncHandler(async (req, res) => {
  49. if (!req.file) {
  50. throw new AppError('未上传文件', HTTP_STATUS.BAD_REQUEST, ERROR_CODES.VALIDATION);
  51. }
  52. res.json({
  53. success: true,
  54. data: {
  55. filename: req.file.filename,
  56. originalname: req.file.originalname,
  57. path: `/uploads/images/${req.file.filename}`,
  58. size: req.file.size,
  59. mimetype: req.file.mimetype,
  60. },
  61. });
  62. })
  63. );
  64. // 上传封面
  65. router.post(
  66. '/cover',
  67. handleMulterError(uploadCover),
  68. asyncHandler(async (req, res) => {
  69. if (!req.file) {
  70. throw new AppError('未上传文件', HTTP_STATUS.BAD_REQUEST, ERROR_CODES.VALIDATION);
  71. }
  72. res.json({
  73. success: true,
  74. data: {
  75. filename: req.file.filename,
  76. originalname: req.file.originalname,
  77. path: `/uploads/covers/${req.file.filename}`,
  78. size: req.file.size,
  79. mimetype: req.file.mimetype,
  80. },
  81. });
  82. })
  83. );
  84. // 上传头像
  85. router.post(
  86. '/avatar',
  87. handleMulterError(uploadImage),
  88. asyncHandler(async (req, res) => {
  89. if (!req.file) {
  90. throw new AppError('未上传文件', HTTP_STATUS.BAD_REQUEST, ERROR_CODES.VALIDATION);
  91. }
  92. res.json({
  93. success: true,
  94. data: {
  95. filename: req.file.filename,
  96. originalname: req.file.originalname,
  97. path: `/uploads/images/${req.file.filename}`,
  98. size: req.file.size,
  99. mimetype: req.file.mimetype,
  100. },
  101. });
  102. })
  103. );
  104. export default router;