refactor(ops): 优化区域路径拼接方法 buildAreaPath
主要改进: - 使用 Stream API 替代传统循环,代码更简洁 - 区域路径增加 "/" 分隔符,格式更规范(如"园区/A栋/B层/电梯厅") - 改进异常处理和日志记录,提升可维护性 - 使用 Hutool StrUtil 替代 Apache Commons Lang - 提前返回策略,减少嵌套层级 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.viewsh.module.ops.environment.service.cleanorder;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.viewsh.module.ops.api.queue.OrderQueueDTO;
|
||||
import com.viewsh.module.ops.api.queue.OrderQueueService;
|
||||
import com.viewsh.module.ops.core.dispatch.DispatchEngine;
|
||||
@@ -21,7 +23,6 @@ import com.viewsh.module.ops.environment.dal.mysql.workorder.OpsOrderCleanExtMap
|
||||
import com.viewsh.module.ops.environment.integration.listener.CleanOrderEventListener;
|
||||
import com.viewsh.module.ops.infrastructure.code.OrderCodeGenerator;
|
||||
import com.viewsh.module.ops.infrastructure.id.OrderIdGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -29,10 +30,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -405,61 +405,73 @@ public class CleanOrderServiceImpl implements CleanOrderService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据区域ID构建完整路径(如"园区A栋B层电梯厅")
|
||||
* 根据区域ID构建完整路径(如"园区/A栋/B层/电梯厅")
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 完整区域路径,用 "/" 分隔
|
||||
*/
|
||||
private String buildAreaPath(Long areaId) {
|
||||
// 1. 参数校验
|
||||
if (areaId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. 查询当前区域
|
||||
OpsBusAreaDO area = opsBusAreaMapper.selectById(areaId);
|
||||
if (area == null) {
|
||||
log.warn("区域不存在: areaId={}", areaId);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 3. 无父级路径,直接返回区域名称
|
||||
String parentPath = area.getParentPath();
|
||||
if (parentPath == null || parentPath.isEmpty()) {
|
||||
if (StrUtil.isEmpty(parentPath)) {
|
||||
return area.getAreaName();
|
||||
}
|
||||
|
||||
String[] parentIds = parentPath.split("/");
|
||||
if (parentIds.length == 0) {
|
||||
// 4. 解析父级ID列表(使用 Stream 过滤无效ID)
|
||||
List<Long> parentIds = Arrays.stream(parentPath.split("/"))
|
||||
.filter(StrUtil::isNotBlank) // 过滤空字符串
|
||||
.filter(pid -> {
|
||||
try {
|
||||
Long.parseLong(pid);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("父级区域ID格式错误: areaId={}, parentId={}", areaId, pid);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.map(Long::parseLong)
|
||||
.filter(pid -> !pid.equals(areaId)) // 排除当前区域,避免重复
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 5. 无有效父级,直接返回区域名称
|
||||
if (parentIds.isEmpty()) {
|
||||
return area.getAreaName();
|
||||
}
|
||||
|
||||
// 收集有效的父级ID
|
||||
List<Long> parentIdList = new ArrayList<>();
|
||||
for (String pid : parentIds) {
|
||||
if (!pid.isEmpty()) {
|
||||
try {
|
||||
parentIdList.add(Long.parseLong(pid));
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("解析父级区域ID失败: pid={}", pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parentIdList.isEmpty()) {
|
||||
// 6. 批量查询所有父级区域(避免 N+1 查询)
|
||||
List<OpsBusAreaDO> parents = opsBusAreaMapper.selectBatchIds(parentIds);
|
||||
if (parents == null || parents.isEmpty()) {
|
||||
log.warn("未找到父级区域: areaId={}, parentIds={}", areaId, parentIds);
|
||||
return area.getAreaName();
|
||||
}
|
||||
|
||||
// 批量查询所有父级,避免 N+1 查询
|
||||
List<OpsBusAreaDO> parents = opsBusAreaMapper.selectBatchIds(parentIdList);
|
||||
Map<Long, OpsBusAreaDO> parentMap = parents.stream()
|
||||
.collect(Collectors.toMap(OpsBusAreaDO::getId, Function.identity()));
|
||||
// 7. 构建ID到区域的映射
|
||||
Map<Long, String> parentNameMap = parents.stream()
|
||||
.collect(Collectors.toMap(
|
||||
OpsBusAreaDO::getId,
|
||||
OpsBusAreaDO::getAreaName,
|
||||
(existing, replacement) -> existing // 处理重复key
|
||||
));
|
||||
|
||||
// 按 parentPath 顺序拼接(排除当前区域)
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Long pid : parentIdList) {
|
||||
// 跳过当前区域,避免重复拼接
|
||||
if (pid.equals(areaId)) {
|
||||
continue;
|
||||
}
|
||||
OpsBusAreaDO parent = parentMap.get(pid);
|
||||
if (parent != null) {
|
||||
sb.append(parent.getAreaName());
|
||||
}
|
||||
}
|
||||
sb.append(area.getAreaName());
|
||||
return sb.toString();
|
||||
// 8. 按顺序拼接区域路径
|
||||
String path = parentIds.stream()
|
||||
.filter(parentNameMap::containsKey) // 过滤掉不存在的父级
|
||||
.map(parentNameMap::get)
|
||||
.collect(Collectors.joining("/"));
|
||||
|
||||
// 9. 拼接当前区域名称
|
||||
return StrUtil.isNotBlank(path) ? path + "/" + area.getAreaName() : area.getAreaName();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user