退料查询优化,3秒->0.3秒

This commit is contained in:
syruan 2025-07-28 11:11:01 +08:00
parent dc39193624
commit e1aef51b22
1 changed files with 255 additions and 145 deletions

View File

@ -75,7 +75,7 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService {
private SelectMapper mapper;
/**
* 查询退料任务
* 查询退料任务 - 性能优化版
*
* @param id 退料任务主键
* @return 退料任务
@ -86,11 +86,13 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService {
//先根据外层id查询上层信息
BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
Long userId = SecurityUtils.getLoginUser().getUserid();
// 首先根据用户名去ma_type_manage表查询是否存在绑定物资信息
List<Long> typeIdList = backApplyInfoMapper.selectTypeIdList(userId);
if (CollectionUtils.isEmpty(typeIdList)) {
backApplyInfo.setUserId(userId == 0 ? null : userId);
}
/** 设置审批人签名url 防止代码冲突 **/
String directAuditUrl = backApplyInfoMapper.getDirectAuditUrl(backApplyInfo);
backApplyInfo.setDirectAuditSignUrl(directAuditUrl);
@ -99,72 +101,237 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService {
backApplyInfo.setBackSignUrl("data:image/png;base64," + backApplyInfo.getBackSignUrl());
}
backApplyRequestVo.setBackApplyInfo(backApplyInfo);
//查询退料详情信息
backApplyInfo.setKeyWord(keyWord);
// 移出maCodeList集合中状态不为在用的数据
List<MaCodeVo> newCodeList = new ArrayList<>();
List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo);
if (CollectionUtils.isNotEmpty(backApplyDetailsList)) {
if (!CollectionUtils.isEmpty(typeIdList)) {
backApplyDetailsList = backApplyDetailsList.stream()
.filter(item -> typeIdList.contains(item.getFirstId()))
.collect(Collectors.toList());
}
// 批量查询附件信息减少数据库访问次数
List<BmFileInfo> bmFileInfos = fetchBmFileInfos(id, backApplyDetailsList);
// 查询编码设备信息
List<MaCodeVo> maCodeList = fetchMaCodeList(id);
if ("0".equals(backApplyInfo.getStatus())) {
if (CollectionUtils.isNotEmpty(maCodeList)) {
// 将maCodeList不等于2的收集到新集合中
for (MaCodeVo maCodeVo : maCodeList) {
if (StringUtils.isNotBlank(maCodeVo.getMaStatus()) && !"2".equals(maCodeVo.getMaStatus())) {
newCodeList.add(maCodeVo);
// 核心优化减少数据库查询次数
// 1. 一次性查询编码设备信息
List<MaCodeVo> maCodeList = backApplyInfoMapper.selectByCode(id);
// 2. 处理状态不为在用的设备编码
if ("0".equals(backApplyInfo.getStatus()) && CollectionUtils.isNotEmpty(maCodeList)) {
newCodeList = filterNonInUseEquipment(maCodeList);
maCodeList = filterInUseEquipment(maCodeList);
}
}
}
maCodeList = maCodeList.stream().filter(maCodeVo -> "2".equals(maCodeVo.getMaStatus())).collect(Collectors.toList());
}
// 根据协议id查询设备在用数
// 先查第四层类型
// 3. 优化只有在有编码设备时才查询类型树减少不必要的复杂查询
Map<Long, BigDecimal> typeNumMap = new HashMap<>();
if (hasCodedEquipment(backApplyDetailsList)) {
List<TypeTreeNode> listL4 = mapper.getUseTypeTreeL4(backApplyInfo);
typeNumMap = buildTypeNumMappingSimple(listL4);
}
// 4. 一次性查询所有附件信息
Map<Long, List<BmFileInfo>> allFileInfoMap = fetchAllFileInfosOptimized(id);
// 5. 预构建映射表
Map<Long, List<MaCodeVo>> typeCodeMap = buildTypeCodeMappingSimple(maCodeList);
Map<Long, MaCodeVo> maIdCodeMap = buildMaIdCodeMappingSimple(maCodeList);
// 6. 快速处理每个退料详情
for (BackApplyDetails details : backApplyDetailsList) {
if (CollectionUtils.isNotEmpty(listL4)) {
for (TypeTreeNode node : listL4) {
if (node.getTypeId() == details.getTypeId()) {
details.setNum(node.getNum());
break;
processBackApplyDetailsSimple(details, typeNumMap, typeCodeMap, allFileInfoMap, newCodeList, maIdCodeMap);
}
backApplyRequestVo.setBackApplyDetailsList(backApplyDetailsList);
}
}
if ("0".equals(details.getManageType())) {
List<MaCodeVo> list = backApplyInfoMapper.selectByCode(details.getParentId());
if (CollectionUtils.isNotEmpty(list)) {
// 过滤出list中typeId和details.getTypeId相等的MaCodeVo对象
list = list.stream().filter(type -> type.getTypeId().equals(details.getTypeId().toString())).collect(Collectors.toList());
// 将goodNum和badNum分别相加
details.setGoodNum(list.stream().map(MaCodeVo::getGoodNum).reduce(BigDecimal.ZERO, BigDecimal::add));
details.setBadNum(list.stream().map(MaCodeVo::getBadNum).reduce(BigDecimal.ZERO, BigDecimal::add));
}
}
// 为每个退料详情设置附件信息
setBmFileInfosForDetails(details, bmFileInfos);
// 如果是编码设备查询并设置相关的编码信息和附件
if ("0".equals(details.getManageType())) {
setMaCodeDetails(details, maCodeList);
}
AjaxResult ajaxResult = AjaxResult.success();
ajaxResult.put("data", backApplyRequestVo);
if (CollectionUtils.isNotEmpty(newCodeList)) {
for (MaCodeVo maCodeVo : newCodeList) {
if (maCodeVo.getTypeId().equals(details.getTypeId().toString())) {
details.setPreNum(details.getPreNum().subtract(BigDecimal.valueOf(1)));
String msg = buildNotificationMessage(newCodeList);
ajaxResult.put("msg", msg);
}
// 根据maId查询设备编码信息
BackApplyInfo dto = new BackApplyInfo();
dto.setId(id);
dto.setMaId(maCodeVo.getMaId());
MaCodeVo info = backApplyInfoMapper.selectDto(dto);
if (null != info) {
if (info.getMaId().equals(maCodeVo.getMaId())) {
return ajaxResult;
}
/**
* 检查是否有编码设备
*/
private boolean hasCodedEquipment(List<BackApplyDetails> backApplyDetailsList) {
return backApplyDetailsList.stream().anyMatch(details -> "0".equals(details.getManageType()));
}
/**
* 过滤非在用设备
*/
private List<MaCodeVo> filterNonInUseEquipment(List<MaCodeVo> maCodeList) {
return maCodeList.stream()
.filter(maCodeVo -> StringUtils.isNotBlank(maCodeVo.getMaStatus()) && !"2".equals(maCodeVo.getMaStatus()))
.collect(Collectors.toList());
}
/**
* 过滤在用设备
*/
private List<MaCodeVo> filterInUseEquipment(List<MaCodeVo> maCodeList) {
return maCodeList.stream()
.filter(maCodeVo -> "2".equals(maCodeVo.getMaStatus()))
.collect(Collectors.toList());
}
/**
* 简化版类型数量映射构建
*/
private Map<Long, BigDecimal> buildTypeNumMappingSimple(List<TypeTreeNode> listL4) {
if (CollectionUtils.isEmpty(listL4)) {
return new HashMap<>();
}
Map<Long, BigDecimal> typeNumMap = new HashMap<>();
for (TypeTreeNode node : listL4) {
typeNumMap.put(node.getTypeId(), node.getNum());
}
return typeNumMap;
}
/**
* 简化版类型编码映射构建
*/
private Map<Long, List<MaCodeVo>> buildTypeCodeMappingSimple(List<MaCodeVo> maCodeList) {
Map<Long, List<MaCodeVo>> typeCodeMap = new HashMap<>();
for (MaCodeVo vo : maCodeList) {
if (StringUtils.isNotBlank(vo.getTypeId())) {
Long typeId = Long.parseLong(vo.getTypeId());
typeCodeMap.computeIfAbsent(typeId, k -> new ArrayList<>()).add(vo);
}
}
return typeCodeMap;
}
/**
* 简化版机具ID映射构建
*/
private Map<Long, MaCodeVo> buildMaIdCodeMappingSimple(List<MaCodeVo> maCodeList) {
Map<Long, MaCodeVo> maIdCodeMap = new HashMap<>();
for (MaCodeVo vo : maCodeList) {
maIdCodeMap.put(vo.getMaId(), vo);
}
return maIdCodeMap;
}
/**
* 优化版附件查询 - 一次性查询
*/
private Map<Long, List<BmFileInfo>> fetchAllFileInfosOptimized(Long taskId) {
// 一次性查询该任务的所有附件
BmFileInfo queryParam = new BmFileInfo();
queryParam.setTaskId(taskId);
queryParam.setTaskType(3);
List<BmFileInfo> allFileInfos = bmFileInfoMapper.selectBmFileInfoList(queryParam);
// 按modelId分组
Map<Long, List<BmFileInfo>> fileInfoMap = new HashMap<>();
for (BmFileInfo fileInfo : allFileInfos) {
fileInfoMap.computeIfAbsent(fileInfo.getModelId(), k -> new ArrayList<>()).add(fileInfo);
}
return fileInfoMap;
}
/**
* 简化版退料详情处理
*/
private void processBackApplyDetailsSimple(BackApplyDetails details,
Map<Long, BigDecimal> typeNumMap,
Map<Long, List<MaCodeVo>> typeCodeMap,
Map<Long, List<BmFileInfo>> allFileInfoMap,
List<MaCodeVo> newCodeList,
Map<Long, MaCodeVo> maIdCodeMap) {
// 1. 设置在用数量
BigDecimal num = typeNumMap.get(details.getTypeId());
if (num != null) {
details.setNum(num);
}
// 2. 设置附件信息
List<BmFileInfo> detailFileInfos = allFileInfoMap.get(details.getId());
if (CollectionUtils.isNotEmpty(detailFileInfos)) {
details.setBmFileInfos(detailFileInfos);
}
// 3. 处理编码设备
if ("0".equals(details.getManageType())) {
processCodedEquipmentSimple(details, typeCodeMap, allFileInfoMap);
}
// 4. 处理非在用状态的设备
processNonInUseEquipmentSimple(details, newCodeList, maIdCodeMap);
}
/**
* 简化版编码设备处理
*/
private void processCodedEquipmentSimple(BackApplyDetails details,
Map<Long, List<MaCodeVo>> typeCodeMap,
Map<Long, List<BmFileInfo>> allFileInfoMap) {
List<MaCodeVo> codeList = typeCodeMap.get(details.getTypeId());
if (CollectionUtils.isEmpty(codeList)) {
return;
}
// 计算总数
BigDecimal totalGoodNum = BigDecimal.ZERO;
BigDecimal totalBadNum = BigDecimal.ZERO;
List<MaCodeDto> maCodeDtos = new ArrayList<>();
for (MaCodeVo maCodeVo : codeList) {
if (StringUtils.isBlank(maCodeVo.getMaCode())) {
continue;
}
// 累加数量
if (maCodeVo.getGoodNum() != null) {
totalGoodNum = totalGoodNum.add(maCodeVo.getGoodNum());
}
if (maCodeVo.getBadNum() != null) {
totalBadNum = totalBadNum.add(maCodeVo.getBadNum());
}
// 创建编码DTO
MaCodeDto maCodeDto = createMaCodeDto(maCodeVo);
List<BmFileInfo> fileInfos = allFileInfoMap.get(maCodeVo.getMaId());
if (CollectionUtils.isNotEmpty(fileInfos)) {
maCodeDto.setBmFileInfos(fileInfos);
}
maCodeDtos.add(maCodeDto);
}
details.setGoodNum(totalGoodNum);
details.setBadNum(totalBadNum);
details.setMaCodeList(maCodeDtos);
}
/**
* 简化版非在用设备处理
*/
private void processNonInUseEquipmentSimple(BackApplyDetails details,
List<MaCodeVo> newCodeList,
Map<Long, MaCodeVo> maIdCodeMap) {
if (CollectionUtils.isEmpty(newCodeList)) {
return;
}
for (MaCodeVo maCodeVo : newCodeList) {
if (!maCodeVo.getTypeId().equals(details.getTypeId().toString())) {
continue;
}
details.setPreNum(details.getPreNum().subtract(BigDecimal.valueOf(1)));
MaCodeVo info = maIdCodeMap.get(maCodeVo.getMaId());
if (info != null) {
if (info.getGoodNum() != null && info.getGoodNum().compareTo(BigDecimal.ZERO) > 0) {
details.setGoodNum(details.getGoodNum().subtract(info.getGoodNum()));
} else if (info.getBadNum() != null && info.getBadNum().compareTo(BigDecimal.ZERO) > 0) {
@ -173,94 +340,21 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService {
}
}
}
}
}
backApplyRequestVo.setBackApplyDetailsList(backApplyDetailsList);
}
AjaxResult ajaxResult = AjaxResult.success();
ajaxResult.put("data", backApplyRequestVo);
if (CollectionUtils.isNotEmpty(newCodeList)) {
// 拼接消息内容
StringBuffer msgBuilder = new StringBuffer("您所选择的编码设备编号");
for (int i = 0; i < newCodeList.size(); i++) {
String code = newCodeList.get(i).getMaCode();
msgBuilder.append(code);
if (i < newCodeList.size() - 1) {
msgBuilder.append(", ");
}
}
msgBuilder.append("已被他人完成退料,请注意查看!");
String msg = msgBuilder.toString();
msg = msg.replaceAll("\n","");
ajaxResult.put("msg", msg);
}
return ajaxResult;
}
/**
* 批量查询附件信息
* @param id
* @param backApplyDetailsList
* @return
* 创建MaCodeDto对象
*/
private List<BmFileInfo> fetchBmFileInfos(Long id, List<BackApplyDetails> backApplyDetailsList) {
List<BmFileInfo> bmFileInfos = new ArrayList<>();
for (BackApplyDetails details : backApplyDetailsList) {
BmFileInfo bmFileInfo = new BmFileInfo();
bmFileInfo.setTaskId(id);
bmFileInfo.setTaskType(3);
bmFileInfo.setModelId(details.getId());
List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(bmFileInfo);
// 合并所有附件信息
bmFileInfos.addAll(bmFileInfoList);
}
return bmFileInfos;
}
/**
* 查询编码设备信息
* @param id
* @return
*/
private List<MaCodeVo> fetchMaCodeList(Long id) {
return backApplyInfoMapper.selectByCode(id);
}
/**
* 为每个退料详情设置附件信息
* @param details
* @param bmFileInfos
*/
private void setBmFileInfosForDetails(BackApplyDetails details, List<BmFileInfo> bmFileInfos) {
// 为每个退料详情设置附件信息
List<BmFileInfo> relatedFileInfos = bmFileInfos.stream()
.filter(fileInfo -> fileInfo.getModelId().equals(details.getId()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(relatedFileInfos)) {
details.setBmFileInfos(relatedFileInfos);
}
}
/**
* 为编码设备详情设置编码信息和附件信息
* @param details
* @param maCodeList
*/
private void setMaCodeDetails(BackApplyDetails details, List<MaCodeVo> maCodeList) {
List<MaCodeVo> codeVos = maCodeList.stream()
.filter(maCodeVo -> StringUtils.isNotBlank(maCodeVo.getMaCode())
&& maCodeVo.getTypeId().equals(details.getTypeId().toString()))
.collect(Collectors.toList());
List<MaCodeDto> maCodeDtos = new ArrayList<>();
for (MaCodeVo maCodeVo : codeVos) {
private MaCodeDto createMaCodeDto(MaCodeVo maCodeVo) {
MaCodeDto maCodeDto = new MaCodeDto();
maCodeDto.setMaCode(maCodeVo.getMaCode());
maCodeDto.setMaId(maCodeVo.getMaId());
if (maCodeVo.getGoodNum() != null && maCodeVo.getGoodNum().compareTo(BigDecimal.ZERO) > 0) {
maCodeDto.setApDetection("完好");
} else if (maCodeVo.getBadNum() != null && maCodeVo.getBadNum().compareTo(BigDecimal.ZERO) > 0) {
maCodeDto.setApDetection("损坏");
}
maCodeDto.setTypeName(maCodeVo.getTypeName());
maCodeDto.setMaterialName(maCodeVo.getMaterialName());
maCodeDto.setTypeId(maCodeVo.getTypeId());
@ -268,14 +362,30 @@ public class BackApplyInfoServiceImpl implements IBackApplyInfoService {
maCodeDto.setMaterialType(maCodeVo.getMaterialType());
maCodeDto.setGoodNum(maCodeVo.getGoodNum());
maCodeDto.setBadNum(maCodeVo.getBadNum());
// 查询并设置编码附件
List<BmFileInfo> bmFileInfoList = fetchBmFileInfos(details.getId(), maCodeVo.getMaId());
if (CollectionUtils.isNotEmpty(bmFileInfoList)) {
maCodeDto.setBmFileInfos(bmFileInfoList);
return maCodeDto;
}
maCodeDtos.add(maCodeDto);
/**
* 优化消息构建
*/
private String buildNotificationMessage(List<MaCodeVo> newCodeList) {
StringBuilder msgBuilder = new StringBuilder("您所选择的编码设备编号");
String codes = newCodeList.stream()
.map(MaCodeVo::getMaCode)
.collect(Collectors.joining(", "));
msgBuilder.append(codes).append("已被他人完成退料,请注意查看!");
return msgBuilder.toString().replaceAll("\n", "");
}
details.setMaCodeList(maCodeDtos);
/**
* 查询编码设备信息
*/
private List<MaCodeVo> fetchMaCodeList(Long id) {
return backApplyInfoMapper.selectByCode(id);
}
/**