react+koa实现留言板功能

前言

自己用react+koa实现一个留言板的功能,留言的内容可以是文字、图片、表情、视频、音频。在这里记录和总结。

项目地址:github地址
预览地址:预览地址



截图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

实现

前台使用了reactantd,富文本编辑器使用的是Braft Editor
后台使用的是koa,后端的上传文件功能参考这里

对于这个项目的留言板的难点我认为主要在富文本编辑器和数据库的设计,对于页面UI渲染和逻辑我认为都不算复杂。

这里我记录了一些关于富文本编辑器的使用

数据库

数据库使用的是mysql
留言可以有回复,回复又可以有子回复,所以它是一种树结构的数据。而mysql比较适合存储一些类似表格的扁平化数据,对于树结构的数据不好处理。
我在网上找了很多方法,大部分就是加pid、path字段还有用左右值编码的设计,这类设计要么需要递归、要么就是插入数据会影响很多数据(可以参考这里)。

最后我想了想不需要用树结构去存储留言
在这里插入图片描述
我将数据分为两种类型留言回复(都存储在一张表中)
留言数据有留言内容和留言人,pid为-1。
回复数据有回复内容、回复人和被回复人,注意它的pid不是被回复的id,而是在哪条留言底下回复pid就是哪条留言的id,上图中两条回复的pid都是“我是吴彦祖”这条留言的id。

CREATE TABLE `messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `type` int(8) DEFAULT NULL COMMENT '0(留言)、1(回复)',
  `createTime` bigint(20) DEFAULT NULL COMMENT '创建信息时间',
  `content` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '信息内容',
  `userId` int(11) DEFAULT NULL COMMENT '回复人id',
  `userIsAdmin` int(8) DEFAULT NULL COMMENT '回复人是否是管理员',
  `userName` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '回复人用户名',
  `userAvatar` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '回复人头像',
  `targetUserId` int(11) DEFAULT NULL COMMENT '被回复人id',
  `targetUserIsAdmin` int(8) DEFAULT NULL COMMENT '被回复人是否是管理员',
  `targetUserName` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '被回复人用户名',
  `targetUserAvatar` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '被回复人头像',
  `pid` int(11) DEFAULT '-1' COMMENT '父id',
  `likeNum` int(11) DEFAULT '0' COMMENT '赞的数量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=190 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

我后台查询数据时,先将所有数据查出来,然后再处理数据
首先将留言数据和回复数据从查询结果分离出来,然后通过回复数据的pid添加到对应留言下的children属性中。可以去控制台中查看数据

/**
 * 获取留言列表
 */
const getMessages = async () => {
    const sql = `select * from messages order by createTime DESC` //按时间降序排列
    const res = await exec(sql)
    //这里可以用sql查两次类型的回复,也可以用js来过滤
    //获取留言类型数据,并且给每个数据添加children属性
    let list = res.reduce((total, current) => {
        if (current.type === 0) {
            total.push({
                ...current,
                children: []
            })
        }
        return total
    }, [])
    //获取回复类型数据
    let subList = res.filter(item => item.type === 1)
    //将回复类型数据根据pid添加到留言类型数据的children属性中
    subList.forEach(item => {
        const index = list.findIndex(i => i.id === item.pid)
        list[index].children.unshift(item)
    })
    return new SuccessModel({
        data: list
    })
}

留言可以发送表情包,但是数据库存储后乱码了,在网上找到解决方法就是设置表的字符集为utf8mb4,可还是不管用,最后找了很久才发现在node连接数据库时要设置字符集

  MYSQL_CONF = {
        host: 'localhost',
        user: 'root',
        password: '1234567890',
        port: '3306',
        database: 'admin',
        charset:'utf8mb4'   //字符集一定要写,否则表情包存储不了
 }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值