SpringBoot + uniapp 实现App评论回复功能

SpringBoot + uniapp 实现App评论回复功能

效果展示:
请添加图片描述
请添加图片描述

一、 数据库表
二、 后端接口
三、 前端实现

一、 表

  1. comment 评论表
    在这里插入图片描述
    content: 评论内容
    art_id: 文章ID 表示属于哪篇文章的评论
    u_id: 评论人ID 用来查询评论人信息的

  2. reply 回复表
    在这里插入图片描述
    r_id: 回复ID
    content: 回复内容
    u_id: 回复人的ID
    comment_id: 评论ID 属于对应评论的回复
    to_r_id: 默认为null 如果不为null 则表明这是一条回复的回复 为null 则为回复

二、 后端接口 ( 这里没做分页,实现分页也非常简单 )

  1. 查询对应文章的所有评论及其回复的数量
    Service
 		// 根据文章ID查询评论
        List<FindCommentsVo> findCommentsVos = commentMapper.findCommentsByArtId(artId);
        // 根据评论ID 查询回复的数量
        for (FindCommentsVo findCommentsVo: findCommentsVos){
            int replyCount = replyService.findReplyCountByCommentId(findCommentsVo.getCId());
            findCommentsVo.setReplyCount(replyCount);
        }
	Mapper
 	// 根据文章ID查询评论
    @Select("SELECT username,u_pic,c.id as c_id,content,c.created_time FROM comment as c inner join user  on user.id = c.u_id WHERE art_id = #{artId}")
    List<FindCommentsVo> findCommentsByArtId(int artId);
  1. 根据评论ID查询所有回复
    Service
 		List<Object> list = new ArrayList<Object>();
        // 第一次查询回复 第二次查询回复的回复
        List<FindReplysVo> findReplysVos = replyMapper.findAllReplyByCommentId(commentId);
        for (FindReplysVo findReplysVo: findReplysVos){
            list.add(findReplysVo);
        }
        // 查询回复的回复
        List<FindReplytoReplyByCommentId> replyToReplys = replyMapper.findAllReplytoRepleByCommentId(commentId);
        for (FindReplytoReplyByCommentId replyToReply: replyToReplys){
            list.add(replyToReply);
        }

上述代码有一个Bug 回复的回复始终会显示在回复的下方
这个问题在前端去解决

	Mapper
 	@Select("SELECT COUNT(*) FROM reply where comment_id = #{commentId}")
    int findCountByCommentId(int commentId);

    @Select(("SELECT username,u_pic,r_id,content,u_id,comment_id,to_r_id,reply.created_time " +
            "FROM reply inner join user on user.id = reply.u_id where comment_id = #{commentId} AND to_r_id IS NULL "))
    List<FindReplysVo> findAllReplyByCommentId(int commentId);

    @Select("SELECT u1.username AS replyUsername,u1.u_pic AS replyUpic,\n" +
            "            r1.r_id AS replyReplyId,r1.content AS replyContent,r1.created_time,\n" +
            "            r2.content AS ByreplyContent,u2.username AS ByreplyUsername,u2.u_pic AS ByreplyUpic\n" +
            "            FROM reply AS r1,user AS u1,reply AS r2,user AS u2\n" +
            "            WHERE r1.u_id = u1.id AND r1.to_r_id = r2.r_id  AND r2.u_id = u2.id\n" +
            "            AND r1.comment_id = #{commentId} ")
    List<FindReplytoReplyByCommentId> findAllReplytoRepleByCommentId(int commentId);

三、 前端实现

  1. 评论
<view class="content">
		<view class="comment animated bounceIn" v-for="(res, index) in commentList" :key="res.cid" >
			<view class="left">
				<image :src="res.upic" mode="aspectFill"></image>
			</view>
			<view class="right">
				<view class="top">
					{{res.username}}
				</view>
				<view class="content">{{ res.content }}</view>
				<view class="reply-box">
					<view class="all-reply" @tap="toAllReply(res)" v-if="res.replyCount != 0 ">
						共{{ res.replyCount }}条回复
						<u-icon class="more" name="arrow-right" :size="26"></u-icon>
					</view>
				</view>
				<view class="bottom">
					{{ res.createdTime }}
					<view class="reply" @tap="toAllReply(res)">回复</view>
				</view>
			</view>
		</view>
	</view>
  1. 回复
		<!-- 被回复的评论 -->
		<view class="comment">
			<view class="top">
				<view class="left">
					<view class="heart-photo">
						<image :src="comment.upic" mode=""></image>
					</view>
					<view class="user-info">
						<view class="name">{{ comment.username }}</view>
						<view class="date">{{ comment.createdTime }}</view>
					</view>
				</view>
			</view>
			<view class="content">{{ comment.content }}</view>
		</view>
		<!-- 全部的回复 -->
		<view class="all-reply">
			<view class="all-reply-top">全部回复({{ comment.replyCount }})</view>
			<view @click="replyToreply(item.username,item.rid,item.replyReplyId)" class="item animated bounceIn" hover-class="itemHover" hover-stay-time="1000"
				v-for="(item, index) in replyList" :key="index">
				<view class="comment">
					<view class="top">
						<view class="left">
							<view class="heart-photo">
								<image v-if="item.toRId == 0 " :src="item.upic" mode=""></image>
								<image v-if="item.toRId != 0 " :src="item.replyUpic" mode=""></image>
							</view>
							<view class="user-info">
								<view class="name">{{ item.toRId == 0 ? item.username: item.replyUsername }}</view>
								<view class="date">{{ item.createdTime }}</view>
							</view>
						</view>
					</view>
					<view class="reply" v-if="item.toRId != 0 ">
						<view class="username">{{ item.byreplyUsername }}</view>
						<view class="text">{{ item.byreplyContent }}</view>
					</view>
					<view class="content">{{ item.toRId == 0 ? item.content: item.replyContent }}</view>
				</view>
			</view>
		</view>

		<!-- 发表评论组件 -->
		<publishComment ref="publishComment" v-on:shuaxin="getReply()" :to_r_id="to_r_id" :comment_type="type"
			:art_id="art_id" :comment_id="c_id" ></publishComment>

此外,为了能够让评论显示的更加友好一些,这里按照发表时间的时间戳进行了降序排列

var compare = function (prop){
    
    return function (obj1, obj2) {
        var v1;
        var v2;
        if(prop === "createdTime"){
            v1 = new Date(obj1[prop]).getTime()
            v2 = new Date(obj2[prop]).getTime()
        }else{
            v1 = new Date(obj1[prop])
            v2 = new Date(obj2[prop])
        }
       
        if (v1 > v2) {
            return -1;
        } else if (v1 < v2) {
            return 1;
        } else {
            return 0;
        }            
    }   

}
export default compare

prop: 是你要进行排序的属性名

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值