代码仓库:https://github.com/changeclass/koa2-weibo

数据模型

  1. 模型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /**
    * @description:用户关注关系
    * @author: 小康
    * @url: https://xiaokang.me
    * @Date: 2020-12-19 15:31:54
    * @LastEditTime: 2020-12-19 15:31:55
    * @LastEditors: 小康
    */

    const seq = require('../seq')
    const { INTEGER } = require('../type')
    const UserRelation = seq.define('userRelation', {
    userId: {
    type: INTEGER,
    allowNull: false,
    comment: '用户ID'
    },
    followerId: {
    type: INTEGER,
    allowNull: false,
    comment: '被关注用户的ID'
    }
    })
    module.exports = UserRelation
  2. 创建关系

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /**
    * @description 数据模型入口文件
    * @author 小康
    */

    const User = require('./User')
    const Blog = require('./Blog')
    const UserRelation = require('./UserRelation')
    // 创建外键
    Blog.belongsTo(User, {
    foreignKey: 'userId'
    })

    UserRelation.belongsTo(User, {
    foreignKey: 'followerId'
    })
    User.hasMany(UserRelation, {
    foreignKey: 'userId'
    })

    module.exports = {
    User,
    Blog,
    UserRelation
    }

粉丝列表

  1. 控制器层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    /**
    * @description: 用户关系的controller
    * @author: 小康
    * @url: https://xiaokang.me
    * @Date: 2020-12-19 15:49:12
    * @LastEditTime: 2020-12-19 15:49:12
    * @LastEditors: 小康
    */

    const { SuccessModel } = require('../model/ResModel')
    const { getUsersByFollower } = require('../services/user-relation')

    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {number} userId 用户id
    * @description: 根据用户id获取粉丝列表
    */
    async function getFans(userId) {
    // service
    const { count, userList } = await getUsersByFollower(userId)
    return new SuccessModel({ count, userList })
    }

    module.exports = {
    getFans
    }

  2. 服务层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    /**
    * @description: 用户关系 services
    * @author: 小康
    * @url: https://xiaokang.me
    * @Date: 2020-12-19 15:50:52
    * @LastEditTime: 2020-12-19 15:50:52
    * @LastEditors: 小康
    */
    const { User, UserRelation } = require('../db/model/index')
    const { formatUser } = require('./_format')

    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {number} followerId 被关注人的ID
    * @description: 获取关注该用户的用户列表
    */
    async function getUsersByFollower(followerId) {
    const result = await User.findAndCountAll({
    attributes: ['id', 'userName', 'nickName', 'picture'],
    order: [['id', 'desc']],
    include: [{ model: UserRelation, where: { followerId } }]
    })
    // 格式化
    let userList = result.rows.map((row) => row.dataValues)
    userList = formatUser(userList)
    return { count: result.count, userList }
    }

    module.exports = {
    getUsersByFollower
    }

判断关注状态

1
2
3
4
5
6
const { count: fansCount, userList: fansList } = fansResult.data
// 我是否关注了此人

const amIFollowed = fansList.some((item) => {
return item.userName === myUserName
})

关注和取消关注

  1. api路由层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 关注用户
    router.post('/follow', loginCheck, async (ctx, next) => {
    const { id: myUserId } = ctx.session.userInfo
    const { userId: curUserId } = ctx.request.body
    // controller
    ctx.body = await follow(myUserId, curUserId)
    })
    // 取消关注
    router.post('/unFollow', loginCheck, async (ctx, next) => {
    const { id: myUserId } = ctx.session.userInfo
    const { userId: curUserId } = ctx.request.body
    // controller
    ctx.body = await unFollow(myUserId, curUserId)
    })
  2. 控制器层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {*} myUserId 我的ID
    * @param {*} curUserId 当前登录的用户ID
    * @description: 关注
    */
    async function follow(myUserId, curUserId) {
    try {
    await addFollow(myUserId, curUserId)
    return new SuccessModel()
    } catch (err) {
    return new ErrorModel(addFollowerFailInfo)
    }
    }

    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {*} myUserId 我的ID
    * @param {*} curUserId 当前登录的用户ID
    * @description: 取消关注
    */
    async function unFollow(myUserId, curUserId) {
    const result = await deleteFollow(myUserId, curUserId)
    if (result) {
    return new SuccessModel()
    } else {
    return new ErrorModel(deleteUserFailInfo)
    }
    }
  3. 服务层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {number} userId 用户ID
    * @param {number} followerId 被关注用户id
    * @description: 添加关注关系
    */
    async function addFollow(userId, followerId) {
    const result = await UserRelation.create({
    userId,
    followerId
    })
    return result.dataValues
    }
    /**
    * @author: 小康
    * @url: https://xiaokang.me
    * @param {number} userId 用户ID
    * @param {number} followerId 被关注用户id
    * @description: 取消关注关系
    */
    async function deleteFollow(userId, followerId) {
    const result = await UserRelation.destroy({
    where: { userId, followerId }
    })
    return result > 0
    }