评论功能
效果展示
dao层
@Mapper
public interface CommentMapper {
// 分页展示某个文章的评论
@Select("SELECT * FROM t_comment WHERE article_id=#{aid} ORDER BY id DESC")
public List<Comment> selectCommentWithPage(Integer aid);
// 后台查询最新几条评论
@Select("SELECT * FROM t_comment ORDER BY id DESC")
public List<Comment> selectNewComment();
// 发表评论
@Insert("INSERT INTO t_comment (article_id,created,author,ip,content)" +
" VALUES (#{articleId}, #{created},#{author},#{ip},#{content})")
public void pushComment(Comment comment);
// 站点服务统计,统计评论数量
@Select("SELECT COUNT(1) FROM t_comment")
public Integer countComment();
// 通过文章id删除评论信息
@Delete("DELETE FROM t_comment WHERE id=#{aid}")
int deleteCommentWithId(Integer aid);
//通过id更新评论
@Update("update t_comment SET content = #{content} where id=#{id}")
int update(int id,String content);
//根据id查询评论
@Select("SELECT * FROM t_comment WHERE id=#{id}")
Comment selectId(Integer id);
}
Service层
在ICommentService编写文章评论的方法
public interface ICommentService {
//用户发表评论
public void pushComment(Comment comment);
}
编写Service层实现接口类方法
public class CommentServiceImpl implements ICommentService {
@Autowired
private CommentMapper commentMapper;
@Autowired
private StatisticMapper statisticMapper;
@Autowired
private RedisTemplate redisTemplate;
//用户发表评论
@Override
public void pushComment(Comment comment) {
commentMapper.pushComment(comment);
//更新文章评论数据量
Statistic statistic =
statisticMapper.selectStatisticWithArticleId(comment.getArticleId());
statistic.setCommentsNum(statistic.getCommentsNum() + 1);
statisticMapper.updateArticleCommentsWithId(statistic);
}
处理层
@Controller
@RequestMapping("/comments")
public class CommentController {
private static final Logger logger = LoggerFactory.getLogger(CommentController.class);
@Autowired
private ICommentService commentServiceImpl;
// 发表评论操作
@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 {
commentServiceImpl.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" οnsubmit="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" οnclick=""> <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"> 回复 </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>