十二、从零模拟新浪微博-艾特提到我
代码仓库:https://github.com/changeclass/koa2-weibo
修改数据模型
/**
* @description: 微博艾特用户的关系
* @author: 小康
* @url: https://xiaokang.me
* @Date: 2020-12-20 11:10:05
* @LastEditTime: 2020-12-20 11:10:05
* @LastEditors: 小康
*/
const seq = require('../seq')
const { INTEGER, BOOLEAN } = require('../type')
const AtRelation = seq.define('atRelation', {
userId: {
type: INTEGER,
allowNull: false,
comment: '用户 id'
},
blogId: {
type: INTEGER,
allowNull: false,
comment: '微博 id'
},
isRead: {
type: BOOLEAN,
allowNull: false,
defaultValue: false,
comment: '是否已读'
}
})
module.exports = AtRelation
入口文件
const AtRelation = require('./AtRelation')
Blog.hasMany(AtRelation, {
foreignKey: 'blogId'
})
建立@关系
修改创建微博时的逻辑,应该在创建微博时创建艾特关系
const { createAtReplation } = require('../services/at-relation')
const { getUserInfo } = require('../services/user')
/**
* @author: 小康
* @url: https://xiaokang.me
* @param {string} userId
* @param {string} content
* @param {string} image
* @description: 创建微博
*/
async function create({ userId, content, image }) {
// 分析并手机 content 中的@用户
// content格式
const atUserNameList = []
content = content.replace(REG_FOR_AT_WHO, (matchStr, nickName, userName) => {
// 目的是获取用户名
atUserNameList.push(userName)
return matchStr //替换不生效
})
// 根据 @ 用户名查询用户信息
const atUserList = await Promise.all(
atUserNameList.map((userName) => getUserInfo(userName))
)
// 根据用户信息 获取id
const atUserIdList = atUserList.map((user) => user.id)
// servers
try {
const blog = await createBlog({ userId, content: xss(content), image })
// 创建at关系
await Promise.all(
atUserIdList.map((userId) => {
createAtReplation(blog.id, userId)
})
)
// 返回
return new SuccessModel(blog)
} catch (error) {
console.error(error.message, error.stack)
return new ErrorModel(createBlogFailInfo)
}
}服务层
/**
* @description: 微博 @ 用户关系
* @author: 小康
* @url: https://xiaokang.me
* @Date: 2020-12-20 11:39:05
* @LastEditTime: 2020-12-20 11:39:06
* @LastEditors: 小康
*/
const { AtRelation } = require('../db/model')
/**
* @author: 小康
* @url: https://xiaokang.me
* @param {*} blogId
* @param {*} userId
* @description: 创建微博艾特用户的关系
*/
async function createAtReplation(blogId, userId) {
const result = await AtRelation.create({
blogId,
userId
})
return result.dataValues
}
module.exports = { createAtReplation }显示at数量
视图路由层
// 获取 @ 数量 const atCount = await getAtMeCount(userId)只需要调用控制器层的方法获取数量即可。
控制器层
/** * @description: 微博 @ 关系 * @author: 小康 * @url: https://xiaokang.me * @Date: 2020-12-20 14:10:21 * @LastEditTime: 2020-12-20 14:10:23 * @LastEditors: 小康 */ const { getAtRelationCount } = require('../services/at-relation') const { SuccessModel } = require('../model/ResModel') /** * @author: 小康 * @url: https://xiaokang.me * @param {*} userId * @description: 获取 @ 我的微博数量 */ async function getAtMeCount(userId) { const count = await getAtRelationCount(userId) return new SuccessModel({ count }) } module.exports = { getAtMeCount }服务层
/** * @author: 小康 * @url: https://xiaokang.me * @param {*} userId * @description: 获取at用户的微博数量(未读) */ async function getAtRelationCount(userId) { const result = await AtRelation.findAndCountAll({ where: { userId, isRead: false } }) return result.count }
@me页面
视图路由层
// @ 我的页面 router.get('/at-me', loginRedirect, async (ctx, next) => { const { id: userId } = ctx.session.userInfo // 获取 @ 我的数量 const atCountResult = await getAtMeCount(userId) const { count: atCount } = atCountResult.data // 获取第一页列表 const result = await getAtMeBlogList(userId) const { isEmpty, blogList, pageSize, pageIndex, count } = result.data // 渲染页面 await ctx.render('atMe', { blogData: { isEmpty, blogList, pageSize, pageIndex, count }, atCount }) // 标记为已读 if (atCount > 0) { } })控制器层
/** * @author: 小康 * @url: https://xiaokang.me * @param {*} userId * @param {*} pageIndex * @description: 获取@ 用户的微博列表 */ async function getAtMeBlogList(userId, pageIndex = 0) { // service const result = await getUserBlogList({ userId, pageIndex, pageSize: PAGE_SIZE }) const { count, blogList } = result // 返回 return new SuccessModel({ isEmpty: blogList.length === 0, blogList, pageSize: PAGE_SIZE, pageIndex, count }) }服务层
/** * @author: 小康 * @url: https://xiaokang.me * @param {*} userId * @param {*} pageIndex * @param {*} pageSize * @description: 获取 @ 用户的微博列表 */ async function getUserBlogList({ userId, pageIndex, pageSize = PAGE_SIZE }) { const result = await Blog.findAndCountAll({ limit: pageSize, offset: pageSize * pageIndex, order: [['id', 'desc']], include: [ // @ 关系 { model: AtRelation, attributes: ['userId', 'blogId'], where: { userId } }, // 用户 { model: User, attributes: ['userName', 'nickName', 'picture'] } ] }) let blogList = result.rows.map((row) => row.dataValues) blogList = formatBlog(blogList) blogList = blogList.map((blogItem) => { blogItem.user = formatUser(blogItem.user.dataValues) return blogItem }) return { count: result.count, blogList } }
@消息已读
试图层
试图层调用方法即可
if (atCount > 0) { markAsRead(userId) }控制层
/** * @author: 小康 * @url: https://xiaokang.me * @param {*} userId * @description: 标记已读 */ async function markAsRead(userId) { try { await updataAtRelation({ newIsRead: true }, { userId, isRead: false }) } catch (error) { console.error(error) } // 不需要返回 }服务层
/** * @author: 小康 * @url: https://xiaokang.me * @param {Object} 要更新的内容 * @param {Object} 条件 * @description: 更新数据 */ async function updataAtRelation({ newIsRead }, { userId, isRead }) { // 拼接更新内容 const updataData = {} if (newIsRead) { updataData.isRead = newIsRead } // 拼接查询条件 const whereData = {} if (userId) { whereData.userId = userId } if (isRead) { whereData.isRead = isRead } // 执行更新 const result = await AtRelation.update(updataData, { where: whereData }) return result[0] > 0 }
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小康博客!
评论
TwikooDisqusjs








