现在要去定义一个头像服务接口,客户端可以通过这个接口获取到指定用户的头像,接口支持客户端设置需要的头像尺寸,因为上传头像接口会把用户上传的头像调整成几种不同的尺寸。
打开 avatar.controller,在文件顶部先导入 path,来自 node.js 的 path 模块,再导入 fs ,来自 fs 模块,这个模块提供了文件系统相关的功能。
然后在 avatar.service 里面,把之前定义的 findAvatarByUserId 导入进来。然后在这个文件里找个地方定义一下 头像服务 接口需要的处理器。名字可以叫 serve 。
在这个处理器里面先获取到用户的 ID,从地址参数里把 userId 解构出来,等会儿设计头像服务接口的时候,我们会在接口的地址里面添加这个参数。
下面用一组 try,catch 区块,先在 catch 区块里面处理一下在 try 区块里遇到的问题,可以执行一下 next ,然后带着 error,把异常交给应用默认的异常处理器去处理。
在 try 区块里面,最后就是要给客户端响应一个用户的头像文件,用一下 response 上的 sendFile 可以响应一个文件数据。先把文件名交给它,可以用一下 filename,再添加一个选项参数,在这个选项里面用 root 设置一下存储文件的目录,然后再添加一个 headers ,设置一下响应里的头部数据,一个对象,里面添加一个 Content-Type ,对应的值可以设置成 avatar 里的 mimetype。
在这个 sendFile 里面需要的 filename,root 还有这个 avatar 里的 mimetype 我们得在上面去准备一下。
这里可以先查找一下用户的头像数据,把结果交给 avatar,await ,用一下 findAvatarByUserId 这个函数,要提供一个用户的 id,用 parseInt 把在上面准备好的 userId 转换成十进制的数字。
有了这个头像数据就可以做一下判断,如果用户没有头像数据,可以 throw 一个错误,新建一个 Error,错误信息设置成 FILE_NOT_FOUND。之们我们在应用的异常处理器里面已经处理过这种异常情况了。
下面可以再准备一下要提供的头像尺寸,这个尺寸可以在客户端通过 size 这个查询符来设置,先把它解构出来,地址查询符都在 request.query 里面。
然后可以准备一些文件名与目录,用 let 声明一个 filename,它的值等于 avatar 里的 filename。
再声明一个 root,它的值可以用一下 path 上的 join 拼接一个路径,第一部分是 uploads,第二部分是 avatar。 然后再声明一个 resized,它的值设置成 resized。
然后再做一下判断,判断的是 size,如果客户端设置了这个 size 地址查询符,先准备一些可用的尺寸,声明一个 imageSizes,它的值是个数组,里面有 large,medium 还有 small,这些就是允许的 size 这个查询符的值。
测试一下可用的头像尺寸,用 if 做一下判断,条件是 ! 用一下 imageSizes 上的 some 这个方法, 提供一个测试器,当前项目叫 item ,检查是不是有等于 size 这个值的项目。
这个判断的条件就是,如果 size 查询符的值不是这个数组里的某个项目的值,我们就可以 throw 一个异常情况,新建一个 Error,错误信息设置成 FILE_NOT_FOUND
然后可以再检查一下文件是否存在,声明一个 fileExist ,用一下 fs 上面提供的 existsSync 这个方法,它可以检查文件是否存在,提供一个文件路径,用 path.join 组织一个文件路径,第一部分是 root,第二部分是 resized,第三部分用一个字符模板,里面先是 filename 的值,小横线,再加上 size 这个查询符的值。
继续再做一下判断,如果文件不存在,就 throw 一个异常,新建一个 Error,错误信息是 FILE_NOT_FOUND。
如果文件存在,可以设置一下 filename 的值,让它等于 filename 小横线,加上 size 。 下面再设置一下 root 的值,用 path 的 join 组织一个路径,第一部分是 root,第二部分是 resized。
整上这段的意思就是,如果客户端在请求头像服务接口的时候设置了 size 指定自己需要的特定尺寸的用户头像,先检查一下这个尺寸是否可用,也就是它必须得是 large,medium 或者 small 。 不可用就报错,可用就继续检查对应的文件是不是存在,如果不存在就报错,如果存在就设置 filename 的值,这个 filename 就是要发给客户端的文件的文件。还要设置一下 root 的值,这个 root 就是存储文件的目录的路径。
下面还得去定义一下头像服务接口,打开 avatar.router,在这个文件里定义一下头像服务接口,用 router 上的 get 方法定义这个接口,地址是 /users/:userId/avatar,接口的处理器设置成 avatarController.serve 。