react+koa2+mongodb实现留言功能(可体验)

网友投稿 239 2022-08-28

react+koa2+mongodb实现留言功能(可体验)

用户发送一个​​TOPIC​​话题,读者可以在该话题下面进行评论,也可以对该话题下的留言进行评论。但是始终只会展示两层树的评论。当然,也可以像掘金这样进行嵌套多层树的结构展示。臣妾觉得嵌套得太深~

实际完成的效果如下:

体验站点请戳 ​​jimmyarea.com​​ 。

前端实现

使用技术

reactant designtypescript

在上面的截图中,很明显,就是一个表单的设计,外加一个列表的展示。

表单的设计使用了​​ant design​​​框架自带的​​form​​组件:

) : null} } /> )}/>

当然,如果是多级地树结构嵌套,你完全可以只是使用​​Comment​​组件进行递归调用

列表是对用户发表的主题,留言以及子留言的展示。如果你纵览上面的代码片段,你会发现里面有一个​​Form​​表单。

是的,其​​Form​​​表单就是给留言使用的,其结构仅仅是剔除了主题留言中的​​subject​​字段输入框,但是实际传参我还是会使用到。

完整的前端代码可前往​​jimmyarea 留言(前端)​​查看。

后端

使用的技术:

mongodb 数据库,这里我使用到了其ODM​​mongoose​​koa2 一个​​Node​​框架pm2 进程守卫apidoc 用来生成接口文档(如果你留意​​体验站点​​,右上角有一个"文档"的链接,链接的内容就是生成的文档内容)

这里的搭建就不进行介绍了,可以参考​​koa2官网​​配合百度解决~

其实,本质上还是增删改查的操作。

首先,我们对自己要存储的数据结构​​schema​​进行相关的定义:

const mongoose = require('mongoose')const Schema = mongoose.Schema// 定义留言字段let MessageSchema = new Schema({ // 关联字段 -- 用户的id userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, type: Number, // 1是留言,2是回复 subject: String, // 留言主题 content: String, // 留言内容 pid: { // 父id type: String, default: '-1' }, replyTargetId: { // 回复目标记录id, 和父pid有所不同 type: String, default: '-1' }, meta: { createAt: { type: Date, default: Date.now() }, updateAt: { type: Date, default: Date.now() } }})mongoose.model('Message', MessageSchema)

这里有个注意的点​​userId​​字段,这里我直接关联了注册的用户。

完成了字段的设定之后,下面就可以进行增删改查了。

详细的​​crud​​​代码可以到​​jimmyarea 留言(后端)​​ 查看。

本篇的重点是,对评论的话题和留言,如何转换成两层的树型结构呢?

这就是涉及到了​​pid​​​这个字段,也就是​​父节点的id​​​: 话题的​​pid​​​为​​-1​​​,话题下留言的​​pid​​为话题的记录值。如下代码:

let count = await Message.count({pid: '-1'})let data = await Message.find({pid: '-1'}) .skip((current-1) * pageSize) .limit(pageSize) .sort({ 'meta.createAt': -1}) .populate({ path: 'userId', select: 'username _id' // select: 'username -_id' -_id 是排除_id }) .lean(true) // 添加lean变成js的json字符串const pids = Array.isArray(data) ? data.map(i i._id) : [];let resReply = []if(pids.length) {resReply = await Message.find({pid: {$in: pids}}) .sort({ 'meta.createAt': 1}) .populate({ path: 'userId', select: 'username _id' // select: 'username -_id' -_id 是排除_id })}const list = data.map(item {const children = JSON.parse(JSON.stringify(resReply.filter(i i.pid === item._id.toString()))) // 引用问题const tranformChildren = children.map(innerItem ({ ...innerItem, canDel: innerItem.userId && innerItem.userId._id.toString() === (user._id&&user._id.toString()) ? 1 : 0}))return { ...item, children: tranformChildren, canDel: item.userId && item.userId._id.toString() === (user._id&&user._id.toString()) ? 1 : 0}})if(list) { ctx.body = { results: list, current: 1, count } return}ctx.body = { code: 10002, msg: '获取留言失败!'

至此,可以愉快地进行留言~

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:YTU 2412: 帮警长数一数【循环、分支简单综合】
下一篇:新品入市,一“会”搞定!你的会议营销做对了吗?(新品发布会是什么意思)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~