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:
lzh
2026-02-04 10:02:29 +08:00
parent 940a968560
commit a18d1a7d8d

View File

@@ -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();
}
}