refactor(ops): 提取 AreaPathBuilder 公共组件,消除保洁/安保 buildAreaPath 重复代码
将 CleanOrderServiceImpl 中的 buildAreaPath 私有方法提取到 ops-biz 公共层
AreaPathBuilder 组件,供各业务模块(保洁、安保等)共享使用。同时优化:
- 用正则 matches("\d+") 替代 try-catch NumberFormatException 做数字校验
- 增加相邻重复ID去重保护
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package com.viewsh.module.ops.infrastructure.area;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.viewsh.module.ops.dal.dataobject.area.OpsBusAreaDO;
|
||||
import com.viewsh.module.ops.dal.mysql.area.OpsBusAreaMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 区域路径构建器
|
||||
* <p>
|
||||
* 根据 areaId 拼接完整的区域路径,如 "A园区/A栋/3层/电梯厅"。
|
||||
* 供保洁、安保等各业务模块共享使用。
|
||||
*
|
||||
* @author lzh
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AreaPathBuilder {
|
||||
|
||||
@Resource
|
||||
private OpsBusAreaMapper opsBusAreaMapper;
|
||||
|
||||
/**
|
||||
* 根据已查询到的区域对象构建完整路径
|
||||
*
|
||||
* @param area 区域对象(非 null)
|
||||
* @return 完整区域路径,用 "/" 分隔
|
||||
*/
|
||||
public String buildPath(OpsBusAreaDO area) {
|
||||
if (area == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String parentPath = area.getParentPath();
|
||||
if (StrUtil.isEmpty(parentPath)) {
|
||||
return area.getAreaName();
|
||||
}
|
||||
|
||||
// 解析父级ID列表
|
||||
List<Long> parentIds = Arrays.stream(parentPath.split("/"))
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.filter(pid -> pid.matches("\\d+"))
|
||||
.map(Long::parseLong)
|
||||
.filter(pid -> !pid.equals(area.getId()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// ID层面去重相邻重复(数据异常保护)
|
||||
List<Long> deduplicatedIds = new ArrayList<>();
|
||||
Long lastId = null;
|
||||
for (Long parentId : parentIds) {
|
||||
if (!parentId.equals(lastId)) {
|
||||
deduplicatedIds.add(parentId);
|
||||
lastId = parentId;
|
||||
} else {
|
||||
log.warn("检测到parent_path中重复的ID: areaId={}, duplicateId={}", area.getId(), parentId);
|
||||
}
|
||||
}
|
||||
|
||||
if (deduplicatedIds.isEmpty()) {
|
||||
return area.getAreaName();
|
||||
}
|
||||
|
||||
// 批量查询父级区域
|
||||
List<OpsBusAreaDO> parents = opsBusAreaMapper.selectBatchIds(deduplicatedIds);
|
||||
if (parents == null || parents.isEmpty()) {
|
||||
log.warn("未找到父级区域: areaId={}, parentIds={}", area.getId(), deduplicatedIds);
|
||||
return area.getAreaName();
|
||||
}
|
||||
|
||||
Map<Long, String> parentNameMap = parents.stream()
|
||||
.collect(Collectors.toMap(OpsBusAreaDO::getId, OpsBusAreaDO::getAreaName, (a, b) -> a));
|
||||
|
||||
List<String> pathSegments = deduplicatedIds.stream()
|
||||
.filter(parentNameMap::containsKey)
|
||||
.map(parentNameMap::get)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String path = String.join("/", pathSegments);
|
||||
return StrUtil.isBlank(path) ? area.getAreaName() : path + "/" + area.getAreaName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 areaId 查询并构建完整路径
|
||||
*
|
||||
* @param areaId 区域ID
|
||||
* @return 完整区域路径,用 "/" 分隔;区域不存在时返回 null
|
||||
*/
|
||||
public String buildPath(Long areaId) {
|
||||
if (areaId == null) {
|
||||
return null;
|
||||
}
|
||||
OpsBusAreaDO area = opsBusAreaMapper.selectById(areaId);
|
||||
if (area == null) {
|
||||
log.warn("区域不存在: areaId={}", areaId);
|
||||
return null;
|
||||
}
|
||||
return buildPath(area);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user