From cae8f9af41e0b2268225799b34839523d788cd1f Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Wed, 26 Feb 2025 20:54:38 +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 --- .../IMesProductionDispatchContextStepService.java | 7 ++ .../serviceimpl/busi/MesQueueOrderPushService.java | 9 +- .../step/MesWorkOrderQueueAcceptStepService.java | 102 +++++++++++++-------- .../MesProductionDispatchContextStepService.java | 15 +++ .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 6 +- 5 files changed, 100 insertions(+), 39 deletions(-) diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java index 4642a9e..df51b07 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java @@ -2,6 +2,7 @@ package cn.estsh.i3plus.ext.mes.pcn.api.busi; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*; import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOrderCutDetailModel; +import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush; import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging; import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; @@ -243,4 +244,10 @@ public interface IMesProductionDispatchContextStepService { @ApiOperation(value = "保存上下文发运队列信息") Boolean dispatchShippingQueueContext(StationRequestBean reqBean, MesShippingQueue shippingQueue); + @ApiOperation(value = "获取上下文推单队列信息") + List getSortQueuePushContext(StationRequestBean reqBean); + + @ApiOperation(value = "保存上下文推单队列信息") + Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List queueOrderPushList); + } 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 a36c39a..f24e7c9 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 @@ -17,7 +17,10 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.TreeSet; import java.util.stream.Collectors; @Service @@ -99,7 +102,11 @@ 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.findByHqlWhere(packBean); + List queueOrderPushList = queueOrderPushRepository.findByHqlWhere(packBean); + //条码去重 + return CollectionUtils.isEmpty(queueOrderPushList) ? null : + queueOrderPushList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProductSn()))).distinct() + .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesQueueOrderPush::getProductSn))), ArrayList::new)); } } 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 fc74278..dc81d47 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 @@ -5,10 +5,13 @@ import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepSer 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.MesCellEquipContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesEquipVariableCollectContext; 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.mes.pcn.serviceimpl.fsm.IStepService; +import cn.estsh.i3plus.mes.pcn.util.StringUtil; import cn.estsh.i3plus.platform.common.tool.TimeTool; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush; @@ -17,6 +20,8 @@ import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; import cn.estsh.i3plus.pojo.mes.model.StationResultBean; import cn.estsh.i3plus.pojo.mes.model.StepResult; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -110,51 +115,76 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService { //搜集需要考虑加锁的推送来源代码 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; - } - } + try { + //验证是否执行加锁 + for (MesQueueOrderPush queueOrderPush : queueOrderPushList) { + if (null == queueOrderPush || StringUtils.isEmpty(queueOrderPush.getWorkOrderNo())) 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()), - getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); - } + //验证是否满足腔数 + 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(curPushList) ? "当前未接收到工位工单队列,持续监听中..." : String.format("当前接收到到工位工单队列个数[%s]不满足腔数[%s],持续监听中...", curPushList.size(), cellEquipContext.getCavity()), + getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); + } + + //搜集工单号 + List workOrderNoList = curPushList.stream().filter(o -> null != o).map(MesQueueOrderPush::getWorkOrderNo).collect(Collectors.toList()); + + //发送工步内容 + productionCustomContextStepService.sendStepContextMessage(reqBean, workOrderNoList.toString(), MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ); + + List equipVariableCollectContextList = new ArrayList<>(); + workOrderNoList.stream().filter(o -> !StringUtils.isEmpty(o)).forEach(o -> + equipVariableCollectContextList.add(new MesEquipVariableCollectContext(reqBean.getOrganizeCode(), o, MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ.getValue()))); + //保存上下文扫/读信息:加工单 + productionDispatchContextStepService.dispatchScanWorkOrderNoContext(reqBean, equipVariableCollectContextList); + this.sendMessage(reqBean, new StationResultBean().writeDbLog(), String.format("获取到工位工单推送队列%s!", workOrderNoList.toString()), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + log.info("工厂{}生产线{}工位{}:FSM STATE DISPATCHER --- DO STEP --- {} EXEC --- QUEUE_ORDER_PUSH:{}", + reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), StringUtil.toLowerCaseFirst(this.getClass().getSimpleName()), JSONObject.toJSONString(curPushList)); + //加工单验证工步 【排序】 + stepResult = ((IStepService) SpringContextsUtil.getBean("mesWorkOrderCheckSortStepService")).executeInState(reqBean); + //保存上下文推单信息 + if (stepResult.isCompleted()) productionDispatchContextStepService.dispatchSortQueuePushContext(reqBean, curPushList); + return stepResult; - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "工位工单接收成功!"); + } finally { + + //验证是否执行解锁 + 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()); + } + } + + } } @@ -163,8 +193,8 @@ public class MesWorkOrderQueueAcceptStepService extends BaseStepService { 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; + //500ms内拿不到锁的情况下监控锁是否已经超时 + if (!lock.tryLock(MesPcnExtConstWords.FIVE_HUNDRED, TimeUnit.MILLISECONDS) && checkTimeOut(key, lock)) return false; lockTimeMap.put(key, TimeTool.getNowTime(true)); return true; } catch (InterruptedException e) { diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java index 96123d1..79c3b3a 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionDispatchContextStepService.java @@ -6,6 +6,7 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOrderCutDetailModel; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush; import cn.estsh.i3plus.pojo.mes.bean.MesRawPartCharging; import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue; import cn.estsh.i3plus.pojo.mes.model.StationKvBean; @@ -550,4 +551,18 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.SHIPPING_QUEUE_CONTEXT, JSONObject.toJSONString(shippingQueue)); } + //获取上下文推单队列信息 + @Override + public List getSortQueuePushContext(StationRequestBean reqBean) { + String sortQueuePushJson = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CONTEXT); + return !StringUtils.isEmpty(sortQueuePushJson) ? JSONObject.parseArray(sortQueuePushJson, MesQueueOrderPush.class) : null; + } + + //保存上下文推单队列信息 + @Override + public Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List queueOrderPushList) { + if (CollectionUtils.isEmpty(queueOrderPushList)) return false; + return dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.QUEUE_PUSH_CONTEXT, JSONObject.toJSONString(queueOrderPushList)); + } + } 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 92ffd36..f140744 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 @@ -629,10 +629,12 @@ public class MesPcnExtConstWords { public static final String EQUIP_SPOT_CHECK_CONTEXT = "EQUIP_SPOT_CHECK_CONTEXT"; // 加工不可用规则上下文 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 QUEUE_PUSH_CONTEXT = "QUEUE_PUSH_CONTEXT"; // 上下文: 展示组件数据 public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT";