feat: Phase 1-3 全部完成 — 沙盒增强、学情分析、学习路径
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import {
|
||||
Controller,
|
||||
Post,
|
||||
UseInterceptors,
|
||||
UploadedFile,
|
||||
BadRequestException,
|
||||
} from '@nestjs/common';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { diskStorage } from 'multer';
|
||||
import { extname, join } from 'path';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
|
||||
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'];
|
||||
const MAX_SIZE = 5 * 1024 * 1024;
|
||||
|
||||
@ApiTags('文件上传')
|
||||
@Controller('upload')
|
||||
export class UploadController {
|
||||
@Post()
|
||||
@UseInterceptors(
|
||||
FileInterceptor('file', {
|
||||
storage: diskStorage({
|
||||
destination: join(process.cwd(), 'uploads'),
|
||||
filename: (_req, file, cb) => {
|
||||
const ext = extname(file.originalname);
|
||||
cb(null, `${randomUUID()}${ext}`);
|
||||
},
|
||||
}),
|
||||
limits: { fileSize: MAX_SIZE },
|
||||
fileFilter: (_req, file, cb) => {
|
||||
if (ALLOWED_TYPES.includes(file.mimetype)) {
|
||||
cb(null, true);
|
||||
} else {
|
||||
cb(new BadRequestException('不支持的文件类型,仅支持 jpg/png/gif/webp/svg'), false);
|
||||
}
|
||||
},
|
||||
}),
|
||||
)
|
||||
uploadFile(@UploadedFile() file: Express.Multer.File) {
|
||||
if (!file) {
|
||||
throw new BadRequestException('请选择文件');
|
||||
}
|
||||
|
||||
return {
|
||||
url: `/uploads/${file.filename}`,
|
||||
filename: file.filename,
|
||||
size: file.size,
|
||||
mimetype: file.mimetype,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { UploadController } from './upload.controller';
|
||||
import { UploadService } from './upload.service';
|
||||
|
||||
@Module({
|
||||
controllers: [UploadController],
|
||||
providers: [UploadService],
|
||||
})
|
||||
export class UploadModule {}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { extname } from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
@Injectable()
|
||||
export class UploadService {
|
||||
private uploadDir = 'uploads';
|
||||
|
||||
ensureUploadDir() {
|
||||
if (!fs.existsSync(this.uploadDir)) {
|
||||
fs.mkdirSync(this.uploadDir, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
getUploadDir(): string {
|
||||
return this.uploadDir;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user