1、调整关注/取消关注项目接口的逻辑

This commit is contained in:
2026-02-13 11:34:20 +08:00
parent 3ec6cfda91
commit cd6a3fc312
4 changed files with 23 additions and 100 deletions

View File

@@ -424,14 +424,14 @@ public class SimulationNodeController implements ISimulationNodeFeignClient {
@PostMapping("/followProject")
@Operation(summary = "关注项目", description = "关注项目")
public SdmResponse followProject(@RequestBody SpdmProjectFollowReq req) {
return nodeService.followProject(req.getNodeId(), req.getUserIdList());
return nodeService.followProject(req.getNodeId());
}
@SysLog("取消关注项目")
@PostMapping("/unFollowProject")
@Operation(summary = "关注项目", description = "关注项目")
public SdmResponse unFollowProject(@RequestBody SpdmProjectFollowReq req) {
return nodeService.unFollowProject(req.getNodeId(), req.getUserIdList());
return nodeService.unFollowProject(req.getNodeId());
}

View File

@@ -13,9 +13,4 @@ public class SpdmProjectFollowReq extends BaseEntity {
*/
private String nodeId;
/**
* 关注项目的用户id集合
*/
List<Long> userIdList;
}

View File

@@ -96,18 +96,16 @@ public interface INodeService extends IService<SimulationNode> {
* 关注项目(批量为多个用户添加项目关注关系)
*
* @param nodeId 项目节点IDuuid
* @param userIdList 要关注项目的用户ID列表
* @return 统一响应结果
*/
SdmResponse followProject(String nodeId, List<Long> userIdList);
SdmResponse followProject(String nodeId);
/**
* 取消关注项目(批量为多个用户删除项目关注关系)
*
* @param nodeId 项目节点IDuuid
* @param userIdList 要关注项目的用户ID列表
* @return 统一响应结果
*/
SdmResponse unFollowProject(String nodeId, List<Long> userIdList);
SdmResponse unFollowProject(String nodeId);
}

View File

@@ -175,7 +175,6 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
};
// 常量定义:提示文案
private static final String PARAM_ERROR_MSG = "参数不正确";
private static final String FOLLOW_PROJECT_NOT_FOUND_MSG = "关注项目失败,原因为:未查询到项目";
private static final String FOLLOW_SAVE_FAIL_MSG = "批量保存关注关系失败";
private static final String PARTIAL_FOLLOW_SUCCESS_MSG = "部分用户关注成功(部分用户已关注)";
@@ -4014,18 +4013,12 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
* 幂等性保障:先查询已关注记录,避免重复插入
*
* @param nodeId 项目节点IDuuid
* @param userIdList 要关注项目的用户ID列表
* @return 统一响应结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse followProject(String nodeId, List<Long> userIdList) {
// 1. 参数校验
if (StringUtils.isEmpty(nodeId) || CollectionUtils.isEmpty(userIdList)) {
log.warn("关注项目参数异常nodeId{}userIdList{}", nodeId, userIdList);
return SdmResponse.failed(PARAM_ERROR_MSG);
}
// 2. 查询项目节点是否存在
public SdmResponse followProject(String nodeId) {
// 1. 查询项目节点是否存在
SimulationNode projectNode = this.lambdaQuery()
.eq(SimulationNode::getUuid, nodeId)
.one();
@@ -4034,38 +4027,31 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
return SdmResponse.failed(FOLLOW_PROJECT_NOT_FOUND_MSG);
}
// 3. 过滤无效用户IDnull/负数)
List<Long> validUserIdList = userIdList.stream()
.filter(userId -> userId != null && userId > 0)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(validUserIdList)) {
log.info("无有效用户ID需要关注项目nodeId{}", nodeId);
return SdmResponse.success();
}
List<Long> validUserIdList = Collections.singletonList(ThreadLocalContext.getUserId());
// 4. 校验幂等性,防止重复关注
// 2. 校验幂等性,防止重复关注
Set<Long> existedFollowedUserIdSet = queryExistedFollowedUserIds(nodeId, validUserIdList);
// 5. 过滤出未关注的用户ID
// 3. 过滤出未关注的用户ID
List<Long> toFollowUserIdList = validUserIdList.stream()
.filter(userId -> !existedFollowedUserIdSet.contains(userId))
.collect(Collectors.toList());
// 6. 处理已全部关注的情况
// 4. 处理已全部关注的情况
if (CollectionUtils.isEmpty(toFollowUserIdList)) {
log.info("所有用户均已关注项目nodeId{},用户列表:{}", nodeId, validUserIdList);
return SdmResponse.success(ALL_FOLLOWED_MSG);
}
// 7. 记录重复关注的用户
// 5. 记录重复关注的用户
List<Long> repeatedUserIdList = validUserIdList.stream()
.filter(existedFollowedUserIdSet::contains)
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(repeatedUserIdList)) {
if (CollectionUtils.isNotEmpty(repeatedUserIdList)) {
log.error("部分用户已关注项目跳过重复关注nodeId{}重复用户ID{}", nodeId, repeatedUserIdList);
}
// 8. 构建批量插入的关注关系列表(仅处理未关注用户)
// 6. 构建批量插入的关注关系列表(仅处理未关注用户)
LocalDateTime currentTime = LocalDateTime.now();
Long currentUserId = ThreadLocalContext.getUserId();
List<SimulationNodeMember> attentionList = new ArrayList<>(toFollowUserIdList.size());
@@ -4080,7 +4066,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
attentionList.add(member);
}
// 9. 批量保存未关注的用户关系
// 7. 批量保存未关注的用户关系
try {
boolean saveResult = simulationNodeMemberService.saveBatch(attentionList);
if (!saveResult) {
@@ -4092,9 +4078,8 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
return SdmResponse.failed("关注项目失败:" + e.getMessage());
}
// 10. 返回结果(区分“全部成功”和“部分成功”)
// 8. 返回结果(区分“全部成功”和“部分成功”)
String successMsg = CollectionUtils.isEmpty(repeatedUserIdList) ? "项目关注成功" : PARTIAL_FOLLOW_SUCCESS_MSG;
log.info("项目关注处理完成nodeId{},成功关注用户数:{},重复关注用户数:{}", nodeId, toFollowUserIdList.size(), repeatedUserIdList.size());
return SdmResponse.success(successMsg);
}
@@ -4102,40 +4087,29 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
* 取消关注项目(批量为多个用户删除项目关注关系)
*
* @param nodeId 项目节点IDuuid
* @param userIdList 要取消关注的用户ID列表
* @return 统一响应结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse unFollowProject(String nodeId, List<Long> userIdList) {
// 1. 参数校验
if (StringUtils.isEmpty(nodeId) || CollectionUtils.isEmpty(userIdList)) {
log.warn("取消关注项目参数异常nodeId{}userIdList{}", nodeId, userIdList);
return SdmResponse.failed(PARAM_ERROR_MSG);
}
// 2. 校验项目是否存在
public SdmResponse unFollowProject(String nodeId) {
// 1. 校验项目是否存在
SimulationNode projectNode = this.lambdaQuery().eq(SimulationNode::getUuid, nodeId).one();
if (projectNode == null) {
log.error("取消关注项目失败根据nodeId{} 未查询到项目节点", nodeId);
return SdmResponse.failed(UN_FOLLOW_PROJECT_NOT_FOUND_MSG);
}
// 3. 过滤无效用户IDnull/负数避免无效SQL条件
List<Long> validUserIdList = userIdList.stream().filter(userId -> userId != null && userId > 0).collect(Collectors.toList());
if (CollectionUtils.isEmpty(validUserIdList)) {
log.info("取消关注项目无有效用户IDnodeId{}", nodeId);
return SdmResponse.success(NO_UNFOLLOW_DATA_MSG);
}
List<Long> validUserIdList = Collections.singletonList(ThreadLocalContext.getUserId());
// 4. 幂等性核心:先查询已存在的关注关系(仅查询需要删除的记录)
// 2. 幂等:先查询已存在的关注关系(仅查询需要删除的记录)
Set<Long> existedFollowedUserIdSet = queryExistedFollowedUserIds(nodeId, validUserIdList);
if (CollectionUtils.isEmpty(existedFollowedUserIdSet)) {
log.info("取消关注项目失败无已关注的用户记录nodeId{},用户列表:{}", nodeId, validUserIdList);
return SdmResponse.success(NO_UNFOLLOW_DATA_MSG);
}
// 5. 仅删除已存在的关注关系(避免无效删除操作)
// 3. 仅删除已存在的关注关系(避免无效删除操作)
try {
LambdaUpdateWrapper<SimulationNodeMember> updateWrapper = new LambdaUpdateWrapper<SimulationNodeMember>()
.eq(SimulationNodeMember::getNodeId, nodeId)
@@ -4149,25 +4123,10 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
return SdmResponse.failed(UNFOLLOW_DELETE_FAIL_MSG);
}
// 6. 返回结果
// 4. 返回结果
return SdmResponse.success(UNFOLLOW_SUCCESS_MSG);
}
// @Override
// public SdmResponse unFollowProject(String nodeId, List<Long> userIdList) {
// if (StringUtils.isBlank(nodeId) || CollectionUtils.isEmpty(userIdList)) {
// return SdmResponse.failed("参数不正确");
// }
// SimulationNode projectNode = this.lambdaQuery().eq(SimulationNode::getUuid, nodeId).one();
// if (ObjectUtils.isEmpty(projectNode)) {
// log.error("followProject根据nodeId{},未查询到项目", nodeId);
// return SdmResponse.failed("取消关注项目失败,原因为:未查询到项目");
// }
// simulationNodeMemberService.lambdaUpdate().eq(SimulationNodeMember::getNodeId,nodeId).in(SimulationNodeMember::getUserId,userIdList).remove();
// return SdmResponse.success();
// }
/**
* 批量查询已关注指定项目的用户ID
*
@@ -4194,35 +4153,6 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
.collect(Collectors.toSet());
}
// @Override
// public SdmResponse followProject(String nodeId, List<Long> userIdList) {
// if (StringUtils.isBlank(nodeId) || CollectionUtils.isEmpty(userIdList)) {
// return SdmResponse.failed("参数不正确");
// }
// SimulationNode projectNode = this.lambdaQuery().eq(SimulationNode::getUuid, nodeId).one();
// if (ObjectUtils.isEmpty(projectNode)) {
// log.error("followProject根据nodeId{},未查询到项目", nodeId);
// return SdmResponse.failed("关注项目失败,原因为:未查询到项目");
// }
// if (CollectionUtils.isNotEmpty(userIdList)) {
// List<SimulationNodeMember> attentionList = new ArrayList<>();
// String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// Long jobNumber = ThreadLocalContext.getUserId();
// // 关注
// for (Long userId : userIdList) {
// SimulationNodeMember simulationNodeMember = new SimulationNodeMember();
// simulationNodeMember.setNodeId(nodeId);
// simulationNodeMember.setUserId(userId);
// simulationNodeMember.setType(NodeMemberTypeEnum.ATTENTION.getCode());
// simulationNodeMember.setCreateTime(curDateStr);
// simulationNodeMember.setCreator(jobNumber);
// attentionList.add(simulationNodeMember);
// }
// simulationNodeMemberService.saveBatch(attentionList);
// }
// return SdmResponse.success();
// }
/**
* 通用分组统计方法 - 按指定键分组统计状态数量
*