From 14dba4b7200428aaa86a1d301566428791251875 Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Wed, 26 Feb 2025 13:49:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=92=E5=BA=8F=E6=8E=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mes/pcn/api/base/IMesProdOrgExtService.java | 8 +- .../IMesProductionCustomContextStepService.java | 9 +++ .../pcn/api/busi/IMesQueueOrderPushService.java | 8 +- .../serviceimpl/base/MesProdOrgExtService.java | 21 ++--- .../serviceimpl/busi/MesQueueOrderPushService.java | 24 +++++- .../step/MesProductSeqCheckNosortStepService.java | 10 +-- .../step/MesWorkOrderQueueAcceptStepService.java | 93 ++++++++++++++++++++-- .../MesProductionCustomContextStepService.java | 24 +++++- .../MesProductionProcessContextStepService.java | 30 ++++++- .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 2 + 10 files changed, 194 insertions(+), 35 deletions(-) diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesProdOrgExtService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesProdOrgExtService.java index 1e8d145..979e94d 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesProdOrgExtService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/base/IMesProdOrgExtService.java @@ -1,6 +1,9 @@ package cn.estsh.i3plus.ext.mes.pcn.api.base; -import cn.estsh.i3plus.pojo.mes.bean.*; +import cn.estsh.i3plus.pojo.mes.bean.MesCraft; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCellExtendCfg; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter; import io.swagger.annotations.ApiOperation; import java.util.List; @@ -53,7 +56,4 @@ public interface IMesProdOrgExtService { @ApiOperation(value = "根据生产线代码,工位代码查询主子工位实虚关系信息") List getWorkCellExtendCfgRvListByBak(String organizeCode, String workCenterCodeBak, String workCellCodeBak); - @ApiOperation(value = "根据生产线代码,工位代码查询生产队列推送工位配置信息") - List getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode, String workCellCode); - } diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java index 220d388..e20c35d 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionCustomContextStepService.java @@ -103,4 +103,13 @@ public interface IMesProductionCustomContextStepService { @ApiOperation(value = "删除打包数据") void removePackageDataContext(StationRequestBean reqBean); + @ApiOperation(value = "获取排序线工单队列推送锁数据") + List getSortQueuePushLockContext(String orgainzeCode, String workCenterCode); + + @ApiOperation(value = "保存排序线工单队列推送锁数据") + Boolean dispatchSortQueuePushLockContext(String organizeCode, String workCenterCode, String queuePushId); + + @ApiOperation(value = "删除排序线工单队列推送锁数据") + void removeSortQueuePushLockContext(String orgainzeCode, String workCenterCode, String queuePushId); + } diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesQueueOrderPushService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesQueueOrderPushService.java index f4d92f8..976561c 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesQueueOrderPushService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesQueueOrderPushService.java @@ -9,6 +9,12 @@ import java.util.List; public interface IMesQueueOrderPushService { + @ApiOperation(value = "根据生产线代码,工位代码查询生产队列推送工位配置信息") + List getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode, String workCellCode); + + @ApiOperation(value = "根据生产线代码查询生产队列推送工位配置信息") + List getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode); + //递增步长10,取整10位; 例如:查询=10 >> 返回=20 ; 查询=29 >> 返回=30 @ApiOperation(value = "获取当前工单对应的工位推单队列中最大的顺序号") Integer getQueueOrderPushMaxSeq(String organizeCode, String workOrderNo); @@ -17,6 +23,6 @@ public interface IMesQueueOrderPushService { void insertQueueOrderPush(String organizeCode, String userInfo, MesProduceSn produceSn, List queueOrderPushCellCfgList); @ApiOperation(value = "根据配置查询生产队列工位推送信息") - List getQueueOrderPushList(String organizeCode, List queueOrderPushCellCfgList, Integer count); + List getQueueOrderPushList(String organizeCode, List queueOrderPushCellCfgList); } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesProdOrgExtService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesProdOrgExtService.java index bc4819c..c5a840e 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesProdOrgExtService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/base/MesProdOrgExtService.java @@ -5,8 +5,14 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; -import cn.estsh.i3plus.pojo.mes.bean.*; -import cn.estsh.i3plus.pojo.mes.repository.*; +import cn.estsh.i3plus.pojo.mes.bean.MesCraft; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCellExtendCfg; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter; +import cn.estsh.i3plus.pojo.mes.repository.MesCraftRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesWorkCellExtendCfgRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesWorkCellRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesWorkCenterRepository; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -33,9 +39,6 @@ public class MesProdOrgExtService implements IMesProdOrgExtService { @Autowired private MesWorkCellExtendCfgRepository workCellExtendCfgRepository; - @Autowired - private MesQueueOrderPushCellCfgRepository queueOrderPushCellCfgRepository; - @Override public MesWorkCenter getWorkCenterDb(String organizeCode, String workCenterCode) { if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null; @@ -183,12 +186,4 @@ public class MesProdOrgExtService implements IMesProdOrgExtService { return getWorkCellExtendCfgList(organizeCode, workCellExtendCfg.getWorkCenterCode(), workCellExtendCfg.getWorkCellCode(), MesExtEnumUtil.WORK_CELL_EXTEND_TYPE.RV.getValue()); } - @Override - public List getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode, String workCellCode) { - if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode)) return null; - return queueOrderPushCellCfgRepository.findByProperty( - new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE}, - new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode}); - } - } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java index eb7ad9a..a36c39a 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesQueueOrderPushService.java @@ -9,6 +9,7 @@ import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn; import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush; import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPushCellCfg; +import cn.estsh.i3plus.pojo.mes.repository.MesQueueOrderPushCellCfgRepository; import cn.estsh.i3plus.pojo.mes.repository.MesQueueOrderPushRepository; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -23,8 +24,27 @@ import java.util.stream.Collectors; public class MesQueueOrderPushService implements IMesQueueOrderPushService { @Autowired + private MesQueueOrderPushCellCfgRepository queueOrderPushCellCfgRepository; + + @Autowired private MesQueueOrderPushRepository queueOrderPushRepository; + @Override + public List getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode, String workCellCode) { + if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode)) return null; + return queueOrderPushCellCfgRepository.findByProperty( + new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE}, + new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode}); + } + + @Override + public List getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode) { + if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null; + return queueOrderPushCellCfgRepository.findByProperty( + new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE}, + new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode}); + } + //获取当前工单对应的工位推单队列中最大的顺序号; 递增步长10,取整10位; 例如:查询=10 >> 返回=20 ; 查询=29 >> 返回=30 @Override public Integer getQueueOrderPushMaxSeq(String organizeCode, String workOrderNo) { @@ -63,7 +83,7 @@ public class MesQueueOrderPushService implements IMesQueueOrderPushService { //根据配置查询生产队列工位推送信息 @Override - public List getQueueOrderPushList(String organizeCode, List queueOrderPushCellCfgList, Integer count) { + public List getQueueOrderPushList(String organizeCode, List queueOrderPushCellCfgList) { if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(queueOrderPushCellCfgList)) return null; //搜集推送来源代码 去重 @@ -79,7 +99,7 @@ public class MesQueueOrderPushService implements IMesQueueOrderPushService { if (pushSourceCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(pushSourceCodeList.get(0), MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean); else DdlPreparedPack.getInPackList(pushSourceCodeList, MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean); DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.CREATE_DATE_TIME}, packBean); - return queueOrderPushRepository.findByHqlTopWhere(packBean, count); + return queueOrderPushRepository.findByHqlWhere(packBean); } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSeqCheckNosortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSeqCheckNosortStepService.java index 58478b0..3a8988c 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSeqCheckNosortStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSeqCheckNosortStepService.java @@ -90,10 +90,10 @@ public class MesProductSeqCheckNosortStepService extends MesProductSeqCheckStepS private void doHandleProductSeqCheck(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, List productionPartContextList) { //非排序顺序防错级别配置[工位参数] - String cavityNosortCfg = getCheckProductSeqCfg(reqBean); + String checkProductSeqCfg = getCheckProductSeqCfg(reqBean); //当是零件级别的配置的时候 搜集工单号 去重 - List filterWorkOrderNoList = StringUtils.isEmpty(cavityNosortCfg) ? null : + List filterWorkOrderNoList = StringUtils.isEmpty(checkProductSeqCfg) ? null : (productionPartContextList.stream().filter(o -> (null != o && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)) .map(MesProductionPartContext::getWorkOrderNo).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList()); @@ -106,7 +106,7 @@ public class MesProductSeqCheckNosortStepService extends MesProductSeqCheckStepS if (productionPartContext.getCheckSeqResult().compareTo(MesPcnExtConstWords.ZERO) != 0) continue; //顺序防错验证 - Boolean result = doProductSeqCheckNosort(reqBean, stepResult, productionProcessContext, productionPartContext, cavityNosortCfg, filterWorkOrderNoList); + Boolean result = doProductSeqCheckNosort(reqBean, stepResult, productionProcessContext, productionPartContext, checkProductSeqCfg, filterWorkOrderNoList); productionPartContext.checkSeqResult(!result ? CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() : CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()); @@ -130,13 +130,13 @@ public class MesProductSeqCheckNosortStepService extends MesProductSeqCheckStepS //前道工艺防错验证 【非排序】 private Boolean doProductSeqCheckNosort(StationRequestBean reqBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, - MesProductionPartContext productionPartContext, String cavityNosortCfg, List workOrderNoList) { + MesProductionPartContext productionPartContext, String checkProductSeqCfg, List workOrderNoList) { String message = StringUtils.isEmpty(stepResult.getMsg()) ? MesPcnExtConstWords.EMPTY : stepResult.getMsg() + MesPcnExtConstWords.SEMICOLON; //根据生产工单顺序号,生产线代码查询上一个生产工单信息 MesWorkOrder workOrder; - if (StringUtils.isEmpty(cavityNosortCfg)) { + if (StringUtils.isEmpty(checkProductSeqCfg)) { workOrder = workOrderExtService.getWorkOrder(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), productionPartContext.getProductSeq()); } else if (workOrderNoList.size() == 1) { //增加零件号条件 diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderQueueAcceptStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderQueueAcceptStepService.java index 99d8bf8..fc74278 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderQueueAcceptStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesWorkOrderQueueAcceptStepService.java @@ -9,6 +9,7 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmCommonService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.platform.common.tool.TimeTool; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush; import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPushCellCfg; @@ -22,10 +23,11 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; /** * @Description : 工位工单接收工步 @@ -50,7 +52,8 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService { @Autowired private IFsmCommonService fsmCommonService; - protected static Map queueAcceptLockMap = new ConcurrentHashMap<>(); + private static Map lockTimeMap = new HashMap<>(); + private static Map lockMap = new ConcurrentHashMap<>(); @Override public StepResult init(StationRequestBean reqBean) { @@ -96,8 +99,50 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService { MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip(); //根据配置查询生产队列工位推送信息 - List queueOrderPushList = queueOrderPushService.getQueueOrderPushList(reqBean.getOrganizeCode(), queueOrderPushCellCfgList, cellEquipContext.getCavity()); - if (CollectionUtils.isEmpty(queueOrderPushList) || queueOrderPushList.size() != cellEquipContext.getCavity()) { + List queueOrderPushList = queueOrderPushService.getQueueOrderPushList(reqBean.getOrganizeCode(), queueOrderPushCellCfgList); + if (CollectionUtils.isEmpty(queueOrderPushList) || queueOrderPushList.size() < cellEquipContext.getCavity()) { + return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, + false, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, + CollectionUtils.isEmpty(queueOrderPushList) ? "当前未接收到工位工单队列,持续监听中..." : String.format("当前接收到到工位工单队列个数[%s]不满足腔数[%s],持续监听中...", queueOrderPushList.size(), cellEquipContext.getCavity()), + getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); + } + + //搜集需要考虑加锁的推送来源代码 + List pushSourceCodeList = queueOrderPushCellCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsNeedLock()))).map(MesQueueOrderPushCellCfg::getPushSourceCode).collect(Collectors.toList()); + + //验证是否执行加锁 + List curPushList = null; + for (MesQueueOrderPush queueOrderPush : queueOrderPushList) { + if (null == queueOrderPush) continue; + //当前遍历中的代码不考虑加锁 + if (CollectionUtils.isEmpty(pushSourceCodeList) || !pushSourceCodeList.contains(queueOrderPush.getPushSourceCode())) { + if (CollectionUtils.isEmpty(curPushList)) curPushList = new ArrayList<>(); + curPushList.add(queueOrderPush); + //满足腔数的情况下退出循环 + if (curPushList.size() >= cellEquipContext.getCavity()) break; + } else { + //当前遍历中的代码考虑加锁; 获取不到锁的情况下退出循环 + if (!tryLock(reqBean.getWorkCenterCode(), queueOrderPush.getPushSourceCode())) break; + List queuePushIdList = productionCustomContextStepService.getSortQueuePushLockContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode()); + if (!CollectionUtils.isEmpty(queuePushIdList) && queuePushIdList.contains(queueOrderPush.getId().toString())) continue; + } + + } + + //验证是否执行解锁 + if (!CollectionUtils.isEmpty(curPushList)) { + for (MesQueueOrderPush queueOrderPush : curPushList) { + if (null == queueOrderPush) continue; + if (CollectionUtils.isEmpty(pushSourceCodeList) || !pushSourceCodeList.contains(queueOrderPush.getPushSourceCode())) continue; + //当需要考虑加锁且满足腔数的情况下, 保存排序线工单队列推送锁数据 + if (curPushList.size() >= cellEquipContext.getCavity()) productionCustomContextStepService.dispatchSortQueuePushLockContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), queueOrderPush.getId().toString()); + //解锁 + unLock(reqBean.getWorkCenterCode(), queueOrderPush.getPushSourceCode()); + } + } + + //验证是否满足腔数 + if (CollectionUtils.isEmpty(curPushList) || curPushList.size() < cellEquipContext.getCavity()) { return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, CollectionUtils.isEmpty(queueOrderPushList) ? "当前未接收到工位工单队列,持续监听中..." : String.format("当前接收到到工位工单队列个数[%s]不满足腔数[%s],持续监听中...", queueOrderPushList.size(), cellEquipContext.getCavity()), @@ -113,4 +158,42 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService { } + //加锁 + private Boolean tryLock(String workCenterCode, String pushSourceCode) { + try { + String key = new StringJoiner(MesPcnExtConstWords.AND).add(workCenterCode).add(pushSourceCode).toString(); + ReentrantLock lock = lockMap.computeIfAbsent(key, item -> new ReentrantLock(true)); + //拿不到锁的情况下监控锁是否已经超时 + if (!lock.tryLock(MesPcnExtConstWords.ONE_HUNDRED, TimeUnit.MILLISECONDS) && checkTimeOut(key, lock)) return false; + lockTimeMap.put(key, TimeTool.getNowTime(true)); + return true; + } catch (InterruptedException e) { + return false; + } + } + + //监控超过10秒的情况下进行自动解锁 + private Boolean checkTimeOut(String key, ReentrantLock lock) { + try { + String lockTime = lockTimeMap.get(key); + if ((StringUtils.isEmpty(lockTime) || TimeTool.getSecoundsBetweenTime(1, lockTime, TimeTool.getNowTime(true)) >= MesPcnExtConstWords.TEN) && lock.isLocked()) lock.unlock(); + } catch (Exception e) { + if (lock.isLocked()) lock.unlock(); + } + return true; + } + + //解锁 + private void unLock(String workCenterCode, String pushSourceCode) { + try { + String key = new StringJoiner(MesPcnExtConstWords.AND).add(workCenterCode).add(pushSourceCode).toString(); + lockMap.computeIfPresent(key, (k, v) -> { + if (!v.isHeldByCurrentThread() || !v.isLocked()) return v; + v.unlock(); + return v; + }); + } catch (Exception e) { + } + } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java index b9ec758..9c48eee 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionCustomContextStepService.java @@ -290,10 +290,32 @@ public class MesProductionCustomContextStepService extends BaseStepService imple return !StringUtils.isEmpty(contextStr) ? JSONObject.parseObject(contextStr, Map.class) : null; } - //删除上下文班次班组信息 + //删除打包数据 @Override public void removePackageDataContext(StationRequestBean reqBean) { removeFsmBusiData(reqBean.getOrganizeCode(), getPackageDataContextKey(reqBean)); } + //排序线工单队列推送锁数据KEY 【PS:生产线级别】 + private String getSortQueuePushLockContextKey(String orgainzeCode, String workCenterCode) { return new StringJoiner(MesPcnExtConstWords.COLON).add(orgainzeCode).add(MesPcnExtConstWords.QUEUE_PUSH_LOCK_CONTEXT).add(workCenterCode).toString(); } + + //获取排序线工单队列推送锁数据 + @Override + public List getSortQueuePushLockContext(String orgainzeCode, String workCenterCode) { + return getFsmBusiList(orgainzeCode, getSortQueuePushLockContextKey(orgainzeCode, workCenterCode)); + } + + //保存排序线工单队列推送锁数据 + @Override + public Boolean dispatchSortQueuePushLockContext(String organizeCode, String workCenterCode, String queuePushId) { + if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(queuePushId)) return false; + return dispatchFsmBusiList(organizeCode, getSortQueuePushLockContextKey(organizeCode, workCenterCode), queuePushId); + } + + //删除排序线工单队列推送锁数据 + @Override + public void removeSortQueuePushLockContext(String orgainzeCode, String workCenterCode, String queuePushId) { + removeFsmBusiList(orgainzeCode, getSortQueuePushLockContextKey(orgainzeCode, workCenterCode), queuePushId); + } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java index e817ad2..40ba826 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java @@ -3,6 +3,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.context; import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEquipmentExtService; import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdOrgExtService; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesQueueOrderPushService; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmRouteDataService; @@ -49,6 +50,9 @@ public class MesProductionProcessContextStepService extends BaseStepService impl private IConfigService configService; @Autowired + private IMesQueueOrderPushService queueOrderPushService; + + @Autowired private SnowflakeIdMaker snowflakeIdMaker; private String getContextKey(StationRequestBean reqBean) { @@ -667,10 +671,28 @@ public class MesProductionProcessContextStepService extends BaseStepService impl private List dispatchQueueOrderPushCellCfgContext(StationRequestBean reqBean) { String queuePushCfgJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CFG_CONTEXT); if (!StringUtils.isEmpty(queuePushCfgJson)) return JSONObject.parseArray(queuePushCfgJson, MesQueueOrderPushCellCfg.class); - //根据生产线代码,工位代码查询生产队列推送工位配置信息 - List queueOrderPushCellCfgList = prodOrgExtService.getQueueOrderPushCellCfgList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode()); - if (!CollectionUtils.isEmpty(queueOrderPushCellCfgList)) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CFG_CONTEXT, JSONObject.toJSONString(queueOrderPushCellCfgList)); - return queueOrderPushCellCfgList; + //根据生产线代码查询生产队列推送工位配置信息 + List queueOrderPushCellCfgList = queueOrderPushService.getQueueOrderPushCellCfgList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode()); + //搜集该工位对应的配置信息 + List filterList = CollectionUtils.isEmpty(queueOrderPushCellCfgList) ? null : + queueOrderPushCellCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPushSourceCode()) && + !StringUtils.isEmpty(o.getPushType()) && !StringUtils.isEmpty(o.getWorkCellCode()) && o.getWorkCellCode().equals(reqBean.getWorkCellCode()))).collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(filterList)) return null; + + //验证是否存在查询队列需要考虑竞争的代码, 赋值是否需要锁定 + for (MesQueueOrderPushCellCfg queueOrderPushCellCfg : filterList) { + if (null == queueOrderPushCellCfg || queueOrderPushCellCfg.getPushType().compareTo(MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.SOURCE.getValue()) == 0) continue; + Optional optional = queueOrderPushCellCfgList.stream().filter(o -> (null != o + && !StringUtils.isEmpty(o.getWorkCellCode()) && !o.getWorkCellCode().equals(reqBean.getWorkCellCode()) + && !StringUtils.isEmpty(o.getPushType()) && o.getPushType().compareTo(MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getValue()) == 0) + && !StringUtils.isEmpty(o.getPushSourceCode()) && o.getPushSourceCode().equals(queueOrderPushCellCfg.getPushSourceCode())).findFirst(); + if (null != optional && optional.isPresent()) queueOrderPushCellCfg.setIsNeedLock(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr()); + } + + //保存排序线推单配置上下文 + if (!CollectionUtils.isEmpty(queueOrderPushCellCfgList)) dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CFG_CONTEXT, JSONObject.toJSONString(filterList)); + return filterList; } } diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java index bf0592f..92ffd36 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/util/MesPcnExtConstWords.java @@ -631,6 +631,8 @@ public class MesPcnExtConstWords { public static final String PROD_RULE_IGNORE_CFG_CONTEXT = "PROD_RULE_IGNORE_CFG_CONTEXT"; // 队列推送配置上下文 public static final String QUEUE_PUSH_CFG_CONTEXT = "QUEUE_PUSH_CFG_CONTEXT"; + // 队列推送锁上下文 + public static final String QUEUE_PUSH_LOCK_CONTEXT = "QUEUE_PUSH_LOCK_CONTEXT"; // 上下文: 展示组件数据 public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";