打开 Avatar 模块,配置一下文件的上传,在模块的 imports 里面,添加一个 MulterModule 模块,用一下 register 方法,给它一个配置对象。
里面用 dest 设置一下存储头像文件的位置,可以设置成 ./uploads/avatar。 然后添加一个 fileFilter 属性,值是个方法,有 req,file ,还有 callback 这几个参数。
这个方法做的事情就是验证允许上传的文件。添加一个 mimetypes ,一个数组,里面添加一些允许上传的文件的类型,比如 image/png ,image/jpg,还有 image/jpeg。
下面添加一个 allowed,用一下 mimetypes.some 方法,给它提供一个方法,方法有个 type 参数,条件是 type 等于 file 里的 mimetype 。
意思就是,如果要上传的文件,它的 mimetype 类型是我们在上面定义的 mimetypes 里的其中一种,这个 allowed 的值就会是 true,如果不包含,它的值就会是 false。
用 if 判断 allowed ,如果它的值是 true,可以用一下 callback ,第一个参数的值是 null,第二个参数的值设置成 true,这样就允许上传文件。
如果 allowed 它的值是 false ,用一下 callback,第一个参数可以设置成一个 Exception ,新建一个 BadRequestException,异常信息是不支持上传此类型的文件。
控制器
下面再去定义上传头像用的接口,打开 Avatar 控制器,在这个控制器里添加一个方法,名字是 store ,标记成一个 async 方法。
在这个方法的上面用 @Post 装饰器装饰一下,添加一个路由,注意在这个控制器上有个参数是 avatar,所以下面这里用 Post 装饰器定义的路由,它的地址就是 avatar,如果在客户端用 HTTP 的 POST 方法请求 avatar 这个地址,就会使用 store 这个方法来处理。
路由需要用一个守卫,@UseGuards,要用的是 AuthGuard(),打开 Avatar 模块,在模块的 improts 里面,需要导入 AuthModule 模块,这个模块是我们之前介绍身份验证的时候创建的。
回到 Avatar 控制器,在 store 方法的上面,需要再用一个拦截器,@UseInterceptors,要用的拦截器是 FileInterceptor,在客户端那里用来上传头像文件的字段的名字设置成 avatar。
继续编辑 store 方法,方法里添加几个参数,先添加一个 data 参数,这个参数用 @UploadedFile 装饰一下,参数值的类型可以设置成 FileDto,这个类型是我们在介绍文件上传功能的时候创建的。这个 data 里的值就是文件上传之后的一些相关的信息,比如文件的名字,类型,路径等等。
再用 @User 装饰器,装饰一下 user 这个参数,参数的类型是 UserEntity,因为文件里导入了两个一样名字的东西,所以可以重命名一下, User as UserEntity。
这样 user 参数的类型就是 UserEntity 。
在方法里面,return,await ,执行 this.avatarService.store 这个方法,把 data 还有 user 交给它。
要使用 AvatarService 需要注入进来,在类里添加一个构造方法,方法里添加一个参数属性,private readonly 名字是 avatarService ,类型是 AvatarService。
服务
打开这个 Avatar 服务,里面需要再添加一个方法,方法的名字叫 store , 方法有两个参数,一个叫 data ,类型是 FileDto,还有一个 user 参数,类型是 User。
方法需要存储一些数据到数据库里,要用一下 Avatar Repository,在这个类里添加一个构造方法,在这个构造方法里注入需要的 Repository。用 @InjectRepository 装饰器,需要的是 Avatar 。
然后添加一个参数属性,private readonly,名字叫 avatarRepository,类型是 Repository
在 store 方法里面,return 的东西,可以用一下 this.avatarRepository 上的 save 方法,给它一个对象,把 data 里的东西放进来,然后再添加一个 user。