From 07ff755b9ce4f95d7fcc90acdfde141eb5d435c2 Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Fri, 11 Jul 2025 06:59:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=B9=E9=85=8D=E5=8E=9F=E6=96=99=E7=AB=99?= =?UTF-8?q?=E7=82=B9=E5=B7=A5=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IMesProductionCustomContextStepService.java | 9 + .../IMesProductionDispatchContextStepService.java | 21 +- .../api/busi/IMesStationContainerSnExtService.java | 6 + .../busi/MesStationContainerSnExtService.java | 27 +- .../rulematch/MesTimeEfficientCfgMatchService.java | 2 +- .../MesFunctionDialogInputOrderQtyService.java | 18 +- .../step/MesAssemblyShowNosortStepService.java | 44 ++- .../step/MesPackageNoGenerateStepService.java | 5 +- .../step/MesProductSnCheckStepService.java | 43 ++- .../step/MesProductSnGenerateStepService.java | 12 +- ...oductionDataSaveBeforeLockOrderStepService.java | 6 +- .../MesStationDeductionAssemblyStepService.java | 55 +--- ...ationFeedContainerPackageDetailStepService.java | 2 +- ...tationFeedContainerSnByAssemblyStepService.java | 46 ++++ ...MesStationFeedContainerSnByFlagStepService.java | 73 +++++ ...MesStationFeedContainerSnByPsInStepService.java | 46 ++++ .../step/MesStationFeedContainerSnStepService.java | 2 +- .../step/MesStationMatchAssemblyStepService.java | 20 +- .../MesStationMatchProductSnInStepService.java | 123 --------- .../step/MesStationMatchProductSnStepService.java | 303 +++++++++++++++++++++ .../MesProductionCustomContextStepService.java | 28 +- .../MesProductionDispatchContextStepService.java | 49 ++-- .../MesWorkOrderCheckCompleteQtyStepService.java | 30 +- ...ionMatchPsProcessMethodStrategyStepService.java | 28 ++ ...onMatchPsProcessMethodContainerStepService.java | 92 +++++++ ...onMatchPsProcessMethodDecoratorStepService.java | 124 +++++++++ ...tchPsProcessMethodManyContainerStepService.java | 15 + ...ationMatchPsProcessMethodSingleStepService.java | 129 +++++++++ .../pcn/apiservice/util/MesReentrantLockUtil.java | 46 ++++ .../context/MesContainerPackageDetailContext.java | 38 +++ .../MesContainerPackageDetailStationContext.java | 51 ++++ .../context/MesEquipVariableCollectContext.java | 8 + .../pcn/pojo/context/MesProductionPsInContext.java | 11 + .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 19 +- 34 files changed, 1247 insertions(+), 284 deletions(-) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByAssemblyStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByFlagStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByPsInStepService.java delete mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnInStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/IMesStationMatchPsProcessMethodStrategyStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodContainerStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodDecoratorStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodManyContainerStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodSingleStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/util/MesReentrantLockUtil.java create mode 100644 modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailStationContext.java 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 cd11249..609e781 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 @@ -143,4 +143,13 @@ public interface IMesProductionCustomContextStepService { @ApiOperation(value = "重置原料条码的缓存库存") void dispatchContainerPackageDetailContext(String organizeCode, Map remainQtyMap2Cache); + @ApiOperation(value = "验证主条码或容器条码是否被占用的key") + String getContainerPackageDetailPsKey(String organizeCode, String suffix, String psOrContainerSnAppendId); + + @ApiOperation(value = "验证主条码或容器条码是否被占用") + Boolean checkContainerPackageDetailPsIsUsed(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId); + + @ApiOperation(value = "锁定主条码或容器条码") + void dispatchContainerPackageDetailPs(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId); + } 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 2433bf5..9443c74 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 @@ -260,10 +260,19 @@ public interface IMesProductionDispatchContextStepService { Boolean dispatchSortQueuePushContext(StationRequestBean reqBean, List queueOrderPushList); @ApiOperation(value = "获取站点用于缺料时进行上料绑定") - List getMatchStationContext(StationRequestBean reqBean); + List getMatchStationContext(StationRequestBean reqBean, String item); - @ApiOperation(value = "保存站点用于缺料时进行上料绑定") - void dispatchMatchStationContext(StationRequestBean reqBean, List stationList); + @ApiOperation(value = "获取装配件站点用于缺料时进行上料绑定") + List getMatchStationAssemblyContext(StationRequestBean reqBean); + + @ApiOperation(value = "保存装配件站点用于缺料时进行上料绑定") + void dispatchMatchStationAssemblyContext(StationRequestBean reqBean, List stationList); + + @ApiOperation(value = "获取站点用于进料时进行上料绑定") + List getMatchStationProductSnContext(StationRequestBean reqBean); + + @ApiOperation(value = "保存站点用于进料时进行上料绑定") + void dispatchMatchStationProductSnContext(StationRequestBean reqBean, List stationList); @ApiOperation(value = "获取站点用于扣料业务中进行LOCK") Map getLockStationContext(StationRequestBean reqBean); @@ -277,10 +286,4 @@ public interface IMesProductionDispatchContextStepService { @ApiOperation(value = "保存站点用于缺料时进行上料绑定的容器条码") void dispatchMatchStationFeedContainerSnContext(StationRequestBean reqBean, String sn); - @ApiOperation(value = "获取站点用于进料时进行上料绑定") - List getPsMatchStationContext(StationRequestBean reqBean); - - @ApiOperation(value = "保存站点用于进料时进行上料绑定") - void dispatchPsMatchStationContext(StationRequestBean reqBean, List stationList); - } diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesStationContainerSnExtService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesStationContainerSnExtService.java index b6df849..1121032 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesStationContainerSnExtService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesStationContainerSnExtService.java @@ -21,6 +21,9 @@ public interface IMesStationContainerSnExtService { Map> getContainerSnStationMap(String organizeCode, List stationList); @ApiOperation(value = "获取站点关联的容器条码") + Map> getContainerSnStationTopMap(String organizeCode, List stationList); + + @ApiOperation(value = "获取站点关联的容器条码") List getContainerSnStationList(String organizeCode, List stationList); @ApiOperation(value = "获取站点关联的容器条码") @@ -35,6 +38,9 @@ public interface IMesStationContainerSnExtService { @ApiOperation(value = "获取容器条码上料主表信息") List getContainerPackageListByContainerSn(String organizeCode, List containerSnList, Integer packageStatus); + @ApiOperation(value = "获取容器条码上料主表信息【进料】的一条数据") + MesContainerPackage getContainerPackageByContainerSn(String organizeCode, List containerSnList, Integer packageStatus); + @ApiOperation(value = "获取容器条码上料明细表信息【可扣减】") List getContainerPackageDetailList(String organizeCode, List containerPackageList); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesStationContainerSnExtService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesStationContainerSnExtService.java index 80f2bb8..43d7c87 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesStationContainerSnExtService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesStationContainerSnExtService.java @@ -63,7 +63,16 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null; List containerSnStationList = getContainerSnStationList(organizeCode, stationList); return CollectionUtils.isEmpty(containerSnStationList) ? null : - containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn)); + containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getContainerSn()))).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn)); + } + + //获取站点关联的容器条码 + @Override + public Map> getContainerSnStationTopMap(String organizeCode, List stationList) { + if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null; + List containerSnStationList = getContainerSnStationList(organizeCode, stationList); + return CollectionUtils.isEmpty(containerSnStationList) ? null : + containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getTopContainerSn()))).collect(Collectors.groupingBy(MesContainerSnStation::getTopContainerSn)); } //获取站点关联的容器条码 @@ -76,6 +85,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx //获取站点关联的容器条码 @Override + @Transactional(propagation = Propagation.NOT_SUPPORTED) public List getContainerSnStationListByStation(String organizeCode, List stationList) { if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(stationList)) return null; DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); @@ -123,6 +133,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx //获取容器条码上料主表信息 @Override + @Transactional(propagation = Propagation.NOT_SUPPORTED) public List getContainerPackageListByContainerSn(String organizeCode, List containerSnList, Integer packageStatus) { if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnList)) return null; DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); @@ -132,6 +143,18 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx return containerPackageRepository.findByHqlWhere(packBean); } + //获取容器条码上料主表信息【进料】的一条数据 + @Override + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public MesContainerPackage getContainerPackageByContainerSn(String organizeCode, List containerSnList, Integer packageStatus) { + if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(containerSnList)) return null; + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + if (containerSnList.size() == 1) DdlPreparedPack.getStringEqualPack(containerSnList.get(0), MesPcnExtConstWords.CONTAINER_SN, packBean); + else DdlPreparedPack.getInPackList(containerSnList, MesPcnExtConstWords.CONTAINER_SN, packBean); + DdlPreparedPack.getNumEqualPack(packageStatus, MesPcnExtConstWords.PACKAGE_STATUS, packBean); + return containerPackageRepository.getByProperty(packBean); + } + //获取容器条码上料明细表信息【可扣减】 @Override public List getContainerPackageDetailList(String organizeCode, List containerPackageList) { @@ -142,6 +165,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx //获取容器条码上料明细表信息【可扣减】 @Override + @Transactional(propagation = Propagation.NOT_SUPPORTED) public List getContainerPackageDetailListById(String organizeCode, List idList) { if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(idList)) return null; DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); @@ -153,6 +177,7 @@ public class MesStationContainerSnExtService implements IMesStationContainerSnEx //获取容器条码的一条上料明细表信息【可扣减】 @Override + @Transactional(propagation = Propagation.NOT_SUPPORTED) public Boolean checkIsExistContainerPackageDetail(String organizeCode, Long id) { if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(id)) return null; DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java index 8755071..895c13b 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/rulematch/MesTimeEfficientCfgMatchService.java @@ -229,7 +229,7 @@ public class MesTimeEfficientCfgMatchService implements IMesTimeEfficientCfgMatc if (null == timeliness || StringUtils.isEmpty(timeliness.getPartNo()) || !timeliness.getPartNo().equals(containerPackageDetailContext.getPartNo())) continue; - Date productDateTime = sdf.parse(containerPackageDetailContext.getCreateDatetime()); + Date productDateTime = sdf.parse(containerPackageDetailContext.getLoadPartTime()); //时差 int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000)); if (!checkTimeliness(timeliness, minDiff)) return backResultMap(resultMap, String.format("原材料条码[%s]时效性零件号[%s]验证失败!", containerPackageDetailContext.getBarCode(), timeliness.getPartNo())); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionDialogInputOrderQtyService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionDialogInputOrderQtyService.java index c41c9c2..e11471d 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionDialogInputOrderQtyService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/station/function/MesFunctionDialogInputOrderQtyService.java @@ -6,7 +6,6 @@ import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrd import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseSwsService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IShippingDispatchService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.function.IFsmModuleFunctionService; @@ -19,7 +18,6 @@ import cn.estsh.i3plus.pojo.mes.model.StepResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.ArrayList; import java.util.List; /** @@ -53,17 +51,13 @@ public class MesFunctionDialogInputOrderQtyService extends BaseSwsService implem //获取上下文产出零件信息 List productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean); - //用弹框输入的工单数量 虚拟产出零件信息 - List productionPsOutContextList = new ArrayList<>(); - productionPartContextList.forEach(o -> { - MesProductionPsOutContext productionPsOutContext = new MesProductionPsOutContext().foreignKey(o.getForeignKey()); - productionPsOutContext.setQty(new Double(buttonDynamicModel.getFunctionValue())); - productionPsOutContextList.add(productionPsOutContext); - }); + //获取上下文产品加工规则数据信息集合 + List prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean); + prodRuleContextList.stream().forEach(o -> o.eachCavityQty(buttonDynamicModel.getFunctionValue())); StepResult stepResult = StepResult.getSuccessComplete(); //验证加工单完成数量 - workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, null, productionPsOutContextList); + workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, null, prodRuleContextList); reqBean.setClientInfo(shippingDispatchService.getActorClientInfo(reqBean)); reqBean.setInterfaceType(MesPcnConstWords.SHIPPING); @@ -72,10 +66,6 @@ public class MesFunctionDialogInputOrderQtyService extends BaseSwsService implem if (!stepResult.isCompleted()) reqBean.setTriggerAutoFsm(true); else { - //获取上下文产品加工规则数据信息集合 - List prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean); - prodRuleContextList.stream().forEach(o -> o.eachCavityQty(buttonDynamicModel.getFunctionValue())); - productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList); reqBean.setButtonCode(buttonDynamicModel.getButtonCode()); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java index 61b8e2a..caac628 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesAssemblyShowNosortStepService.java @@ -84,9 +84,6 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { //从上下文中取出生产线对象 MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip(); - //获取上下文加工规则数据信息集合 - List prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean); - //获取上下文产出零件数据信息集合 List productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean); @@ -97,8 +94,34 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { if (CollectionUtils.isEmpty(productionPartContextList) && CollectionUtils.isEmpty(productionPsInContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("生产线[%s]工位[%s]当前已不存在产成零件或进料条码数据信息,请重置工序!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode())); - //根据现有数据【产出零件数据】【进料零件条码信息】比对上下文中已经存在的加工规则数据信息集合, 没有加工规则的数据进行查询 + //获取上下文加工规则数据信息集合 + List prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean); if (CollectionUtils.isEmpty(prodRuleContextList)) prodRuleContextList = new ArrayList<>(); + + //业务处理后显示装配件扫描项 + return doHandleAssemblyShowNosort(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList); + + } + + //业务处理后显示装配件扫描项 + private StepResult doHandleAssemblyShowNosort(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext, + List prodRuleContextList, List productionPartContextList, List productionPsInContextList) { + //业务处理 + doHandleProdRuleContext(reqBean, resultBean, stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList); + + //显示装配件信息 + Boolean isShow = showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList); + + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, + isShow ? "已显示装配件清单,请查看!" : "当前腔匹配的加工规则无装配件清单!", + MesPcnEnumUtil.PROMPT_SOUND.SUCCESS.getValue()); + } + + //业务处理 + public StepResult doHandleProdRuleContext(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, MesProductionProcessContext productionProcessContext, MesCellEquipContext cellEquipContext, + List prodRuleContextList, List productionPartContextList, List productionPsInContextList) { + + //根据现有数据【产出零件数据】【进料零件条码信息】比对上下文中已经存在的加工规则数据信息集合, 没有加工规则的数据进行查询 Integer initSize = prodRuleContextList.size(); //封装非排序加工规则 @@ -106,7 +129,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { //验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则 workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext( - reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList); + reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList); //匹配失败需要清除本次扫描/读取信息 if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList)) @@ -121,12 +144,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { if (!CollectionUtils.isEmpty(productionPsInContextList)) productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList); } - //显示装配件信息 - Boolean isShow = showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList); - - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, - isShow ? "已显示装配件清单,请查看!" : "当前腔匹配的加工规则无装配件清单!", - MesPcnEnumUtil.PROMPT_SOUND.SUCCESS.getValue()); + return stepResult; } //封装非排序加工规则 @@ -250,7 +268,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { //【非排序线】获取产品加工规则对应的装配件信息 -同时- 关联不可用规则 MesProdRuleContext prodRuleContext = new MesProdRuleContext( reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode()) - .copy(filterList.get(0)).productSn(productionPsInContext.getProductSn()).foreignKey(productionPsInContext.foreignKey(foreignKey += 1).getForeignKey()); + .copy(filterList.get(0)).productSn(productionPsInContext.getProductSn()).eachCavityQty(productionPsInContext.getQty()).foreignKey(productionPsInContext.foreignKey(foreignKey += 1).getForeignKey()); prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext(prodRuleContext, prodRuleIgnoreCfgMap); prodRuleContextList.add(prodRuleContext); @@ -365,7 +383,7 @@ public class MesAssemblyShowNosortStepService extends BaseStepService { //【非排序线】获取产品加工规则对应的装配件信息 -同时- 关联不可用规则 MesProdRuleContext prodRuleContext = prodRuleCfgExtService.getProdRuleNosortContext( new MesProdRuleContext(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), reqBean.getProcessCode(), productionProcessContext.getCraftCode()) - .copy(innerfilterList.get(0)).productSn(productSn.getProductSn()), + .copy(innerfilterList.get(0)).productSn(productSn.getProductSn()).eachCavityQty(productSn.getQty()), prodRuleIgnoreCfgMap); prodRuleContext.foreignKey(productionPartContext.getForeignKey()); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesPackageNoGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesPackageNoGenerateStepService.java index d883f71..38d04bb 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesPackageNoGenerateStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesPackageNoGenerateStepService.java @@ -126,8 +126,11 @@ public class MesPackageNoGenerateStepService extends BaseStepService implements /**Map> productSnMap2Part = productionPsOutContextList.stream() .filter(o -> (null != o && o.getQcStatus().compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue()) == 0 && foreignKeyList.contains(o.getForeignKey()))) .collect(Collectors.groupingBy(MesProductionPsOutContext::getPartNo, Collectors.mapping(MesProductionPsOutContext::getProductSn, Collectors.toList())));**/ + //适配单个产品条码QTY大于1 Map> productSnMap2Part = new HashMap<>(); - productionPsOutContextList.forEach(o -> productSnMap2Part.computeIfAbsent(o.getPartNo(), k -> new LinkedList<>()).addAll(generateVirtualPs(o.getQty(), o.getProductSn()))); + productionPsOutContextList.stream() + .filter(o -> (null != o && o.getQcStatus().compareTo(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue()) == 0 && foreignKeyList.contains(o.getForeignKey()))) + .forEach(o -> productSnMap2Part.computeIfAbsent(o.getPartNo(), k -> new LinkedList<>()).addAll(generateVirtualPs(o.getQty(), o.getProductSn()))); //获取包装规则信息 Map packageRuleContextMap = productionProcessContextStepService.getPackageRuleContext(reqBean); diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java index 3cc588c..36ba61c 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnCheckStepService.java @@ -9,7 +9,6 @@ import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService; import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; -import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; import cn.estsh.i3plus.pojo.mes.bean.MesConfig; import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn; import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell; @@ -18,7 +17,6 @@ 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 lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -82,6 +80,19 @@ public class MesProductSnCheckStepService extends BaseStepService { //清除本次已获取得到的主条码信息 productionDispatchContextStepService.removeScanProductSnContext(reqBean); + //获取进料主条码数据信息 + List productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean); + + //处理条码验证逻辑 + checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, equipVariableCollectContextList, productionPsInContextList); + + return stepResult; + + } + + //处理条码验证逻辑 + public List checkProduceSnValid(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, + List equipVariableCollectContextList, List productionPsInContextList) { //搜集主条码值 List productSnList = equipVariableCollectContextList.stream().filter(o -> null != o).map(MesEquipVariableCollectContext::getEquipVariableValue).collect(Collectors.toList()); @@ -89,19 +100,20 @@ public class MesProductSnCheckStepService extends BaseStepService { MesWorkCell workCell = productionProcessContext.getWorkCell(); //验证上下文中主条码的有效性 封装 读/扫主条件信息到进料主条码数据信息中 - List productionPsInContextList = new ArrayList<>(); - if (!checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, workCell, productSnList, equipVariableCollectContextList, productionPsInContextList).isCompleted()) - return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("验证失败!原因:%s!", stepResult.getMsg())); + List productionPsInContextList2Cur = new ArrayList<>(); + if (!checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, workCell, productSnList, equipVariableCollectContextList, productionPsInContextList).isCompleted()) { + stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog(), stepResult, String.format("验证失败!原因:%s!", stepResult.getMsg())); + return productionPsInContextList; + } - //获取进料主条码数据信息 - List productionPsInContext = productionDispatchContextStepService.getProductionPsInContext(reqBean); - if (!CollectionUtils.isEmpty(productionPsInContext)) productionPsInContextList.addAll(productionPsInContext); + if (!CollectionUtils.isEmpty(productionPsInContextList)) productionPsInContextList2Cur.addAll(productionPsInContextList); //保存进料主条码数据 - productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList); + productionDispatchContextStepService.dispatchProductionPsInContext(reqBean, productionPsInContextList2Cur); - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), stepResult, String.format("主条码%s验证条码状态成功!", productSnList.toString())); + stepSuccessCompleteAndSendMsg(reqBean, resultBean.writeDbLog().scanInfo(productSnList.toString()), stepResult, String.format("主条码%s验证条码状态成功!", productSnList.toString())); + return productionPsInContextList2Cur; } private List filterEquipVariableCollectContextList(MesProductionProcessContext productionProcessContext, List equipVariableCollectContextList) { @@ -115,9 +127,14 @@ public class MesProductSnCheckStepService extends BaseStepService { Map> produceSnMap = produceSnExtService.getProduceSnMap(reqBean.getOrganizeCode(), productSnList); for (MesEquipVariableCollectContext equipVariableCollectContext : equipVariableCollectContextList) { if (null == equipVariableCollectContext || StringUtils.isEmpty(equipVariableCollectContext.getEquipVariableValue())) continue; - if (CollectionUtils.isEmpty(produceSnMap) || !produceSnMap.containsKey(equipVariableCollectContext.getEquipVariableValue())) - productionPsInContextList.add(new MesProductionPsInContext(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue()).messageSource(equipVariableCollectContext.getMessageSource())); - else createProductionPsInContext(reqBean, stepResult, workCell, equipVariableCollectContext, produceSnMap.get(equipVariableCollectContext.getEquipVariableValue()), productionPsInContextList); + if (CollectionUtils.isEmpty(produceSnMap) || !produceSnMap.containsKey(equipVariableCollectContext.getEquipVariableValue())) { + MesProductionPsInContext productionPsInContext = new MesProductionPsInContext(reqBean.getOrganizeCode(), equipVariableCollectContext.getEquipVariableValue()).messageSource(equipVariableCollectContext.getMessageSource()); + //适配智慧内饰容器进料的qty + if (!StringUtils.isEmpty(equipVariableCollectContext.getQty())) productionPsInContext.qty(equipVariableCollectContext.getQty()); + productionPsInContextList.add(productionPsInContext); + } else { + createProductionPsInContext(reqBean, stepResult, workCell, equipVariableCollectContext, produceSnMap.get(equipVariableCollectContext.getEquipVariableValue()), productionPsInContextList); + } } return stepResult; } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java index c6d6abc..a5006dc 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnGenerateStepService.java @@ -131,6 +131,15 @@ public class MesProductSnGenerateStepService extends BaseStepService { //获取上下文进料零件条码信息集合 List productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean); + //生产零件条码业务处理 + doHandleProductSnGenerate(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList, prodShiftContext); + + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "生成零件条码成功!"); + + } + + //生产零件条码业务处理 + public void doHandleProductSnGenerate(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, List productionPartContextList, List productionPsInContextList, List prodRuleContextList, MesProdShiftContext prodShiftContext) { //获取上下文零件数据信息 List partNoList = (prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getOutPartNo()))).map(MesProdRuleContext::getOutPartNo).collect(Collectors.toList())).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList()); partDataMapSaveStepService.savePartDataMap(reqBean, resultBean, stepResult, partNoList, false, true, false); @@ -153,9 +162,6 @@ public class MesProductSnGenerateStepService extends BaseStepService { //保存上下文产出条码数据信息集合 productionDispatchContextStepService.dispatchProductionPsOutContext(reqBean, productionPsOutContextList); - - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "生成零件条码成功!"); - } //生成零件条码 diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java index 5b20968..527ee99 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductionDataSaveBeforeLockOrderStepService.java @@ -3,6 +3,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.MesWorkOrderCheckCompleteQtyStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsInContext; @@ -60,11 +61,14 @@ public class MesProductionDataSaveBeforeLockOrderStepService extends BaseStepSer //获取上下文进料零件条码信息集合 List productionPsInContextList = productionDispatchContextStepService.getProductionPsInContext(reqBean); + //获取上下文加工规则信息集合 + List prodRuleContextList = productionDispatchContextStepService.getProdRuleDataContext(reqBean); + synchronized (new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode()).add(reqBean.getWorkCenterCode()).add(MesPcnExtConstWords.WORK_ORDER_COMPLETE_CONTEXT).toString().intern()) { //验证加工单完成数量 workOrderCheckCompleteQtyStepService.dispatchWorkOrderCompleteQtyContext( - reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList); + reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList); //匹配失败需要清除本次扫描/读取信息 if (!stepResult.isCompleted() && workOrderCheckCompleteQtyStepService.doBusiCheckToDelete(reqBean, stepResult, productionPartContextList, productionPsInContextList)) diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationDeductionAssemblyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationDeductionAssemblyStepService.java index 83812c4..d4b9570 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationDeductionAssemblyStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationDeductionAssemblyStepService.java @@ -3,6 +3,7 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesReentrantLockUtil; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext; import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; @@ -27,13 +28,11 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; 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 : 站点扣减装配件工步 + * @Description : 装配件站点扣减工步 * @Author : wangjie **/ @Slf4j @@ -52,8 +51,6 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { @Autowired private IFsmCommonService fsmCommonService; - private final static Map lockMap = new ConcurrentHashMap<>(); - @Override public StepResult init(StationRequestBean reqBean) { @@ -63,13 +60,10 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT; if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) { stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).writeDbLog().checkRepeat(), - stepResult.isCompleted(false).msg(String.format("当前未能执行完成站点扣减装配件超过[%s]次!", endlessLoopReadTimes)), + stepResult.isCompleted(false).msg(String.format("当前未能执行完成装配件站点扣减超过[%s]次!", endlessLoopReadTimes)), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); } - //发送工步内容 - productionCustomContextStepService.sendStepContextMessage(reqBean); - return stepResult; } @@ -95,7 +89,7 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { Optional optional = prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsMatchContainer()))).findFirst(); if (null == optional || !optional.isPresent()) { return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true, - MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过站点扣减装配件!"); + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过装配件站点扣减!"); } //获取站点用于扣料业务中进行LOCK @@ -107,9 +101,9 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { List acquiredLocks = new ArrayList<>(); try { - if (!tryLock(acquiredLocks, stationNameList)) { + if (!MesReentrantLockUtil.tryLock(acquiredLocks, stationNameList, MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT + MesPcnExtConstWords.COLON, 3000L)) { return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false, - MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "站点扣减装配件扣减失败,即将重试!"); + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "装配件站点扣减LOCK失败,即将重试!"); } //用于重置原料条码的缓存库存 @@ -136,12 +130,12 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { } catch (InterruptedException e) { Thread.currentThread().interrupt(); return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false, - MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "站点扣减装配件扣减异常,即将重试!"); + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "装配件站点扣减异常,即将重试!"); } finally { - unLockAll(acquiredLocks); + MesReentrantLockUtil.unLockAll(acquiredLocks); } - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点扣减装配件验证成功!"); + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "装配件站点扣减验证成功!"); } @@ -156,7 +150,7 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { } if (!CollectionUtils.isEmpty(needFeedPartNoList)) { stepResult.isCompleted(false) - .msg(String.format("站点匹配装配件时验证零件号%s当前缺料,请扫描上料条码!", + .msg(String.format("装配件站点扣减时验证零件号%s当前缺料,请扫描上料条码!", (needFeedPartNoList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList())).toString())); } return isNeedSavePrc; @@ -244,33 +238,4 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { return isNeedSavePrc; } - - private Boolean tryLock(List acquiredLocks, List stationNameList) throws InterruptedException { - - Collections.sort(stationNameList); - - long remaining = TimeUnit.MILLISECONDS.toNanos(3000); - long endTime = System.nanoTime() + remaining; - - for (String stationName : stationNameList) { - - if (StringUtils.isEmpty(stationName)) continue; - - ReentrantLock lock = lockMap.computeIfAbsent(stationName, o -> new ReentrantLock()); - - if (!lock.tryLock(remaining, TimeUnit.NANOSECONDS)) return false; - - acquiredLocks.add(lock); - - remaining = endTime - System.nanoTime(); - } - - return true; - - } - - private void unLockAll(List acquiredLocks) { - for (int i = acquiredLocks.size() - 1; i >= 0; i --) acquiredLocks.get(i).unlock(); - } - } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerPackageDetailStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerPackageDetailStepService.java index c087eb7..b1ce645 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerPackageDetailStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerPackageDetailStepService.java @@ -84,7 +84,7 @@ public class MesStationFeedContainerPackageDetailStepService extends BaseStepSer } //获取站点用于缺料时进行上料绑定 - List stationList = productionDispatchContextStepService.getMatchStationContext(reqBean); + List stationList = productionDispatchContextStepService.getMatchStationAssemblyContext(reqBean); if (CollectionUtils.isEmpty(stationList)) { return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "容器条码扣减装配件时验证设备未关联支持上料的站点"); } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByAssemblyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByAssemblyStepService.java new file mode 100644 index 0000000..76b68d1 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByAssemblyStepService.java @@ -0,0 +1,46 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +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.impp.framework.boot.util.SpringContextsUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @Description : 装配件站点上料扫描容器条码工步 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationFeedContainerSnByAssemblyStepService") +public class MesStationFeedContainerSnByAssemblyStepService extends BaseStepService { + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + @Override + public StepResult guide(StationRequestBean reqBean) { + + //发送工步内容 + productionCustomContextStepService.sendStepContextMessage(reqBean); + + return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!"); + + } + + @Override + public StepResult execute(StationRequestBean reqBean) { + + reqBean.getDataMap().put(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG, MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT); + + return ((IStepService) SpringContextsUtil.getBean("mesStationFeedContainerSnByFlagStepService")).executeInState(reqBean); + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByFlagStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByFlagStepService.java new file mode 100644 index 0000000..b185c0f --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByFlagStepService.java @@ -0,0 +1,73 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService; +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.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesStation; +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 lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.List; + +/** + * @Description : 站点上料扫描容器条码工步 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationFeedContainerSnByFlagStepService") +public class MesStationFeedContainerSnByFlagStepService extends BaseStepService { + + @Autowired + private IMesProductionDispatchContextStepService productionDispatchContextStepService; + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + @Override + public StepResult guide(StationRequestBean reqBean) { + + //发送工步内容 + productionCustomContextStepService.sendStepContextMessage(reqBean); + + return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!"); + + } + +// @Override +// public StepResult execute(StationRequestBean reqBean) { +// +// StationResultBean resultBean = new StationResultBean(); +// +// StepResult stepResult = StepResult.getSuccessComplete(); +// +// //投料站点标识 +// String flag = (String) reqBean.getDataMap().get(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG); +// +// if (StringUtils.isEmpty(flag)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点上料扫描容器条码时验证缺失必要flag参数!"); +// +// if (StringUtils.isEmpty(reqBean.getScanInfo())) stepSendGuideAndThrowEx(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!"); +// +// //获取站点用于缺料时进行上料绑定 +// List stationList = productionDispatchContextStepService.getMatchStationContext(reqBean, flag); +// if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点上料扫描容器条码时验证缺失站点信息!"); +// +// //删除源工步传过来的参数标识 +// reqBean.getDataMap().remove(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG); +// +// MesStation station = stationList.get(0); +// +// Integer packageStatus = flag.equals(MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT) ? MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue() : +// station +// +// } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByPsInStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByPsInStepService.java new file mode 100644 index 0000000..bfb0a26 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnByPsInStepService.java @@ -0,0 +1,46 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +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.impp.framework.boot.util.SpringContextsUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @Description : 原料站点上料扫描容器条码工步 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationFeedContainerSnByPsInStepService") +public class MesStationFeedContainerSnByPsInStepService extends BaseStepService { + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + @Override + public StepResult guide(StationRequestBean reqBean) { + + //发送工步内容 + productionCustomContextStepService.sendStepContextMessage(reqBean); + + return stepSuccessCompleteAndSendGuideReturn(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描容器条码!"); + + } + + @Override + public StepResult execute(StationRequestBean reqBean) { + + reqBean.getDataMap().put(MesPcnExtConstWords.MATCH_STATION_CONTEXT_FLAG, MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT); + + return ((IStepService) SpringContextsUtil.getBean("mesStationFeedContainerSnByFlagStepService")).executeInState(reqBean); + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnStepService.java index 81b76c9..b616c60 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationFeedContainerSnStepService.java @@ -76,7 +76,7 @@ public class MesStationFeedContainerSnStepService extends BaseStepService { } //获取站点用于缺料时进行上料绑定 - List stationList = productionDispatchContextStepService.getMatchStationContext(reqBean); + List stationList = productionDispatchContextStepService.getMatchStationAssemblyContext(reqBean); if (CollectionUtils.isEmpty(stationList)) { stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "容器条码扣减装配件时验证设备未关联支持上料的站点"); } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchAssemblyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchAssemblyStepService.java index 244315b..e544f31 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchAssemblyStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchAssemblyStepService.java @@ -29,7 +29,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; /** - * @Description : 站点匹配装配件工步 + * @Description : 匹配装配件站点工步 * @Author : wangjie **/ @Slf4j @@ -72,23 +72,23 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { Optional optional = prodRuleContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getIsMatchContainer()))).findFirst(); if (null == optional || !optional.isPresent()) { return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true, - MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过站点匹配装配件!"); + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "验证每腔不存在容器匹配的装配件,默认跳过匹配装配件站点!"); } //处理设备站点【装配件站点&&混料站点】 - List stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(), - Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())); - - if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点匹配装配件时验证设备未关联支持扣减的站点!"); + List stationTypeList = Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_20.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList()); + List stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(), stationTypeList); + if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), + String.format("匹配装配件站点时时验证设备未关联[%s]站点!", MesExtEnumUtil.STATION_TYPE.valueOfDescription(stationTypeList, MesPcnExtConstWords.SLANT_R))); //保存站点用于缺料时进行上料绑定 - productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList); + productionDispatchContextStepService.dispatchMatchStationAssemblyContext(reqBean, stationList); //获取容器条码上料明细表信息【可扣减】【根据 主表seq,主表createDatetime,明细表createDatetime 正序】 List containerPackageDetailContextList = stationContainerSnExtService.getContainerPackageDetailContext(reqBean.getOrganizeCode(), stationList); if (CollectionUtils.isEmpty(containerPackageDetailContextList)) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), - stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "站点匹配装配件时验证当前无可扣减的原材料信息!"); + stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "匹配装配件站点时验证当前无可扣减的原材料信息!"); //将可扣减的条码进行原子性缓存, 并获取最新的实际库存 productionCustomContextStepService.dispatchContainerPackageDetailAtomicity(reqBean.getOrganizeCode(), containerPackageDetailContextList); @@ -115,7 +115,7 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { //保存站点用于后面扣料业务中进行LOCK productionDispatchContextStepService.dispatchLockStationContext(reqBean, stationMap2Lock); - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点匹配装配件验证成功!"); + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "匹配装配件站点验证成功!"); } //匹配装配件的工序用量【遍历加工规则】 @@ -130,7 +130,7 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { } if (!CollectionUtils.isEmpty(needFeedPartNoList)) { stepResult.isCompleted(false) - .msg(String.format("站点匹配装配件时验证零件号%s当前缺料,请扫描上料条码!", + .msg(String.format("匹配装配件站点时验证零件号%s当前缺料,请扫描上料条码!", (needFeedPartNoList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList())).toString())); } return isNeedSavePrc; diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnInStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnInStepService.java deleted file mode 100644 index a8b9935..0000000 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnInStepService.java +++ /dev/null @@ -1,123 +0,0 @@ -package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; - -import cn.estsh.i3plus.ext.mes.pcn.api.busi.*; -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.serviceimpl.fsm.BaseStepService; -import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage; -import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation; -import cn.estsh.i3plus.pojo.mes.bean.MesStation; -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 lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * @Description : 站点匹配进料工步 - * @Author : wangjie - **/ -@Slf4j -@Service("mesStationMatchProductSnInStepService") -public class MesStationMatchProductSnInStepService extends BaseStepService { - - @Autowired - private IMesProductionProcessContextStepService productionProcessContextStepService; - - @Autowired - private IMesProductionDispatchContextStepService productionDispatchContextStepService; - - @Autowired - private IMesProductionCustomContextStepService productionCustomContextStepService; - - @Autowired - private IMesStationContainerSnExtService stationContainerSnExtService; - - @Autowired - private IMesTimeEfficientCfgMatchService timeEfficientCfgMatchService; - - @Override - public StepResult execute(StationRequestBean reqBean) { - - StationResultBean resultBean = new StationResultBean(); - - StepResult stepResult = StepResult.getSuccessComplete(); - - //获取工位当前设备信息 - MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean); - - //配置错误 抛出异常 - if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); - - //处理设备站点【原料站点&&混料站点&&成品站点&&可疑站点】 - List stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(), - Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue(), - MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())); - - //搜集设备站点 【进料】【原料站点&&混料站点】 - String suffix = new StringJoiner(MesPcnExtConstWords.SLANT_R).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getDescription()).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription()).toString(); - List stationList2PsIn = productionProcessContextStepService.dispatchEquipmentStationContext(stationList, - Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())); - if (CollectionUtils.isEmpty(stationList2PsIn)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("站点匹配进料时验证设备未关联[%s]站点!", suffix)); - - //验证【原料站点&&混料站点】是否存在【已关箱】的容器条码 - if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult, stationList2PsIn, suffix, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20).isCompleted()) return stepResult; - - //验证【成品站点】是否存在【未关箱】的容器条码 - if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult, - productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue()).collect(Collectors.toList())), - MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult; - - //验证【可疑站点】是否存在【未关箱】的容器条码 - if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult, - productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())), - MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult; - - //验证【混料站点】是否存在容器条码 - if (!checkIsFeedContainerSn(reqBean, resultBean, stepResult, - productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())), - MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription(), null).isCompleted()) return stepResult; - - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点匹配进料验证成功!"); - - } - - private StepResult checkIsFeedContainerSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, - List stationList, String suffix, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS containerPackageStatus) { - //获取站点关联的容器条码【进料】 - Map> containerSnStationMap = stationContainerSnExtService.getContainerSnStationMap(reqBean.getOrganizeCode(), stationList); - //获取容器条码上料主表信息【进料】 除了混料不带状态查询, 其他均查询【已关箱】的数据 - List containerPackageList = stationContainerSnExtService.getContainerPackageListByContainerSn(reqBean.getOrganizeCode(), - CollectionUtils.isEmpty(containerSnStationMap) ? null : new ArrayList<>(containerSnStationMap.keySet()), - null != containerPackageStatus ? MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue() : null); - if (CollectionUtils.isEmpty(stationList)) return stepResult; - //混料站点 或 判断已关箱的情况下 , containerPackageList 存在数据则通过 - if ((null == containerPackageStatus || MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue() == containerPackageStatus.getValue()) - && !CollectionUtils.isEmpty(containerPackageList)) return stepResult; - //判断未关箱的情况下,需要看当前的容器条码是否全部是已关箱的,如果是则验证不通过 【不存在已关箱状态的数据就默认是未关箱的, 及不存在数据也默认是未关箱的】 - if (null != containerPackageStatus && MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10.getValue() == containerPackageStatus.getValue()) { - List containerSnList = CollectionUtils.isEmpty(containerPackageList) ? null : - (containerPackageList.stream().filter(o -> null != o).map(MesContainerPackage::getContainerSn).collect(Collectors.toList())) - .stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList()); - if (CollectionUtils.isEmpty(containerSnList) || containerSnList.size() != containerSnStationMap.keySet().size()) return stepResult; - } - - //保存站点用于绑定进料容器条码 - productionDispatchContextStepService.dispatchPsMatchStationContext(reqBean, stationList); - return stepNonCompleteAndSendMsgReturn(reqBean, resultBean, stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), - String.format("站点匹配进料时验证[%s]站点未绑定[%s]的容器条码!", suffix, containerPackageStatus.getDescription())); - - } - -} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnStepService.java new file mode 100644 index 0000000..39c0cc8 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnStepService.java @@ -0,0 +1,303 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesProdShiftRecordService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm.IMesStationMatchPsProcessMethodStrategyStepService; +import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesReentrantLockUtil; +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.IFsmCommonService; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.*; +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 lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @Description : 匹配原料站点工步 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationMatchProductSnStepService") +public class MesStationMatchProductSnStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionDispatchContextStepService productionDispatchContextStepService; + + @Autowired + private MesProductSnCheckStepService productSnCheckStepService; + + @Autowired + private MesAssemblyShowNosortStepService assemblyShowNosortStepService; + + @Autowired + private MesProductSnGenerateStepService productSnGenerateStepService; + + @Autowired + private IMesStationContainerSnExtService stationContainerSnExtService; + + @Autowired + private IMesProdShiftRecordService prodShiftRecordService; + + @Autowired + private IFsmCommonService fsmCommonService; + + @Override + public StepResult init(StationRequestBean reqBean) { + + StepResult stepResult = StepResult.getSuccessComplete(); + + String endlessLoopReadTimes = fsmCommonService.handleFsmWcpcMapDataForDoScanThenBackValue(reqBean, MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES); + if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT; + if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) { + stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false).writeDbLog().checkRepeat(), + stepResult.isCompleted(false).msg(String.format("当前未能执行完成匹配原料站点超过[%s]次!", endlessLoopReadTimes)), + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); + } + + return stepResult; + + } + + @Override + public StepResult execute(StationRequestBean reqBean) { + + StationResultBean resultBean = new StationResultBean(); + + StepResult stepResult = StepResult.getSuccessComplete(); + + //获取工位当前设备信息 + MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean); + + //配置错误 抛出异常 + if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + + //获取生产线的当前班组班次信息 + MesProdShiftContext prodShiftContext = prodShiftRecordService.getMesProdShiftKvBean(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode()); + if (null == prodShiftContext) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在生产开班记录,请重新开班!"); + + //处理设备站点【原料站点&&混料站点&&成品站点&&可疑站点】 + List stationList = productionProcessContextStepService.dispatchEquipmentStationContext(reqBean, productionProcessContext.getCurCellEquip().getEquipmentCode(), + Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue(), + MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())); + + //搜集设备站点 【进料】【原料站点&&混料站点】 + List stationList2Ps = filterStationList2Ps(reqBean, resultBean, stationList); + + //验证【成品站点】是否存在【未关箱】的容器条码 + if (!beforeCheckIsExistContainerSn(reqBean, resultBean, stepResult, + productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue()).collect(Collectors.toList())), + MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult; + + //验证【可疑站点】是否存在【未关箱】的容器条码 + if (!beforeCheckIsExistContainerSn(reqBean, resultBean, stepResult, + productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())), + MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getDescription(), MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10).isCompleted()) return stepResult; + + //验证【混料站点】是否存在容器条码 + if (!beforeCheckIsExistContainerSn(reqBean, resultBean, stepResult, + productionProcessContextStepService.dispatchEquipmentStationContext(stationList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())), + MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription(), null).isCompleted()) return stepResult; + + //加工模式策略 + IMesStationMatchPsProcessMethodStrategyStepService strategyService = (IMesStationMatchPsProcessMethodStrategyStepService) SpringContextsUtil.getBean(MesExtEnumUtil.STATION_PROCESS_METHOD.valueOfStrategyClass(stationList.get(0).getProcessMethod())); + + //【原料站点】获取容器条码上料明细表信息 + MesContainerPackageDetailStationContext containerPackageDetailStationContext = strategyService.getContainerPackageDetailStationContext(reqBean.getOrganizeCode(), stationList2Ps); + if (null == containerPackageDetailStationContext) { + return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "匹配原料站点时验证[原料]站点当前已无进料信息!"); + } + + //从上下文中取出生产线对象 + MesWorkCenter workCenter = productionProcessContext.getWorkCenter(); + //从上下文中取出工位当前要使用的设备 + MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip(); + + //获取上下文产出零件信息 + List productionPartContextList = productionDispatchContextStepService.getProductionPartContext(reqBean); + //剔除空腔 + List productionPartContextList2UnFinish = CollectionUtils.isEmpty(productionPartContextList) ? null : productionPartContextList.stream().filter(o -> (null != o && o.getIsFinishCode().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)).collect(Collectors.toList()); + + //进料主条码数据信息 + List productionPsInContextList = null; + //加工规则数据信息集合 + List prodRuleContextList = new ArrayList<>(); + + //获取工步参数 + Optional> stepParamMap = getStepParams(reqBean); + //是否验证工艺路线配置 + String isCheckCraft = (null != stepParamMap && stepParamMap.isPresent() && stepParamMap.get().containsKey(MesPcnExtConstWords.IS_CHECK_CRAFT_CFG)) ? stepParamMap.get().get(MesPcnExtConstWords.IS_CHECK_CRAFT_CFG).getParamValue() : null; + + List stationNameList = containerPackageDetailStationContext.getStationList().stream().filter(o -> null != o).map(MesStation::getStation).collect(Collectors.toList()); + + List acquiredLocks = new ArrayList<>(); + try { + if (!MesReentrantLockUtil.tryLock(acquiredLocks, stationNameList, MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT + MesPcnExtConstWords.COLON, 3000L)) { + return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false, + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "匹配原料站点时LOCK失败,即将重试!"); + } + + // 结尾需要缓存锁定的数据 + List needCachedList = null; + + //循环到全部验证成功或根据场景验证失败结束 + for (int i = 0; i >= 0; i ++) { + + stepResult = StepResult.getSuccessComplete(); + + //【原料站点】获取进料主条码信息 + List containerPackageDetailContextList = strategyService.getContainerPackageDetailContext(reqBean, containerPackageDetailStationContext, cellEquipContext.getCavity(), !CollectionUtils.isEmpty(productionPartContextList2UnFinish)); + + //验证是否满足腔数【前置验证】 + if (!strategyService.checkIsMatchCavity(getListSize(containerPackageDetailContextList), getListSize(prodRuleContextList), getListSize(productionPartContextList2UnFinish), cellEquipContext.getCavity(), true)) { + return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), "匹配原料站点时验证[原料]站点当前进料不足!"); + } + + //封装主条码信息上下文 + List equipVariableCollectContextList = new ArrayList<>(); + containerPackageDetailContextList.stream().filter(o -> null != o).forEach(o -> + equipVariableCollectContextList.add(new MesEquipVariableCollectContext(reqBean.getOrganizeCode(), o.getBarCode(), MesExtEnumUtil.CELL_MESSAGE_SOURCE.READ.getValue()).qty(o.getQty()))); + + //处理条码验证逻辑 【条码验证失败直接抛出异常】 + productionPsInContextList = productSnCheckStepService.checkProduceSnValid(reqBean, resultBean, stepResult, productionProcessContext, equipVariableCollectContextList, productionPsInContextList); + if (!stepResult.isCompleted()) stepSendGuideAndThrowEx(reqBean, new StationResultBean(), "主条码验证失败!请人工处理!"); + + //显示装配件扫描项工步【非排序】【业务处理】 + assemblyShowNosortStepService.doHandleProdRuleContext(reqBean, new StationResultBean().isIgnore(true), stepResult, workCenter, productionProcessContext, cellEquipContext, prodRuleContextList, productionPartContextList, productionPsInContextList); + + //前道工艺防错工步【非排序】 + if (stepResult.isCompleted() && !StringUtils.isEmpty(isCheckCraft) && !(((IStepService) SpringContextsUtil.getBean("mesProdCraftRouteCheckNosortStepService")).executeInState(reqBean)).isCompleted()) { + stepSendGuideAndThrowEx(reqBean, new StationResultBean(), "主条码前道工艺防错验证失败!请人工处理!"); + } + + //验证是否满足腔数【后置验证】 + Boolean result = strategyService.checkIsMatchCavity(getListSize(containerPackageDetailContextList), getListSize(prodRuleContextList), getListSize(productionPartContextList2UnFinish), cellEquipContext.getCavity(), false); + if (null != result && !result) { + stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog(), stepResult, stepResult.getMsg()); + stepSendGuideAndThrowEx(reqBean, new StationResultBean(), "加工规则匹配失败!请人工处理!"); + } + + if (stepResult.isCompleted()) { + if (CollectionUtils.isEmpty(needCachedList)) needCachedList = new ArrayList<>(); + needCachedList.addAll(containerPackageDetailContextList); + } + + if (null != result && result) break; + + //result为null需要继续循环处理 + containerPackageDetailContextList.get(0).matchResult(stepResult.isCompleted() ? CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr() : CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr()); + + } + + //锁定当前已被验证了的主条码或容器条码 + strategyService.dispatchContainerPackageDetailPs(reqBean, needCachedList); + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, false, + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "匹配原料站点异常,即将重试!"); + } finally { + MesReentrantLockUtil.unLockAll(acquiredLocks); + } + + //显示装配件扫描项 + assemblyShowNosortStepService.showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList); + + //生产零件条码业务处理 + productSnGenerateStepService.doHandleProductSnGenerate(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, prodRuleContextList, prodShiftContext); + + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "匹配原料站点验证成功!", MesPcnEnumUtil.PROMPT_SOUND.SUCCESS.getValue()); + + } + + //获取集合的个数 + private Integer getListSize(List list) { return CollectionUtils.isEmpty(list) ? MesPcnExtConstWords.ZERO : list.size(); } + + //搜集设备站点 【进料】【原料站点&&混料站点】 + private List filterStationList2Ps(StationRequestBean reqBean, StationResultBean resultBean, List stationList) { + + //剔除没有加工模式的站点数据 + List filterList = stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProcessMethod()))).collect(Collectors.toList()); + + //原料站点 + List stationList10 = productionProcessContextStepService.dispatchEquipmentStationContext(filterList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue()).collect(Collectors.toList())); + //混料站点 + List stationList40 = productionProcessContextStepService.dispatchEquipmentStationContext(filterList, Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())); + + //原料站点根据加工模式分组 + Map> processMethodMap10 = CollectionUtils.isEmpty(stationList10) ? null : stationList10.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getProcessMethod)); + //混料站点根据加工模式分组 + Map> processMethodMap40 = CollectionUtils.isEmpty(stationList40) ? null : stationList40.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getProcessMethod)); + + if (CollectionUtils.isEmpty(processMethodMap10) && CollectionUtils.isEmpty(processMethodMap40)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("匹配原料站点时验证设备未关联有效的[%s]站点!", + new StringJoiner(MesPcnExtConstWords.SLANT_R).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getDescription()).add(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getDescription()).toString())); + + //验证加工模式, 原料站点只能维护一种加工模式 + if (!CollectionUtils.isEmpty(processMethodMap10) && processMethodMap10.size() != 1) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "匹配原料站点时验证设备关联的原料站点的加工模式配置错误!"); + //验证加工模式, 原料站点不存在的时候, 混料站点只能维护一种加工模式 + if (CollectionUtils.isEmpty(processMethodMap10) && processMethodMap40.size() != 1) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "匹配原料站点时验证设备关联的混料站点的加工模式配置错误!"); + + //存在原料站点时,合并跟原料站点相同加工模式的混料站点 + if (!CollectionUtils.isEmpty(stationList10)) { + stationList40 = CollectionUtils.isEmpty(stationList40) ? null : stationList40.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProcessMethod()) && o.getProcessMethod().compareTo(stationList10.get(0).getProcessMethod()) == 0)).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(stationList40)) stationList10.addAll(stationList40); + return stationList10; + } + + //不存在原料站点时, 返回混料站点 + return stationList40; + + } + + //前置验证不同类型的站点是否至少存在一个保底的容器条码用于存放产成品 + private StepResult beforeCheckIsExistContainerSn(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, + List stationList, String suffix, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS containerPackageStatus) { + if (CollectionUtils.isEmpty(stationList)) return stepResult; + + //获取站点关联的容器条码【进料】 + Map> containerSnStationMap = stationContainerSnExtService.getContainerSnStationTopMap(reqBean.getOrganizeCode(), stationList); + List containerSnList = CollectionUtils.isEmpty(containerSnStationMap) ? null : new ArrayList<>(containerSnStationMap.keySet()); + + //获取容器条码上料主表信息【进料】的一条数据 + MesContainerPackage containerPackage = stationContainerSnExtService.getContainerPackageByContainerSn( + reqBean.getOrganizeCode(), containerSnList, null == containerPackageStatus ? null : containerPackageStatus.getValue()); + if (null != containerPackage) return stepResult; + + //成品|可疑场景下,如果上面查询的containerPackage不存在, 需要判断当前所有容器条码是否全部是已封箱的, 如果是则验证不通过 【不存在已关箱状态的数据即默认是未关箱的】 + if (null != containerPackageStatus && MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_10.getValue() == containerPackageStatus.getValue()) { + List containerPackageList = stationContainerSnExtService.getContainerPackageListByContainerSn( + reqBean.getOrganizeCode(), containerSnList, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue()); + List containerSnListDistinct = CollectionUtils.isEmpty(containerPackageList) ? null : + (containerPackageList.stream().filter(o -> null != o).map(MesContainerPackage::getContainerSn).collect(Collectors.toList())) + .stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(containerSnList) && (CollectionUtils.isEmpty(containerSnListDistinct) || containerSnListDistinct.size() != containerSnList.size())) return stepResult; + } + + //保存站点用于绑定进料容器条码 + productionDispatchContextStepService.dispatchMatchStationProductSnContext(reqBean, stationList); + return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), + String.format("匹配原料站点时验证[%s]站点未绑定%s容器条码!", suffix, null == containerPackageStatus ? MesPcnExtConstWords.EMPTY : String.format("[%s]状态的", containerPackageStatus.getDescription()))); + + } + +} 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 7fabd41..803ec9f 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 @@ -401,7 +401,7 @@ public class MesProductionCustomContextStepService extends BaseStepService imple public String getContainerPackageDetailAtomicityKey(String organizeCode, MesContainerPackageDetailContext context) { return new StringJoiner(MesPcnExtConstWords.COLON) .add(organizeCode) - .add(MesPcnExtConstWords.CONTAINER_SN_REMAIN_CONTEXT) + .add(MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT) .add(context.getStation()) .add(context.getContainerSn()) .add(new StringJoiner(MesPcnExtConstWords.AND).add(context.getBarCode()).add(context.getId().toString()).toString()) @@ -432,6 +432,7 @@ public class MesProductionCustomContextStepService extends BaseStepService imple return containerPackageDetailContextList; } + //重置原料条码的缓存库存 @Override public void dispatchContainerPackageDetailContext(String organizeCode, Map remainQtyMap2Cache) { for (Map.Entry entry : remainQtyMap2Cache.entrySet()) { @@ -441,4 +442,29 @@ public class MesProductionCustomContextStepService extends BaseStepService imple dispatchFsmBusiData(organizeCode, containerPackageDetailContext.getRemainKey(), containerPackageDetailContext.getRemainQty().toString(), MesPcnEnumUtil.EXPIRE_TIME.DEFAULT.getValue()); } } + + //可扣减条码的缓存key + @Override + public String getContainerPackageDetailPsKey(String organizeCode, String suffix, String psOrContainerSnAppendId) { + return new StringJoiner(MesPcnExtConstWords.COLON) + .add(organizeCode) + .add(MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT) + .add(suffix) + .add(psOrContainerSnAppendId) + .toString(); + } + + //验证主条码或容器条码是否被占用 + @Override + public Boolean checkContainerPackageDetailPsIsUsed(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId) { + String location = getFsmBusiData(reqBean.getOrganizeCode(), getContainerPackageDetailPsKey(reqBean.getOrganizeCode(), suffix, psOrContainerSnAppendId)); + return (StringUtils.isEmpty(location) || location.equals(reqBean.getClientInfo())) ? false : true; + } + + //锁定主条码或容器条码 + @Override + public void dispatchContainerPackageDetailPs(StationRequestBean reqBean, String suffix, String psOrContainerSnAppendId) { + dispatchFsmBusiData(reqBean.getOrganizeCode(), getContainerPackageDetailPsKey(reqBean.getOrganizeCode(), suffix, psOrContainerSnAppendId), reqBean.getClientInfo(), MesPcnEnumUtil.EXPIRE_TIME.ONE_QUARTER.getValue()); + } + } 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 31e9989..26a8385 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 @@ -21,9 +21,11 @@ import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.StringJoiner; +import java.util.stream.Collectors; /** * @Description : 获取生产过程上下文对象接口实现【BUSI】 @@ -591,16 +593,37 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp //获取站点用于缺料时进行上料绑定 @Override - public List getMatchStationContext(StationRequestBean reqBean) { - String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT); - return !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null; + public List getMatchStationContext(StationRequestBean reqBean, String item) { + String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), item); + List stationList = !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null; + if (!CollectionUtils.isEmpty(stationList)) stationList = stationList.stream().sorted(Comparator.comparing(MesStation::getStationType).thenComparing(MesStation::getCreateDatetime)).collect(Collectors.toList()); + return stationList; } - //保存站点用于缺料时进行上料绑定 + //获取装配件站点用于缺料时进行上料绑定 @Override - public void dispatchMatchStationContext(StationRequestBean reqBean, List stationList) { + public List getMatchStationAssemblyContext(StationRequestBean reqBean) { + return getMatchStationContext(reqBean, MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT); + } + + //保存装配件站点用于缺料时进行上料绑定 + @Override + public void dispatchMatchStationAssemblyContext(StationRequestBean reqBean, List stationList) { if (CollectionUtils.isEmpty(stationList)) return; - dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_CONTEXT, JSONObject.toJSONString(stationList)); + dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_ASSEMBLY_CONTEXT, JSONObject.toJSONString(stationList)); + } + + //获取站点用于进料时进行上料绑定 + @Override + public List getMatchStationProductSnContext(StationRequestBean reqBean) { + return getMatchStationContext(reqBean, MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT); + } + + //保存站点用于进料时进行上料绑定 + @Override + public void dispatchMatchStationProductSnContext(StationRequestBean reqBean, List stationList) { + if (CollectionUtils.isEmpty(stationList)) return; + dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_PRODUCT_SN_CONTEXT, JSONObject.toJSONString(stationList)); } //获取站点用于扣料业务中进行LOCK @@ -630,18 +653,4 @@ public class MesProductionDispatchContextStepService extends BaseStepService imp dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.MATCH_STATION_FEED_CONTAINER_SN_CONTEXT, sn); } - //获取站点用于进料时进行上料绑定 - @Override - public List getPsMatchStationContext(StationRequestBean reqBean) { - String stationContext = getFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PS_MATCH_STATION_CONTEXT); - return !StringUtils.isEmpty(stationContext) ? JSONObject.parseArray(stationContext, MesStation.class) : null; - } - - //保存站点用于进料时进行上料绑定 - @Override - public void dispatchPsMatchStationContext(StationRequestBean reqBean, List stationList) { - if (CollectionUtils.isEmpty(stationList)) return; - dispatchFsmBusiData(reqBean.getOrganizeCode(), getContextKey(reqBean), MesPcnExtConstWords.PS_MATCH_STATION_CONTEXT, JSONObject.toJSONString(stationList)); - } - } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java index 19de831..538061e 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/MesWorkOrderCheckCompleteQtyStepService.java @@ -46,16 +46,8 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { public List dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesProductionProcessContext productionProcessContext, List productionPartContextList, - List productionPsInContextList) { - return dispatchWorkOrderCompleteQtyContext(reqBean, resultBean, stepResult, productionProcessContext, productionPartContextList, productionPsInContextList, null); - } - - //验证加工单完成数量, 验证的前提条件: 每腔均已匹配到加工规则;存在工单; - public List dispatchWorkOrderCompleteQtyContext(StationRequestBean reqBean, StationResultBean resultBean, - StepResult stepResult, MesProductionProcessContext productionProcessContext, - List productionPartContextList, List productionPsInContextList, - List productionPsOutContextList) { + List prodRuleContextList) { //是否存在产成零件信息 if (!stepResult.isCompleted() || CollectionUtils.isEmpty(productionPartContextList)) return null; @@ -74,8 +66,8 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { Map productionPsInContextMap = CollectionUtils.isEmpty(productionPsInContextList) ? null : productionPsInContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsInContext::getForeignKey, o -> o)); //根据foreignkey分组产出零件条码 - Map productionPsOutContextMap = CollectionUtils.isEmpty(productionPsOutContextList) ? null : - productionPsOutContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProductionPsOutContext::getForeignKey, o -> o)); + Map prodRuleContextMap = CollectionUtils.isEmpty(prodRuleContextList) ? null : + prodRuleContextList.stream().filter(o -> !StringUtils.isEmpty(o.getForeignKey())).collect(Collectors.toMap(MesProdRuleContext::getForeignKey, o -> o)); //生产线与工位信息 MesWorkCenter workCenter = productionProcessContext.getWorkCenter(); @@ -90,7 +82,7 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { //验证加工单完成数量 MesWorkOrderCompleteQtyContext workOrderCompleteQtyContext = dispatchWorkOrderCompleteQty( - reqBean, resultBean, stepResult, workCenter, noCalcOrderQty, entry.getValue(), productionPsInContextMap, productionPsOutContextMap); + reqBean, resultBean, stepResult, workCenter, noCalcOrderQty, entry.getValue(), productionPsInContextMap, prodRuleContextMap); //验证失败直接退出 if (!stepResult.isCompleted()) break; @@ -118,17 +110,17 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { StepResult stepResult, MesWorkCenter workCenter, Boolean noCalcOrderQty, List productionPartContextList, Map productionPsInContextMap, - Map productionPsOutContextMap) { + Map prodRuleContextMap) { Double calcCompleteQty = new Double(MesPcnExtConstWords.ZERO); for (MesProductionPartContext productionPartContext : productionPartContextList) { MesProductionPsInContext productionPsInContext = getProductionPsInContext(productionPsInContextMap, productionPartContext.getForeignKey()); - MesProductionPsOutContext productionPsOutContext = getProductionPsOutContext(productionPsOutContextMap, productionPartContext.getForeignKey()); + MesProdRuleContext prodRuleContext = getProdRuleContext(prodRuleContextMap, productionPartContext.getForeignKey()); //验证进料零件与产出零件是否一致 Boolean isSamePart = isSamePart(productionPsInContext, productionPartContext, null); //验证是否计数 Boolean isCalcCompleteQty = isCalcCompleteQty(isSamePart, productionPsInContext, productionPartContext); - if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, null != productionPsOutContext ? productionPsOutContext.getQty() : new Double(MesPcnExtConstWords.ONE)); + if (isCalcCompleteQty) calcCompleteQty = MathOperation.add(calcCompleteQty, null != prodRuleContext ? prodRuleContext.getEachCavityQty() : new Double(MesPcnExtConstWords.ONE)); } //当前工单无须计算工单完成数 if (MathOperation.compareTo(calcCompleteQty, new Double(MesPcnExtConstWords.ZERO)) == 0) return null; @@ -184,10 +176,10 @@ public class MesWorkOrderCheckCompleteQtyStepService extends BaseStepService { return productionPsInContextMap.get(foreignKey); } - //根据数据关联键获取产出零件信息 - private MesProductionPsOutContext getProductionPsOutContext(Map productionPsOutContextMap, Integer foreignKey) { - if (CollectionUtils.isEmpty(productionPsOutContextMap) || StringUtils.isEmpty(foreignKey)) return null; - return productionPsOutContextMap.get(foreignKey); + //根据数据关联键获取加工规则数据 + private MesProdRuleContext getProdRuleContext(Map prodRuleContextMap, Integer foreignKey) { + if (CollectionUtils.isEmpty(prodRuleContextMap) || StringUtils.isEmpty(foreignKey)) return null; + return prodRuleContextMap.get(foreignKey); } //验证工单完成数 diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/IMesStationMatchPsProcessMethodStrategyStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/IMesStationMatchPsProcessMethodStrategyStepService.java new file mode 100644 index 0000000..14b7ff5 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/IMesStationMatchPsProcessMethodStrategyStepService.java @@ -0,0 +1,28 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm; + +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext; +import cn.estsh.i3plus.pojo.mes.bean.MesStation; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import io.swagger.annotations.ApiOperation; + +import java.util.List; + +public interface IMesStationMatchPsProcessMethodStrategyStepService { + + @ApiOperation(value = "【原料站点】获取容器条码上料明细表信息") + default MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List stationList) { return null; } + + @ApiOperation(value = "【原料站点】获取容器条码上料明细表信息") + default MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(IMesStationMatchPsProcessMethodStrategyStepService decoratorService, String organizeCode, List stationList) { return null; } + + @ApiOperation(value = "【原料站点】获取进料主条码信息") + default List getContainerPackageDetailContext(StationRequestBean reqBean, MesContainerPackageDetailStationContext context, Integer cavity, Boolean isExistProductionPart) { return null; } + + @ApiOperation(value = "【原料站点】验证进料主条码个数是否满足腔数 【count1=进料主条码个数 count2=加工规则对象个数 count3=产成零件个数[腔数] cavity=设备腔数】") + default Boolean checkIsMatchCavity(Integer count1, Integer count2, Integer count3, Integer cavity, Boolean isBeforeCheck) { return true; } + + @ApiOperation(value = "【原料站点】锁定进料主条码信息") + default void dispatchContainerPackageDetailPs(StationRequestBean reqBean, List needCachedList) {} + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodContainerStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodContainerStepService.java new file mode 100644 index 0000000..de1071e --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodContainerStepService.java @@ -0,0 +1,92 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.pojo.mes.bean.MesStation; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * @Description : 加工模式 - 整箱 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationMatchPsProcessMethodContainerStepService") +public class MesStationMatchPsProcessMethodContainerStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService { + + @Autowired + private IMesStationMatchPsProcessMethodStrategyStepService defaultDecoratorService; + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + //【原料站点】获取容器条码上料明细表信息 + @Override + public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List stationList) { + return getContainerPackageDetailStationContext(defaultDecoratorService, organizeCode, stationList); + } + + //【原料站点】获取容器条码上料明细表信息 + @Override + public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(IMesStationMatchPsProcessMethodStrategyStepService decoratorService, String organizeCode, List stationList) { + MesContainerPackageDetailStationContext decoratorContext = decoratorService.getContainerPackageDetailStationContext(organizeCode, stationList); + if (null == decoratorContext) return decoratorContext; + return new MesContainerPackageDetailStationContext().addStationList(decoratorContext.getStationList()).addStationContainerSnDetailList(decoratorContext); + } + + //【原料站点】获取进料主条码信息 + @Override + public List getContainerPackageDetailContext(StationRequestBean reqBean, MesContainerPackageDetailStationContext context, Integer cavity, Boolean isExistProductionPart) { + if (null == context) return null; + List containerPackageDetailStationContextList = context.getStationContainerSnDetailList(); + for (MesContainerPackageDetailStationContext containerPackageDetailStationContext : containerPackageDetailStationContextList) { + if (null == containerPackageDetailStationContext) continue; + LinkedHashMap> containerSnDataMap = containerPackageDetailStationContext.getTopContainerSnDetailMap2Sort(); + for (Map.Entry> entry : containerSnDataMap.entrySet()) { + if (null == entry || !StringUtils.isEmpty(entry.getValue().get(0).getIsUsed())) continue; + //验证是否被使用 + if (productionCustomContextStepService.checkContainerPackageDetailPsIsUsed(reqBean, MesPcnExtConstWords.CONTAINER_SN, entry.getKey())) { + //标记被使用 + entry.getValue().get(0).isUsed(); + continue; + } + //返回整箱 + return entry.getValue(); + } + } + return null; + } + + //【原料站点】验证进料主条码个数是否满足腔数 + // count1=进料主条码个数 count2=加工规则对象个数 count3=产成零件个数[腔数] cavity=设备腔数 + @Override + public Boolean checkIsMatchCavity(Integer count1, Integer count2, Integer count3, Integer cavity, Boolean isBeforeCheck) { + //前置验证 + if (isBeforeCheck) { + //不存在产成,按箱加工则不验证腔数,箱内条数即腔数 + if (count3.compareTo(MesPcnExtConstWords.ZERO) == 0) return true; + //存在产成, 验证进料是否满足产成腔数 + return count1.compareTo(count3) == 0; + } + + //后置验证 为true或者false 均退出循环 + return count1.compareTo(count2) == 0; + } + + //【原料站点】锁定进料主条码信息 + @Override + public void dispatchContainerPackageDetailPs(StationRequestBean reqBean, List needCachedList) { + productionCustomContextStepService.dispatchContainerPackageDetailPs(reqBean, MesPcnExtConstWords.CONTAINER_SN, needCachedList.get(0).getTopContainerSnKey()); + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodDecoratorStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodDecoratorStepService.java new file mode 100644 index 0000000..86f6dda --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodDecoratorStepService.java @@ -0,0 +1,124 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesStationContainerSnExtService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackage; +import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail; +import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation; +import cn.estsh.i3plus.pojo.mes.bean.MesStation; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description : 加工模式 - Decorator + * @Author : wangjie + **/ +@Slf4j +@Primary +@Service("mesStationMatchPsProcessMethodDecoratorStepService") +public class MesStationMatchPsProcessMethodDecoratorStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService { + + @Autowired + private IMesStationContainerSnExtService stationContainerSnExtService; + + @Override + @Transactional(propagation = Propagation.NOT_SUPPORTED) + public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List stationList) { + + //获取站点关联的容器条码 + List containerSnStationList = stationContainerSnExtService.getContainerSnStationList(organizeCode, stationList); + containerSnStationList = CollectionUtils.isEmpty(containerSnStationList) ? null : + containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getContainerSn()) && !StringUtils.isEmpty(o.getTopContainerSn()))).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(containerSnStationList)) return null; + + //容器条码根据TOP容器条码分组 + Map> topContainerSnMap = CollectionUtils.isEmpty(containerSnStationList) ? null : + containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getTopContainerSn)); + //容器条码根据容器条码分组 + Map> containerSnMap = CollectionUtils.isEmpty(containerSnStationList) ? null : + containerSnStationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerSnStation::getContainerSn)); + + //容器条码根据创建时间正序 【暂不考虑seq, 因为站点没有顺序, 没法比较多站点的情况, 一个站点的情况下, 创建时间正序正常情况下等同于seq正序】 + containerSnStationList = containerSnStationList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesContainerSnStation::getCreateDatetime)).collect(Collectors.toList()); + //根据TOP去重 + List containerSnStationList2TopDistinct = containerSnStationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getTopContainerSn()))) + .distinct().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesContainerSnStation::getTopContainerSn))), ArrayList::new)); + //搜集料架车容器条码 + List topContainerSnList = containerSnStationList2TopDistinct.stream().filter(o -> (null != o && !o.getTopContainerSn().equals(o.getContainerSn()))).map(MesContainerSnStation::getTopContainerSn).collect(Collectors.toList()); + + //料桶容器条码 + List containerSnList = new ArrayList<>(containerSnMap.keySet()); + //最外层料架车与料桶容器条码 + List allContainerSnList = new ArrayList<>(containerSnList); + //合并 + if (!CollectionUtils.isEmpty(topContainerSnList)) allContainerSnList.addAll(topContainerSnList); + //去重 + allContainerSnList = allContainerSnList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList()); + + //获取合并的容器条码上料主表信息【已关箱】 + List containerPackageList = stationContainerSnExtService.getContainerPackageListByContainerSn(organizeCode, allContainerSnList, MesExtEnumUtil.CONTAINER_PACKAGE_STATUS.STATUS_20.getValue()); + //料桶对应的上料主表数据 + List containerPackageList2Detail = CollectionUtils.isEmpty(containerPackageList) ? null : + containerPackageList.stream().filter(o -> (null != o && containerSnList.contains(o.getContainerSn()))).collect(Collectors.toList()); + if (CollectionUtils.isEmpty(containerPackageList) || CollectionUtils.isEmpty(containerPackageList2Detail)) return null; + + //获取料桶对应的上料明细表信息【可扣减】 + List containerPackageDetailList = stationContainerSnExtService.getContainerPackageDetailList(organizeCode, containerPackageList2Detail); + if (CollectionUtils.isEmpty(containerPackageDetailList)) return null; + + //已关箱的容器条码信息根据条码分组 + Map> containerPackageMap = containerPackageList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerPackage::getContainerSn)); + + //站点根据名称分组 + Map> stationMap = stationList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesStation::getStation)); + Map stationMap2Back = new HashMap<>(); + //封装容器条码对应的【可扣减】的上料明细表信息 + List containerSnStationContextList = new ArrayList<>(); + for (MesContainerPackageDetail containerPackageDetail : containerPackageDetailList) { + if (null == containerPackageDetail) continue; + MesContainerSnStation containerSnStation = containerSnMap.get(containerPackageDetail.getContainerSn()).get(0); + containerSnStationContextList.add( + new MesContainerPackageDetailContext(containerPackageDetail) + .containerSnStation(containerSnStation, containerPackageMap.get(containerSnStation.getTopContainerSn()).get(0).getId()) + .station(stationMap.get(containerSnStation.getStation()).get(0)) + ); + if (!stationMap2Back.containsKey(containerSnStation.getStation())) stationMap2Back.put(containerSnStation.getStation(), stationMap.get(containerSnStation.getStation()).get(0)); + } + + //上料明细数据根据TOP容器条码分组 + Map> topContainerSnDetailMap = containerSnStationContextList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesContainerPackageDetailContext::getTopContainerSn)); + + //已关箱的料架车容器条码 + List topContainerSnList2Colsed = (CollectionUtils.isEmpty(containerPackageList) || CollectionUtils.isEmpty(topContainerSnList)) ? null : + containerPackageList.stream().filter(o -> (null != o && topContainerSnList.contains(o.getContainerSn()))).map(MesContainerPackage::getContainerSn).collect(Collectors.toList()); + + LinkedHashMap> topContainerSnDetailMap2Sort = new LinkedHashMap<>(); + //遍历 根据创建时间正序,TOP去重后的容器条码 + for (MesContainerSnStation containerSnStation : containerSnStationList2TopDistinct) { + //跳过被扣减完的容器条码 + if (null == containerSnStation || !topContainerSnDetailMap.containsKey(containerSnStation.getTopContainerSn())) continue; + //跳过未封箱的料架车 + if (!containerSnStation.getTopContainerSn().equals(containerSnStation.getContainerSn()) && !topContainerSnList2Colsed.contains(containerSnStation.getTopContainerSn())) continue; + //将明细数据按照主表createDatetime,明细表createDatetime 正序 后, 存入有序集合内 + List detailList2Sort = topContainerSnDetailMap.get(containerSnStation.getTopContainerSn()).stream().filter(o -> null != o) + .sorted(Comparator.comparing(MesContainerPackageDetailContext::getCreateDatetime2Package).thenComparing(MesContainerPackageDetailContext::getCreateDatetime)).collect(Collectors.toList()); + topContainerSnDetailMap2Sort.put(detailList2Sort.get(0).getTopContainerSnKey(), detailList2Sort); + } + + return new MesContainerPackageDetailStationContext((List) stationMap2Back.values(), topContainerSnDetailMap2Sort); + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodManyContainerStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodManyContainerStepService.java new file mode 100644 index 0000000..23d2d66 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodManyContainerStepService.java @@ -0,0 +1,15 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm; + +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * @Description : 加工模式 - 整摞 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationMatchPsProcessMethodManyContainerStepService") +public class MesStationMatchPsProcessMethodManyContainerStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService { + //TODO +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodSingleStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodSingleStepService.java new file mode 100644 index 0000000..09c9bb7 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/method/stationpm/MesStationMatchPsProcessMethodSingleStepService.java @@ -0,0 +1,129 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step.method.stationpm; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesContainerPackageDetailStationContext; +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.MesStation; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @Description : 加工模式 - 单件 + * @Author : wangjie + **/ +@Slf4j +@Service("mesStationMatchPsProcessMethodSingleStepService") +public class MesStationMatchPsProcessMethodSingleStepService extends BaseStepService implements IMesStationMatchPsProcessMethodStrategyStepService { + + @Autowired + private IMesStationMatchPsProcessMethodStrategyStepService defaultDecoratorService; + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + //【原料站点】获取容器条码上料明细表信息 + @Override + public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(String organizeCode, List stationList) { + return getContainerPackageDetailStationContext(defaultDecoratorService, organizeCode, stationList); + } + + //【原料站点】获取容器条码上料明细表信息 + @Override + public MesContainerPackageDetailStationContext getContainerPackageDetailStationContext(IMesStationMatchPsProcessMethodStrategyStepService decoratorService, String organizeCode, List stationList) { + MesContainerPackageDetailStationContext containerPackageDetailStationContext = null; + for (MesStation station : stationList) { + if (null == station) continue; + MesContainerPackageDetailStationContext decoratorContext = decoratorService.getContainerPackageDetailStationContext(organizeCode, stationList); + if (null == decoratorContext) continue; + if (null == containerPackageDetailStationContext) containerPackageDetailStationContext = new MesContainerPackageDetailStationContext(); + containerPackageDetailStationContext.addStationList(decoratorContext.getStationList()).addStationContainerSnDetailList(decoratorContext); + } + return containerPackageDetailStationContext; + } + + //【原料站点】获取进料主条码信息 + @Override + public List getContainerPackageDetailContext(StationRequestBean reqBean, MesContainerPackageDetailStationContext context, Integer cavity, Boolean isExistProductionPart) { + List resultList = null; + if (null == context) return resultList; + List containerPackageDetailStationContextList = context.getStationContainerSnDetailList(); + for (MesContainerPackageDetailStationContext containerPackageDetailStationContext : containerPackageDetailStationContextList) { + if (null == containerPackageDetailStationContext) continue; + LinkedHashMap> containerSnDataMap = containerPackageDetailStationContext.getTopContainerSnDetailMap2Sort(); + LOOP: + for (Map.Entry> entry : containerSnDataMap.entrySet()) { + if (null == entry) continue; + List containerSnDetailList = entry.getValue(); + for (MesContainerPackageDetailContext containerPackageDetailContext : containerSnDetailList) { + //验证是否已经被使用 + if (null == containerPackageDetailContext || !StringUtils.isEmpty(containerPackageDetailContext.getIsUsed())) continue; + //已经被匹配成功 matchResult不为空只会是在存在产成的情况下, 下面会先标记为0 + if (!StringUtils.isEmpty(containerPackageDetailContext.getMatchResult()) && containerPackageDetailContext.getMatchResult().equals(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr())) continue; + //已经被匹配失败, 跳到下个站点进行验证第一个未匹配的进料主条码 + if (!StringUtils.isEmpty(containerPackageDetailContext.getMatchResult()) && containerPackageDetailContext.getMatchResult().equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr())) break LOOP; + //验证是否被使用 + if (productionCustomContextStepService.checkContainerPackageDetailPsIsUsed(reqBean, MesPcnExtConstWords.PRODUCT_SN, containerPackageDetailContext.getBarCodeKey())) { + //标记被使用 + containerPackageDetailContext.isUsed(); + continue; + } + + //如果存在产成, 标记即将进行匹配, 直接返回进行单腔验证, 支持跨站点按照站点内的容器条码顺序进行一个个匹配 + if (isExistProductionPart) { + //一个个匹配才需要标记为0, 匹配完成之后需要将0的数据标记为1或者2 + containerPackageDetailContext.matchResult(MesPcnExtConstWords.ZERO_STR); + return Stream.of(containerPackageDetailContext).collect(Collectors.toList()); + } + + //不存在产成, 按顺序添加进料主条码,直到满足设备腔数 + if (CollectionUtils.isEmpty(resultList)) resultList = new ArrayList<>(); + resultList.add(containerPackageDetailContext); + if (resultList.size() == cavity) return resultList; + } + } + } + return resultList; + } + + //【原料站点】验证进料主条码个数是否满足腔数 + // count1=进料主条码个数 count2=加工规则对象个数 count3=产成零件个数[腔数] cavity=设备腔数 + @Override + public Boolean checkIsMatchCavity(Integer count1, Integer count2, Integer count3, Integer cavity, Boolean isBeforeCheck) { + + //前置验证 + if (isBeforeCheck) { + //不存在产成, 需要一次取出满足设备腔数个数的进料, 验证进料是否满足设备腔数 + if (count3.compareTo(MesPcnExtConstWords.ZERO) == 0) return count1.compareTo(cavity) == 0; + //存在产成, 进料等于0则是一定不够腔数的,因为后面满足腔数就进入下一个工步集了 + return count1.compareTo(MesPcnExtConstWords.ZERO) > 0; + } + + //后置验证, 为true或者false 均退出循环 + //不存在产成, 验证加工规则是否满足设备腔数 + if (count3.compareTo(MesPcnExtConstWords.ZERO) == 0) return count2.compareTo(cavity) == 0; + //存在产成, 验证加工规则是否满足产成腔数, 为null继续循环处理 + return count2.compareTo(count3) == 0 ? true : null; + } + + //【原料站点】锁定进料主条码信息 + @Override + public void dispatchContainerPackageDetailPs(StationRequestBean reqBean, List needCachedList) { + needCachedList.forEach(o -> productionCustomContextStepService.dispatchContainerPackageDetailPs(reqBean, MesPcnExtConstWords.PRODUCT_SN, o.getBarCodeKey())); + } + + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/util/MesReentrantLockUtil.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/util/MesReentrantLockUtil.java new file mode 100644 index 0000000..701aab7 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/util/MesReentrantLockUtil.java @@ -0,0 +1,46 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.util; + +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +@Component +public class MesReentrantLockUtil { + + private final static Map lockMap = new ConcurrentHashMap<>(); + + public static Boolean tryLock(List acquiredLocks, List keyList, String prefix, Long milliseconds) throws InterruptedException { + + Collections.sort(keyList); + + long remaining = TimeUnit.MILLISECONDS.toNanos(milliseconds); + long endTime = System.nanoTime() + remaining; + + for (String key : keyList) { + + if (StringUtils.isEmpty(key)) continue; + + ReentrantLock lock = lockMap.computeIfAbsent(prefix + key, o -> new ReentrantLock()); + + if (!lock.tryLock(remaining, TimeUnit.NANOSECONDS)) return false; + + acquiredLocks.add(lock); + + remaining = endTime - System.nanoTime(); + } + + return true; + + } + + public static void unLockAll(List acquiredLocks) { + for (int i = acquiredLocks.size() - 1; i >= 0; i --) acquiredLocks.get(i).unlock(); + } + +} diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailContext.java index 32eb38f..4d52701 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailContext.java @@ -1,6 +1,7 @@ package cn.estsh.i3plus.ext.mes.pcn.pojo.context; import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; +import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.mes.bean.MesContainerPackageDetail; import cn.estsh.i3plus.pojo.mes.bean.MesContainerSnStation; import cn.estsh.i3plus.pojo.mes.bean.MesStation; @@ -10,6 +11,7 @@ import org.springframework.beans.BeanUtils; import org.springframework.util.StringUtils; import java.io.Serializable; +import java.util.StringJoiner; /** * 生产过程上下文对象-容器条码上料明细 @@ -49,6 +51,22 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail @ApiParam(name = "加工模式") private Integer processMethod; + @ApiParam("顶层容器条码") + private String topContainerSn; + + @ApiParam("顶层容器条码KEY") + private String topContainerSnKey; + + @ApiParam("进料条码KEY") + private String barCodeKey; + + //0=即将进行匹配, 1=成功, 2=失败 + @ApiParam("匹配结果") + private String matchResult; + + @ApiParam("是否被使用") + private String isUsed; + public MesContainerPackageDetailContext() {} public MesContainerPackageDetailContext(MesContainerPackageDetail containerPackageDetail) { @@ -63,6 +81,16 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail this.station = containerSnStation.getStation(); this.seq = !StringUtils.isEmpty(containerSnStation.getSeq()) ? containerSnStation.getSeq() : MesPcnExtConstWords.ZERO; this.createDatetime2Package = containerSnStation.getCreateDatetime(); + this.topContainerSn = containerSnStation.getTopContainerSn(); + return this; + } + + public MesContainerPackageDetailContext containerSnStation(MesContainerSnStation containerSnStation, Long topContainerSnId) { + this.containerSnStation(containerSnStation); + //容器条码&ID + this.topContainerSnKey = new StringJoiner(MesPcnExtConstWords.AND).add(this.topContainerSn).add(topContainerSnId.toString()).toString(); + //BARCODE&ID + this.barCodeKey = new StringJoiner(MesPcnExtConstWords.AND).add(super.getBarCode()).add(super.getId().toString()).toString(); return this; } @@ -97,6 +125,16 @@ public class MesContainerPackageDetailContext extends MesContainerPackageDetail return this; } + public MesContainerPackageDetailContext matchResult(String matchResult) { + this.matchResult = matchResult; + return this; + } + + public MesContainerPackageDetailContext isUsed() { + this.isUsed = CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr(); + return this; + } + public MesStation getStationInfo() { MesStation station = new MesStation(); station.setEquipmentCode(this.equipmentCode); diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailStationContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailStationContext.java new file mode 100644 index 0000000..be2cf05 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesContainerPackageDetailStationContext.java @@ -0,0 +1,51 @@ +package cn.estsh.i3plus.ext.mes.pcn.pojo.context; + +import cn.estsh.i3plus.pojo.mes.bean.MesStation; +import io.swagger.annotations.ApiParam; +import lombok.Data; +import org.springframework.util.CollectionUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +/** + * 生产过程上下文对象-站点容器条码上料明细 + */ +@Data +public class MesContainerPackageDetailStationContext implements Serializable { + + private static final long serialVersionUID = -6056654777597346815L; + + @ApiParam(name = "站点信息") + private List stationList; + + @ApiParam(name = "站点信息") + private LinkedHashMap> topContainerSnDetailMap2Sort; + + //从这个里面存取数据 + @ApiParam(name = "多个站点的容器条码上料明细") + private List stationContainerSnDetailList; + + public MesContainerPackageDetailStationContext() {} + + public MesContainerPackageDetailStationContext(List stationList, + LinkedHashMap> topContainerSnDetailMap2Sort) { + this.stationList = stationList; + this.topContainerSnDetailMap2Sort = topContainerSnDetailMap2Sort; + } + + public MesContainerPackageDetailStationContext addStationList(List stationList) { + if (CollectionUtils.isEmpty(this.stationList)) this.stationList = new ArrayList<>(); + this.stationList.addAll(stationList); + return this; + } + + public MesContainerPackageDetailStationContext addStationContainerSnDetailList(MesContainerPackageDetailStationContext containerPackageDetailStationContext) { + if (CollectionUtils.isEmpty(this.stationContainerSnDetailList)) this.stationContainerSnDetailList = new ArrayList<>(); + this.stationContainerSnDetailList.add(containerPackageDetailStationContext); + return this; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesEquipVariableCollectContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesEquipVariableCollectContext.java index bb15eee..e97ee1b 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesEquipVariableCollectContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesEquipVariableCollectContext.java @@ -97,6 +97,9 @@ public class MesEquipVariableCollectContext implements Serializable { @ApiParam("是否被消费/是否被验证") private Integer isConsume = CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(); + @ApiParam("数量") + private Double qty; + public MesEquipVariableCollectContext() {} public MesEquipVariableCollectContext(Long equipVariableId) { @@ -143,4 +146,9 @@ public class MesEquipVariableCollectContext implements Serializable { return this; } + public MesEquipVariableCollectContext qty(Double qty) { + this.qty = qty; + return this; + } + } diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java index 03e5dc7..d33291b 100644 --- a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/context/MesProductionPsInContext.java @@ -49,6 +49,9 @@ public class MesProductionPsInContext implements Serializable { @ApiParam("零件条码状态【用于发送设备加工参数】") private Integer snStatus; + @ApiParam(name = "数量") + private Double qty = new Double(1); + @ApiParam("打印状态") private Integer printStatus; @@ -98,6 +101,9 @@ public class MesProductionPsInContext implements Serializable { @ApiParam("裁片方案代码") private String cutCode; + @ApiParam("容器匹配信息") + public String containerSnData; + public MesProductionPsInContext() {} public MesProductionPsInContext(String organizeCode, String productSn) { @@ -153,4 +159,9 @@ public class MesProductionPsInContext implements Serializable { return this; } + public MesProductionPsInContext qty(Double qty) { + if (!StringUtils.isEmpty(qty)) this.qty = qty; + return this; + } + } 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 c42d810..4b90d8a 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 @@ -491,6 +491,8 @@ public class MesPcnExtConstWords { public static final String IS_FILTER_PARALLEL = "isFilterParallel"; //是否根据工序顺序号过滤后道[工步参数] public static final String IS_FILTER_AFTER_CRAFT = "isFilterAfterCraft"; + //是否验证工艺路线[工步参数] + public static final String IS_CHECK_CRAFT_CFG = "isCheckCraftCfg"; // 装配件显示规则配置[工位参数] public static final String ASSEMBLY_SHOW_MR_CFG = "ASSEMBLY_SHOW_MR_CFG"; @@ -695,8 +697,6 @@ public class MesPcnExtConstWords { public static final String CHOOSE_SHIPPING_RFID_ROUTE_MODE = "CHOOSE_SHIPPING_RFID_ROUTE_MODE"; // 设备站点 public static final String EQUIPMENT_STATION_CONTEXT = "EQUIPMENT_STATION_CONTEXT"; - // 容器条码扣减剩余上下文 - public static final String CONTAINER_SN_REMAIN_CONTEXT = "CONTAINER_SN_REMAIN_CONTEXT"; // 上下文: 展示组件数据 public static final String MODULE_CONTENT_CONTEXT = "MODULE_CONTENT_CONTEXT"; @@ -742,8 +742,15 @@ public class MesPcnExtConstWords { public static final String PROD_TEMP_DATA_CONTEXT = "PROD_TEMP_DATA_CONTEXT"; // 上下文: 发运队列 public static final String SHIPPING_QUEUE_CONTEXT = "SHIPPING_QUEUE_CONTEXT"; - // 用于缺料时进行上料绑定的站点 - public static final String MATCH_STATION_CONTEXT = "MATCH_STATION_CONTEXT"; + + // 投料站点标识 + public static final String MATCH_STATION_CONTEXT_FLAG = "MATCH_STATION_CONTEXT_FLAG"; + + // 用于缺料时进行上料绑定的装配件站点 + public static final String MATCH_STATION_ASSEMBLY_CONTEXT = "MATCH_STATION_ASSEMBLY_CONTEXT"; + // 用于缺料时进行上料绑定的进料站点 + public static final String MATCH_STATION_PRODUCT_SN_CONTEXT = "MATCH_STATION_PRODUCT_SN_CONTEXT"; + // 用于扣料业务中进行LOCK public static final String LOCK_STATION_CONTEXT = "LOCK_STATION_CONTEXT"; @@ -754,10 +761,6 @@ public class MesPcnExtConstWords { // 工步上料关箱码 public static final String MATCH_STATION_FEED_CLOSE_PACKAGE = "MATCH_STATION_FEED_CLOSE_PACKAGE"; - // 用于进料绑定的站点 - public static final String PS_MATCH_STATION_CONTEXT = "PS_MATCH_STATION_CONTEXT"; - - //OPC_API_PARAM public static final String OPC_LINK_URL = "OPC_LINK_URL"; public static final String VALUE = "value";