springboot+vue前后分离实现仿qq空间评论功能

Java项目开发

共 9468字,需浏览 19分钟

 · 2021-01-13


案例功能效果图

前端评论列表页面效果图

环境介绍

前端:vue

后端:springboot

jdk:1.8及以上

数据库:mysql


完整源码获取方式



源码获取方式

扫码关注回复【plgn】获取完整源码


如果你在运行这个代码的过程中有遇到问题,请加小编微信xxf960513,我拉你进对应微信学习群!!帮助你快速掌握这个功能代码!




核心代码介绍

pom.xml

            <dependency>            <groupId>mysqlgroupId>            <artifactId>mysql-connector-javaartifactId>            <scope>runtimescope>        dependency>
<dependency> <groupId>org.mybatis.spring.bootgroupId> <artifactId>mybatis-spring-boot-starterartifactId> <version>2.1.1version> dependency>
<dependency> <groupId>ch.qos.logbackgroupId> <artifactId>logback-coreartifactId> <version>1.1.3version> dependency> <dependency> <groupId>ch.qos.logbackgroupId> <artifactId>logback-accessartifactId> <version>1.1.3version> dependency> <dependency> <groupId>ch.qos.logbackgroupId> <artifactId>logback-classicartifactId> <version>1.1.3version> dependency>
<dependency> <groupId>org.slf4jgroupId> <artifactId>slf4j-apiartifactId> <version>1.7.25version> dependency> <dependency> <groupId>org.slf4jgroupId> <artifactId>slf4j-simpleartifactId> <version>1.7.25version> <scope>compilescope> dependency>
<dependency> <groupId>io.springfoxgroupId> <artifactId>springfox-swagger2artifactId> <version>2.9.2version> dependency> <dependency> <groupId>io.swaggergroupId> <artifactId>swagger-modelsartifactId> <version>1.5.21version> dependency> <dependency> <groupId>com.github.xiaoymingroupId> <artifactId>swagger-bootstrap-uiartifactId> <version>1.9.3version> dependency>
<dependency> <groupId>com.alibabagroupId> <artifactId>fastjsonartifactId> <version>1.2.62version> dependency>
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> <scope>testscope> <exclusions> <exclusion> <groupId>org.junit.vintagegroupId> <artifactId>junit-vintage-engineartifactId> exclusion> exclusions> dependency> dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-maven-pluginartifactId> plugin> plugins>    build>project>

application.properties

server.port=8002spring.datasource.url=jdbc:mysql://xxx.xxx.xxx.xxx:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaispring.datasource.username=xxxxxxspring.datasource.password=xxxxxxspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

CommonMapper.java

package com.example.demo.mapper;import com.example.demo.vo.ReplyVO;import org.apache.ibatis.annotations.*;import java.util.List;@Mapperpublic interface CommonMapper {    @Select("select * from reply_info where comId = #{comId} order by updateTime")    List<ReplyVOqueryReplyList(@Param("comId")int comId);    @Delete("delete from reply_info where id = #{id}")    int deleteReply(int id);}

CommonController.java

package com.example.demo.controller;import com.example.demo.service.CommonService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.*;
@Api(description = "文章评论")@RequestMapping("/common")@RestControllerpublic class CommonController { @Autowired    private CommonService commonService; @ApiOperation(value = "获取文章评论列表", notes = "获取文章评论列表接口") @GetMapping("/replyList/{comId}") public Map getReplyList(@PathVariable("comId") int comId) { List list = commonService.queryReplyList(comId); Map resMap = new HashMap(); resMap.put("STATUS", "0000"); resMap.put("DATA", list); return resMap;    } @ApiOperation(value = "删除评论", notes = "删除评论接口") @PostMapping("/removeReply/{id}") public Map deleteReply(@PathVariable("id") int id) { commonService.deleteReply(id); Map map = new HashMap(); map.put("STATUS", "0000"); return map; }}

Home.vue

<template>  <div class="comment-wrap">    <div v-if="myComment.length" class="comment-list">      <h4>热门评论h4>      <div>        <div v-for="(item, index) in myComment" :key="item.id" class="comment-item">          <div class="top-wrap">            <div class="top-left">              <el-image :src="checkImg(item.userId)" alt="" lazy class="top-left-avatar"> el-image>              <div class="top-left-con">                <div class="top-left-con-title">                  <h3>{{ item.userName }}h3>                div>                <div class="top-left-con-time">{{ item.updateTime | moment('YYYY-MM-DD HH:mm') }}div>              div>            div>            <div class="top-right" v-if="loginId === item.userId">              <div class="top-right-item" @click="handleDelete(index)">                <img src="@/assets/delete.png" alt="" />              div>            div>          div>          <div class="label">            {{ item.msg }}          div>
<div v-if="item.newSub && item.newSub.length" class="reply-wrap"> <div v-for="(reply, i) in item.newSub" :key="reply.id" class="reply-item"> <div class="top-wrap"> <div class="top-left"> <el-image :src="checkImg(reply.userId)" alt="" lazy class="top-left-avatar"> el-image> <div class="top-left-con"> <div class="top-left-con-title"> <h3>{{ reply.userName }}h3> div> <div class="top-left-con-time">{{ reply.updateTime | moment('YYYY-MM-DD HH:mm') }}div> div> div> <div v-if="loginId === reply.userId" class="top-right"> <div class="top-right-item" @click="handleDelete(index, i + 1)"> <img src="@/assets/delete.png" alt="" /> div> div> div> <div class="label"> {{ reply.msg }} div> div> <div v-if="item.subList.length > 1"> <div v-if="!item.isMoreReply" class="showMoreReply" @click="showMoreReply(true, index)">查看更多回复div> <div v-else class="showMoreReply" @click="showMoreReply(false, index)">收起div> div> div> div> div> div> <el-pagination background :page-size="pageSize" :page-count="pageNo" layout="prev, pager, next" :total="allComment.length" @current-change="handleChangePage" @pre-click="handlePrePage" @next-click="handleNextPage" > el-pagination> div>template>
<script>import { mapGetters } from 'vuex';import axios from 'axios';export default { components: {}, props: {}, data() { return { textarea: '', isMoreComment: false, replyCon: '', myComment: [], allComment: [], loading: false, pageNo: 1, pageSize: 5 }; }, computed: { ...mapGetters(['loginId']) }, watch: {}, created() {}, mounted() { this.getData(); }, methods: { checkImg(id) { if (id === 1) { return require('@/assets/face.png'); } else { return require('@/assets/comment.png'); } }, showMoreReply(type, index) { this.myComment[index].isMoreReply = type; if (type) { this.myComment[index].newSub = this.myComment[index].subList; } else { this.myComment[index].newSub = this.myComment[index].subList.slice(0, 1); } }, handleDelete(index, i) { console.log(index, i, this.myComment); let id = 0; if (i) { id = this.myComment[index].newSub[i - 1].id; this.myComment[index].newSub.splice(i - 1, 1); } else { id = this.myComment[index].id; this.myComment.splice(index, 1); } axios({ method: 'post', url: `http://xxx.xxx.xxx.xxx:8002/common/removeReply/${id}` }).then(res => { console.log(res, 'res'); }); }, handleChangePage(val) { console.log(val, 'val'); this.pageNo = val; let begin = (val - 1) * this.pageSize;
this.myComment = this.allComment.slice(begin, begin + this.pageSize); }, handlePrePage() { if (this.pageNo > 1) { this.pageNo--; } let begin = (this.pageNo - 1) * this.pageSize; this.myComment = this.allComment.slice(begin, begin + this.pageSize); }, handleNextPage() { this.pageNo++; let begin = (this.pageNo - 1) * this.pageSize; this.myComment = this.allComment.slice(begin, this.pageSize); }, getData() { axios({ method: 'get', url: `http://xxx.xxx.xxx.xxx:8002/common/replyList/1` }).then(res => { console.log(res, 'res'); let data = res.data.DATA; const list = data.map(item => { return { ...item, newSub: item.subList.slice(0, 1), showReply: false, isMoreReply: false, isMoreComment: false }; });
console.log(list, 'list'); this.allComment = [].concat(list); this.myComment = list.slice(this.pageNo - 1, this.pageSize); }); } }};

reply_info.sql

SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;DROP TABLE IF EXISTS `reply_info`;CREATE TABLE `reply_info` (  `id` int NOT NULL AUTO_INCREMENT,  `userId` int DEFAULT NULL,  `comId` int DEFAULT NULL,  `msg` varchar(255) DEFAULT NULL,  `updatetime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,  `userName` varchar(255) DEFAULT NULL,  `replyId` int DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
BEGIN;INSERT INTO `reply_info` VALUES (1, 2, 1, '6', '2020-12-20 22:28:18', '评论人1', NULL);INSERT INTO `reply_info` VALUES (3, 2, 1, '666', '2020-12-30 22:28:19', '评论人1', 2);INSERT INTO `reply_info` VALUES (5, 3, 1, '8', '2020-12-20 22:28:29', '评论人2', NULL);INSERT INTO `reply_info` VALUES (7, 2, 1, '7', '2020-12-20 23:39:19', '评论人1', NULL);INSERT INTO `reply_info` VALUES (8, 3, 1, '88', '2020-12-30 23:40:12', '评论人2', 7);INSERT INTO `reply_info` VALUES (11, 3, 1, '8888', '2020-12-31 20:28:21', '评论人2', 10);INSERT INTO `reply_info` VALUES (12, 1, 1, '88888', '2020-12-31 20:28:35', '发表人', 11);INSERT INTO `reply_info` VALUES (13, 3, 1, '888888', '2020-12-31 20:28:48', '评论人2', 12);INSERT INTO `reply_info` VALUES (14, 1, 1, '8888888', '2020-12-31 20:29:06', '发表人', 13);INSERT INTO `reply_info` VALUES (15, 3, 1, '88888888', '2020-12-31 20:29:22', '评论人2', 14);INSERT INTO `reply_info` VALUES (17, 4, 1, '4', '2020-12-31 22:08:02', '评论人4', NULL);INSERT INTO `reply_info` VALUES (19, 5, 1, '5', NULL, '评论人5', NULL);INSERT INTO `reply_info` VALUES (21, 6, 1, '6', NULL, '评论人6', NULL);INSERT INTO `reply_info` VALUES (23, 7, 1, '7', NULL, '评论人7', NULL);INSERT INTO `reply_info` VALUES (24, 1, 1, '77', NULL, '发表人', 23);INSERT INTO `reply_info` VALUES (25, 8, 1, '8', NULL, '评论人8', NULL);INSERT INTO `reply_info` VALUES (26, 1, 1, '88', NULL, '发表人', 25);INSERT INTO `reply_info` VALUES (27, 9, 1, '9', NULL, '评论人9', NULL);INSERT INTO `reply_info` VALUES (29, 10, 1, '10', NULL, '评论人10', NULL);INSERT INTO `reply_info` VALUES (31, 11, 1, '11', NULL, '评论人11', NULL);COMMIT;SET FOREIGN_KEY_CHECKS = 1;
- END -

推荐案例

温暖提示

为了方便大家更好的学习,本公众号经常分享一些完整的单个功能案例代码给大家去练习,如果本公众号没有你要学习的功能案例,你可以联系小编(微信:xxf960513)提供你的小需求给我,我安排我们这边的开发团队免费帮你完成你的案例。
注意:只能提单个功能的需求不能要求功能太多,比如要求用什么技术,有几个页面,页面要求怎么样?


请长按识别二维码

想学习更多的java功能案例请关注

Java项目开发

如果你觉得这个案例以及我们的分享思路不错,对你有帮助,请分享给身边更多需要学习的朋友。别忘了《留言+点在看》给作者一个鼓励哦!

浏览 47
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报