Pārlūkot izejas kodu

Merge branch 'mode-min-unit-sc' into mode-min-unit

sucheng 6 mēneši atpakaļ
vecāks
revīzija
dde297dd52

+ 2 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/dao/ApsBlankOrderDao.java

@@ -159,4 +159,6 @@ public interface ApsBlankOrderDao extends BaseMapper<ApsBlankOrderDo> {
     void removeLockNextDayProcessEqu(@Param("needScheduleDate") String needScheduleDate);
 
     void removeLockNextTwoDayProcessEqu(@Param("needScheduleDate") String needScheduleDate);
+
+    List<ApsProcessOperationProcessEquChongpaiVo> selectNeedRescheduleEqu(@Param("needScheduleDate") String needScheduleDate,@Param("tenantId") String tenantId);
 }

+ 2 - 2
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/ApsService.java

@@ -11,8 +11,8 @@ import java.util.Map;
 
 public interface ApsService {
 
-    void apsSchedule(List<ApsBlankOrderVo> apsBlankOrders, ApsTypeVo apsType, SysUserVo currentUser);
+    void apsSchedule(List<ApsBlankOrderVo> apsBlankOrders, ApsTypeVo apsType, SysUserVo currentUser,List<String> needUnLockProcessIdList);
 
-    ProductionScheduleVo apsProductionScheduleInit(List<ApsBlankOrderVo> apsBlankOrders, Date apsPlanStartDate);
+    ProductionScheduleVo apsProductionScheduleInit(List<ApsBlankOrderVo> apsBlankOrders, Date apsPlanStartDate,List<String> needUnLockProcessIdList);
 
 }

+ 148 - 11
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsBlankOrderServiceImpl.java

@@ -733,7 +733,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
      */
     @Override
     public void blankOrderAps(List<ApsBlankOrderVo> apsBlankOrders) {
-        apsService.apsSchedule(apsBlankOrders, null, null);
+        apsService.apsSchedule(apsBlankOrders, null, null,null);
     }
 
     /**
@@ -3267,7 +3267,7 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
     public void insertSchedule(Map<String, Object> params) {
         List<ApsBlankOrderVo> apsBlankOrders = apsBlankOrderDao.getByOrderBlanckId(params.get("PRODUCTIONORDERID").toString(), params.get("BLANKORDERID").toString());
         if (apsBlankOrders != null && apsBlankOrders.size() > 0) {
-            apsService.apsSchedule(apsBlankOrders, new ApsTypeVo(), null);
+            apsService.apsSchedule(apsBlankOrders, new ApsTypeVo(), null,null);
         }
     }
 
@@ -3986,21 +3986,158 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
         }
 
         if (ObjectUtil.isNotEmpty(needScheduleDate)) {
+            //计算重排开始时间和结束时间
+            DateTime chongpaiStartDate = DateUtil.parseDate(needScheduleDate);
+            DateTime chongpaiEndDate = DateUtil.endOfDay(chongpaiStartDate);
+
             //将实际完工时间大于明天的作业挪到实际完工时间
             this.baseMapper.updateFinishDateAboutProcessEqu(needScheduleDate);
-            //解锁明天有开工作业明细的坯料计划的所有作业明细
-            this.baseMapper.removeLockNextDayProcessEqu(needScheduleDate);
-            //解锁后天开工的所有作业明细
-            this.baseMapper.removeLockNextTwoDayProcessEqu(needScheduleDate);
-            //获取排程类型
+            //查询在重排时间前一天之后的所有作业明细信息,不包括:铸轧、成退、中退、小卷成退
+            List<ApsProcessOperationProcessEquChongpaiVo> list = this.baseMapper.selectNeedRescheduleEqu(needScheduleDate, CXCommonUtils.getCurrentUserFactoryId(null));
+            //查询重排时间的所有作业明细
+            List<ApsProcessOperationProcessEquChongpaiVo> needScheduleList = list.stream().filter(item ->
+                    item.getPlanstartdate().compareTo(chongpaiStartDate) >= 0
+                            && item.getPlanstartdate().compareTo(chongpaiEndDate) <= 0
+            ).collect(Collectors.toList());
+            //查询重排时间前一天的所有作业明细
+            List<ApsProcessOperationProcessEquChongpaiVo> beforeScheduleList = list.stream().filter(item -> item.getPlanstartdate().compareTo(chongpaiStartDate) < 0).collect(Collectors.toList());
+            //重排时间前一天的所有作业明细ID
+            List<String> beforeScheduleIdList = beforeScheduleList.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList());
+            //查询重排时间后的所有作业明细
+            List<ApsProcessOperationProcessEquChongpaiVo> afterScheduleList = list.stream().filter(item -> item.getPlanstartdate().compareTo(chongpaiEndDate) > 0).collect(Collectors.toList());
+            //重排时间后的所有作业明细ID
+            List<String> afterScheduleIdList = beforeScheduleList.stream().map(ApsProcessOperationProcessEquDo::getId).collect(Collectors.toList());
+
+            //排程设置
             ApsScheduleConfigDo apsScheduleConfigDo = apsScheduleConfigService.getById("1");
+            //分析重排时间之后的作业明细,将(可以开工时间)为重排时间的加入
+            for (ApsProcessOperationProcessEquChongpaiVo apsProcessOperationProcessEquDo : afterScheduleList) {
+                //如果有前道明细
+                if (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getPreviousprocessesids())) {
+                    //查询前道明细
+                    ApsProcessOperationProcessEquChongpaiVo previousEqu = needScheduleList.stream().filter(item -> item.getId().equals(apsProcessOperationProcessEquDo.getPreviousprocessesids())).findFirst().orElse(null);
+                    //前道明细不为null
+                    if (ObjectUtil.isNotEmpty(previousEqu)) {
+                        //当前明细对应作业的最小流转时间
+                        long minReturnTime = apsProcessOperationProcessEquDo.getMinflowwaitmin().longValue();
+                        //确定使用哪个最小流转时间
+                        /*
+                         * 如果作业明细加工设备相同,则该作业最小流转时间=取其大(排程设置的机台流转时间,作业的最小流转等待时间)
+                         * 如果作业明细加工车间不同,则该作业最小流转时间=取其大(排程设置的车间流转时间,作业的最小流转等待时间)
+                         * 如果作业明细加工工厂不同,则该作业最小流转时间=取其大(排程设置的工厂流转时间,作业的最小流转等待时间)
+                         */
+                        //作业明细加工设备不相同
+                        if (!previousEqu.getProcessdeviceid().equals(apsProcessOperationProcessEquDo.getProcessdeviceid())) {
+                            if (apsScheduleConfigDo.getWorkshopin().longValue() > minReturnTime) {
+                                minReturnTime = apsScheduleConfigDo.getWorkshopin().longValue();
+                            }
+                        }
+                        //作业明细加工车间不同
+                        if (!previousEqu.getProcessworkshopid().equals(apsProcessOperationProcessEquDo.getProcessworkshopid())) {
+                            if (apsScheduleConfigDo.getWorkshopcross().longValue() > minReturnTime) {
+                                minReturnTime = apsScheduleConfigDo.getWorkshopcross().longValue();
+                            }
+                        }
+                        if (!previousEqu.getDeviceFactory().equals(apsProcessOperationProcessEquDo.getDeviceFactory())) {
+                            if (apsScheduleConfigDo.getFactorycross().longValue() > minReturnTime) {
+                                minReturnTime = apsScheduleConfigDo.getFactorycross().longValue();
+                            }
+                        }
+                        //可以开工时间 = 前道明细计划完工时间+最小流转时间
+                        DateTime canStartDate = DateUtil.offsetMinute(previousEqu.getPlanenddate(), Integer.parseInt(String.valueOf(minReturnTime)));
+                        //可以开工时间 <= 重排结束时间,放入重排
+                        if (canStartDate.isBeforeOrEquals(chongpaiEndDate)) {
+                            needScheduleList.add(apsProcessOperationProcessEquDo);
+                        }
+                    }
+                }
+            }
+
+            //所有需要解锁的明细集合
+            List<ApsProcessOperationProcessEquChongpaiVo> needUnLockList = new LinkedList<>(needScheduleList);
+
+            for (ApsProcessOperationProcessEquChongpaiVo apsProcessOperationProcessEquDo : needScheduleList) {
+                //前道作业明细ID不为空
+                if (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getPreviousprocessesids())) {
+                    //如果存在
+                    if (beforeScheduleIdList.contains(apsProcessOperationProcessEquDo.getPreviousprocessesids())) {
+                        String previousprocessesid = apsProcessOperationProcessEquDo.getPreviousprocessesids();
+                        //循环寻找前道明细
+                        while (true) {
+                            if (StringUtils.isBlank(previousprocessesid)) {
+                                break;
+                            }
+                            //上一个明细
+                            String finalPreviousprocessesid = previousprocessesid;
+                            ApsProcessOperationProcessEquChongpaiVo previousEqu = beforeScheduleList.stream().filter(item -> finalPreviousprocessesid.equals(item.getId())).findFirst().orElse(null);
+                            if (ObjectUtil.isNotEmpty(previousEqu)) {
+                                needUnLockList.add(previousEqu);
+                                if (ObjectUtil.isNotEmpty(previousEqu.getPreviousprocessesids())) {
+                                    previousprocessesid = previousEqu.getPreviousprocessesids();
+                                } else {
+                                    break;
+                                }
+                            } else {
+                                break;
+                            }
+                        }
+                    }
+                }
+                //后道明细不为空
+                if (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getNextprocessesids())) {
+                    getNextProcess(apsProcessOperationProcessEquDo.getNextprocessesids(),afterScheduleList,afterScheduleIdList,needUnLockList);
+                }
+            }
+            //需要解锁的明细ID
+            List<String> needUnLockProcessEquIdList = needUnLockList.stream().map(ApsProcessOperationProcessEquChongpaiVo::getId).distinct().collect(Collectors.toList());
+            //需要解锁的作业ID
+            List<String> needUnLockProcessIdList = needUnLockList.stream().map(ApsProcessOperationProcessEquChongpaiVo::getProcessid).distinct().collect(Collectors.toList());
+            //解锁
+            apsProcessOperationProcessEquService.update(
+                    new LambdaUpdateWrapper<ApsProcessOperationProcessEquDo>()
+                            .set(ApsProcessOperationProcessEquDo::getLockmark,"n")
+                            .in(ApsProcessOperationProcessEquDo::getId,needUnLockProcessEquIdList));
+            apsProcessOperationService.update(
+                    new LambdaUpdateWrapper<ApsProcessOperationDo>()
+                            .set(ApsProcessOperationDo::getLockmark, "n")
+                            .in(ApsProcessOperationDo::getId,needUnLockProcessIdList)
+            );
+
+//            //解锁明天有开工作业明细的坯料计划的所有作业明细
+//            this.baseMapper.removeLockNextDayProcessEqu(needScheduleDate);
+//            //解锁后天开工的所有作业明细
+//            this.baseMapper.removeLockNextTwoDayProcessEqu(needScheduleDate);
             String scheduletype = apsScheduleConfigDo.getScheduletype();
             ApsTypeVo apsTypeVo = BeanUtil.toBean(scheduletype, ApsTypeVo.class);
-            apsTypeVo.setMixIf("mix");
-            apsTypeVo.setThMergeMode("notThMergeBf");
-            apsTypeVo.setConstraintMode("lz");
+//            apsTypeVo.setMixIf("mix");
+//            apsTypeVo.setThMergeMode("notThMergeBf");
+//            apsTypeVo.setConstraintMode("lz");
             //重新排程
-            apsService.apsSchedule(new ArrayList<>(), apsTypeVo, null);
+            apsService.apsSchedule(new ArrayList<>(), apsTypeVo, null,needUnLockProcessIdList);
+        }
+    }
+
+    //迭代处理寻找下道明细
+    private void getNextProcess(String nextprocessesids,
+                                List<ApsProcessOperationProcessEquChongpaiVo> afterScheduleList,
+                                List<String> afterScheduleIdList,
+                                List<ApsProcessOperationProcessEquChongpaiVo> needUnLockList) {
+        if (ObjectUtil.isEmpty(nextprocessesids)) {
+            return;
+        }
+        for (String nextProcessEquId : nextprocessesids.split(",")) {
+            //如果存在
+            if (afterScheduleIdList.contains(nextProcessEquId)) {
+                //下一个明细
+                ApsProcessOperationProcessEquChongpaiVo nextEqu = afterScheduleList.stream().filter(item -> item.getId().equals(nextProcessEquId)).findFirst().orElse(null);
+                if (ObjectUtil.isNotEmpty(nextEqu)) {
+                    needUnLockList.add(nextEqu);
+                    if (ObjectUtil.isNotEmpty(nextEqu.getPreviousprocessesids())) {
+                        String nextNewProcessesids = nextEqu.getPreviousprocessesids();
+                        getNextProcess(nextNewProcessesids,afterScheduleList,afterScheduleIdList,needUnLockList);
+                    }
+                }
+            }
         }
     }
 }

+ 19 - 12
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONConfig;
 import cn.hutool.json.JSONUtil;
@@ -88,9 +89,10 @@ public class ApsServiceImpl implements ApsService {
      * Aps排程
      * @param apsBlankOrders
      * @param apsType cd:插单,lzcp:冷轧连续重排,mix:混合排程
+     * @param needUnLockProcessIdList 需要过滤的工序作业ID集合
      */
     @Override
-    public void apsSchedule(List<ApsBlankOrderVo> apsBlankOrders,ApsTypeVo apsType,SysUserVo currentUser) {
+    public void apsSchedule(List<ApsBlankOrderVo> apsBlankOrders,ApsTypeVo apsType,SysUserVo currentUser,List<String> needUnLockProcessIdList) {
         logger.info("**********排程请求开始**********");
         // 当前等路人所属工厂
         if(currentUser == null){
@@ -145,9 +147,9 @@ public class ApsServiceImpl implements ApsService {
                 }
                 // 冷轧连续性问题重排
                 if(apsType != null && StrUtil.isNotBlank(apsType.getMixIf()) && "mix".equals(apsType.getMixIf())){
-                    lzlxOrderSchedule(apsBlankOrders,currentUser,apsType);
+                    lzlxOrderSchedule(apsBlankOrders,currentUser,apsType,needUnLockProcessIdList);
                 }else{
-                    apsOrderScheduleNew(apsBlankOrders,currentUser,apsType);
+                    apsOrderScheduleNew(apsBlankOrders,currentUser,apsType,needUnLockProcessIdList);
                 }
             } catch (Exception e) {
                 e.printStackTrace();
@@ -285,7 +287,7 @@ public class ApsServiceImpl implements ApsService {
                 dataMapOrder.put(bo.getId(),bo);
 
                 // 模型转换
-                ProductionScheduleVo productionScheduleVo = apsProductionScheduleInit(v,new Date());
+                ProductionScheduleVo productionScheduleVo = apsProductionScheduleInit(v,new Date(),null);
                 productionScheduleVos.add(productionScheduleVo);
                 dataMap.put(productionScheduleVo.getProductionScheduleId(),v);
 //                        int mergeThNum = mergeThNum(bo, productionScheduleVo);
@@ -337,7 +339,7 @@ public class ApsServiceImpl implements ApsService {
         });
     }
 
-    private void apsOrderScheduleNew(List<ApsBlankOrderVo> apsBlankOrders,SysUserVo currentUser,ApsTypeVo apsType){
+    private void apsOrderScheduleNew(List<ApsBlankOrderVo> apsBlankOrders,SysUserVo currentUser,ApsTypeVo apsType,List<String> needUnLockProcessIdList){
         // 插单重排的优先排程
         List<ApsBlankOrderVo> cdorders = apsBlankOrders.stream().filter(v -> "1".equals(v.getCdbs())).collect(Collectors.toList());
         // 先按合金,合金状态分组,再每组分别排程
@@ -364,7 +366,7 @@ public class ApsServiceImpl implements ApsService {
         Date finalApsPlanStartDate = apsPlanStartDate;
         if(cdorders != null && cdorders.size()>0){
             try{
-                apsOrderScheduleApsNew(cdorders,currentUser,allEqs, finalApsPlanStartDate,apsType);
+                apsOrderScheduleApsNew(cdorders,currentUser,allEqs, finalApsPlanStartDate,apsType,needUnLockProcessIdList);
             }catch (Exception e) {
                 e.printStackTrace();
                 logger.info("排程异常",e);
@@ -460,7 +462,7 @@ public class ApsServiceImpl implements ApsService {
                         }
                         return a;
                     });
-                    apsOrderScheduleApsNew(v,currentUser,allEqs, finalApsPlanStartDate,apsType);
+                    apsOrderScheduleApsNew(v,currentUser,allEqs, finalApsPlanStartDate,apsType,null);
                 }catch (Exception e) {
                     e.printStackTrace();
                     logger.info("排程异常",e);
@@ -490,7 +492,7 @@ public class ApsServiceImpl implements ApsService {
      * @param apsBlankOrders
      * @param currentUser
      */
-    private void lzlxOrderSchedule(List<ApsBlankOrderVo> apsBlankOrders,SysUserVo currentUser,ApsTypeVo apsType){
+    private void lzlxOrderSchedule(List<ApsBlankOrderVo> apsBlankOrders,SysUserVo currentUser,ApsTypeVo apsType,List<String> needUnLockProcessIdList){
         // 坯料计划排序
         Collections.sort(apsBlankOrders,(v1,v2)->{
             // 合金
@@ -579,10 +581,10 @@ public class ApsServiceImpl implements ApsService {
             }
         }
         Date finalApsPlanStartDate = apsPlanStartDate;
-        apsOrderScheduleApsNew(apsBlankOrders,currentUser,allEqs, finalApsPlanStartDate,apsType);
+        apsOrderScheduleApsNew(apsBlankOrders,currentUser,allEqs, finalApsPlanStartDate,apsType,needUnLockProcessIdList);
     }
 
-    private void apsOrderScheduleApsNew(List<ApsBlankOrderVo> apsBlankOrders,SysUserVo currentUser,Map<String,Equipment> allEqs,Date apsPlanStartDate,ApsTypeVo apsType){
+    private void apsOrderScheduleApsNew(List<ApsBlankOrderVo> apsBlankOrders,SysUserVo currentUser,Map<String,Equipment> allEqs,Date apsPlanStartDate,ApsTypeVo apsType,List<String> needUnLockProcessIdList){
         // 设备数据每批次开始清空
         allEqs.clear();
         // 排程前解锁所有待排程订单
@@ -630,7 +632,7 @@ public class ApsServiceImpl implements ApsService {
                 dataMapOrder.put(bo.getId(),bo);
 
                 // 模型转换
-                ProductionScheduleVo productionScheduleVo = apsProductionScheduleInit(v,apsPlanStartDate);
+                ProductionScheduleVo productionScheduleVo = apsProductionScheduleInit(v,apsPlanStartDate,needUnLockProcessIdList);
                 productionScheduleVos.add(productionScheduleVo);
                 dataMap.put(productionScheduleVo.getProductionScheduleId(),v);
 //                        int mergeThNum = mergeThNum(bo, productionScheduleVo);
@@ -855,7 +857,7 @@ public class ApsServiceImpl implements ApsService {
      * @return
      */
     @Override
-    public ProductionScheduleVo apsProductionScheduleInit(List<ApsBlankOrderVo> apsBlankOrders,Date apsPlanStartDate) {
+    public ProductionScheduleVo apsProductionScheduleInit(List<ApsBlankOrderVo> apsBlankOrders,Date apsPlanStartDate,List<String> needUnLockProcessIdList) {
         // 待排程坯料计划ID集合
         List<String> blankids = apsBlankOrders.stream().map(v -> v.getId()).collect(Collectors.toList());
         // 查询当前坯料计划的历史排程明细
@@ -906,6 +908,11 @@ public class ApsServiceImpl implements ApsService {
                 Map<String, ProductionProcesses> lockHbPp = new HashMap<>();
                 // 转换工序模型数据
                 for (ApsProcessOperationDo operationDo : operationDos) {
+                    if (null != needUnLockProcessIdList){
+                        if (!needUnLockProcessIdList.contains(operationDo.getId())){
+                            continue;
+                        }
+                    }
                     processIdss.add(operationDo.getId());
                     ProductionProcesses processes = new ProductionProcesses();
                     // 工序所属订单

+ 17 - 0
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsBlankOrderDao.xml

@@ -406,4 +406,21 @@
             apo.DELETED = 0
           AND apo.ID = #{productionorderid}
     </select>
+    <select id="selectNeedRescheduleEqu"
+            resultType="com.rongwei.bsentity.vo.ApsProcessOperationProcessEquChongpaiVo">
+        SELECT
+            apope.*,
+            IFNULL(apo.MINFLOWWAITMIN,0) AS 'minflowwaitmin',
+            aci.TENANTID AS 'deviceFactory'
+        FROM
+            aps_process_operation apo
+                LEFT JOIN aps_process_operation_process_equ apope ON apo.ID = apope.PROCESSID AND apope.DELETED = 0
+                LEFT JOIN asp_check_items aci ON apope.PROCESSDEVICEID = aci.ID AND aci.DELETED = 0
+        WHERE
+            apo.DELETED = 0
+          AND apo.PROCESS NOT IN ( '铸轧', '成退', '中退', '小卷成退' )
+          AND apope.PLANSTARTDATE >= DATE_SUB('2025-02-12', INTERVAL 1 DAY)
+          and apope.WORKSTATUS = '待开工'
+          AND apope.TENANTID = #{tenantId}
+    </select>
 </mapper>

+ 23 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/ApsProcessOperationProcessEquChongpaiVo.java

@@ -0,0 +1,23 @@
+package com.rongwei.bsentity.vo;
+
+import com.rongwei.bsentity.domain.ApsProcessOperationProcessEquDo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author :sc
+ * @since :2025/2/11
+ */
+@Data
+public class ApsProcessOperationProcessEquChongpaiVo extends ApsProcessOperationProcessEquDo {
+    /**
+     * 最小流转等待时间
+     */
+    private BigDecimal minflowwaitmin;
+
+    /**
+     * 设备所属工厂ID
+     */
+    private String deviceFactory;
+}