在Uniapp里面实现评论回复和评论展开收起功能

1.前言

     这是本人课程设计中其中一个功能点,就是用户在使用unapp中的首页模块中可以对发表的文章进行评论。

2.实现效果

3.实现思路

(1)首先,在前端页码编写好一个循环评论组件,把它看成一个List列表,因为需要在大List里面去渲染小List列表。

(2)其次,就是需要在服务端编写一个接口,查询数据库中所有的相关评论,让后端把它构造成里面大List带着小List的数据,我用是的springboot编写的后端逻辑代码。

4.实现代码

4.1Uniapp实现代码

<template>
	<view>
		<scroll-view scroll-y="true" >
			<uni-card :title="items.title">
				<view class="flex-space u-m-5">
					<view class="flex">
						<u-avatar :src="items.userPic"></u-avatar>
						<view class="" style="">
							<view class="">{{items.username}}</view>
							<view class="">
								<u-tag text="原创" type="error"></u-tag>
							</view>
						</view>
					</view>
					<view class="" style="align-content: center;text-align: right;">
						<view class="">{{items.state}}</view>
						<text class="ts">{{items.createTime}}</text>
					</view>
				</view>
				<image :src="items.coverImg" style="width: 100%;" mode="aspectFill"></image>
				<u-read-more  ref="uReadMore" :toggle="true">
				    <rich-text :nodes="items.content"></rich-text>
				</u-read-more>
			</uni-card>
			
			<view class="u-flex-col" style=" width: 100%; left: 0;">
				<view class="u-m-l-40 u-m-b-20 u-m-r-20" style="height: 30px;">
					<u-section title="评论列表" sub-title="评论" @click="openDialog"></u-section>
				</view>
				<u-empty :show="list.length==0"
				        mode="list"
				        icon="http://cdn.uviewui.com/uview/empty/list.png">
				</u-empty>
				<uni-list>
					<uni-list-item v-for="(item,index) in list">
						<view class="" slot="header">
							<view class="">
								<view class="flex-row" @click="toReply(item)">
									<u-avatar :src="item.userPic"></u-avatar>
								<!-- 	<image :src="item.userPic" mode="aspectFill" style="width: 100upx;height: 100upx;border-radius: 50dp;"></image> -->
									<view class="">
										<view class="" style="color: #999;font-size: 30upx;">{{item.username}}</view>
										<view class="" >{{item.content}}</view>
										<view class="" style="color: #999;font-size: 18upx;">{{item.createTime}}</view>
									</view>
								</view>
							</view>
							<uni-list-item v-for="(item1,index1) in item.commentList.slice(0,(item.status==1?item.status:item.commentList.length))">
								<view class="" slot="header" @click="toReply(item1)">
									<view class="flex-center">
										<u-avatar :src="item1.userPic"></u-avatar>
										<!-- <image :src="item1.userPic" mode="aspectFill" style="width: 100upx;height: 100upx;border-radius: 50dp;"></image> -->
										<view class="">
											<view class="" style="color: #999;font-size: 30upx;">{{item1.username}}
											<u-icon name="play-right-fill"></u-icon>
											{{item1.replyName}}</view>
											<view class="" >{{item1.content}}</view>
											<view class="" style="color: #999;font-size: 18upx;">{{item1.createTime}}</view>
										</view>
									</view>
								</view>
							</uni-list-item>
							<view class="" v-if="item.commentList.length-1>0" @click="toMore(index)">
								<text>{{item.status==0?"收起":`展开${item.commentList.length-1}条回复`}}</text>
							</view>
						</view>
					</uni-list-item>
					<u-divider class="u-m-t-40" v-if="list.length!=0" style="bottom: 35px;width: 100%;">已显示全部评论</u-divider>
				</uni-list>
			</view>
			<view class="u-m-l-20" style="position: fixed; width: 100%;height: 50px;bottom: -14px;
			background-color: #FFFFFF;">
				<view class="flex-row u-m-r-50">
					<view class="" style="width: 70%;" @click="openDialog">
						<uni-easyinput disabled prefixIcon="compose" placeholder="写评论..." />
					</view>
					<view class="u-m-l-40 flex-space" style="width: 80px;">
						<uni-icons type="hand-up" size="30" :color="thumbState?'#2979ff':'#d5d5d5'" >
							<uni-badge :text="items.thumbNum" @click="addThumb"/>
						</uni-icons>
						<uni-icons type="star" size="30" :color="collectState?'#2979ff':'#d5d5d5'" >
							<uni-badge :text="items.collectNum" @click="addCollect"></uni-badge>
						</uni-icons>
					</view>
				</view>
			</view>
		</scroll-view>
		
		<uni-popup ref="addDialog"  type="bottom" maskClick>
			<uni-popup-dialog mode="input" :duration="2000" style="width: 100%;"
			:before-close="true" @close="addClose" @confirm="addConfirm" :title="`添加回复${replyname}`">
			</uni-popup-dialog>
		</uni-popup>
		
		<uni-popup ref="Dialog" type="dialog" maskClick>
			<uni-popup-dialog mode="input" :duration="2000"
			:before-close="true" @close="close" @confirm="confirm" title="添加评论对话框">
			</uni-popup-dialog>
		</uni-popup>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				items:{},
				form:{
					articleId:'',
					content:'',
					replyUser:'',
					commentId:'',
					treeId:''
				},
				list:[],
				replyname:'',
				collectState:false,
				thumbState:false,
				itemId:0
			}
		},
		onLoad(e) {
			this.itemId = e.id
			this.getDetail()
		},
		methods: {
			getDetail(){
				this.request('/article/detail?id='+this.itemId).then(res=>{
					console.log(res)
					this.items = res.data
					this.form.articleId = this.items.id
					console.log(this.items)
					this.getList()
					this.$nextTick(() => {
						this.$refs.uReadMore.init();
					})
					this.request(`/collect/myLike?articleId=${this.itemId}`).then(res=>{
						if(res.code==200)
						this.collectState = res.data
						console.log(res)
					})
					this.request(`/thumb/myLike?articleId=${this.itemId}`).then(res=>{
						if(res.code==200)
						this.thumbState = res.data
						console.log(res)
					})
				})
				
			},
			getList(){
				this.request(`/comment?articleId=${this.form.articleId}`).then(res=>{
					this.list = res.data
					console.log(res.data)
				})
			},
			openDialog(){
				this.$refs.Dialog.open()
			},
			toReply(item){
				console.log(item)
				this.replyname = item.username
				this.form.replyUser = item.usersId
				this.form.commentId = item.id
				if(item.treeId)this.form.treeId = item.treeId  //有根给根
				else this.form.treeId = item.id  //无根给自己id
				console.log(this.form)
				this.$refs.addDialog.open()
			},
			addConfirm(e){
				this.form.content = e
				this.toAddRequest(1)
			},
			addClose(){
				this.$refs.addDialog.close()
				this.clear()
			},
			confirm(e){
				this.form.content = e
				this.toAddRequest(0)
			},
			close(){
				this.$refs.Dialog.close()
				this.clear()
			},
			toAddRequest(idx){
				this.request('/comment','post',{...this.form}).then(res=>{
					uni.showToast({
						title:res.message
					})
					this.getList()
					if(idx==0)this.close()
					else this.addClose()
					this.clear()
				})
			},
			clear(){
				this.replyname = ''
				this.form.content = ''
				this.form.replyUser = ''
				this.form.commentId = ''
				this.form.treeId = ''
			},
			toMore(index){
				console.log('你点击了'+index)
				if(this.list[index].status){
					this.list[index].status = 0
				}
				else {
					this.list[index].status = 1
				}
			},
			addCollect(){
				console.log('你点击了收藏')
				if(!this.collectState)this.request(`/collect/add?categoryId=${this.items.categoryId}&articleId=${this.itemId}`).then(res=>{
					console.log(res)
					if(res.code==200){
						uni.showToast({
							title:'收藏成功'
						})
						this.getDetail()
					}
				})
				else {
					this.request(`/collect/delete?articleId=${this.itemId}`,'delete').then(res=>{
						if(res.code==200){
							uni.showToast({
								title:'取消收藏成功'
							})
							this.getDetail()
						}
						
					})
				}
				
			},
			addThumb(){
				console.log('你点击了点赞')
				if(!this.thumbState)this.request(`/thumb/add?categoryId=${this.items.categoryId}&articleId=${this.itemId}`).then(res=>{
					if(res.code==200){
						uni.showToast({
							title:'点赞成功'
						})
						this.getDetail()
					}
				})
				else {
					this.request(`/thumb/delete?articleId=${this.itemId}`,'delete').then(res=>{
						if(res.code==200){
							uni.showToast({
								title:'取消点赞成功'
							})
							this.getDetail()
						}
					})
				}
				
			}
		}
	}
</script>

<style>

</style>

4.2Java实现代码

(1)entity层

@Data
@Schema(description = "评论实体")
public class Comment {
    @NotEmpty
    @Schema(description = "评论id") //这个是swagger里面的定义,建议删除
    private Integer id;//主键ID
    @Schema(description = "评论内容")
    private String content;//文章内容
    @Schema(description = "文章id")
    private Integer articleId;//文章id
    @Schema(description = "创建用户id")
    private Integer usersId;//创建用户id
    @Schema(description = "回复人id")
    private Integer replyUser;//回复人id
    @Schema(description = "回复评论id")
    private Integer commentId;//回复评论id
    @Schema(description = "父级评论id")
    private Integer treeId;//父级评论id
    @Schema(description = "创建人头像")
    private String userPic;//创建人头像
    @Schema(description = "创建人姓名")
    private String username;//创建人姓名
    @Schema(description = "回复人姓名")
    private String replyName;//回复人姓名
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" )
    @Schema(description = "创建时间")
    private LocalDateTime createTime;//创建时间
}
@Schema(description = "评论列表实体")
@Data
public class CommentBean {
    @NotEmpty
    @Schema(description = "评论id")
    private Integer id;//主键ID
    @Schema(description = "评论内容")
    private String content;//文章内容
    @Schema(description = "文章id")
    private Integer articleId;//文章id
    @Schema(description = "创建用户id")
    private Integer usersId;//创建用户id
    @Schema(description = "回复人id")
    private Integer replyUser;//回复人id
    @Schema(description = "回复评论id")
    private Integer commentId;//回复评论id
    @Schema(description = "父级评论id")
    private Integer treeId;//父级评论id
    @Schema(description = "创建人头像")
    private String userPic;//创建人头像
    @Schema(description = "创建人姓名")
    private String username;//创建人姓名
    @Schema(description = "回复人姓名")
    private String replyName;//回复人姓名
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" )
    @Schema(description = "创建时间")
    private LocalDateTime createTime;//创建时间
    @Schema(description = "评论列表折叠状态")
    private Integer status; //1,表示显示1个,0表示显示全部
    private List<Comment> commentList;
}

@Schema表示swagger生成在线文档里面的定义,如果没有用到建议删掉

(2)controller层

   @Operation(summary = "获取评论列表接口",operationId = "获取评论列表接口")
    @GetMapping
    public Result<List<CommentBean>> list(@RequestParam(required = false) Integer articleId){
        List<CommentBean> commentList =  commentService.list(articleId);
        return Result.success(commentList);
    }

 @Operation(summary = "获取评论列表接口",operationId = "获取评论列表接口")表示swagger生成在线文档里面的定义,如果没有用到建议删掉

(3)service接口

public interface CommentService {
    //获取评论列表
    List<CommentBean> list(Integer id);

}

(4)service实现类

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;

    @Override
    public List<CommentBean> list(Integer articleId) {
        List<CommentBean> commentBeanList  = new ArrayList<>(); //创建返回的值
        List<Comment> commentList = commentMapper.list(articleId);     //找到母体的数组
        for(Comment comment:commentList){
            CommentBean commentBean = new CommentBean();
            commentBean.setCommentList(commentMapper.treeList(articleId,comment.getId()));
            commentBean.setId(comment.getId());
            commentBean.setContent(comment.getContent());
            commentBean.setArticleId(comment.getArticleId());
            commentBean.setUsersId(comment.getUsersId());
            commentBean.setTreeId(comment.getTreeId());
            commentBean.setUserPic(comment.getUserPic());
            commentBean.setUsername(comment.getUsername());
            commentBean.setCreateTime(comment.getCreateTime());
            commentBean.setStatus(1); 
            commentBeanList.add(commentBean);
        }
        return commentBeanList;
    }

}

(5)mapper层

@Mapper
public interface CommentMapper {

    //获取根评论
    @Select("select comment.id,comment.content,comment.article_id,comment.users_id,comment.create_time,comment.tree_id,users.user_pic,users.username " +
            "from users,comment where users.id = comment.users_id and article_id = #{articleId} and comment.tree_id is null")
    List<Comment> list(Integer articleId);

    //获取父id得到子评论
    @Select("select comment.id,comment.content,comment.article_id,comment.users_id,comment.reply_user,comment.comment_id,comment.create_time,comment.tree_id,users.user_pic,users.username," +
            "(select users.username from users where users.id=comment.reply_user) as replyname  from users,comment where users.id = comment.users_id and article_id = #{articleId} and comment.tree_id = #{Id} ")
    List<Comment> treeList(Integer articleId,Integer Id);


}

 做完上述步骤即可完成此功能,切记上面有些sql语句采用了多表级联查询的功能,大家根据自己的需求来修改自己的代码,最后祝大家都能解决所有bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值