Bladeren bron

钢坯实绩异常组批开发

qiangxuan 2 weken geleden
bovenliggende
commit
bf5924dd1a

+ 14 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetActual/controller/BilletBasicInfoExceptionController.java

@@ -14,6 +14,7 @@ import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletBasicInfoException;
 import org.jeecg.modules.actualControl.billetActual.billetActual.service.IBilletBasicInfoExceptionService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
 
@@ -159,4 +160,17 @@ public class BilletBasicInfoExceptionController extends JeecgController<BilletBa
        return super.importExcel(request, response, BilletBasicInfoException.class);
    }
 
+    // 5号机 2分钟一次,执行定时任务
+//    @Scheduled(cron = "0 */2 * * * ?")
+    public void executeDayShiftTask() {
+        billetBasicInfoExceptionService.assemblyHandle("5");
+    }
+
+    @AutoLog(value = "钢坯实绩异常组批单元测试")
+    @ApiOperation(value="钢坯实绩异常组批单元测试", notes="钢坯实绩异常组批单元测试")
+    @GetMapping(value = "/assembly")
+    public Result<String> assemblyHandleTest() {
+        billetBasicInfoExceptionService.assemblyHandle("5");
+        return Result.OK("钢坯实绩异常组批成功!");
+    }
 }

+ 69 - 127
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetActual/entity/BilletBasicInfoException.java

@@ -30,180 +30,106 @@ import java.util.Date;
 public class BilletBasicInfoException implements Serializable {
     private static final long serialVersionUID = 1L;
 
-    /**
-     * 主键
-     */
+    /**主键*/
     @TableId(type = IdType.ASSIGN_ID)
     @ApiModelProperty(value = "主键")
     private String id;
-    /**
-     * 创建人
-     */
+    /**创建人*/
     @ApiModelProperty(value = "创建人")
     private String createBy;
-    /**
-     * 创建日期
-     */
-    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    /**创建日期*/
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
     @ApiModelProperty(value = "创建日期")
     private Date createTime;
-    /**
-     * 更新人
-     */
+    /**更新人*/
     @ApiModelProperty(value = "更新人")
     private String updateBy;
-    /**
-     * 更新日期
-     */
-    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    /**更新日期*/
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
     @ApiModelProperty(value = "更新日期")
     private Date updateTime;
-    /**
-     * 所属部门
-     */
+    /**所属部门*/
     @ApiModelProperty(value = "所属部门")
     private String sysOrgCode;
-    /**
-     * 炉号
-     */
+    /**炉号*/
     @Excel(name = "炉号", width = 15)
-    @ApiModelProperty(value = "炉号", required = true)
+    @ApiModelProperty(value = "炉号",required = true)
     private String heatNo;
-    /**
-     * 铸机号
-     */
+    /**铸机号*/
     @Excel(name = "铸机号", width = 15)
-    @ApiModelProperty(value = "铸机号", required = true)
+    @ApiModelProperty(value = "铸机号",required = true)
     private Integer ccmNo;
-    /**班组*/
-    @Excel(name = "班组", width = 15)
-    @ApiModelProperty(value = "班组")
-    @Dict(dicCode = "lg_bz")
-    private String shiftGroup;
-    /**班别*/
-    @Excel(name = "班别", width = 15)
-    @ApiModelProperty(value = "班别")
-    @Dict(dicCode = "lg_bb")
-    private String shift;
-
-    /**
-     * 流号
-     */
-    @Excel(name = "流号", width = 15)
-    @ApiModelProperty(value = "流号", required = true)
-    private Integer strandNo;
-    /**
-     * 拉速
-     */
+    /**拉速*/
     @Excel(name = "拉速", width = 15)
-    @ApiModelProperty(value = "拉速", required = true)
+    @ApiModelProperty(value = "拉速",required = true)
     private Double castingSpeed;
-
-    /**
-     * 坯重
-     */
-    @Excel(name = "坯重", width = 15)
-    @ApiModelProperty(value = "坯重", required = true)
-    private Double billetWeight;
-
-    /**
-     * 流号
-     */
+    /**钢包号*/
     @Excel(name = "钢包号", width = 15)
-    @ApiModelProperty(value = "钢包号", required = true)
-    private Integer ladleNo;
-    /**
-     * 支号
-     */
+    @ApiModelProperty(value = "钢包号",required = true)
+    private String ladleNo;
+    /**流号*/
+    @Excel(name = "流号", width = 15)
+    @ApiModelProperty(value = "流号",required = true)
+    private Integer strandNo;
+    /**炉内顺序号*/
     @Excel(name = "炉内顺序号", width = 15)
-    @ApiModelProperty(value = "炉内顺序号", required = true)
+    @ApiModelProperty(value = "炉内顺序号",required = true)
     private Integer heatnoIndex;
-    /**
-     * 钢种
-     */
+    /**钢种*/
     @Excel(name = "钢种", width = 15)
-    @ApiModelProperty(value = "钢种", required = true)
+    @ApiModelProperty(value = "钢种",required = true)
     private String grade;
-    /**
-     * 定尺
-     */
+    /**定尺*/
     @Excel(name = "定尺", width = 15)
-    @ApiModelProperty(value = "定尺", required = true)
+    @ApiModelProperty(value = "定尺",required = true)
     private Integer length;
-    /**
-     * 实际长度
-     */
+    /**实际长度*/
     @Excel(name = "实际长度", width = 15)
-    @ApiModelProperty(value = "实际长度", required = true)
+    @ApiModelProperty(value = "实际长度",required = true)
     private Integer actualLength;
-    /**
-     * 宽度
-     */
+    /**宽度*/
     @Excel(name = "宽度", width = 15)
-    @ApiModelProperty(value = "宽度", required = true)
+    @ApiModelProperty(value = "宽度",required = true)
     private Integer width;
-    /**
-     * 厚度
-     */
+    /**厚度*/
     @Excel(name = "厚度", width = 15)
-    @ApiModelProperty(value = "厚度", required = true)
+    @ApiModelProperty(value = "厚度",required = true)
     private Integer thickness;
-    /**
-     * 规格
-     */
+    /**规格*/
     @Excel(name = "规格", width = 15)
-    @ApiModelProperty(value = "规格", required = true)
+    @ApiModelProperty(value = "规格",required = true)
     private String spec;
-    /**
-     * 定重
-     */
+    /**定重*/
     @Excel(name = "定重", width = 15)
-    @ApiModelProperty(value = "定重", required = true)
+    @ApiModelProperty(value = "定重",required = true)
     private Double weight;
-    /**
-     * 坯号
-     */
+    /**坯号*/
     @Excel(name = "坯号", width = 15)
-    @ApiModelProperty(value = "坯号", required = true)
+    @ApiModelProperty(value = "坯号",required = true)
     private String billetNo;
-    /**
-     * 顺序号
-     */
+    /**坯号*/
     @Excel(name = "流内顺序号", width = 15)
-    @ApiModelProperty(value = "流内顺序号", required = true)
+    @ApiModelProperty(value = "流内顺序号",required = true)
     private Integer strandnoIndex;
-    /**
-     * 开始切割时间
-     */
+    /**开始切割时间*/
     @Excel(name = "开始切割时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
-    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "开始切割时间", required = true)
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "开始切割时间",required = true)
     private Date cutStartTime;
-    /**
-     * 停止切割时间
-     */
+    /**停止切割时间*/
     @Excel(name = "停止切割时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
-    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @ApiModelProperty(value = "停止切割时间", required = true)
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "停止切割时间",required = true)
     private Date cutStopTime;
-    /**
-     * 判级结果
-     */
+    /**判级结果*/
     @Excel(name = "判级结果", width = 15)
-    @ApiModelProperty(value = "判级结果", required = true)
+    @ApiModelProperty(value = "判级结果",required = true)
     private String ratingsResult;
 
-    /**
-     * 编辑条件
-     */
-    @Excel(name = "编辑条件", width = 15)
-    @ApiModelProperty(value = "编辑条件", required = true)
-    private Integer optype;
-
     /**所属表*/
     @Excel(name = "所属表", width = 15)
     @ApiModelProperty(value = "所属表",required = true)
@@ -219,6 +145,22 @@ public class BilletBasicInfoException implements Serializable {
     @ApiModelProperty(value = "目的地",required = true)
     private String bhtcId;
 
+    /**班组*/
+    @Excel(name = "班组", width = 15)
+    @ApiModelProperty(value = "班组")
+    @Dict(dicCode = "lg_bz")
+    private String shiftGroup;
+    /**班别*/
+    @Excel(name = "班别", width = 15)
+    @Dict(dicCode = "lg_bb")
+    @ApiModelProperty(value = "班别")
+    private String shift;
+
+    /**坯重*/
+    @Excel(name = "坯重", width = 15)
+    @ApiModelProperty(value = "坯重",required = true)
+    private Double billetWeight;
+
     /**
      * 组坯号
      */

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

@@ -11,4 +11,5 @@ import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletBa
  */
 public interface IBilletBasicInfoExceptionService extends IService<BilletBasicInfoException> {
 
+    void assemblyHandle(String ccmNo);
 }

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

@@ -1,20 +1,42 @@
 package org.jeecg.modules.actualControl.billetActual.billetActual.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.util.DateUtils;
 import org.jeecg.common.util.oConvertUtils;
 
+import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletBasicInfo;
 import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletBasicInfoException;
 import org.jeecg.modules.actualControl.billetActual.billetActual.mapper.BilletBasicInfoExceptionMapper;
+import org.jeecg.modules.actualControl.billetActual.billetActual.mapper.BilletBasicInfoMapper;
+import org.jeecg.modules.actualControl.billetActual.billetActual.mapper.BilletRulerConfigMapper;
 import org.jeecg.modules.actualControl.billetActual.billetActual.service.IBilletBasicInfoExceptionService;
+import org.jeecg.modules.actualControl.billetActual.billetActual.service.IBilletBasicInfoService;
+import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.entity.BilletAssemblyNumber;
+import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.mapper.BilletAssemblyNumberMapper;
+import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.service.IBilletAssemblyNumberService;
+import org.jeecg.modules.actualControl.heatsActuals.entity.HeatsActuals;
+import org.jeecg.modules.actualControl.heatsActuals.mapper.HeatsActualsMapper;
+import org.jeecg.modules.actualControl.heatsActuals.service.IHeatsActualsService;
+import org.jeecg.modules.billet.billetHotsend.entity.BilletHotsend;
+import org.jeecg.modules.billet.billetHotsend.mapper.BilletHotsendBaseMapper;
+import org.jeecg.modules.billet.billetHotsend.service.IBilletHotsendBaseService;
+import org.jeecg.modules.billet.billetHotsendConfig.service.IBilletHotsendTypeConfigService;
+import org.jeecg.modules.connConfig.mapper.ConfigMqttMapper;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 钢坯实绩异常表
@@ -26,7 +48,217 @@ import java.util.Date;
 @Slf4j
 public class BilletBasicInfoExceptionServiceImpl extends ServiceImpl<BilletBasicInfoExceptionMapper, BilletBasicInfoException> implements IBilletBasicInfoExceptionService {
 
+    @Autowired
+    private IBilletHotsendTypeConfigService billetHotsendTypeConfigService;
+
+    @Autowired
+    private IBilletBasicInfoService billetBasicInfoService;
+
+    @Autowired
+    private ConfigMqttMapper configMqttMapper;
+
+    @Autowired
+    BilletRulerConfigMapper billetRulerConfigMapper;
+
+    @Autowired
+    IBilletAssemblyNumberService billetAssemblyNumberService;
+
+    @Autowired
+    HeatsActualsMapper heatsActualsMapper;
+
+    @Autowired
+    private IBilletHotsendBaseService billetHotsendBaseService;
+
+    @Autowired
+    private IHeatsActualsService heatsActualsService;
+
     @Autowired
     RedisTemplate redisTemplate;
 
+    @Override
+    public void assemblyHandle(String ccmNo) {
+
+        String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
+        String classShift = String.format("class:shift:%s", ccmNo); // 班
+
+        String classShiftStr = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
+        String classShiftGroupStr = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
+
+        log.info("{}{}", "钢坯实绩接收时缓存中的班组班别:", classShiftGroupStr + " " + classShiftStr);
+
+        if (oConvertUtils.isEmpty(classShiftStr) || oConvertUtils.isEmpty(classShiftGroupStr)) {
+            log.info("{}{}", "钢坯实绩接收时缓存中的班组班别为空!", ccmNo);
+            return;
+        }
+        // 根据ccmNo、班别、班组查询钢坯实绩异常表
+        LambdaQueryWrapper<BilletBasicInfoException> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(BilletBasicInfoException::getCcmNo, ccmNo)
+                .eq(BilletBasicInfoException::getShift, classShiftStr)
+                .eq(BilletBasicInfoException::getShiftGroup, classShiftGroupStr);
+                queryWrapper.orderByDesc(BilletBasicInfoException::getCreateTime);
+        List<BilletBasicInfoException> billetBasicInfoExceptionList = baseMapper.selectList(queryWrapper);
+        if (oConvertUtils.listIsEmpty(billetBasicInfoExceptionList) || billetBasicInfoExceptionList.size() < 4) {
+            log.info("{}{}",  "钢坯实绩异常表数据不足4条!", ccmNo);
+            return;
+        }
+        List<BilletBasicInfo> billetBasicInfoList = new ArrayList<>();
+        billetBasicInfoExceptionList.forEach(x -> {
+            BilletBasicInfo billetBasicInfo = new BilletBasicInfo();
+            BeanUtils.copyProperties(x, billetBasicInfo);
+            billetBasicInfo.setId(String.valueOf(IdWorker.getId()));
+            billetBasicInfoList.add(billetBasicInfo);
+        });
+
+        // 根据ccmNo、班别、班组查询钢坯炉次传递单表
+        LambdaQueryWrapper<BilletHotsend> billetHotsendLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        billetHotsendLambdaQueryWrapper.eq(BilletHotsend::getCcmNo, ccmNo)
+                .eq(BilletHotsend::getShift, classShiftStr)
+                .eq(BilletHotsend::getShiftGroup, classShiftGroupStr)
+                .orderByDesc(BilletHotsend::getCreateTime);
+        List<BilletHotsend> billetHotsendList = billetHotsendBaseService.list(billetHotsendLambdaQueryWrapper);
+        if (oConvertUtils.listIsEmpty(billetHotsendList)) {
+            log.info("{}{}", "当班炉次传递单为空,无法组批!", ccmNo);
+            return;
+        }
+        BilletHotsend secondLastBilletHotsend;
+        // 获取第二条炉次传递单数据
+        if (billetHotsendList.size() >= 2) {
+            secondLastBilletHotsend = billetHotsendList.get(1);
+        } else {
+            log.info("{}", "列表中数据不足,无法获取倒数第二条记录");
+            return;
+        }
+        String heatNo = secondLastBilletHotsend.getHeatNo();
+        // 根据ccmno、heatNo获取钢坯实绩最新的一条
+        LambdaQueryWrapper<BilletBasicInfo> billetBasicInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        billetBasicInfoLambdaQueryWrapper.eq(BilletBasicInfo::getCcmNo, Integer.valueOf(ccmNo))
+                .eq(BilletBasicInfo::getHeatNo, heatNo)
+                .orderByDesc(BilletBasicInfo::getCreateTime).last("limit 1");
+        BilletBasicInfo billetBasicInfo = billetBasicInfoService.getOne(billetBasicInfoLambdaQueryWrapper);
+        if (oConvertUtils.isEmpty(billetBasicInfo)) {
+            log.info("{}{}", "获取指定炉号最新一条钢坯实绩数据为空!", ccmNo + " && " + heatNo);
+            return;
+        }
+        // 获取钢包号
+        String ladleNo = billetBasicInfo.getLadleNo();
+        // 获取炉内顺序号
+        int heatnoIndex = billetBasicInfo.getHeatnoIndex();
+        // 收集最终要移除的钢坯实绩异常数据
+        List<String> removeBilletBasicInfoExceptionIds = new ArrayList<>();
+        // 收集所有需要组批完成后的钢坯实绩信息
+        List<BilletBasicInfo> saveBilletBasicInfoList = new ArrayList<>();
+        // 收集组批实绩
+        List<BilletAssemblyNumber> billetAssemblyNumberList = new ArrayList<>();
+        int size = billetBasicInfoList.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);
+            // 生成组批号(优化:直接生成随机数,避免雪花算法开销)
+            String assemblyNumber = generateUniqueAssemblyNumber(ccmNo, heatNo);
+            // 为当前分组的4条记录设置相同组批号,并添加到更新列表
+            List<BilletBasicInfo> assemblyData = billetBasicInfoList.subList(start, end);
+            List<String> idList = assemblyData.stream()
+                    .map(BilletBasicInfo::getId)
+                    .collect(Collectors.toList());
+            // 记录当前批次的起始索引值
+            final int baseIndex = heatnoIndex + i;
+            assemblyData.forEach(item -> {
+                String billetNo = generateUniqueBilletNo(Integer.valueOf(ccmNo), heatNo);
+                item.setId(String.valueOf(IdWorker.getId()));
+                item.setBilletNo(billetNo);
+                item.setAssemblyNumber(assemblyNumber);
+                item.setHeatNo(heatNo);
+                item.setLadleNo(ladleNo);
+                item.setStrandnoIndex(item.getStrandnoIndex() + 1);
+                item.setShift(classShiftStr);
+                item.setShiftGroup(classShiftGroupStr);
+                // 从baseIndex开始递增设置HeatnoIndex
+                int indexValue = baseIndex + assemblyData.indexOf(item);
+                item.setHeatnoIndex(indexValue);
+            });
+            // 将处理后的4条数据的坯号用逗号连接
+            String joinedBilletNos = assemblyData.stream()
+                    .map(BilletBasicInfo::getBilletNo)
+                    .collect(Collectors.joining(","));
+            // 创建BilletAssemblyNumber记录并添加到列表
+            BilletAssemblyNumber billetAssemblyNumber = new BilletAssemblyNumber();
+            billetAssemblyNumber.setAssemblyNumber(assemblyNumber);
+            billetAssemblyNumber.setHeatNo(heatNo);
+            billetAssemblyNumber.setCcmNo(billetBasicInfo.getCcmNo()); // 使用第一条数据的ccmNo
+            billetAssemblyNumber.setLength(billetBasicInfo.getLength());
+            billetAssemblyNumber.setShift(classShiftStr);
+            billetAssemblyNumber.setShiftGroup(classShiftGroupStr);
+            billetAssemblyNumber.setAssemblyTime(new Date());
+            billetAssemblyNumber.setBilletsNo(joinedBilletNos); // 添加拼接的坯号
+            double totalBilletWeight = assemblyData.stream()
+                    .mapToDouble(BilletBasicInfo::getBilletWeight)
+                    .sum();
+            billetAssemblyNumber.setBilletWeight(totalBilletWeight);
+
+            // 收集组批实绩信息
+            billetAssemblyNumberList.add(billetAssemblyNumber);
+
+            // 收集钢坯实绩信息
+            saveBilletBasicInfoList.addAll(assemblyData);
+
+            // 收集组批成功后,需要移除的钢坯实绩异常数据
+            removeBilletBasicInfoExceptionIds.addAll(idList);
+        }
+
+        // 批量保存钢坯实绩
+        billetBasicInfoService.saveBatch(saveBilletBasicInfoList);
+
+        // 保存组批实绩
+        billetAssemblyNumberService.saveBatch(billetAssemblyNumberList);
+
+        // 更新炉次传递单中的数量和总重
+        double totalBilletWeight = saveBilletBasicInfoList.stream()
+                .mapToDouble(BilletBasicInfo::getBilletWeight)
+                .sum();
+        secondLastBilletHotsend.setBlankOutput(totalBilletWeight);
+        secondLastBilletHotsend.setAmountTotal(saveBilletBasicInfoList.size());
+        billetHotsendBaseService.updateById(secondLastBilletHotsend);
+
+        // 更新炉次实绩中的总重和数量
+        HeatsActuals heatsActuals = heatsActualsService.getOne(new LambdaQueryWrapper<HeatsActuals>()
+                .eq(HeatsActuals::getHeatsCode, heatNo)
+                .eq(HeatsActuals::getCasterCode, ccmNo));
+        if (heatsActuals != null){
+            heatsActuals.setBlankOutput(totalBilletWeight);
+            heatsActuals.setBilletSum(saveBilletBasicInfoList.size());
+            heatsActualsService.updateById(heatsActuals);
+        }
+
+        // 移除组批成功的钢坯实绩异常数据
+        if (oConvertUtils.listIsNotEmpty(removeBilletBasicInfoExceptionIds)){
+            baseMapper.deleteBatchIds(removeBilletBasicInfoExceptionIds);
+        }
+    }
+
+    /**
+     * 生成唯一的坯号
+     *
+     * @return 坯号
+     */
+    private String generateUniqueBilletNo(Integer ccmNo, String heatNo) {
+        String billetNo;
+        do {
+            billetNo = heatNo + String.format("%04d", (int)(Math.random() * 10000));
+        } while (billetBasicInfoService.exists(new QueryWrapper<BilletBasicInfo>().eq("billet_no", billetNo). eq("ccm_no", ccmNo)));
+        return billetNo;
+    }
+
+    /**
+     * 生成唯一的组坯号
+     *
+     * @return 坯号
+     */
+    private String generateUniqueAssemblyNumber(String ccmNo, String heatNo) {
+        String assembly_number;
+        do {
+            assembly_number = heatNo + String.format("%07d", (int)(Math.random() * 10000000));
+        } while (billetAssemblyNumberService.checkAssemblyNumberNumber(ccmNo, assembly_number));
+        return assembly_number;
+    }
 }

+ 1 - 1
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetAssemblyNumber/service/IBilletAssemblyNumberService.java

@@ -10,5 +10,5 @@ import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.entity.
  * @Version: V1.0
  */
 public interface IBilletAssemblyNumberService extends IService<BilletAssemblyNumber> {
-
+    boolean checkAssemblyNumberNumber(String ccmNo, String assemblyNumber);
 }

+ 13 - 0
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/actualControl/billetActual/billetAssemblyNumber/service/impl/BilletAssemblyNumberServiceImpl.java

@@ -1,9 +1,12 @@
 package org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.entity.BilletAssemblyNumber;
 import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.mapper.BilletAssemblyNumberMapper;
 import org.jeecg.modules.actualControl.billetActual.billetAssemblyNumber.service.IBilletAssemblyNumberService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
@@ -15,4 +18,14 @@ import org.springframework.stereotype.Service;
 @Service
 public class BilletAssemblyNumberServiceImpl extends ServiceImpl<BilletAssemblyNumberMapper, BilletAssemblyNumber> implements IBilletAssemblyNumberService {
 
+    @Autowired
+    private BilletAssemblyNumberMapper billetAssemblyNumberMapper;
+
+    @Override
+    public boolean checkAssemblyNumberNumber(String ccmNo, String assemblyNumber) {
+        LambdaQueryWrapper<BilletAssemblyNumber> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(BilletAssemblyNumber::getAssemblyNumber, assemblyNumber)
+                .eq(BilletAssemblyNumber::getCcmNo, ccmNo);
+        return billetAssemblyNumberMapper.exists(queryWrapper);
+    }
 }