仿牛客网社区项目(二十七)发送系统通知

触发事件

  • 触发事件
    • 评论后,发布通知
    • 点赞后,发布通知
    • 关注后,发布通知
  • 处理事件
    • 封装事件对象
    • 开发事件的生产者
    • 开发事件的消费者
  1. 创建对象实体
public class Event {
	//事件类型
    private String topic;
  	//消息发送方Id,1为管理消息
    private int userId;
    //实体类型,点赞,评论,关注
    private int entityType;
    //对应的实体id
    private int entityId;
    //接收方Id
    private int entityUserId;
    private Map<String, Object> data = new HashMap<>();

    public String getTopic() {
        return topic;
    }
	//链式编程
    public Event setTopic(String topic) {
        this.topic = topic;
        return this;
    }

    public int getUserId() {
        return userId;
    }

    public Event setUserId(int userId) {
        this.userId = userId;
        return this;
    }

    public int getEntityType() {
        return entityType;
    }

    public Event setEntityType(int entityType) {
        this.entityType = entityType;
        return this;
    }

    public int getEntityId() {
        return entityId;
    }

    public Event setEntityId(int entityId) {
        this.entityId = entityId;
        return this;
    }

    public int getEntityUserId() {
        return entityUserId;
    }

    public Event setEntityUserId(int entityUserId) {
        this.entityUserId = entityUserId;
        return this;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public Event setData(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

}

  1. 创建生产者,也就是队列消息的发送端
@Component
public class EventProduce {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    //传递User对象将其转换为Json,接收方再转回object,使用序列号也可以,自行尝试
    public void send(Event event){
        rabbitTemplate.convertAndSend("X",event.getTopic(), JSONObject.toJSONString(event));
    }
}
  1. 创建消费者,也就是消息的处理者
@Slf4j
@Component
public class EventConsumer implements CommunityConstant {
    @Autowired
    private MessageService messageService;
    //三种类型消息,分别处理
    //follow队列
    @RabbitListener(queues = "QA")
    public void receiveLike(String jsonString, Channel channel){
      if(  jsonString==null||jsonString.length()==0){
          log.error("消息为空");
      }
        Event event = JSONObject.parseObject(jsonString, Event.class);
      if (event==null){
          log.error("类型转换失败");
      }
    sendMessage(event);
    }
    //comment队列
    @RabbitListener(queues = "QB")
    public void receiveComment(String jsonString, Channel channel){
        if(  jsonString==null||jsonString.length()==0){
            log.error("消息为空");
        }
        Event event = JSONObject.parseObject(jsonString, Event.class);
        if (event==null){
            log.error("类型转换失败");
        }
        sendMessage(event);

    }
    //like 队列
    @RabbitListener(queues = "QC")
    public void receiveFollow(String jsonString, Channel channel){
        if(  jsonString==null||jsonString.length()==0){
            log.error("消息为空");
        }
        Event event = JSONObject.parseObject(jsonString, Event.class);
        if (event==null){
            log.error("类型转换失败");
        }
        sendMessage(event);
    }

    public void sendMessage(Event event){
    // 发送站内通知
    Message message = new Message();
        message.setFromId(SYSTEM_USER_ID);
        message.setToId(event.getEntityUserId());
        message.setConversationId(event.getTopic());
        message.setCreateTime(new Date());

    Map<String, Object> content = new HashMap<>();
        content.put("userId", event.getUserId());
        content.put("entityType", event.getEntityType());
        content.put("entityId", event.getEntityId());

        if (!event.getData().isEmpty()) {
        for (Map.Entry<String, Object> entry : event.getData().entrySet()) {
            content.put(entry.getKey(), entry.getValue());
        }
    }
        message.setContent(JSONObject.toJSONString(content));
        messageService.addMessage(message);
}
  1. 更新一些静态变量在CommunityConstant中
 	/**
     * 主题: 评论
     */
    String TOPIC_COMMENT = "comment";

    /**
     * 主题: 点赞
     */
    String TOPIC_LIKE = "like";

    /**
     * 主题: 关注
     */
    String TOPIC_FOLLOW = "follow";

​ 1.CommentController 更新Controller层,我们要对关注、点赞、评论 三个业务层去修改方法,在其中增加事件

 ```java	
  @RequestMapping(path = "/add/{discussPostId}", method = RequestMethod.POST)
     public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment) {
         comment.setUserId(hostHolder.getUser().getId());
         comment.setStatus(0);
         comment.setCreateTime(new Date());
         commentService.addComment(comment);
 
         // 触发评论事件
         Event event = new Event()
                 .setTopic(TOPIC_COMMENT)
                 .setUserId(hostHolder.getUser().getId())
                 .setEntityType(comment.getEntityType())
                 .setEntityId(comment.getEntityId())
                 .setData("postId", discussPostId);
         if (comment.getEntityType() == ENTITY_TYPE_POST) {
             DiscussPost target = discussPostService.getDiscussPostById(comment.getEntityId());
             event.setEntityUserId(target.getUserId());
         } else if (comment.getEntityType() == ENTITY_TYPE_COMMENT) {
             Comment target = commentService.findCommentById(comment.getEntityId());
             event.setEntityUserId(target.getUserId());
         }
         eventProduce.send(event);
 
         return "redirect:/discuss/detail/" + discussPostId;
     }
 
 ```

​ 2.LikeController

 @RequestMapping(path = "/like", method = RequestMethod.POST)
    @ResponseBody
    //此处未限制未登录点赞,会抛异常 可以采用之前的全局异常注解,后期会对代码重构 增加SpringSecurity框架权限控制
    public String like(int entityType, int entityId, int entityUserId,int postId) {
        User user = hostHolder.getUser();

        // 点赞
        likeService.like(user.getId(), entityType, entityId, entityUserId);

        // 数量
        long likeCount = likeService.findEntityLikeCount(entityType, entityId);
        // 状态
        int likeStatus = likeService.findEntityLikeStatus(user.getId(), entityType, entityId);
        // 返回的结果
        Map<String, Object> map = new HashMap<>();
        map.put("likeCount", likeCount);
        map.put("likeStatus", likeStatus);
        // 触发点赞事件
        if (likeStatus == 1) {
            Event event = new Event()
                    .setTopic(TOPIC_LIKE)
                    .setUserId(hostHolder.getUser().getId())
                    .setEntityType(entityType)
                    .setEntityId(entityId)
                    .setEntityUserId(entityUserId)
                    .setData("postId", postId);
            eventProduce.send(event);
        }

        return CommunityUtil.getJSONString(0, null, map);
    }

​ 3.FollowController


    @RequestMapping(path = "/follow", method = RequestMethod.POST)
    @ResponseBody
    public String follow(int entityType, int entityId) {
        User user = hostHolder.getUser();

        followService.follow(user.getId(), entityType, entityId);
        // 触发关注事件
        Event event = new Event()
                .setTopic(TOPIC_FOLLOW)
                .setUserId(hostHolder.getUser().getId())
                .setEntityType(entityType)
                .setEntityId(entityId)
                .setEntityUserId(entityId);
        eventProduce.send(event);

        return CommunityUtil.getJSONString(0, "已关注!");
    }
  1. 由于like事件触发时是对帖子,所以缺少一个PostId,所以我们在前端传参时需要传入PostId,在页面添加一下即可,js也要修改噢

    以后的笔记中就不更新静态资源类 ,自取即可,写出来意义不大,浪费时间

posted @   卷皇  阅读(379)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
点击右上角即可分享
微信分享提示
主题色彩