Kaynağa Gözat

批量生成整炉逻辑优化

qiangxuan 2 hafta önce
ebeveyn
işleme
ab4222422c

+ 22 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetActual/mapper/BilletBasicInfoMapper.java

@@ -1,6 +1,8 @@
 package org.jeecg.modules.actualControl.billetActual.billetActual.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
 import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletBasicInfo;
 
 import java.util.List;
@@ -13,4 +15,24 @@ import java.util.List;
  */
 public interface BilletBasicInfoMapper extends BaseMapper<BilletBasicInfo> {
     int insertBatch(List<BilletBasicInfo> list);
+
+
+    /**
+     * 批量更新组批号
+     * @param billetList 钢坯列表
+     * @return 更新条数
+     */
+    @Update("<script>" +
+            "UPDATE billet_basic_info " +
+            "SET assembly_number = CASE id " +
+            "<foreach collection=\"list\" item=\"item\" separator=\"\">" +
+            "   WHEN #{item.id} THEN #{item.assemblyNumber} " +
+            "</foreach>" +
+            "END " +
+            "WHERE id IN " +
+            "<foreach collection=\"list\" item=\"item\" open=\"(\" separator=\",\" close=\")\">" +
+            "#{item.id}" +
+            "</foreach>" +
+            "</script>")
+    int batchUpdateAssemblyNumber(@Param("list") List<BilletBasicInfo> billetList);
 }

+ 2 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetActual/service/IBilletBasicInfoService.java

@@ -31,4 +31,6 @@ public interface IBilletBasicInfoService extends IService<BilletBasicInfo> {
     void addB(BilletBasicInfo billetBasicInfo, Integer num);
 
     String addBilletBasicHandle(BilletBasicInfoAdd billetBasicInfoAdd);
+
+    int batchUpdateAssemblyNumber(List<BilletBasicInfo> billetList);
 }

+ 5 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetActual/service/impl/BilletBasicInfoServiceImpl.java

@@ -752,4 +752,9 @@ public class BilletBasicInfoServiceImpl extends ServiceImpl<BilletBasicInfoMappe
     public boolean exists(QueryWrapper<BilletBasicInfo> eq) {
         return baseMapper.selectCount(eq) > 0;
     }
+
+    @Override
+    public int batchUpdateAssemblyNumber(List<BilletBasicInfo> billetList) {
+        return billetBasicInfoMapper.batchUpdateAssemblyNumber(billetList);
+    }
 }

+ 51 - 40
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/billetHotsend/service/impl/BilletHotsendBaseServiceImpl.java

@@ -78,6 +78,8 @@ import java.math.BigDecimal;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -141,13 +143,12 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 	private IHeatsActualsService heatsActualsService;
 	@Autowired
 	private ConfigMqttMapper configMqttMapper;
-
-	@Resource
-	private BilletAssemblyNumberMapper billetAssemblyNumberMapper;
-
 	@Autowired
 	private IBilletRulerConfigService billetRulerConfigService;
 
+	private static final Random RANDOM = ThreadLocalRandom.current();
+	private static final AtomicInteger COUNTER = new AtomicInteger(0);
+
 	@Override
 	@Transactional
 	public JSONObject saveBilletHotsendDetails(BilletHotsendDetailsVo billetHotsendDetailsVo) {
@@ -1392,7 +1393,7 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 				.orderByDesc(HeatsActuals::getCreateTime).last("limit 1");
 		HeatsActuals actualsCheck = heatsActualsService.getOne(queryWrapper1);
 		if (actualsCheck != null){
-			return "炉号重复,补录失败!";
+			return "炉次实绩中炉号重复,补录失败!";
 		}
 
 		// 查询基础信息
@@ -1483,42 +1484,52 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 
 			// 4流补录钢坯
 			if (oConvertUtils.isNotEmpty(billetBasicInfoAdd.getFourStrandNo()) && billetBasicInfoAdd.getFourStrandNoSum() > 0){
+				log.info("4流保存钢坯实绩开始:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 				int addSum = billetBasicInfoAdd.getFourStrandNoSum();
 				int strandNo = billetBasicInfoAdd.getFourStrandNo();
 				int length = billetBasicInfoAdd.getFourLength();
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, addSum, strandNo, length);
+				log.info("4流保存钢坯实绩结束:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			}
 
 			// 5流补录钢坯
 			if (oConvertUtils.isNotEmpty(billetBasicInfoAdd.getFiveStrandNo()) && billetBasicInfoAdd.getFiveStrandNoSum() > 0){
+				log.info("5流保存钢坯实绩开始:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 				int addSum = billetBasicInfoAdd.getFiveStrandNoSum();
 				int strandNo = billetBasicInfoAdd.getFiveStrandNo();
 				int length = billetBasicInfoAdd.getFiveLength();
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, addSum, strandNo, length);
+				log.info("5流保存钢坯实绩结束:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			}
 
 			// 6流补录钢坯
 			if (oConvertUtils.isNotEmpty(billetBasicInfoAdd.getSixStrandNo()) && billetBasicInfoAdd.getSixStrandNoSum() > 0){
+				log.info("6流保存钢坯实绩开始:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 				int addSum = billetBasicInfoAdd.getSixStrandNoSum();
 				int strandNo = billetBasicInfoAdd.getSixStrandNo();
 				int length = billetBasicInfoAdd.getSixLength();
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, addSum, strandNo, length);
+				log.info("6流保存钢坯实绩结束:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			}
 
 			// 7流补录钢坯
 			if (oConvertUtils.isNotEmpty(billetBasicInfoAdd.getSevenStrandNo()) && billetBasicInfoAdd.getSevenStrandNoSum() > 0){
+				log.info("7流保存钢坯实绩开始:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 				int addSum = billetBasicInfoAdd.getSevenStrandNoSum();
 				int strandNo = billetBasicInfoAdd.getSevenStrandNo();
 				int length = billetBasicInfoAdd.getSevenLength();
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, addSum, strandNo, length);
+				log.info("7流保存钢坯实绩结束:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			}
 
 			// 8流补录钢坯
 			if (oConvertUtils.isNotEmpty(billetBasicInfoAdd.getEightStrandNo()) && billetBasicInfoAdd.getEightStrandNoSum() > 0){
+				log.info("8流保存钢坯实绩开始:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 				int addSum = billetBasicInfoAdd.getEightStrandNoSum();
 				int strandNo = billetBasicInfoAdd.getEightStrandNo();
 				int length = billetBasicInfoAdd.getEightLength();
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, addSum, strandNo, length);
+				log.info("8流保存钢坯实绩结束:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			}
 			// 查询整个炉钢坯基础信息
 			List<BilletBasicInfo> resultList = billetBasicInfoService.list(new LambdaQueryWrapper<BilletBasicInfo>()
@@ -1528,14 +1539,21 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 					.eq(BilletBasicInfo::getShiftGroup, billetBasicInfoAdd.getShiftGroup()));
 			log.info("开始组批号更新处理:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			if (oConvertUtils.listIsNotEmpty(resultList) && resultList.size() >= 4) {
+				// 收集所有需要更新的钢坯
+				List<BilletBasicInfo> updateList = new ArrayList<>();
 				int size = resultList.size();
 				int maxProcessed = (size / 4) * 4; // 计算可处理的最大4的倍数
 				for (int i = 0; i < maxProcessed; i += 4) {
 					int start = i;
 					int end = Math.min(i + 4, maxProcessed);
-					//组批成功的,对钢坯实绩进行组批号更新
-					updateBilletBasicInfoAsendAssemblyHandle(resultList.subList(start, end), billetBasicInfoAdd);
+					// 生成组批号(优化:直接生成随机数,避免雪花算法开销)
+					String assemblyNumber = generateUniqueAssemblyNumber(billetBasicInfoAdd.getHeatNo());
+					// 为当前分组的4条记录设置相同组批号,并添加到更新列表
+					List<BilletBasicInfo> batch = resultList.subList(start, end);
+					batch.forEach(item -> item.setAssemblyNumber(assemblyNumber));
+					updateList.addAll(batch);
 				}
+				billetBasicInfoService.batchUpdateAssemblyNumber(updateList);
 			}
 			log.info("结束组批号更新处理:"+ DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 
@@ -1586,7 +1604,7 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 					rulerConfigMap.put(config.getLength(), config);
 				}
 			}
-
+			log.info("开始去棒一数据组装:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			// 遍历 RollClubOneInfo 列表
 			for (RollClubOneInfo item : rollClubOneList) {
 				Integer strandNo = item.getStrandNo();
@@ -1629,11 +1647,15 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 					rollClubOneResultList.add(billet);
 				}
 			}
+			log.info("结束去棒一数据组装:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			if (oConvertUtils.listIsNotEmpty(rollClubOneResultList)){
+				log.info("开始整炉去棒一明细处理:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 				// 去棒一明细处理
 				saveRollClubOneInfo(rollClubOneResultList, billetBasicInfoAdd);
+				log.info("结束整炉去棒一明细处理:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			}
 
+			log.info("开始处理每流剩余:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			if (oneStrandRemainSum > 0){
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, oneStrandRemainSum, 1, billetBasicInfoAdd.getOneLength());
 			}
@@ -1660,7 +1682,7 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 			if (oConvertUtils.isNotEmpty(billetBasicInfoAdd.getEightStrandNoSum()) && billetBasicInfoAdd.getEightStrandNoSum() > 0){
 				saveBilletBasicInfoList(billetBasicInfo, billetBasicInfoAdd, billetBasicInfoAdd.getSevenStrandNoSum(), 8, billetBasicInfoAdd.getSevenLength());
 			}
-
+			log.info("结束处理每流剩余:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			// 查询去除棒一,整炉 剩余钢坯基础信息
 			List<BilletBasicInfo> result = billetBasicInfoService.list(new LambdaQueryWrapper<BilletBasicInfo>()
 					.eq(BilletBasicInfo::getCcmNo, billetBasicInfoAdd.getCcmNo())
@@ -1668,17 +1690,25 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 					.eq(BilletBasicInfo::getShift, billetBasicInfoAdd.getShift())
 					.eq(BilletBasicInfo::getShiftGroup, billetBasicInfoAdd.getShiftGroup())
 					.isNull(BilletBasicInfo::getBelongTable));
-			log.info("整炉去除棒一需要组批的钢坯总数:{}", result.size());
+			log.info("开始整炉去除棒一组批更新处理:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			if (oConvertUtils.listIsNotEmpty(result) && result.size() >= 4) {
+				// 收集所有需要更新的钢坯
+				List<BilletBasicInfo> updateList = new ArrayList<>();
 				int size = result.size();
 				int maxProcessed = (size / 4) * 4; // 计算可处理的最大4的倍数
 				for (int i = 0; i < maxProcessed; i += 4) {
 					int start = i;
 					int end = Math.min(i + 4, maxProcessed);
-					//组批成功的,对钢坯实绩进行组批号更新
-					updateBilletBasicInfoAsendAssemblyHandle(result.subList(start, end), billetBasicInfoAdd);
+					// 生成组批号(优化:直接生成随机数,避免雪花算法开销)
+					String assemblyNumber = generateUniqueAssemblyNumber(billetBasicInfoAdd.getHeatNo());
+					// 为当前分组的4条记录设置相同组批号,并添加到更新列表
+					List<BilletBasicInfo> batch = result.subList(start, end);
+					batch.forEach(item -> item.setAssemblyNumber(assemblyNumber));
+					updateList.addAll(batch);
 				}
+				billetBasicInfoService.batchUpdateAssemblyNumber(updateList);
 			}
+			log.info("结束整炉去除棒一组批更新处理:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 
 			// 去棒一的和组批的合计钢坯实绩信息
 			result.addAll(rollClubOneResultList);
@@ -1693,12 +1723,13 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 			if (oConvertUtils.listIsNotEmpty(rollClubOneResultList) && rollClubOneResultList.size() > 0){
 				billetHotsend.setRollcluboneNum(rollClubOneResultList.size());
 			}
-
+			log.info("炉次传递单更新:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			billetHotsendBaseMapper.updateById(billetHotsend);
 
 			// 更新炉次实绩中的总数和坯重
 			heatsActuals.setBlankOutput(totalBilletWeight);
 			heatsActuals.setBilletSum(result.size());
+			log.info("炉次实绩更新:{}" + DateUtils.date2Str(new Date(), DateUtils.datetimeFormat.get()));
 			heatsActualsService.updateById(heatsActuals);
 		}
 
@@ -1837,37 +1868,20 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 		billetBasicInfoService.saveOrUpdateBatch(resultList);
 	}
 
-	/**
-	 * 组批处理
-	 * @param billetBasicInfoList
-	 * @param billetBasicInfoAdd
-	 */
-	private void updateBilletBasicInfoAsendAssemblyHandle(List<BilletBasicInfo> billetBasicInfoList, BilletBasicInfoAdd billetBasicInfoAdd){
-		if (CollectionUtils.isEmpty(billetBasicInfoList)) {
-			return;
-		}
-		String assemblyNumber = generateUniqueAssemblyNumber(billetBasicInfoAdd.getHeatNo());
-
-		// 为所有记录设置相同的组批号
-		billetBasicInfoList.forEach(item -> item.setAssemblyNumber(assemblyNumber));
-
-		// 使用 MyBatis-Plus 的批量更新方法(默认 batchSize=1000)
-		billetBasicInfoService.updateBatchById(billetBasicInfoList);
-	}
 	/**
 	 * 生成唯一的坯号
 	 *
 	 * @return 坯号
 	 */
 	private String generateUniqueBilletNo(Integer ccmNo, String heatNo) {
-		// 生成雪花算法ID
-		long snowflakeId = IdWorker.getId();
+		// 获取当前时间戳的后4位(毫秒级精度)
+		long timestampPart = System.currentTimeMillis() % 10000;
 
-		// 获取ID的最后3位数字(100-999范围内)
-		int randomPart = (int) (snowflakeId % 900 + 100);
+		// 使用原子计数器确保同一毫秒内的唯一性
+		int counterPart = COUNTER.getAndIncrement() % 1000; // 0-999循环
 
-		// 拼接钢坯号:heatNo + ccmNo + 三位随机数
-		return heatNo + ccmNo + String.format("%03d", randomPart);
+		// 拼接:heatNo + ccmNo + 时间戳后4位 + 3位计数器
+		return heatNo + ccmNo + String.format("%04d", timestampPart) + String.format("%03d", counterPart);
 	}
 
 	/**
@@ -1876,15 +1890,12 @@ public class BilletHotsendBaseServiceImpl extends ServiceImpl<BilletHotsendBaseM
 	 * @return 坯号
 	 */
 	private String generateUniqueAssemblyNumber(String heatNo) {
-		// 生成雪花算法ID
+
 		long snowflakeId = IdWorker.getId();
 
-		// 获取ID的最后3位数字(100-999范围内)
 		int randomPart = (int) (snowflakeId % 900 + 100);
 
-		// 拼接钢坯号:heatNo + ccmNo + 三位随机数
 		return heatNo + String.format("%03d", randomPart);
 	}
-
 }