10-5-发表评论

一、业务处理层实现

1、在ICommentService接口增加用户发表评论的方法

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

2、实现该方法

    @Autowired
    private StatisticMapper statisticMapper;

     // 用户发表评论
    @Override
    public void pushComment(Comment comment){
        commentMapper.pushComment(comment);
        // 更新文章评论数据量
        Statistic statistic = statisticMapper.selectStatisticWithArticleId(comment.getArticleId());
        statistic.setCommentsNum(statistic.getCommentsNum()+1);
        statisticMapper.updateArticleCommentsWithId(statistic);
    }

二、请求处理层实现

        创建一个控制类CommentController,编写一个处理“/comments/publish”请求的方法。

该方法对用户评论信息进行了获取和封装,然后进行插入操作,最后根据执行结果向原页面返回状态信息。 

@Controller
@RequestMapping("/comments")
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();
        }
    }
}

三、实现前端页面功能

在文章详情展示页面articleDetails.html中展示了文章的评论页面位置为client/comments::comments,在client文件夹下的comments.html文件进行具体的评论展示和发布实现。

comments.html

<!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="5" maxlength="2000"></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>

注:

使用sec:*和th:*属性进行评论框管理控制以及评论列表获取展示。在评论发布框控制中,只有登录用户才可以查看到评论框并发布评论。在评论发布的<form>表单中特别添加了一个用于CSRF防御时进行CSRF Token认证的隐藏域“<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>”

在页面底部<div th:replace="comm/tale_comment::tale_comment"></div>的作用是将该标签替换为tale_comment.html的内容,该内容的作用是响应评论页面中的表单的οnsubmit="return TaleComment.subComment();"

tale_comment.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: '/comments/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>

四、效果展示

启动项目进行测试,登录并进入到某个文章详情页面,在文章底部的评论框中发布评论进行效果测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值