nest 记录(四)

nest 记录(四)

message wall 这个项目的后端写完了。没有很大的拓展空间。
于是想起来写一个博客,博客GITHUB地址 https://github.com/abigmiu/blog

把这几天的nest遇到的问题记录一下。(文章里面删除了部分代码。
完整代码请查看git仓库) > 发现以前上传的代码都没有记录下来,
原来是电脑配置git的时候邮箱弄错了。 嗳,少了好多绿色小方块

文件上传

首先生成一个resource

file.controller.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { FileInterceptor } from '@nestjs/platform-express'; // 引入express的文件处理模块(只能识别formData)import { UploadDto } from './dto/upload.dto';import { ConfigService } from '@nestjs/config';@ApiTags('文件')
@Controller('admin/file')
export class FileController {
constructor(
private readonly fileService: FileService, private readonly configService: ConfigService, ) {}
@Post()
@ApiOperation({
summary: '上传文件', })
@ApiConsumes('multipart/form-data') // swagger 对于文件的处理 @ApiBody({
description: '文件', type: UploadDto, })
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
// 在这里调用configService是为了返回一个域名形式的路径,你打印file可以发现path是一个相对路径。 这样可能不太好处理。 你可以把后端域名放在config里面。 这样返回的就是可以浏览器直接访问的完整路径了。 当然, 用相对路径也可以, 在nginx 配置一下转发就行。 // 你可能疑问,这里没有为什么不保存文件,下文将写明 return `${this.configService.get('fullHost')}/api/${file.path}`; }
}

upload.dto.ts 给swagger 用的

1
2
3
4
import { ApiProperty } from '@nestjs/swagger';export class UploadDto {
@ApiProperty({
type: 'string', format: 'binary', })
file: any;}

file.module.ts

1
2
3
4
5
6
7
import { Module } from '@nestjs/common';import { FileController } from './file.controller';import { MulterModule } from '@nestjs/platform-express';import { diskStorage } from 'multer';import { v4 } from 'uuid';import * as path from 'path';@Module({
imports: [
// 在这里自定义文件保存位置 MulterModule.register({
storage: diskStorage({
destination: `./public/${new Date().toLocaleDateString()}`, filename(req, file, callback) {
const name = `${v4()}${path.extname(file.originalname)}`; return callback(null, name); }, }), }), ], controllers: [FileController],})
export class AdminFileModule {}

如何使保存的文件可以直接访问?

需要用到express的静态文件处理方法

main.ts

1
2
3
4
import { ConfigService } from '@nestjs/config';import { NestFactory } from '@nestjs/core';import { AppModule } from './app.module';import { TransformInterceptor } from './interceptor/transform.interceptor';import { ValidationPipe } from 'src/common/pipe/Validate.pipe';import { HttpExceptionFilter } from './common/filter/httpException.filter';import bootStrap from './bootstrap';import { NestExpressApplication } from '@nestjs/platform-express';import { join } from 'path';async function main() {
// 注意这个类型定义, 是expressApplication, 不然无法使用useStaticAssets const app = await NestFactory.create<NestExpressApplication>(AppModule); app.useStaticAssets(join(__dirname, '../public'), {
prefix: `/static`, // 虚拟路径 比如localhost:3000/static/a.png 就是访问的跟目录下的public/a.png 文件。 注意public和src文件夹是平级的 }); bootStrap(app); const port = config.get('port'); await app.listen(port); console.log(`app running in ${port}`);}
main();

CORS

由于axios 拦截了 allow-origin = *
的请求,所以nest开启cors的时候注意下

1
2
app.enableCors({
origin: 'http://localhost:3000', credentials: true,});

可空查询字段的sql处理

有一个接口是可以根据tagId 来查询相关文章的, 这个tagId是可以不传的。
我本来是打算这样select * from tag where id in (null)
不传的话就用null表示, 但是这样什么数据都查询不出来,
后来问了一下公司的后端,可以用字符串拼接

1
2
3
4
5
6
7
8
9
async list(query: AdminArticlePageDto) {
const queryBuilder = this.articleRepository .createQueryBuilder('article')
.leftJoinAndSelect('article.tags', 'tag')
.where(`article.isDel = 0`); if (query.tagId) {
queryBuilder.andWhere(`tag.id = ${query.tagId}`); }
const res = await queryBuilder
.take(+query.size)
.skip((+query.page - 1) * +query.size)
.getManyAndCount(); }