个人博客-评论管理

  • 目录

    详情页分页显示评论列表

    详情页评论文章

    仪表盘列表显示当前用户评论总数、评论列表、按时间先后顺序显示15条

  • 评论管理必须要和其他的功能关联起来不然是做不出来的

    首先要创建一个数据库

  • /*
    SQLyog v10.2 
    MySQL - 5.7.17-log : Database - blog_system
    *********************************************************************
    */
    
    /*!40101 SET NAMES utf8 */;
    
    /*!40101 SET SQL_MODE=''*/;
    
    /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
    CREATE DATABASE /*!32312 IF NOT EXISTS*/`blog_system` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_polish_ci */;
    
    USE `blog_system`;
    
    /*Table structure for table `t_comment` */
    
    DROP TABLE IF EXISTS `t_comment`;
    
    CREATE TABLE `t_comment` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '评论id',
      `article_id` int(11) NOT NULL COMMENT '关联的文章id',
      `created` date NOT NULL COMMENT '评论时间',
      `ip` varchar(200) DEFAULT NULL COMMENT '评论用户登录的ip地址',
      `content` text NOT NULL COMMENT '评论内容',
      `status` varchar(200) NOT NULL DEFAULT 'approved' COMMENT '评论状态',
      `author` varchar(200) NOT NULL COMMENT '评论用户用户名',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8;
    
    /*Data for the table `t_comment` */
    
    insert  into `t_comment`(`id`,`article_id`,`created`,`ip`,`content`,`status`,`author`) values (3,10,'2018-12-13','0:0:0:0:0:0:0:1','关于Docker虚拟容器的讲解挺好的额,学习中','approved','李四'),(9,1,'2018-12-13','0:0:0:0:0:0:0:1','非常不错,赞一个!','approved','李四'),(10,1,'2018-12-13','0:0:0:0:0:0:0:1','博主,这资料怎么弄的?有相关资源和教材推荐吗?','approved','李四'),(11,1,'2018-12-13','0:0:0:0:0:0:0:1','很详细,感谢...','approved','东方不败'),(12,1,'2018-12-13','0:0:0:0:0:0:0:1','很全,努力学习中...','approved','东方不败'),(13,1,'2018-12-13','0:0:0:0:0:0:0:1','好东西,先收藏起来,哈哈','approved','tom'),(14,8,'2018-12-13','0:0:0:0:0:0:0:1','very good blog','approved','tom'),(15,17,'2023-11-11','0:0:0:0:0:0:0:1','11111','approved','admin'),(17,16,'2023-11-11','0:0:0:0:0:0:0:1','1111','approved','admin'),(18,1,'2023-11-11','0:0:0:0:0:0:0:1','1111','approved','admin'),(19,1,'2023-11-11','0:0:0:0:0:0:0:1','1111111111111','approved','admin'),(20,10,'2023-11-13','0:0:0:0:0:0:0:1','kkkmmvvv','approved','admin'),(21,10,'2023-11-13','0:0:0:0:0:0:0:1','发','approved','admin'),(22,10,'2023-11-13','0:0:0:0:0:0:0:1','啊','approved','admin'),(23,18,'2023-11-13','0:0:0:0:0:0:0:1','kkk','approved','admin'),(24,18,'2023-11-13','0:0:0:0:0:0:0:1','反反复复','approved','admin'),(25,18,'2023-11-13','0:0:0:0:0:0:0:1','发发发发发','approved','admin'),(26,18,'2023-11-13','0:0:0:0:0:0:0:1','发发发发发发','approved','admin'),(28,18,'2023-11-13','0:0:0:0:0:0:0:1','发发发发发','approved','admin'),(29,18,'2023-11-13','0:0:0:0:0:0:0:1','发发发发发','approved','admin'),(30,18,'2023-11-13','0:0:0:0:0:0:0:1','啊啊啊啊啊','approved','admin'),(31,18,'2023-11-13','0:0:0:0:0:0:0:1','发发发vvvv','approved','admin'),(32,18,'2023-11-13','0:0:0:0:0:0:0:1','vvvvvv','approved','admin'),(33,18,'2023-11-13','0:0:0:0:0:0:0:1','VB不不不不','approved','admin'),(34,18,'2023-11-13','0:0:0:0:0:0:0:1','vvvvvv','approved','admin'),(35,18,'2023-11-13','0:0:0:0:0:0:0:1','谢谢小星星','approved','admin'),(36,18,'2023-11-13','0:0:0:0:0:0:0:1','vvvvvv','approved','admin'),(37,18,'2023-11-13','0:0:0:0:0:0:0:1','湘西自治州','approved','admin'),(38,18,'2023-11-13','0:0:0:0:0:0:0:1','英语与银行','approved','admin'),(39,18,'2023-11-13','0:0:0:0:0:0:0:1','看看嘛密密麻麻','approved','admin'),(40,18,'2023-11-13','0:0:0:0:0:0:0:1','啧啧啧啧啧啧','approved','admin'),(41,18,'2023-11-13','0:0:0:0:0:0:0:1','热热热热热','approved','admin'),(42,18,'2023-11-13','0:0:0:0:0:0:0:1','发发发','approved','admin'),(43,18,'2023-11-13','0:0:0:0:0:0:0:1','反反复复','approved','admin');
    
    /*Table structure for table `t_statistic` */
    
    DROP TABLE IF EXISTS `t_statistic`;
    
    CREATE TABLE `t_statistic` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `article_id` int(11) NOT NULL COMMENT '关联的文章id',
      `hits` int(11) NOT NULL DEFAULT '0' COMMENT '文章点击总量',
      `comments_num` int(11) NOT NULL DEFAULT '0' COMMENT '文章评论总量',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
    
    /*Data for the table `t_statistic` */
    
    insert  into `t_statistic`(`id`,`article_id`,`hits`,`comments_num`) values (1,1,106,7),(2,2,3,0),(3,3,4,0),(4,4,4,0),(5,5,4,0),(6,6,16,0),(7,7,9,0),(8,8,24,1),(9,9,18,0),(10,10,25,4),(11,11,11,1),(12,12,50,1),(13,13,1,0),(14,14,1,0),(15,15,2,0),(16,16,19,1),(17,17,19,2),(18,18,30,21),(19,19,14,5),(20,20,1,0),(22,22,6,0),(23,23,0,0),(24,24,1,0),(25,25,0,0),(26,26,0,0);
    
    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

    然后再创建实体类

  • public class Comment {
        private Integer id;         // 评论id
        private Integer articleId; // 评论的文章id
        private String content;    // 评论内容
        private Date created;      // 评论日期
        private String author;     // 评论作者名
        private String ip;          // 评论用户登录ip
        private String status;     // 评论状态,默认审核通过approved
        //此处省略get、set语句
        //此处省略toString语句
    public class Statistic {
        private Integer id;
        private Integer articleId; // 评论的文章id
        private Integer hits; // 点击量
        private Integer commentsNum; // 评论总量
    
        //此处省略get、set语句
  • 再写个Service类

public interface ICommentService {
    // 获取文章下的评论
    public PageInfo<Comment> getComments(Integer aid, int page, int count);

    // 用户发表评论
    public void pushComment(Comment comment);
public interface ISiteService {

    // 最新收到的评论
    public List<Comment> recentComments(int count);

    // 最新发表的文章
    public List<Article> recentArticles(int count);

    // 获取后台统计数据
    public StaticticsBo getStatistics();

    // 更新某个文章的统计数据
    public void updateStatistics(Article article);

}
@Service
@Transactional
public class CommentServiceImpl implements ICommentService {
    @Autowired
    private CommentMapper commentMapper;
   
    // 根据文章id分页查询评论
    @Override
    public PageInfo<Comment> getComments(Integer aid, int page, int count) {
        PageHelper.startPage(page,count);
        List<Comment> commentList = commentMapper.selectCommentWithPage(aid);
        PageInfo<Comment> commentInfo = new PageInfo<>(commentList);
        return commentInfo;
    }
    // 用户发表评论
    @Override
    public void pushComment(Comment comment){
        commentMapper.pushComment(comment);
        // 更新文章评论数据量
        Statistic statistic = statisticMapper.selectStatisticWithArticleId(comment.getArticleId());
        statistic.setCommentsNum(statistic.getCommentsNum()+1);
        statisticMapper.updateArticleCommentsWithId(statistic);
    }

@Service
@Transactional
public class SiteServiceImpl implements ISiteService {
    @Autowired
    private CommentMapper commentMapper;
    

    @Override
    public void updateStatistics(Article article) {
        Statistic statistic = statisticMapper.selectStatisticWithArticleId(article.getId());
        statistic.setHits(statistic.getHits() + 1);
        statisticMapper.updateArticleHitsWithId(statistic);
    }

    @Override
    public List<Comment> recentComments(int limit) {
        PageHelper.startPage(1, limit > 10 || limit < 1 ? 10 : limit);
        List<Comment> byPage = commentMapper.selectNewComment();
        return byPage;
    }

最后再创个Controller类,后端就完成了

@Controller
@RequestMapping("/admin")
public class CommentController {
    private static final Logger logger = LoggerFactory.getLogger(CommentController.class);

    @Autowired
    private ICommentService commentServcieImpl;

    // 发表评论操作
    @PostMapping(value = "/publish")
    @ResponseBody
    public ArticleResponseData publishComment(HttpServletRequest request, @RequestParam Integer aid, @RequestParam String text) {
        // 去除js脚本
        text = MyUtils.cleanXSS(text);
        text = EmojiParser.parseToAliases(text);
        // 获取当前登录用户
        User user=(User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        // 封装评论信息
        Comment comments = new Comment();
        comments.setArticleId(aid);
        comments.setIp(request.getRemoteAddr());
        comments.setCreated(new Date());
        comments.setAuthor(user.getUsername());
        comments.setContent(text);
        try {
            commentServcieImpl.pushComment(comments);
            logger.info("发布评论成功,对应文章id: "+aid);
            return ArticleResponseData.ok();
        } catch (Exception e) {
            logger.error("发布评论失败,对应文章id: "+aid +";错误描述: "+e.getMessage());
            return ArticleResponseData.fail();
        }
    }

前端

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:fragment="comments"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<body>
<div th:if="${article}!=null">
    <div th:id="${article.id ?: 0}" class="comment-container">
        <div id="comments" class="clearfix">
            <div th:if="${article.allowComment}">
                <span class="response">
                    <form name="logoutform" th:action="@{/logout}" method="post"></form>
                    <th:block sec:authorize="isAuthenticated()">
                        Hello,<a data-no-instant="" sec:authentication="name"></a>
                        如果你想 <a href="javascript:document.logoutform.submit();">注销</a> ?
                    </th:block>
                    <th:block sec:authorize="isAnonymous()">
                        用户想要评论,请先<a th:href="@{/login}" title="登录" data-no-instant="">登录</a>!
                    </th:block>
                </span>
                <div sec:authorize="isAuthenticated()">
                    <form id="comment-form" class="comment-form" role="form" onsubmit="return TaleComment.subComment();">
                        <input type="hidden" name="aid" id="aid" th:value="${article.id}"/>
                        <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
                        <textarea name="text" id="textarea" class="form-control" placeholder="以上信息可以为空,评论不能为空哦!"
                                  required="required" minlength="1" maxlength="100"></textarea>
                        <button type="submit" class="submit" id="misubmit">提交</button>
                    </form>
                </div>
            </div>
            <!-- 分页显示其他评论内容 -->
            <div th:if="${comments}">
                <ol class="comment-list">
                    <th:block th:each="comment :${comments.list}">
                        <li th:id="'li-comment-'+${comment.id}" class="comment-body comment-parent comment-odd">
                            <div th:id="'comment-'+${comment.id}">
                                <div class="comment-view" onclick="">
                                    <div class="comment-header">
                                        <!--设置人物头像和名称-->
                                        <img class="avatar" th:src="@{/assets/img/avatars.jpg}" height="50"/>
                                        <a class="comment-author" rel="external nofollow" th:text="${comment.author}" />
                                    </div>
                                    <!-- 评论内容 -->
                                    <div class="comment-content">
                                        <span class="comment-author-at"></span>
                                        <p th:utext="${commons.article(comment.content)}"></p>
                                    </div>
                                    <!-- 评论日期 -->
                                    <div class="comment-meta">
                                        <time class="comment-time" th:text="${commons.dateFormat(comment.created)}"></time>
                                        <a sec:authorize="isAuthenticated()" th:if="${comment.author}!= ${session.SPRING_SECURITY_CONTEXT.authentication.principal.username}" href="javascript:void(0)" style="color: #1b961b">
                                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;回复
                                        </a>
                                    </div>
                                </div>
                            </div>
                        </li>
                    </th:block>
                </ol>
                <!-- 进行评论分页 -->
                <div class="lists-navigator clearfix">
                    <ol class="page-navigator">
                        <!-- 判断并展示上一页 -->
                        <th:block th:if="${comments.hasPreviousPage}">
                            <li class="prev"><a th:href="'?cp='+${comments.prePage}+'#comments'">上一页</a></li>
                        </th:block>
                        <!-- 判断并展示中间页 -->
                        <th:block th:each="navIndex : ${comments.navigatepageNums}">
                            <th:block th:if="${comments.pages} <= 5">
                                <li th:class="${comments.pageNum}==${navIndex}?'current':''">
                                    <a th:href="'?cp='+${navIndex}+'#comments'" th:text="${navIndex}"></a>
                                </li>
                            </th:block>
                            <th:block th:if="${comments.pages} > 5">
                                <li th:if="${comments.pageNum <=3 &&  navIndex <= 5}" th:class="${comments.pageNum}==${navIndex}?'current':''">
                                    <a th:href="'?cp='+${navIndex}+'#comments'" th:text="${navIndex}"></a>
                                </li>
                                <li th:if="${comments.pageNum >= comments.pages-2 &&  navIndex > comments.pages-5}" th:class="${comments.pageNum}==${navIndex}?'current':''">
                                    <a th:href="'?cp='+${navIndex}+'#comments'" th:text="${navIndex}"></a>
                                </li>
                                <li th:if="${comments.pageNum >=4 && comments.pageNum <= comments.pages-3 &&  navIndex >= comments.pageNum-2 && navIndex <= comments.pageNum+2}"  th:class="${comments.pageNum}==${navIndex}?'current':''">
                                    <a th:href="'?cp='+${navIndex}+'#comments'" th:text="${navIndex}"></a>
                                </li>
                            </th:block>
                        </th:block>
                        <!-- 判断并展示下一页 -->
                        <th:block th:if="${comments.hasNextPage}">
                            <li class="next"><a th:href="'?cp='+${comments.nextPage}+'#comments'">下一页</a></li>
                        </th:block>
                    </ol>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<div th:replace="comm/tale_comment::tale_comment"></div>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:fragment="tale_comment" >
<body>
<script type="text/javascript">
    /*<![CDATA[*/
    (function () {
        window.TaleComment = {
            subComment: function () {
                    $.ajax({
                    type: 'post',
                    url: '/admin/publish',
                    data: $('#comment-form').serialize(),
                    async: false,
                    dataType: 'json',
                    success: function (result) {
                        if (result && result.success) {
                            window.alert("评论提交成功!");
                            window.location.reload();
                        } else {
                            window.alert("发送失败")
                            if (result.msg) {
                                alert(result.msg);
                            }
                        }
                    }
                });
                return false;
            }
        };
    })();
</script>
</body>
</html>

这样就完成了,小萌新希望可以帮到大家 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值