feat(relation): 实现用户关注功能并集成RocketMQ消息队列
- 新增关注用户MQ消息传输对象 FollowUserMqDTO - 定义MQ常量类 MQConstants,包含关注/取关主题与标签 - 引入RocketMQ依赖及自动配置类 RocketMQConfig - 在关注接口中构造并异步发送关注操作消息 - 使用JsonUtils将消息体序列化为JSON字符串 - 添加日志记录MQ发送状态及异常处理回调
This commit is contained in:
@@ -96,6 +96,11 @@
|
|||||||
<artifactId>han-note-user-api</artifactId>
|
<artifactId>han-note-user-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Rocket MQ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.rocketmq</groupId>
|
||||||
|
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.hanserwei.hannote.user.relation.biz.config;
|
||||||
|
|
||||||
|
import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Import(RocketMQAutoConfiguration.class)
|
||||||
|
public class RocketMQConfig {
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.hanserwei.hannote.user.relation.biz.constant;
|
||||||
|
|
||||||
|
public interface MQConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Topic: 关注、取关共用一个
|
||||||
|
*/
|
||||||
|
String TOPIC_FOLLOW_OR_UNFOLLOW = "FollowUnfollowTopic";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关注标签
|
||||||
|
*/
|
||||||
|
String TAG_FOLLOW = "Follow";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取关标签
|
||||||
|
*/
|
||||||
|
String TAG_UNFOLLOW = "Unfollow";
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.hanserwei.hannote.user.relation.biz.model.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class FollowUserMqDTO {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private Long followUserId;
|
||||||
|
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
@@ -6,11 +6,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder;
|
import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder;
|
||||||
import com.hanserwei.framework.common.exception.ApiException;
|
import com.hanserwei.framework.common.exception.ApiException;
|
||||||
import com.hanserwei.framework.common.response.Response;
|
import com.hanserwei.framework.common.response.Response;
|
||||||
|
import com.hanserwei.framework.common.utils.JsonUtils;
|
||||||
import com.hanserwei.hannote.user.dto.resp.FindUserByIdRspDTO;
|
import com.hanserwei.hannote.user.dto.resp.FindUserByIdRspDTO;
|
||||||
|
import com.hanserwei.hannote.user.relation.biz.constant.MQConstants;
|
||||||
import com.hanserwei.hannote.user.relation.biz.constant.RedisKeyConstants;
|
import com.hanserwei.hannote.user.relation.biz.constant.RedisKeyConstants;
|
||||||
import com.hanserwei.hannote.user.relation.biz.domain.dataobject.FollowingDO;
|
import com.hanserwei.hannote.user.relation.biz.domain.dataobject.FollowingDO;
|
||||||
import com.hanserwei.hannote.user.relation.biz.enums.LuaResultEnum;
|
import com.hanserwei.hannote.user.relation.biz.enums.LuaResultEnum;
|
||||||
import com.hanserwei.hannote.user.relation.biz.enums.ResponseCodeEnum;
|
import com.hanserwei.hannote.user.relation.biz.enums.ResponseCodeEnum;
|
||||||
|
import com.hanserwei.hannote.user.relation.biz.model.dto.FollowUserMqDTO;
|
||||||
import com.hanserwei.hannote.user.relation.biz.model.vo.FollowUserReqVO;
|
import com.hanserwei.hannote.user.relation.biz.model.vo.FollowUserReqVO;
|
||||||
import com.hanserwei.hannote.user.relation.biz.rpc.UserRpcService;
|
import com.hanserwei.hannote.user.relation.biz.rpc.UserRpcService;
|
||||||
import com.hanserwei.hannote.user.relation.biz.service.FollowingDOService;
|
import com.hanserwei.hannote.user.relation.biz.service.FollowingDOService;
|
||||||
@@ -18,9 +21,14 @@ import com.hanserwei.hannote.user.relation.biz.service.RelationService;
|
|||||||
import com.hanserwei.hannote.user.relation.biz.util.DateUtils;
|
import com.hanserwei.hannote.user.relation.biz.util.DateUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.rocketmq.client.producer.SendCallback;
|
||||||
|
import org.apache.rocketmq.client.producer.SendResult;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
|
import org.springframework.messaging.support.MessageBuilder;
|
||||||
import org.springframework.scripting.support.ResourceScriptSource;
|
import org.springframework.scripting.support.ResourceScriptSource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -39,6 +47,8 @@ public class RelationServiceImpl implements RelationService {
|
|||||||
private RedisTemplate<Object, Object> redisTemplate;
|
private RedisTemplate<Object, Object> redisTemplate;
|
||||||
@Resource
|
@Resource
|
||||||
private FollowingDOService followingDOService;
|
private FollowingDOService followingDOService;
|
||||||
|
@Resource
|
||||||
|
private RocketMQTemplate rocketMQTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response<?> follow(FollowUserReqVO followUserReqVO) {
|
public Response<?> follow(FollowUserReqVO followUserReqVO) {
|
||||||
@@ -118,7 +128,36 @@ public class RelationServiceImpl implements RelationService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 发送 MQ
|
// 发送 MQ
|
||||||
|
// 构造消息体DTO
|
||||||
|
FollowUserMqDTO followUserMqDTO = FollowUserMqDTO.builder()
|
||||||
|
.userId(userId)
|
||||||
|
.followUserId(followUserId)
|
||||||
|
.createTime(now)
|
||||||
|
.build();
|
||||||
|
// 构造消息对象,并把DTO转换为JSON字符串设置到消息体中
|
||||||
|
Message<String> message = MessageBuilder
|
||||||
|
.withPayload(JsonUtils.toJsonString(followUserMqDTO))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 通过冒号连接, 可让 MQ 发送给主题 Topic 时,携带上标签 Tag
|
||||||
|
String destination = MQConstants.TOPIC_FOLLOW_OR_UNFOLLOW + ":" + MQConstants.TAG_FOLLOW;
|
||||||
|
|
||||||
|
log.info("==> 开始发送关注操作 MQ, 消息体: {}", followUserMqDTO);
|
||||||
|
|
||||||
|
// 异步发送MQ消息,提升接口响应速度
|
||||||
|
rocketMQTemplate.asyncSend(destination, message, new SendCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(SendResult sendResult) {
|
||||||
|
log.info("==> MQ 发送成功,SendResult: {}", sendResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onException(Throwable throwable) {
|
||||||
|
log.error("==> MQ 发送异常: ", throwable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return Response.success();
|
return Response.success();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user