09-blog-关注与取关

183 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

前言:

关注者:当前正在登陆的账号

被关注者:在param中为username唯一参数。

例如:

http://localhost:3000/api/v1/follows/zhangsan

就是当前帐号要关注zhangsan这个作者。

大致流程:

00 A用户登录校验,检查是否携带token //中间件
01 获取被关注者的username(唯一参数)
02 获取被关注者信息(依据username=>userB)
03 获取关注者的email
04 获取关注者的信息(依据email=>userA)
05 添加关注(涉及到新表,比较复杂,会单抽离出写)

正文:

建立中间件与路由和控制器

router.post('/:username',authMiddleware,followController)

username为作者的名字,可通过 req.params.username获得。

当url为http://localhost:3000/api/v1/follows/zhangsan 可以得到zhangsan的名字。

然后去验证zhangsan这个名字是否存在?

const username = req.params.username;
      const userA = await User.findOne({
        where:{
            username //登录状态无法确定,应该是模糊的查找
        }
      })
      if(!userA){// 如果不存在
        throw new HttpException(401,"被关注者不存在","userA is not defined")
      }

接着,去获得关注者的信息,通过登录时直接传给req的user。里面包含了用户的基本所有可公开信息。

const {email} = req.user;
      const userB = await User.findByPk(email)//应该是已登录状态的信息
      if(!userB){
        throw new HttpException(401,"关注者不存在","userB is not defined")
      }

获取关注行为:

当初在建表之后定义的关联关系:user内部之间形成了一个单独表:

 User.belongsToMany(User,{
        through:"Followers",
        as:"followors",
        timestamps:false
    })

其中Followers为表名,as为关联表中后续追加的方法,因为在关联表內部可以实现添加数据,删除数据,修改数据等操作。那如果使用这些操作呢?

已知:关注行为是粉丝关注作者,即粉丝是被作者赋予了一个叫做关注的主动行为。

所以,使用这些方法的应该是粉丝,因为它被赋予了行动的含义。

那我们就来打印一下粉丝的__proto__,可以看到有这么多这么多行为。

//添加关注行为:关注者(粉丝)给被关注者(作者)添加的主动行为
      console.log(userA.__proto__,"__Proto__"); //打印粉丝

image.png

使用方法,追加关注:

await userA.addFollowor(userB) //粉丝.addFollowor(作者)
      //返回被关注者的信息
      const beConcerned = {
        username:userA.username,
        email:userA.email,
        bio:userA.bio,
        follow:true // 用来控制前端的按钮颜色
      }

同时响应给前台关注成功的信息。

取关:

流程相同,只不过是将粉丝的行为更换为取关:remove

同时将follow的状态设置为false。

image.png

提交方式为delete:

router.delete('/:username',authMiddleware,cancelController)
 await userA.removeFollowor(userB) //取关
      const beConcerned = {
        username:userA.username,
        email:userA.email,
        bio:userA.bio,
        follow:false //按钮颜色
      }

判断该登录用户是否关注了这个作者。

场景:进入到用户界面,查看其粉丝,这个粉丝是否关注了我。

使用get请求方式获取到关联表的信息。关联表中,有一个用户关注了几个用户的表格。通过这个表格就可以判断这个登录者是否关注了这个作者。

首先获取到该作者的username,判读他是否存在于关联表中。

const username = req.params.username;
      //查看该作者是否在关联表中
      const userAuthor = await User.findOne({
        where:{
          username
        },
        include:['followors'] //通过followors中间表查询user1,user2
      })

如果查询不到的话,那就说明该作者不存在关联关系。

 if(!userAuthor){
        throw new HttpException(404,"作者的用户名不存在","user with this username not found")
}

再获取该登录者的信息:

 const {email} = req.user;

因为我们要判断是否登录,这是一个布尔类型的值,可以初始设置为false。

去遍历所有存在于 与userAuthor(该作者)相关联主键的 关联表中的 用户email,如果该作者的email与遍历关联表中的所有email有相等的,那就说明之间存在关联的关系。

同时,将这个用户的信息放进数组当中在res中显示出来。

let following = false;
let followers = []
  for(const user of userAuthor.followors){
        if(email===user.dataValues.followors){
          following=true;
        }
        delete user.dataValues.password; //删掉敏感信息
        delete user.dataValues.Followers;
        followers.push(user.dataValues)
      }
 const profile ={
        username:userAuthor.username,
        bio:userAuthor.bio,
        avatar:userAuthor.avatar,
        following,
        followers
      }
      res.status(200)
      .json({
        status:1,
        messsage:'获取成功',
        data:profile
      })