diff --git a/content/template/模板1.xlsx b/content/template/模板1.xlsx new file mode 100644 index 0000000..8b5ce6e Binary files /dev/null and b/content/template/模板1.xlsx differ diff --git a/src/common/cache/cache.module.ts b/src/common/cache/cache.module.ts index b54184e..8336fae 100644 --- a/src/common/cache/cache.module.ts +++ b/src/common/cache/cache.module.ts @@ -11,12 +11,16 @@ import { redisStore } from 'cache-manager-redis-store'; inject: [ConfigService], useFactory: (config: ConfigService) => { const { host, port } = config.redis; + // TODO + let store: any; + if (store) { + store = () => + redisStore({ + commandsQueueMaxLength: 1000, + socket: { host, port }, + }) as any; + } return { - // store: () => - // redisStore({ - // commandsQueueMaxLength: 1000, - // socket: { host, port }, - // }) as any, db: 0, ttl: 600, }; diff --git a/src/common/response/notcaptured.filter.ts b/src/common/response/notcaptured.filter.ts index 846e106..297c2fc 100644 --- a/src/common/response/notcaptured.filter.ts +++ b/src/common/response/notcaptured.filter.ts @@ -14,6 +14,7 @@ export class AllExecptionFilter implements ExceptionFilter { const response = ctx.getResponse<_Response>(); const message = exception.message; const code = ResponseCode.UNKNOWN_ERROR; + console.trace(exception); this.logger.error(exception, `${request.method} ${request.url}`); response.status(HttpStatus.INTERNAL_SERVER_ERROR).json(Response.create({ code, message, data: null })); } diff --git a/src/common/response/response.decorator.ts b/src/common/response/response.decorator.ts index c636dd4..95bc8a0 100644 --- a/src/common/response/response.decorator.ts +++ b/src/common/response/response.decorator.ts @@ -5,31 +5,29 @@ import { SetMetadata } from '@nestjs/common'; */ export const RESPONSE_KEY = 'APP:RESPONSE'; -type RespondFn = { - (type: 'raw' | 'wrap' | 'pagination'): any; +/** + * 响应结果类型 + */ +export enum RespondType { /** * 原始,返回的数据不会被包装 */ - RAW: 'raw'; + RAW = 'raw', /** * 包装,返回的数据会被包装成统一的格式 */ - WRAP: 'wrap'; + WRAP = 'wrap', /** * 分页,需返回 `[data, total]` 格式的数据 */ - PAGINATION: 'pagination'; -}; + PAGINATION = 'pagination', +} /** * 响应结果装饰器 * @param type 类型 * @returns */ -export const Respond = ((type = 'wrap') => { +export const Respond = (type = RespondType.WRAP) => { return SetMetadata(RESPONSE_KEY, type); -}); - -Respond.RAW = 'raw'; -Respond.WRAP = 'wrap'; -Respond.PAGINATION = 'pagination'; +}; diff --git a/src/common/response/response.interceptor.ts b/src/common/response/response.interceptor.ts index df12ba7..fae79c2 100644 --- a/src/common/response/response.interceptor.ts +++ b/src/common/response/response.interceptor.ts @@ -2,7 +2,7 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nes import { Reflector } from '@nestjs/core'; import { Observable, map } from 'rxjs'; import { Response } from './response'; -import { RESPONSE_KEY, Respond } from './response.decorator'; +import { RESPONSE_KEY, RespondType } from './response.decorator'; import { Request } from 'express'; import { ConfigService } from '@/config'; @@ -16,10 +16,10 @@ export class ResponseInterceptor implements NestInterceptor { const type = this.reflector.getAllAndOverride(RESPONSE_KEY, [controller, handler]); return next.handle().pipe( map((data: any) => { - if (type === Respond.RAW) { + if (type === RespondType.RAW) { return data; } - if (type === Respond.PAGINATION) { + if (type === RespondType.PAGINATION) { const request = context.switchToHttp().getRequest(); const [list, total] = data; if (request.query.meta) { diff --git a/src/modules/permission/permission.controller.ts b/src/modules/permission/permission.controller.ts index f425636..4ae877b 100644 --- a/src/modules/permission/permission.controller.ts +++ b/src/modules/permission/permission.controller.ts @@ -1,4 +1,4 @@ -import { Respond } from '@/common/response'; +import { Respond, RespondType } 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'; @@ -17,7 +17,7 @@ export class PermissionController { } @Get() - @Respond(Respond.PAGINATION) + @Respond(RespondType.PAGINATION) @ApiOperation({ description: '批量查询权限', operationId: 'getPermissions' }) findAll() { return this.permissionService.findAll(); diff --git a/src/modules/post/dto/create-post.dto.ts b/src/modules/post/dto/create-post.dto.ts index 1a2b3c5..fbaba55 100644 --- a/src/modules/post/dto/create-post.dto.ts +++ b/src/modules/post/dto/create-post.dto.ts @@ -1 +1,19 @@ -export class CreatePostDto {} +import { IsString } from 'class-validator'; + +export class CreatePostDto { + /** + * 文章标题 + */ + @IsString() + title: string; + /** + * 文章描述 + */ + @IsString() + description: string; + /** + * 文章内容 + */ + @IsString() + content: string; +} diff --git a/src/modules/post/dto/find-post.dto.ts b/src/modules/post/dto/find-post.dto.ts new file mode 100644 index 0000000..642a034 --- /dev/null +++ b/src/modules/post/dto/find-post.dto.ts @@ -0,0 +1,4 @@ +import { PaginationDto } from '@/common/response'; +import { IntersectionType } from '@nestjs/swagger'; + +export class FindPostDto extends IntersectionType(PaginationDto) {} diff --git a/src/modules/post/post.controller.ts b/src/modules/post/post.controller.ts index 0b221b1..8192a84 100644 --- a/src/modules/post/post.controller.ts +++ b/src/modules/post/post.controller.ts @@ -1,13 +1,33 @@ -import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common'; +import { + Body, + Controller, + Delete, + Get, + NotFoundException, + Param, + ParseIntPipe, + Patch, + Post, + Query, + Res, +} from '@nestjs/common'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { CreatePostDto } from './dto/create-post.dto'; import { UpdatePostDto } from './dto/update-post.dto'; import { PostService } from './post.service'; +import { join } from 'path'; +import { readFileSync } from 'fs'; +import { Response } from 'express'; +import { BaseController } from '@/common/base'; +import { Respond, RespondType } from '@/common/response'; +import { FindPostDto } from './dto/find-post.dto'; -@Controller('post') @ApiTags('post') -export class PostController { - constructor(private readonly postService: PostService) {} +@Controller('posts') +export class PostController extends BaseController { + constructor(private readonly postService: PostService) { + super(); + } @Post() @ApiOperation({ description: '创建文章', operationId: 'addPost' }) @@ -15,27 +35,42 @@ export class PostController { return this.postService.create(createPostDto); } + @Get('template.xlsx') + @ApiOperation({ description: '获取文章下载模板', operationId: 'getPostTemplate' }) + getTemplate(@Res() res: Response) { + try { + const filePath = join(process.cwd(), './content/template/模板1.xlsx'); + res.type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + res.attachment('模板1.xlsx'); + // res.sendFile(filePath); + res.send(readFileSync(filePath)); + } catch (e) { + throw new NotFoundException('模板不存在'); + } + } + @Get() + @Respond(RespondType.PAGINATION) @ApiOperation({ description: '批量查询文章', operationId: 'getPosts' }) - findAll() { - return this.postService.findAll(); + findAll(@Query() findPostDto: FindPostDto) { + return this.postService.findAll(findPostDto); } @Get(':id') @ApiOperation({ description: '查询文章', operationId: 'getPost' }) - findOne(@Param('id') id: string) { - return this.postService.findOne(+id); + findOne(@Param('id', ParseIntPipe) id: number) { + return this.postService.findOne(id); } @Patch(':id') @ApiOperation({ description: '更新文章', operationId: 'updatePost' }) - update(@Param('id') id: string, @Body() updatePostDto: UpdatePostDto) { - return this.postService.update(+id, updatePostDto); + update(@Param('id', ParseIntPipe) id: number, @Body() updatePostDto: UpdatePostDto) { + return this.postService.update(id, updatePostDto); } @Delete(':id') @ApiOperation({ description: '删除文章', operationId: 'delPost' }) - remove(@Param('id') id: string) { + remove(@Param('id', ParseIntPipe) id: number) { return this.postService.remove(+id); } } diff --git a/src/modules/post/post.service.ts b/src/modules/post/post.service.ts index 494d484..33d8c8a 100644 --- a/src/modules/post/post.service.ts +++ b/src/modules/post/post.service.ts @@ -4,10 +4,14 @@ import { UpdatePostDto } from './dto/update-post.dto'; import { InjectRepository } from '@nestjs/typeorm'; import { Post } from './entities/post.entity'; import { Repository } from 'typeorm'; +import { BaseService } from '@/common/base'; +import { FindPostDto } from './dto/find-post.dto'; @Injectable() -export class PostService { - constructor(@InjectRepository(Post) private postRepository: Repository) {} +export class PostService extends BaseService { + constructor(@InjectRepository(Post) private postRepository: Repository) { + super(); + } async create(createPostDto: CreatePostDto) { const post = this.postRepository.create(createPostDto); @@ -15,12 +19,13 @@ export class PostService { return post.id; } - findAll() { - return this.postRepository.findAndCount(); + findAll(findPostDto: FindPostDto) { + const { skip, take } = this.formatPagination(findPostDto.page, findPostDto.size); + return this.postRepository.findAndCount({ skip, take }); } findOne(id: number) { - return this.postRepository.findOne({ where: { id } }); + return this.postRepository.findOneOrFail({ where: { id } }); } update(id: number, updatePostDto: UpdatePostDto) { diff --git a/src/modules/role/role.controller.ts b/src/modules/role/role.controller.ts index 682c939..91f0821 100644 --- a/src/modules/role/role.controller.ts +++ b/src/modules/role/role.controller.ts @@ -1,4 +1,4 @@ -import { Respond } from '@/common/response'; +import { Respond, RespondType } 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'; @@ -17,7 +17,7 @@ export class RoleController { } @Get() - @Respond(Respond.PAGINATION) + @Respond(RespondType.PAGINATION) @ApiOperation({ description: '批量查询角色', operationId: 'getRoles' }) findAll() { return this.roleService.findAll(); diff --git a/src/modules/upload/upload.controller.ts b/src/modules/upload/upload.controller.ts index 95890bc..977f4c5 100644 --- a/src/modules/upload/upload.controller.ts +++ b/src/modules/upload/upload.controller.ts @@ -1,4 +1,4 @@ -import { Respond } from '@/common/response'; +import { Respond, RespondType } from '@/common/response'; import { Controller, Delete, Get, Ip, Param, Patch, Post, Req, UploadedFile, UseInterceptors } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger'; @@ -22,7 +22,7 @@ export class UploadController { } @Get() - @Respond(Respond.PAGINATION) + @Respond(RespondType.PAGINATION) @ApiOperation({ description: '批量查询', operationId: 'getUploads' }) findAll() { return this.uploadService.findAll(); diff --git a/src/modules/user/user.controller.ts b/src/modules/user/user.controller.ts index f1546a0..040423c 100644 --- a/src/modules/user/user.controller.ts +++ b/src/modules/user/user.controller.ts @@ -1,5 +1,5 @@ import { BaseController } from '@/common/base'; -import { Respond } from '@/common/response'; +import { Respond, RespondType } from '@/common/response'; import { Body, Controller, Delete, Get, Param, Patch, Post, Query, Version } from '@nestjs/common'; import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { CreateUserDto } from './dto/create-user.dto'; @@ -22,7 +22,7 @@ export class UserController extends BaseController { } @Get() - @Respond(Respond.PAGINATION) + @Respond(RespondType.PAGINATION) @ApiOkResponse({ isArray: true, type: User }) @ApiOperation({ description: '批量查询用户', operationId: 'getUsers' }) async findMany(@Query() query: FindUserDto) {