refactor(material): 优化物料编码查询逻辑

- 移除 Mapper 层的 code 字段查询,统一在 Service 层处理
- 添加中铜编码和中铝编码的属性查询支持
- 实现物料编码查询的性能优化,减少数据库查询次数
- 添加分类筛选与编码查询的联合处理逻辑
- 实现属性ID的本地缓存机制,避免重复查询
- 优化查询结果为空时的提前返回逻辑
This commit is contained in:
wuzongyong
2026-01-07 11:14:46 +08:00
parent 9eb3198ce1
commit 426c410818
2 changed files with 89 additions and 1 deletions

View File

@@ -24,7 +24,7 @@ public interface MaterialInfomationMapper extends BaseMapperX<MaterialInfomation
default PageResult<MaterialInfomationDO> selectPage(MaterialInfomationPageReqVO reqVO, Collection<Long> infomationIds) {
return BaseMapperX.super.selectPage(reqVO, new LambdaQueryWrapperX<MaterialInfomationDO>()
.likeIfPresent(MaterialInfomationDO::getCode, reqVO.getCode())
// code 字段的查询已在 Service 层处理(包含中铜编码、中铝编码),此处不再重复查询
.likeIfPresent(MaterialInfomationDO::getName, reqVO.getName())
.likeIfPresent(MaterialInfomationDO::getRemark, reqVO.getRemark())
.betweenIfPresent(MaterialInfomationDO::getCreateTime, reqVO.getCreateTime())

View File

@@ -22,6 +22,7 @@ import com.zt.plat.module.base.dal.dataobject.materialhasclasses.MaterialHasClas
import com.zt.plat.module.base.dal.dataobject.materialhasproperties.MaterialHasPropertiesDO;
import com.zt.plat.module.base.dal.dataobject.materialproperties.MaterialPropertiesDO;
import com.zt.plat.module.base.dal.mysql.base.MaterialInfomationMapper;
import com.zt.plat.module.base.service.masterdatasync.support.MasterDataPropertyDefinition;
import com.zt.plat.module.erp.api.ErpExternalApi;
import com.zt.plat.module.erp.api.dto.ErpProductiveVersionReqDTO;
import jakarta.annotation.Resource;
@@ -229,6 +230,18 @@ public class MaterialInfomationServiceImpl implements MaterialInfomationService
.collect(Collectors.toList());
}
// 如果搜索物料编码,需要同时搜索中铜编码和中铝编码(作为物料属性存储)
if (StrUtil.isNotBlank(pageReqVO.getCode())) {
// 优化:将分类筛选结果传入,在数据库层面就完成筛选,减少数据传输
List<Long> codeMatchedIds = queryMaterialIdsByCodeOrAttribute(pageReqVO.getCode(), infomationIds);
if (CollUtil.isEmpty(codeMatchedIds)) {
// 按编码查询无结果,直接返回空(无论是否有分类筛选)
return PageResult.empty();
}
// 直接使用编码查询结果(已包含分类筛选)
infomationIds = codeMatchedIds;
}
PageResult<MaterialInfomationDO> pageResult = materialInfomationMapper.selectPage(pageReqVO, infomationIds);
if (CollUtil.isEmpty(pageResult.getList())) {
return PageResult.empty(pageResult.getTotal());
@@ -251,6 +264,81 @@ public class MaterialInfomationServiceImpl implements MaterialInfomationService
return new PageResult<>(respList, pageResult.getTotal());
}
/**
* 根据物料编码或属性编码中铜编码、中铝编码查询物料ID列表
* 优化版本:减少数据库查询次数,提升性能
*
* @param code 编码关键字(支持模糊查询)
* @param classIdFilter 分类筛选的物料ID列表可为null
* @return 匹配的物料ID列表
*/
private List<Long> queryMaterialIdsByCodeOrAttribute(String code, List<Long> classIdFilter) {
Set<Long> materialIds = new HashSet<>();
// 1. 查询物料表的 code 字段
List<MaterialInfomationDO> directMatches = materialInfomationMapper.selectList(
new LambdaQueryWrapperX<MaterialInfomationDO>()
.like(MaterialInfomationDO::getCode, code)
.in(Objects.nonNull(classIdFilter), MaterialInfomationDO::getId, classIdFilter)
);
if (CollUtil.isNotEmpty(directMatches)) {
materialIds.addAll(directMatches.stream()
.map(MaterialInfomationDO::getId)
.filter(Objects::nonNull)
.collect(Collectors.toSet()));
}
// 2. 查询中铜编码和中铝编码属性使用缓存的属性ID
List<Long> propertyIds = getCachedCodePropertyIds();
if (CollUtil.isNotEmpty(propertyIds)) {
// 查询属性值表中匹配的物料
List<MaterialHasPropertiesDO> hasProperties = materialHasPropertiesMapper.selectList(
new LambdaQueryWrapperX<MaterialHasPropertiesDO>()
.in(MaterialHasPropertiesDO::getPropertiesId, propertyIds)
.like(MaterialHasPropertiesDO::getValue, code)
.in(Objects.nonNull(classIdFilter),MaterialHasPropertiesDO::getInfomationId, classIdFilter)
);
if (CollUtil.isNotEmpty(hasProperties)) {
materialIds.addAll(hasProperties.stream()
.map(MaterialHasPropertiesDO::getInfomationId)
.filter(Objects::nonNull)
.collect(Collectors.toSet()));
}
}
return new ArrayList<>(materialIds);
}
/**
* 获取中铜编码和中铝编码的属性ID使用本地缓存避免重复查询
*/
private static volatile List<Long> cachedCodePropertyIds = null;
private List<Long> getCachedCodePropertyIds() {
if (cachedCodePropertyIds == null) {
synchronized (MaterialInfomationServiceImpl.class) {
if (cachedCodePropertyIds == null) {
List<MaterialPropertiesDO> properties = materialPropertiesMapper.selectList(
new LambdaQueryWrapperX<MaterialPropertiesDO>()
.in(MaterialPropertiesDO::getCode, Arrays.asList(
MasterDataPropertyDefinition.CHALCO_CODE.getCode(),
MasterDataPropertyDefinition.ZHONGTONG_CODE.getCode()))
);
if (CollUtil.isNotEmpty(properties)) {
cachedCodePropertyIds = properties.stream()
.map(MaterialPropertiesDO::getId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
} else {
cachedCodePropertyIds = Collections.emptyList();
}
}
}
}
return cachedCodePropertyIds;
}
@Override
public String getOneTest() {
ErpProductiveVersionReqDTO reqDTO = new ErpProductiveVersionReqDTO();