feat(relation): 实现用户关注功能
- 新增关注用户接口,支持通过用户ID关注其他用户 - 添加参数校验,确保被关注用户ID不为空 - 实现关注用户时的业务逻辑,包括: -不能关注自己 - 校验被关注用户是否存 - 集成Feign客户端,调用用户服务查询用户信息 - 定义关注相关的异常码和错误信息 - 更新网关配置,路由/relation/**请求到用户关系服务- 添加HTTP客户端测试用例,用于验证关注功能 - 引入用户API依赖,支持远程调用用户服务
This commit is contained in:
@@ -91,6 +91,12 @@
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.hanserwei</groupId>
|
||||
<artifactId>han-note-user-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.hanserwei.hannote.user.relation.biz;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.hanserwei.hannote.user.relation.biz.domain.mapper")
|
||||
@EnableFeignClients(basePackages = "com.hanserwei.hannote")
|
||||
public class HannoteUserRelationBizApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(HannoteUserRelationBizApplication.class, args);
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.hanserwei.hannote.user.relation.biz.controller;
|
||||
|
||||
import com.hanserwei.framework.biz.operationlog.aspect.ApiOperationLog;
|
||||
import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.user.relation.biz.model.vo.FollowUserReqVO;
|
||||
import com.hanserwei.hannote.user.relation.biz.service.RelationService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/relation")
|
||||
@Slf4j
|
||||
public class RelationController {
|
||||
|
||||
@Resource
|
||||
private RelationService relationService;
|
||||
|
||||
@PostMapping("/follow")
|
||||
@ApiOperationLog(description = "关注用户")
|
||||
public Response<?> follow(@Validated @RequestBody FollowUserReqVO followUserReqVO) {
|
||||
return relationService.follow(followUserReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,8 @@ public enum ResponseCodeEnum implements BaseExceptionInterface {
|
||||
PARAM_NOT_VALID("RELATION-10001", "参数错误"),
|
||||
|
||||
// ----------- 业务异常状态码 -----------
|
||||
CANT_FOLLOW_YOUR_SELF("RELATION-20001", "无法关注自己"),
|
||||
FOLLOW_USER_NOT_EXISTED("RELATION-20002", "关注的用户不存在"),
|
||||
;
|
||||
|
||||
// 异常码
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hanserwei.hannote.user.relation.biz.model.vo;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class FollowUserReqVO {
|
||||
|
||||
@NotNull(message = "被关注用户 ID 不能为空")
|
||||
private Long followUserId;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.hanserwei.hannote.user.relation.biz.rpc;
|
||||
|
||||
import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.user.api.UserFeignApi;
|
||||
import com.hanserwei.hannote.user.dto.req.FindUserByIdReqDTO;
|
||||
import com.hanserwei.hannote.user.dto.resp.FindUserByIdRspDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Component
|
||||
public class UserRpcService {
|
||||
|
||||
@Resource
|
||||
private UserFeignApi userFeignApi;
|
||||
|
||||
/**
|
||||
* 根据用户 ID 查询
|
||||
*
|
||||
* @param userId 用户 ID
|
||||
* @return 用户信息
|
||||
*/
|
||||
public FindUserByIdRspDTO findById(Long userId) {
|
||||
FindUserByIdReqDTO findUserByIdReqDTO = new FindUserByIdReqDTO();
|
||||
findUserByIdReqDTO.setId(userId);
|
||||
|
||||
Response<FindUserByIdRspDTO> response = userFeignApi.findById(findUserByIdReqDTO);
|
||||
|
||||
if (!response.isSuccess() || Objects.isNull(response.getData())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return response.getData();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.hanserwei.hannote.user.relation.biz.service;
|
||||
|
||||
import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.user.relation.biz.model.vo.FollowUserReqVO;
|
||||
|
||||
public interface RelationService {
|
||||
|
||||
/**
|
||||
* 关注用户
|
||||
*
|
||||
* @param followUserReqVO 关注用户请求
|
||||
* @return 响应
|
||||
*/
|
||||
Response<?> follow(FollowUserReqVO followUserReqVO);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.hanserwei.hannote.user.relation.biz.service.impl;
|
||||
|
||||
import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder;
|
||||
import com.hanserwei.framework.common.exception.ApiException;
|
||||
import com.hanserwei.framework.common.response.Response;
|
||||
import com.hanserwei.hannote.user.dto.resp.FindUserByIdRspDTO;
|
||||
import com.hanserwei.hannote.user.relation.biz.enums.ResponseCodeEnum;
|
||||
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.service.RelationService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class RelationServiceImpl implements RelationService {
|
||||
|
||||
@Resource
|
||||
private UserRpcService userRpcService;
|
||||
|
||||
@Override
|
||||
public Response<?> follow(FollowUserReqVO followUserReqVO) {
|
||||
// 获取被关注用户 ID
|
||||
Long followUserId = followUserReqVO.getFollowUserId();
|
||||
|
||||
// 获取当前登录用户 ID
|
||||
Long userId = LoginUserContextHolder.getUserId();
|
||||
if (Objects.equals(userId, followUserId)) {
|
||||
throw new ApiException(ResponseCodeEnum.CANT_FOLLOW_YOUR_SELF);
|
||||
}
|
||||
// 校验关注的用户是否存在
|
||||
FindUserByIdRspDTO findUserByIdRspDTO = userRpcService.findById(followUserId);
|
||||
if (Objects.isNull(findUserByIdRspDTO)){
|
||||
throw new ApiException(ResponseCodeEnum.FOLLOW_USER_NOT_EXISTED);
|
||||
}
|
||||
|
||||
// TODO: 校验关注数是否已经达到上限
|
||||
|
||||
// TODO: 写入 Redis ZSET 关注列表
|
||||
|
||||
// TODO: 发送 MQ
|
||||
|
||||
return Response.success();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user