feat: 优化文件上传

master
绝弹 2023-08-02 21:50:54 +08:00
parent f11b7e85e1
commit 2ec5aac04c
16 changed files with 71 additions and 100 deletions

Binary file not shown.

View File

@ -1,5 +1,5 @@
import { Inject } from '@nestjs/common';
import { ConfigService } from '@/config';
import { Inject } from '@nestjs/common';
/**
*
@ -15,6 +15,9 @@ export class BaseService {
*
*/
formatPagination(page = this.config.defaultPage, size = this.config.defaultPageSize) {
if (size == 0) {
return {};
}
return {
skip: (page - 1) * size,
take: size,

View File

@ -22,7 +22,7 @@ export class PaginationDto {
*/
@IsOptional()
@IsNumber()
@Min(1)
@Min(0)
@Transform(({ value }) => Number(value))
size?: number;
}

View File

@ -1,8 +1,8 @@
import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { AuthService } from './auth.service';
import { Public } from './jwt';
import { AuthUserDto } from './dto/auth-user.dto';
import { Public } from './jwt';
@ApiTags('auth')
@Controller('auth')
@ -14,7 +14,7 @@ export class AuthController {
@HttpCode(HttpStatus.OK)
@ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '账号或密码错误' })
@ApiResponse({ description: '登录成功' })
@ApiOperation({ summary: '账号登录', operationId: 'login' })
@ApiOperation({ description: '账号登录', operationId: 'login' })
login(@Body() user: AuthUserDto) {
return this.authService.signIn(user);
}

View File

@ -1,9 +1,9 @@
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { PermissionService } from './permission.service';
import { Respond } from '@/common/response';
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { CreatePermissionDto } from './dto/create-permission.dto';
import { UpdatePermissionDto } from './dto/update-permission.dto';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { Respond } from '@/common/response';
import { PermissionService } from './permission.service';
@ApiTags('permission')
@Controller('permissions')
@ -11,32 +11,32 @@ export class PermissionController {
constructor(private readonly permissionService: PermissionService) {}
@Post()
@ApiOperation({ summary: '创建权限', operationId: 'addPermission' })
@ApiOperation({ description: '创建权限', operationId: 'addPermission' })
create(@Body() createPermissionDto: CreatePermissionDto) {
return this.permissionService.create(createPermissionDto);
}
@Get()
@Respond(Respond.PAGINATION)
@ApiOperation({ summary: '批量查询权限', operationId: 'getPermissions' })
@ApiOperation({ description: '批量查询权限', operationId: 'getPermissions' })
findAll() {
return this.permissionService.findAll();
}
@Get(':id')
@ApiOperation({ summary: '查询权限', operationId: 'getPermission' })
@ApiOperation({ description: '查询权限', operationId: 'getPermission' })
findOne(@Param('id') id: string) {
return this.permissionService.findOne(+id);
}
@Patch(':id')
@ApiOperation({ summary: '更新权限', operationId: 'updatePermission' })
@ApiOperation({ description: '更新权限', operationId: 'updatePermission' })
update(@Param('id') id: string, @Body() updatePermissionDto: UpdatePermissionDto) {
return this.permissionService.update(+id, updatePermissionDto);
}
@Delete(':id')
@ApiOperation({ summary: '删除权限', operationId: 'delPermission' })
@ApiOperation({ description: '删除权限', operationId: 'delPermission' })
remove(@Param('id') id: string) {
return this.permissionService.remove(+id);
}

View File

@ -23,13 +23,8 @@ export class PermissionService {
return `This action returns a #${id} permission`;
}
<<<<<<< HEAD
async update(id: number, updatePermissionDto: UpdatePermissionDto) {
await this.permissionRepository.update(id, updatePermissionDto);
=======
update(id: number, updatePermissionDto: UpdatePermissionDto) {
return this.permissionRepository.update(id, updatePermissionDto);
>>>>>>> 1a32173fc73bbb94906f9ffde5874d47f6dfdad8
}
remove(id: number) {

View File

@ -1,8 +1,8 @@
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { PostService } from './post.service';
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { CreatePostDto } from './dto/create-post.dto';
import { UpdatePostDto } from './dto/update-post.dto';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { PostService } from './post.service';
@Controller('post')
@ApiTags('post')
@ -10,31 +10,31 @@ export class PostController {
constructor(private readonly postService: PostService) {}
@Post()
@ApiOperation({ summary: '创建文章', operationId: 'addPost' })
@ApiOperation({ description: '创建文章', operationId: 'addPost' })
create(@Body() createPostDto: CreatePostDto) {
return this.postService.create(createPostDto);
}
@Get()
@ApiOperation({ summary: '批量查询文章', operationId: 'getPosts' })
@ApiOperation({ description: '批量查询文章', operationId: 'getPosts' })
findAll() {
return this.postService.findAll();
}
@Get(':id')
@ApiOperation({ summary: '查询文章', operationId: 'getPost' })
@ApiOperation({ description: '查询文章', operationId: 'getPost' })
findOne(@Param('id') id: string) {
return this.postService.findOne(+id);
}
@Patch(':id')
@ApiOperation({ summary: '更新文章', operationId: 'updatePost' })
@ApiOperation({ description: '更新文章', operationId: 'updatePost' })
update(@Param('id') id: string, @Body() updatePostDto: UpdatePostDto) {
return this.postService.update(+id, updatePostDto);
}
@Delete(':id')
@ApiOperation({ summary: '删除文章', operationId: 'delPost' })
@ApiOperation({ description: '删除文章', operationId: 'delPost' })
remove(@Param('id') id: string) {
return this.postService.remove(+id);
}

View File

@ -1,9 +1,9 @@
import { Respond } from '@/common/response';
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
import { RoleService } from './role.service';
import { Respond } from '@/common/response';
@ApiTags('role')
@Controller('roles')
@ -11,32 +11,32 @@ export class RoleController {
constructor(private readonly roleService: RoleService) {}
@Post()
@ApiOperation({ summary: '创建角色', operationId: 'addRole' })
@ApiOperation({ description: '创建角色', operationId: 'addRole' })
create(@Body() createRoleDto: CreateRoleDto) {
return this.roleService.create(createRoleDto);
}
@Get()
@Respond(Respond.PAGINATION)
@ApiOperation({ summary: '批量查询角色', operationId: 'getRoles' })
@ApiOperation({ description: '批量查询角色', operationId: 'getRoles' })
findAll() {
return this.roleService.findAll();
}
@Get(':id')
@ApiOperation({ summary: '查询角色', operationId: 'getRole' })
@ApiOperation({ description: '查询角色', operationId: 'getRole' })
findOne(@Param('id') id: string) {
return this.roleService.findOne(+id);
}
@Patch(':id')
@ApiOperation({ summary: '更新角色', operationId: 'updateRole' })
@ApiOperation({ description: '更新角色', operationId: 'updateRole' })
update(@Param('id') id: string, @Body() updateRoleDto: UpdateRoleDto) {
return this.roleService.update(+id, updateRoleDto);
}
@Delete(':id')
@ApiOperation({ summary: '删除角色', operationId: 'delRole' })
@ApiOperation({ description: '删除角色', operationId: 'delRole' })
remove(@Param('id') id: string) {
return this.roleService.remove(+id);
}

View File

@ -26,16 +26,8 @@ export class RoleService {
return `This action returns a #${id} role`;
}
<<<<<<< HEAD
async update(id: number, updateRoleDto: UpdateRoleDto) {
if (updateRoleDto.permissions) {
delete updateRoleDto.permissions;
}
await this.roleRepository.update(id, updateRoleDto);
=======
update(id: number, updateRoleDto: UpdateRoleDto) {
return this.roleRepository.update(id, updateRoleDto);
>>>>>>> 1a32173fc73bbb94906f9ffde5874d47f6dfdad8
}
remove(id: number) {

View File

@ -9,30 +9,35 @@ export class Upload extends BaseEntity {
*/
@Column({ comment: '文件名' })
name: string;
/**
*
* @example 1024
*/
@Column({ comment: '文件大小' })
size: number;
/**
*
* @example "image/jpeg"
*/
@Column({ comment: '文件类型' })
mimetype: string;
/**
*
* @example "/upload/2021/10/01/xxx.jpg"
*/
@Column({ comment: '文件路径' })
path: string;
/**
*
* @example "xxx"
*/
@Column({ comment: '文件哈希' })
hash: string;
/**
*
* @example ".jpg"

View File

@ -1,9 +1,9 @@
import { Controller, Delete, Get, Param, Patch, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
import { UploadService } from './upload.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { Respond } from '@/common/response';
import { Controller, Delete, Get, Param, Patch, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
import { CreateUploadDto } from './dto/create-upload.dto';
import { UploadService } from './upload.service';
@ApiTags('upload')
@Controller('upload')
@ -12,34 +12,34 @@ export class UploadController {
@Post()
@UseInterceptors(FileInterceptor('file'))
@ApiOperation({ summary: '上传文件', operationId: 'upload' })
@ApiConsumes('multipart/form-data')
@ApiBody({ description: '文件', type: CreateUploadDto })
@ApiBody({ description: '要上传的文件', type: CreateUploadDto })
@ApiOperation({ description: '上传文件', operationId: 'upload' })
create(@UploadedFile() file: Express.Multer.File) {
return this.uploadService.create(file);
}
@Get()
@Respond(Respond.PAGINATION)
@ApiOperation({ summary: '批量查询', operationId: 'getUploads' })
@ApiOperation({ description: '批量查询', operationId: 'getUploads' })
findAll() {
return this.uploadService.findAll();
}
@Get(':id')
@ApiOperation({ summary: '查询', operationId: 'getUpload' })
@ApiOperation({ description: '查询', operationId: 'getUpload' })
findOne(@Param('id') id: string) {
return this.uploadService.findOne(+id);
}
@Patch(':id')
@ApiOperation({ summary: '更新', operationId: 'updateUpload' })
@ApiOperation({ description: '更新', operationId: 'updateUpload' })
update() {
return this.uploadService.update();
}
@Delete(':id')
@ApiOperation({ summary: '删除', operationId: 'delUpload' })
@ApiOperation({ description: '删除', operationId: 'delUpload' })
remove(@Param('id') id: string) {
return this.uploadService.remove(+id);
}

View File

@ -1,33 +1,25 @@
import { ConfigService } from '@/config';
import { Module } from '@nestjs/common';
import { MulterModule } from '@nestjs/platform-express';
import { TypeOrmModule } from '@nestjs/typeorm';
import { diskStorage } from 'multer';
import { Upload } from './entities/upload.entity';
import { UploadController } from './upload.controller';
import { UploadService } from './upload.service';
import { MulterModule } from '@nestjs/platform-express';
import { ConfigService } from '@/config';
import dayjs from 'dayjs';
import { join, parse } from 'path';
import { diskStorage } from 'multer';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Upload } from './entities/upload.entity';
@Module({
imports: [
TypeOrmModule.forFeature([Upload]),
MulterModule.registerAsync({
useFactory: async (config: ConfigService) => {
const dest = config.uploadDir;
const storage = diskStorage({
destination: join(dest),
filename: (req, file, cb) => {
const yearMonth = dayjs().format('YYYY-MM');
const { name, ext } = parse(file.originalname);
const randomName = Array(32)
.fill(null)
.map(() => Math.round(Math.random() * 16).toString(16))
.join('');
cb(null, `${yearMonth}/${name}-${randomName}${ext}`);
},
});
return { storage };
return {
storage: diskStorage({
destination: config.uploadDir,
filename: (req, file, cb) => {
cb(null, file.originalname);
},
}),
};
},
inject: [ConfigService],
}),

View File

@ -1,7 +1,8 @@
import { Injectable } from '@nestjs/common';
import { Upload } from './entities/upload.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { parse } from 'path';
import { Repository } from 'typeorm';
import { Upload } from './entities/upload.entity';
@Injectable()
export class UploadService {
@ -14,6 +15,7 @@ export class UploadService {
size: file.size,
hash: file.filename,
path: file.path,
extension: parse(file.originalname).ext,
});
await this.uploadRepository.save(upload);
return upload.id;

View File

@ -1,10 +1,6 @@
import { PaginationDto } from '@/features/pagination';
import { PaginationDto } from '@/common/response';
import { IntersectionType } from '@nestjs/swagger';
import { IsOptional, IsString } from 'class-validator';
<<<<<<< HEAD
=======
import { PaginationDto } from '@/common/response';
>>>>>>> 1a32173fc73bbb94906f9ffde5874d47f6dfdad8
export class FindUserDto extends IntersectionType(PaginationDto) {
/**

View File

@ -1,21 +1,12 @@
import { BaseController } from '@/features/base';
import { Respond } from '@/features/response';
import { BaseController } from '@/common/base';
import { Respond } from '@/common/response';
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Version } from '@nestjs/common';
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
<<<<<<< HEAD
import { CreateUserDto, UpdateUserDto } from './dto';
=======
import { Respond } from '@/common/response';
import { BaseController } from '@/common/base';
import { CreateUserDto } from './dto/create-user.dto';
>>>>>>> 1a32173fc73bbb94906f9ffde5874d47f6dfdad8
import { FindUserDto } from './dto/find-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
import { UserService } from './user.service';
<<<<<<< HEAD
=======
import { UpdateUserDto } from './dto/update-user.dto';
>>>>>>> 1a32173fc73bbb94906f9ffde5874d47f6dfdad8
@ApiTags('user')
@Controller('users')

View File

@ -1,11 +1,11 @@
import { BaseService } from '@/common/base';
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Like, Repository } from 'typeorm';
import { FindUserDto } from './dto/find-user.dto';
import { User } from './entities/user.entity';
import { BaseService } from '@/common/base';
import { CreateUserDto } from './dto/create-user.dto';
import { FindUserDto } from './dto/find-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
@Injectable()
export class UserService extends BaseService {
@ -29,15 +29,10 @@ export class UserService extends BaseService {
*
*/
async findMany(findUserdto: FindUserDto) {
const { nickname, page, size } = findUserdto;
const { nickname: _nickname, page, size } = findUserdto;
const nickname = _nickname && Like(`%${_nickname}%`);
const { skip, take } = this.formatPagination(page, size);
return this.userRepository.findAndCount({
skip,
take,
where: {
nickname: nickname && Like(`%${nickname}%`),
},
});
return this.userRepository.findAndCount({ skip, take, where: { nickname } });
}
/**