仿牛客社区项目笔记-帖子模块(核心)

仿牛客社区项目笔记-帖子模块(核心)

  • 1. 帖子模块
    • 1.1 过滤敏感词
    • 1.2 发布帖子
    • 1.3 帖子详情
    • 1.4 显示评论
    • 1.5 添加评论
    • 1.6 私信列表
    • 1.7 发送私信

1. 帖子模块

分为 过滤敏感词,发布帖子,帖子详情,显示评论,添加评论,私信列表,发送私信。

1.1 过滤敏感词

位于 util 包下的 SensitiveFilter 。 略

1.2 发布帖子

使用 Ajax 在 index 页面发送异步请求(局部刷新)。在 Controller 层返回 Json 数据显示。

  1. 前提用户已经登录,否则不显示 “我要发布” 按钮。(通过hostHolder中的 loginUser 是否为空判断)
  2. 在首页点击 “我要发布”,填写标题和正文,映射到DiscussPostController(/discuss)层的 /add 路径。新建 DiscussPost 类,通过 hostHolder 的 User 设置 id,设置 title,content,createTime。其余默认为0。使用 discussPostService.addDiscussPost(post) 方法将其插入数据库。
  3. discussPostService.addDiscussPost 方法将post 中的 title,content 转义HTML标记和过滤敏感词。然后调用 discussPostMapper.insertDiscussPost(post) 存入数据。
		// 转义HTML标记
        post.setTitle(HtmlUtils.htmlEscape(post.getTitle()));
        post.setContent(HtmlUtils.htmlEscape(post.getContent()));
        // 过滤敏感词
        post.setTitle(sensitiveFilter.filter(post.getTitle()));
        post.setContent(sensitiveFilter.filter(post.getContent()));
  1. 触发发帖事件,构造 Topic 为 TOPIC_PUBLISH 的 Event,需要设置userId,EntityType,EntityId。然后使用 eventProducer.fireEvent 开始生产。(更新Elasticsearch 服务器中的帖子)
  2. 返回发布成功 Json 信息,异步显示,并刷新网页。
$(function(){
	$("#publishBtn").click(publish);
});

function publish() {
	$("#publishModal").modal("hide");

	// 获取标题和内容
	var title = $("#recipient-name").val();
	var content = $("#message-text").val();
	// 发送异步请求(POST)
	$.post(
	    CONTEXT_PATH + "/discuss/add",
	    {"title":title,"content":content},
	    function(data) {
	        data = $.parseJSON(data);
	        // 在提示框中显示返回消息
	        $("#hintBody").text(data.msg);
	        // 显示提示框
            $("#hintModal").modal("show");
            // 2秒后,自动隐藏提示框
            setTimeout(function(){
                $("#hintModal").modal("hide");
                // 刷新页面
                if(data.code == 0) {
                    window.location.reload();
                }
            }, 2000);
	    }
	);

}

1.3 帖子详情

  1. 在 index 页面点击帖子,映射到DiscussPostController(/discuss)层的 /detail/{discussPostId} 路径,并将帖子的 id 传入。
  2. 根据 id 利用 discussPostService.findDiscussPostById 方法查出 post。 根据 post.getUserId() 利用 userService.findUserById 方法查出 User。将 post,user 加入model。
  3. 新增将点赞数量和状态查询处理加入model。
  4. 返回 /site/discuss-detail 页面。在 /site/discuss-detail 页面显示帖子和发布帖子的用户信息。

1.4 显示评论

继1.3 帖子详情后显示帖子的评论。同样在 DiscussPostController(/discuss)层的 /detail/{discussPostId} 映射中。我们将 comment 表中的 entity_type 属性在 CommunityConstant 工具类中设置了两个常量:

    // 实体类型: 帖子
    int ENTITY_TYPE_POST = 1;
    
    // 实体类型: 评论
    int ENTITY_TYPE_COMMENT = 2;
  1. 首先设置评论分页信息。
  2. 根据该帖子的 id 和类型利用 commentService.findCommentsByEntity 方法查询所有评论。将该评论和该评论的作者(通过 comment 中的 userId 获取),点赞数量和该用户的点赞状态加入到Map中,同时还在该Map中嵌套插入一个包括该评论的所有回复,回复作者和回复目标(target),点赞数量和该用户的点赞状态的Map。再将回复数量插入Map。最后将每个评论的Map插入List,传入Model。
  3. 最后返回 /site/discuss-detail 页面。在页面中展示,其中分页模块复用 index::pagination。

1.5 添加评论

添加评论有三种方式:① 回帖,② 回复评论,③ 回复某人的评论。

  1. ① 在 discuss-detail 页面点击最下方的回帖,映射到 CommentController 层的 /add/{discussPostId}。传入了 entityType = 1 和 entityId = post.id 。
  2. ② 在评论下方回复,与①映射相同,传入entityType = 2 和 entityId = comment.id。
  3. ③ 对某人的评论回复,与①映射相同,传入entityType = 2 和 entityId = comment.id 和 targetId。
  4. 对传入的 comment 进一步设置userId,Status,CreateTime。然后调用commentService.addComment(comment) 方法插入数据库。
  5. commentService.addComment 使用了事务注解。该方法对 comment 的 content 进行转义HTML标记和过滤敏感词。然后使用 commentMapper.insertComment 插入评论。然后通过 commentMapper.selectCountByEntity 查询帖子的评论数量,再使用 discussPostService.updateCommentCount 方法将评论数量插入帖子详情表。
		// 更新帖子评论数量
        if (comment.getEntityType() == ENTITY_TYPE_POST) {
            int count = commentMapper.selectCountByEntity(comment.getEntityType(), comment.getEntityId());
            discussPostService.updateCommentCount(comment.getEntityId(), count);
        }
  1. 触发 Topic 为 TOPIC_COMMENT 的事件: 构建Event,设置当前登录用户id,被评论对象的type,被评论对象的id,被评论对象所在的帖子id(因为被评论的对象可能是帖子或者回复),被评论对象的用户id。然后调用 eventProducer 将 Event 发布到指定 Topic。
  2. 然后判断一下评论的是不是帖子,如果是则触发发帖事件。构造 Topic 为 TOPIC_PUBLISH 的 Event,需要设置userId,EntityType,EntityId。然后使用 eventProducer.fireEvent 开始生产。(更新Elasticsearch 服务器中的帖子)
  3. 重定向 return “redirect:/discuss/detail/” + discussPostId。 刷新帖子详情页面。

1.6 私信列表

两部分:① 点击消息进入会话列表,②点击某个会话进入私信详情页面。

  1. 在 index 点击消息,映射到 MessageController 层的 /letter/list 下。设置分页信息。

  2. 通过 messageService.findConversations 查询当前用户的会话列表, 针对每个会话只返回一条最新的私信。将每个会话装入Map, 并且使用 messageService.findLetterCount(message.getConversationId())) 方法查询会话的私信数量并装入Map。将会话的未读私信数量查出装入Map,并且将与用户对话的对方 User 装入Map。

  3. 把Map依次装入List,List装入Model。再将所有的未读消息数量查询出,装入Model,返回 /site/letter 。在页面中显示。

  4. 在私信列表点击私信内容,进入私信详情页面。映射到 MessageController 层的 /letter/detail/{conversationId}。设置分页信息。

  5. 通过 messageService.findLetters 方法返回与对方的全部私信。将私信和发送私信的用户 User 装入Map。将多个Map装入List。将List装入Model。将与当前用户对话的对方User装入Model。

  6. 放回 /site/letter-detail 页面,将数据在页面中显示。

1.7 发送私信

分为两部分:
一、① 在消息页面发私信 ,② 在与某人会话中给TA发私信。
二、将未读消息转为已读。(其实应该放置在 1.6 私信列表 )

  1. 在弹出框中填写发送对象和内容,点击发送。利用 letter.js 发送ajax异步请求。映射到 MessageController 层的 /letter/send 下。构造 message 对象,包括通过发送对象名称查询对象id,拼接 ConversationId。最后将 message 传递给 messageService.addMessage 方法。
  2. messageService.addMessage 方法将message 中的 content 进行转义HTML标记和过滤敏感词。然后插入数据库。MessageController 层中如果发送对象为空,返回 json 错误信息。否则返回 code=0。
  3. letter.js 接受到返回数据,显示信息并重新加载当前页面。②与① 功能实现都是调用的 letter.js。只不过在 ② 中弹出框中自动填入了发送对象名称。
  4. 接受私信的用户在打开私信详情页面时,未读消息就应该变成已读。在 MessageController 层的 /letter/detail/{conversationId} 路径下实现该功能。将私信列表传给 getLetterIds 函数,获得 id 列表。使用 messageService.readMessage 方法将 id 列表代表的 message 的 status 改为1。

你可能感兴趣的:(仿牛客社区项目笔记,java)