材料站供应平衡

This commit is contained in:
mashuai 2025-09-28 23:33:28 +08:00
parent 91515b24e8
commit aed825e462
4 changed files with 64 additions and 34 deletions

View File

@ -185,4 +185,7 @@ public class MaterialProvideNumInfo {
private String endTime; private String endTime;
private String unitValue; private String unitValue;
@ApiModelProperty(value = "协议id")
private String agreementIds;
} }

View File

@ -266,4 +266,7 @@ public class MaterialRetainedEquipmentInfo {
@ApiModelProperty(value = "工程集合") @ApiModelProperty(value = "工程集合")
private List<MaterialRetainedEquipmentInfo> proNameList; private List<MaterialRetainedEquipmentInfo> proNameList;
@ApiModelProperty(value = "协议id")
private String agreementIds;
} }

View File

@ -1328,39 +1328,57 @@ public class MaterialMachineServiceImpl implements MaterialMachineService {
return recordList; return recordList;
} }
// 1. 过滤数据保留原逻辑使用并行流加速大集合过滤 // 1. 过滤数据并行流加速大集合过滤
if (teamData != null) { if (teamData != null) {
recordList = recordList.parallelStream() // 并行流适合大集合过滤 recordList = recordList.parallelStream()
.filter(item -> StringUtils.isBlank(item.getIdCard()) || username.equals(item.getIdCard())) .filter(item -> StringUtils.isBlank(item.getIdCard()) || username.equals(item.getIdCard()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
// 2. 提取批量查询的关键参数工程ID + typeId避免重复创建对象 // 2. 转换参数将agreementIds逗号字符串转为List<String>
List<Map<String, Object>> queryParams = recordList.stream() List<Map<String, Object>> queryParams = recordList.stream()
.map(record -> { .map(record -> {
Map<String, Object> param = new HashMap<>(2); Map<String, Object> param = new HashMap<>(3);
param.put("proId", record.getProId()); param.put("proId", record.getProId());
param.put("typeId", record.getTypeId()); param.put("typeId", record.getTypeId());
// 逗号分隔的agreementIds转为List
String agreementIds = record.getAgreementIds();
if (StringUtils.isNotBlank(agreementIds)) {
List<String> agreementIdList = Arrays.asList(agreementIds.split(","));
param.put("agreementIds", agreementIdList);
} else {
param.put("agreementIds", Collections.emptyList());
}
return param; return param;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
// 3. 批量查询核心优化2次查询替代N次循环查询减少99%+的数据库交互 // 3. 核心分批处理查询参数避免数据包过大
// 3.1 批量查询领料数据构建映射key=projectId_typeIdvalue=businessNum int batchSize = 300; // 每批大小根据实际测试调整建议200-500
Map<String, BigDecimal> leaseBusinessMap = materialMachineMapper.batchQueryLeaseDemand(queryParams).stream() Map<String, BigDecimal> leaseBusinessMap = new HashMap<>(); // 最终合并结果
.collect(Collectors.toMap(
info -> getCompositeKey(info.getProId(), info.getTypeId()), // 抽成方法避免重复代码 // 计算总批次数
MaterialProvideNumInfo::getBusinessNum, int totalBatches = (int) Math.ceil((double) queryParams.size() / batchSize);
(existing, replacement) -> existing // 重复key保留第一个按业务需求调整
)); for (int i = 0; i < totalBatches; i++) {
// 计算当前批次的起止索引
int start = i * batchSize;
int end = Math.min(start + batchSize, queryParams.size());
List<Map<String, Object>> subParams = queryParams.subList(start, end);
// 分批查询
List<MaterialProvideNumInfo> batchResult = materialMachineMapper.batchQueryLeaseDemand(subParams);
// 将当前批次结果合并到总Map中
batchResult.stream()
.forEach(info -> {
String key = getCompositeKey(info.getProId(), info.getTypeId());
// 若有重复key保留第一个与原逻辑一致
leaseBusinessMap.putIfAbsent(key, info.getBusinessNum());
});
}
// 3.2 批量查询领用数据构建映射
Map<String, BigDecimal> publishBusinessMap = materialMachineMapper.batchQueryUseDemand(queryParams).stream()
.collect(Collectors.toMap(
info -> getCompositeKey(info.getProId(), info.getTypeId()),
MaterialProvideNumInfo::getBusinessNum,
(existing, replacement) -> existing
));
// 4. 并行流处理大集合计算总和并设置record的businessNum内存操作并行化 // 4. 并行流处理大集合计算总和并设置record的businessNum内存操作并行化
// 用数组存储四个总和比对象更高效减少gc // 用数组存储四个总和比对象更高效减少gc
@ -1370,9 +1388,7 @@ public class MaterialMachineServiceImpl implements MaterialMachineService {
recordList.parallelStream().forEach(record -> { recordList.parallelStream().forEach(record -> {
String key = getCompositeKey(record.getProId(), record.getTypeId()); String key = getCompositeKey(record.getProId(), record.getTypeId());
// 从Map获取数据默认0避免null // 从Map获取数据默认0避免null
BigDecimal leaseNum = leaseBusinessMap.getOrDefault(key, BigDecimal.ZERO); BigDecimal businessNum = leaseBusinessMap.getOrDefault(key, BigDecimal.ZERO);
BigDecimal publishNum = publishBusinessMap.getOrDefault(key, BigDecimal.ZERO);
BigDecimal businessNum = leaseNum.add(publishNum);
// 设置record的businessNum原逻辑保留 // 设置record的businessNum原逻辑保留
record.setBusinessNum(businessNum); record.setBusinessNum(businessNum);

View File

@ -2015,7 +2015,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
'安全工器具' '安全工器具'
ELSE ELSE
'施工机具' '施工机具'
END jiJuType END jiJuType,
subquery1.agreementId AS agreementIds
FROM ma_type mt FROM ma_type mt
LEFT JOIN ( LEFT JOIN (
SELECT SELECT
@ -2034,7 +2035,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bp.imp_unit AS impUnit, bp.imp_unit AS impUnit,
bu.bzz_idcard AS idCard, bu.bzz_idcard AS idCard,
df.project_dept AS proCenter, df.project_dept AS proCenter,
sd.dept_name AS departName sd.dept_name AS departName,
GROUP_CONCAT(DISTINCT sai.agreement_id) AS agreementId
FROM FROM
slt_agreement_info sai slt_agreement_info sai
LEFT JOIN ma_type mt ON mt.type_id = sai.type_id LEFT JOIN ma_type mt ON mt.type_id = sai.type_id
@ -2256,26 +2258,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select> </select>
<select id="batchQueryLeaseDemand" resultType="com.bonus.material.clz.domain.vo.MaterialProvideNumInfo"> <select id="batchQueryLeaseDemand" resultType="com.bonus.material.clz.domain.vo.MaterialProvideNumInfo">
<!-- 批量查询领料数据 -->
SELECT SELECT
bp.pro_id AS proId, bp.pro_id AS proId,
lad.type_id AS typeId, lad.type_id AS typeId,
IFNULL( sum( lad.pre_num ), 0 ) AS businessNum IFNULL(SUM(lad.pre_num), 0) AS businessNum
FROM FROM
lease_apply_info lai lease_apply_info lai
LEFT JOIN lease_apply_details lad ON lai.id = lad.parent_id LEFT JOIN lease_apply_details lad ON lai.id = lad.parent_id
LEFT JOIN tm_task tt ON tt.task_id = lai.task_id LEFT JOIN tm_task tt ON tt.task_id = lai.task_id
LEFT JOIN tm_task_agreement tta on tta.task_id = lai.task_id LEFT JOIN tm_task_agreement tta ON tta.task_id = lai.task_id
LEFT JOIN bm_agreement_info bagi on bagi.agreement_id = tta.agreement_id LEFT JOIN bm_agreement_info bagi ON bagi.agreement_id = tta.agreement_id
AND bagi.`status` = '1' AND bagi.`status` = '1'
LEFT JOIN bm_project bp on bp.pro_id = bagi.project_id LEFT JOIN bm_project bp ON bp.pro_id = bagi.project_id
AND bp.del_flag = '0' AND bp.del_flag = '0'
WHERE WHERE
tt.task_status IN (3, 4) lad.type_id IS NOT NULL -- 基础条件type_id不为空
AND tt.task_type = 2 -- 批量条件遍历list中的每个item用OR连接多个条件组
AND (bp.pro_id, lad.type_id) IN <foreach collection="list" item="item" separator="OR" open="AND (" close=")">
<foreach collection="list" item="item" separator="," open="(" close=")"> -- 单个item的条件typeId匹配 + agreementIds在集合中
(#{item.proId}, #{item.typeId}) (
lad.type_id = #{item.typeId}
AND tta.agreement_id IN (
<foreach collection="item.agreementIds" item="aid" separator=",">
#{aid} -- 遍历agreementIds集合生成IN条件
</foreach>
)
)
</foreach> </foreach>
GROUP BY GROUP BY
bp.pro_id, bp.pro_id,