From 7cc05f616ff1532cbb8feb0f3d86038414475265 Mon Sep 17 00:00:00 2001 From: "logic.fang" Date: Thu, 29 May 2025 15:01:49 +0800 Subject: [PATCH 01/12] =?UTF-8?q?47241=20PCN=EF=BC=9A=E8=B5=9B=E5=8A=9B?= =?UTF-8?q?=E6=96=AFjis=E9=98=9F=E5=88=97=E6=8E=A5=E6=94=B6=E5=92=8C?= =?UTF-8?q?=E8=B5=9B=E5=8A=9B=E6=96=AFJIS=E5=8D=95=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=8F=96=E6=B6=88=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E6=8C=89=E9=92=AE=EF=BC=8C=E6=8C=89=E9=92=AE=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=AE=A1=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pcn/api/report/IMesCimSeresReportService.java | 4 ++++ .../report/MesCimSeresReportController.java | 28 ++++++++++++++++++++++ .../report/MesCimSeresReportServiceImpl.java | 28 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/report/IMesCimSeresReportService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/report/IMesCimSeresReportService.java index a6193bc..1c90f39 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/report/IMesCimSeresReportService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/report/IMesCimSeresReportService.java @@ -14,9 +14,13 @@ public interface IMesCimSeresReportService { void doSrmSunSheetJisNormal(List ids); + void doSrmSunSheetJisCancel(List ids); + ListPager queryJisQueueLogByPager(Integer checkStatus, String vin, String materielCode, String partClassCode, String partClassName, Pager pager); void doJisQueueNormal(List ids); + void doJisQueueCancel(List ids); + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/report/MesCimSeresReportController.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/report/MesCimSeresReportController.java index 377e176..62f1390 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/report/MesCimSeresReportController.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/report/MesCimSeresReportController.java @@ -56,6 +56,20 @@ public class MesCimSeresReportController { } } + @ApiOperation(value = "赛力斯JIS单-取消", notes = "赛力斯JIS单-取消") + @PostMapping("/srm-sun-sheet-jis-cancel") + public ResultBean doSrmSunSheetJisCancel(@RequestBody Long[] idArray) { + try { + List idList = Arrays.asList(idArray); + mesCimSeresReportService.doSrmSunSheetJisCancel(idList); + return ResultBean.success("执行成功"); + } catch (ImppBusiException e) { + return ResultBean.fail(e); + } catch (Exception e) { + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } + } + @ApiOperation(value = "赛力斯JIS队列接收日志", notes = "赛力斯JIS队列接收日志") @GetMapping("/query-jis-queue-log") public ResultBean queryJisQueueLogByPager(Integer checkStatus, String vin, String materielCode, @@ -86,4 +100,18 @@ public class MesCimSeresReportController { } } + @ApiOperation(value = "赛力斯JIS队列-取消", notes = "赛力斯JIS队列-取消") + @PostMapping("/jis-queue-cancel") + public ResultBean doJisQueueCancel(@RequestBody Long[] idArray) { + try { + List idList = Arrays.asList(idArray); + mesCimSeresReportService.doJisQueueCancel(idList); + return ResultBean.success("执行成功"); + } catch (ImppBusiException e) { + return ResultBean.fail(e); + } catch (Exception e) { + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } + } + } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/report/MesCimSeresReportServiceImpl.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/report/MesCimSeresReportServiceImpl.java index 91aee5d..b71dd0b 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/report/MesCimSeresReportServiceImpl.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/report/MesCimSeresReportServiceImpl.java @@ -56,6 +56,20 @@ public class MesCimSeresReportServiceImpl implements IMesCimSeresReportService { } @Override + public void doSrmSunSheetJisCancel(List ids) { + final String organizeCode = AuthUtil.getOrganize().getOrganizeCode(); + final String username = AuthUtil.getSessionUser().getUserName(); + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getInPackList(ids, "id", packBean); + + runSheetJisRDao.updateByProperties( + new String[]{"isValid", "isDeleted", "modifyUser", "modifyDatetime"}, + new Object[]{CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), + username, TimeTool.getNowTime(true)}, + packBean); + } + + @Override public ListPager queryJisQueueLogByPager(Integer checkStatus, String vin, String materielCode, String partClassCode, String partClassName, Pager pager) { final String organizeCode = AuthUtil.getOrganize().getOrganizeCode(); @@ -82,4 +96,18 @@ public class MesCimSeresReportServiceImpl implements IMesCimSeresReportService { queueJisRDao.updateByProperties(new String[]{"checkStatus","modifyUser","modifyDatetime"},new Object[]{MesExtEnumUtil.CIM_SERES_JIS_STATUS.WAIT_CHECK.getValue(), username, TimeTool.getNowTime(true)}, packBean); } + @Override + public void doJisQueueCancel(List ids) { + final String organizeCode = AuthUtil.getOrganize().getOrganizeCode(); + final String username = AuthUtil.getSessionUser().getUserName(); + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getInPackList(ids, "id", packBean); + + queueJisRDao.updateByProperties( + new String[]{"isValid", "isDeleted", "modifyUser", "modifyDatetime"}, + new Object[]{CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue(), + username, TimeTool.getNowTime(true)}, + packBean); + } + } From ece6e4f88dd5a2a1c7477b5d92d2ba6006d66fa8 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 12 Jun 2025 11:02:42 +0800 Subject: [PATCH 02/12] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=88=90=E9=83=BD?= =?UTF-8?q?=E5=B7=A5=E4=BD=8D=E7=AB=AF=E6=89=93=E5=8D=B0DataMatrix?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../print/strategy/ChengDuSplitFixCharPrintStrategy.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java index e2a2358..5b7b2a7 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java @@ -77,7 +77,7 @@ public class ChengDuSplitFixCharPrintStrategy implements IPrintTemplateStrategyS MesProduceSnPrintDataModel printDataModel = getModel(produceSn, custPartNo); mesProduceSnPrintModel.getMesProduceSnPrintDataModelList().clear(); mesProduceSnPrintModel.getMesProduceSnList().add(produceSn); - Map printTemplateData = new HashMap<>(getPrintContextMap(produceSn, custPartNo)); + Map printTemplateData = new HashMap<>(getPrintContextMap(produceSn, custPartNo, isStep)); mesProduceSnPrintModel.getPrintContextList().add(printTemplateData); //保存打印记录 mesProduceSnPrintModel.getMesPrintedSnLogList().add(mesPrintedSnLogService.getMesCustomPrintedSnLog(mesProduceSnPrintModel.getUserName(), organizeCode, printDataModel, printTemplateData)); @@ -87,7 +87,7 @@ public class ChengDuSplitFixCharPrintStrategy implements IPrintTemplateStrategyS //封装打印信息 MesProduceSnPrintDataModel printDataModel = getModel(mesProduceSn, custPartNo); mesProduceSnPrintModel.getMesProduceSnPrintDataModelList().clear(); - Map printTemplateData = new HashMap<>(getPrintContextMap(mesProduceSn, custPartNo)); + Map printTemplateData = new HashMap<>(getPrintContextMap(mesProduceSn, custPartNo, isStep)); List> printDataMapList = new ArrayList<>(); printDataMapList.add(printTemplateData); mesProduceSnPrintModel.getPrintContextList().add(packResultMap(mesProduceSnPrintModel, printDataMapList)); @@ -131,7 +131,7 @@ public class ChengDuSplitFixCharPrintStrategy implements IPrintTemplateStrategyS return mesProduceSnPrintDataModel; } - private Map getPrintContextMap(MesProduceSn produceSn, String custPartNo) { + private Map getPrintContextMap(MesProduceSn produceSn, String custPartNo, boolean isStep) { Map result = new HashMap<>(); String[] splitSn = produceSn.getProductSn().split("#"); if (splitSn.length < 3) { @@ -173,7 +173,11 @@ public class ChengDuSplitFixCharPrintStrategy implements IPrintTemplateStrategyS log.error("ChengDuSplitFixCharPrintStrategy --- execute --- 报错:{}", e.getMessage()); return result; } - result.put(MesPcnExtConstWords.CUST_SN_DATA_MATRIX, "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(dataMatrixCode.toByteArray())); + String encoderCode = Base64.getEncoder().encodeToString(dataMatrixCode.toByteArray()); + if (!isStep) { + encoderCode = "data:image/jpeg;base64," + encoderCode; + } + result.put(MesPcnExtConstWords.CUST_SN_DATA_MATRIX, encoderCode); return result; } From e181519b04115b81a51676f77e980672510606cd Mon Sep 17 00:00:00 2001 From: "logic.fang" Date: Fri, 13 Jun 2025 09:11:15 +0800 Subject: [PATCH 03/12] =?UTF-8?q?47191=20DM202504290012=20=E9=BE=99?= =?UTF-8?q?=E5=85=B4=E5=B7=A5=E5=8E=82CKPT=E7=BA=BF=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=8B=86=E5=8D=95=E9=9C=80=E6=B1=82-EDI?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BF=AE=E6=94=B9=EF=BC=88=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E5=8F=91=E8=BF=90=E6=96=B0=E5=A2=9E=E2=80=9C=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=9C=AB=E5=8D=95=E2=80=9D=E3=80=81=E2=80=9C?= =?UTF-8?q?=E5=8F=91=E9=80=81=E7=94=A8=E6=88=B7=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E8=87=B3PLC=E7=82=B9=E4=BD=8D=E2=80=9D?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../step/MesSendUserDefinedCmdStepService.java | 176 +++++++++++++++++++++ ...ckCimSeresLastOrderShippingCodeStepService.java | 89 +++++++++++ .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 3 + 3 files changed, 268 insertions(+) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java new file mode 100644 index 0000000..b9e2b97 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java @@ -0,0 +1,176 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesEquipVariableRwExtService; +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext; +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.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariable; +import cn.estsh.i3plus.pojo.mes.bean.MesEquipmentVariableCfg; +import cn.estsh.i3plus.pojo.mes.bean.MesProdRouteOptParam; +import cn.estsh.i3plus.pojo.mes.model.MesEquipVariableRwResult; +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 com.alibaba.fastjson.JSONObject; +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.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @Description : 向PLC点位发送自定义指令工步 + * @Reference : + * @Author : logic + * @CreateDate : 2025/6/9 16:58 + * @Modify: + **/ +@Slf4j +@Service("mesSendUserDefinedCmdStepService") +public class MesSendUserDefinedCmdStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesEquipVariableRwExtService equipVariableRwExtService; + + @Override + public StepResult execute(StationRequestBean reqBean) { + + StepResult stepResult = StepResult.getSuccessComplete(); + + StationResultBean resultBean = new StationResultBean(); + + //获取工步参数 + Optional> stepParamMap = getStepParams(reqBean); + + //获取上下文信息 + MesProductionProcessContext productionProcessContext = + productionProcessContextStepService.dispatchCurCellEquipment(reqBean, stepParamMap); + + //获取生产过程上下文对象有异常信息 抛出异常 + if (!productionProcessContextStepService.getEquipmentVariableCfgList(productionProcessContext).getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //从上下文的设备数据变量接口逻辑对象集合中取出当前设备信息的逻辑类型对应的接口逻辑对象集合 + List equipmentVariableCfgList = productionProcessContext.getEquipVariableCfgListByVct(); + + //根据变量类别[用户自定义指令]搜集设备数据变量接口逻辑信息 + equipmentVariableCfgList = productionProcessContextStepService.collectEquipmentVariableCfgList( + equipmentVariableCfgList, MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY); + + //当前工位使用的设备 + MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip(); + + //配置错误 抛出异常 + if (!productionProcessContextStepService.checkNecessaryEquipmentVariableCfgAndValue(productionProcessContext, + cellEquipContext, equipmentVariableCfgList, MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY).getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //搜集设备数据变量接口逻辑信息中的二级变量 + List categoryLevelTwoList = productionProcessContextStepService.collectCategoryLevelTwoList(equipmentVariableCfgList); + + //根据变量类型与二级变量获取设备数据变量信息 + List equipmentVariableList = productionProcessContextStepService.findEquipmentVariableList( + productionProcessContext, MesExtEnumUtil.EQUIP_VARIABLE_TYPE.PRODUCTION.getValue(), categoryLevelTwoList); + + //配置错误 抛出异常 + if (!productionProcessContextStepService.checkIsEmptyEquipmentVariableList(productionProcessContext, + cellEquipContext, equipmentVariableList, MesExtEnumUtil.EQUIP_VARIABLE_TYPE.PRODUCTION, categoryLevelTwoList).getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //存储生产过程上下文对象 + productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext); + + //发送数据给设备的数据变量 + return execSendInitializationCmd(reqBean, resultBean, stepParamMap, stepResult, cellEquipContext, + equipmentVariableCfgList, equipmentVariableList, + cellEquipContext.getKepwareFlag(equipmentVariableList.get(0).getChannel())); + + } + + private StepResult execSendInitializationCmd(StationRequestBean reqBean, StationResultBean resultBean, + Optional> stepParamMap, + StepResult stepResult, MesCellEquipContext cellEquipContext, + List equipmentVariableCfgList, + List equipmentVariableList, String kepwareFlag) { + + //最大重试次数[工步参数] + Integer maxRetryTimes = getMaxRetryTimes(stepParamMap); + + MesEquipVariableRwResult equipVariableRwResult = null; + + Map> categoryLevelTwoMap = equipmentVariableCfgList.stream().filter( + Objects::nonNull).collect(Collectors.groupingBy(MesEquipmentVariableCfg::getCategoryLevelTwo)); + + for (int i = 1; i <= maxRetryTimes; i ++) { + + //写值 + for (MesEquipmentVariable equipmentVariable : equipmentVariableList) { + + equipVariableRwResult = equipVariableRwExtService.writeVariable( + categoryLevelTwoMap.get(equipmentVariable.getCategoryLevelTwo()).get(0), equipmentVariable, kepwareFlag); + + if (equipVariableRwResult.getIsSuccessed()) { + this.sendMessage(reqBean, new StationResultBean().writeDbLog().checkRepeat(), + String.format("[%s]%s", cellEquipContext.getEquipmentName(), equipVariableRwResult.getMessage()), + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + } else { + this.sendMessage(reqBean, new StationResultBean().writeDbLog().checkRepeat(), + String.format("设备[%s]:初始化指令发送失败!原因:%s", cellEquipContext.getEquipmentName(), + JSONObject.toJSONString(equipVariableRwResult)), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, + MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); + break; + } + } + + if (!equipVariableRwResult.getIsSuccessed() && equipVariableRwResult.getIsNoCfg()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("设备[%s]:初始化指令发送失败!原因:%s", + cellEquipContext.getEquipmentName(), equipVariableRwResult.getMessage())); + } + + if (equipVariableRwResult.getIsSuccessed()) { + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("设备[%s]:初始化指令发送成功!", cellEquipContext.getEquipmentName())); + } + + stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, String.format("设备[%s]:初始化指令发送失败!累计次数[%s]!原因:%s", cellEquipContext.getEquipmentName(), i, equipVariableRwResult.getMessage())); + + //每失败一次 睡眠 + if (i != maxRetryTimes) { + threadSleep(stepParamMap, MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME); + } + + } + + stepSendTaskCompleteAndThrowEx(reqBean, stepResult, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT); + + return stepResult; + + } + + //最大重试次数[工步参数] + private Integer getMaxRetryTimes(Optional> stepParamMap) { + Integer maxRetryTimes = null; + try { + maxRetryTimes = (null != stepParamMap && stepParamMap.isPresent() && + stepParamMap.get().containsKey(MesPcnExtConstWords.MAX_RETRY_TIMES)) ? + Integer.valueOf(stepParamMap.get().get(MesPcnExtConstWords.MAX_RETRY_TIMES).getParamValue()) : null; + } catch (NumberFormatException e) { + } + return !StringUtils.isEmpty(maxRetryTimes) ? maxRetryTimes : MesPcnExtConstWords.MAX_RETRY_TIMES_DEFAULT; + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java new file mode 100644 index 0000000..7799a77 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java @@ -0,0 +1,89 @@ +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.IMesProductionProcessContextStepService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService; +import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.IStepService; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.model.StationKvBean; +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.repository.seres.shipping.MesCimSeresLastOrderShippingCodeRepository; +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.StringUtils; + +import java.util.List; + +/** + * @Description : 校验当前扫描的发运单是否为“末单” + * @Reference : + * @Author : logic + * @CreateDate : 2025/6/9 16:38 + * @Modify: + **/ +@Slf4j +@Service("mesShippingCheckCimSeresLastOrderShippingCodeStepService") +public class MesShippingCheckCimSeresLastOrderShippingCodeStepService extends BaseStepService { + + @Autowired + private IMesProductionProcessContextStepService productionProcessContextStepService; + + @Autowired + private IMesProductionCustomContextStepService productionCustomContextStepService; + + @Autowired + private MesCimSeresLastOrderShippingCodeRepository mesCimSeresLastOrderShippingCodeRepository; + + @Override + public StepResult execute(StationRequestBean reqBean) { + StationResultBean resultBean = new StationResultBean(); + + //获取上下文信息 + MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean); + + //配置错误 抛出异常 + if (!productionProcessContext.getSuccess()) { + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); + } + + //存储生产过程上下文对象 + productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext); + + //扫描信息置空 + String scanInfo = reqBean.resetScanInfo(reqBean.getScanInfo()); + + //验证发运组信息是否有效 + List resultList = null; + + if (StringUtils.isEmpty(scanInfo)) { + stepSendGuideAndThrowEx(reqBean, + resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), + "[人工模式]请扫描发运单号!"); + } + + //发送工步内容 + productionCustomContextStepService.sendStepContextMessage(reqBean, scanInfo, MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN); + + //判断当前扫描的发运单号是否是“末单” + DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode()); + DdlPreparedPack.getStringEqualPack(scanInfo, "shippingCode", ddlPackBean); + boolean exitByHql = mesCimSeresLastOrderShippingCodeRepository.isExitByHql(ddlPackBean); + if (exitByHql) { + //当前发运单号为“末单”,则调用“向PLC点位发送自定义指令”工步向PLC点位发送用户自定义指令 + return ((IStepService) SpringContextsUtil.getBean("mesSendUserDefinedCmdStepService")).executeInState(reqBean); + }else { + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), null, + String.format("当前扫描信息发运单号[%s]无须发送末单指令!", scanInfo)); + } + + } + +} 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 29aeea5..50695b6 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 @@ -943,4 +943,7 @@ public class MesPcnExtConstWords { public static final String VOLVO_SEQUENCENUMBER = "sequenceNumber"; public static final String VOLVO_RACKID = "rackId"; public static final String VOLVO_POSITION = "position"; + + //向PLC点位发送用户自定义指令的变量类别 + public static final String USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY = "USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY"; } From a57f3e7cb5c8890313f3f3a508c79f5f60a93aec Mon Sep 17 00:00:00 2001 From: "logic.fang" Date: Thu, 26 Jun 2025 10:37:23 +0800 Subject: [PATCH 04/12] =?UTF-8?q?47191=20DM202504290012=20=E9=BE=99?= =?UTF-8?q?=E5=85=B4=E5=B7=A5=E5=8E=82CKPT=E7=BA=BF=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=8B=86=E5=8D=95=E9=9C=80=E6=B1=82-EDI?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BF=AE=E6=94=B9=EF=BC=88=E6=89=AB=E6=8F=8F?= =?UTF-8?q?=E5=8F=91=E8=BF=90=E6=96=B0=E5=A2=9E=E2=80=9C=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=9C=AB=E5=8D=95=E2=80=9D=E3=80=81=E2=80=9C?= =?UTF-8?q?=E5=8F=91=E9=80=81=E7=94=A8=E6=88=B7=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E8=87=B3PLC=E7=82=B9=E4=BD=8D=E2=80=9D-?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../serviceimpl/step/MesSendUserDefinedCmdStepService.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java index b9e2b97..60c3734 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java @@ -67,15 +67,21 @@ public class MesSendUserDefinedCmdStepService extends BaseStepService { List equipmentVariableCfgList = productionProcessContext.getEquipVariableCfgListByVct(); //根据变量类别[用户自定义指令]搜集设备数据变量接口逻辑信息 + String userDefinedEquipVariableCfgCategory = ( + null != stepParamMap && + stepParamMap.isPresent() && + stepParamMap.get().containsKey(MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY)) ? + stepParamMap.get().get(MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY).getParamValue() : + null; equipmentVariableCfgList = productionProcessContextStepService.collectEquipmentVariableCfgList( - equipmentVariableCfgList, MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY); + equipmentVariableCfgList, userDefinedEquipVariableCfgCategory); //当前工位使用的设备 MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip(); //配置错误 抛出异常 if (!productionProcessContextStepService.checkNecessaryEquipmentVariableCfgAndValue(productionProcessContext, - cellEquipContext, equipmentVariableCfgList, MesPcnExtConstWords.USER_DEFINED_EQUIP_VARIABLE_CFG_CATEGORY).getSuccess()) { + cellEquipContext, equipmentVariableCfgList, userDefinedEquipVariableCfgCategory).getSuccess()) { stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); } From afe4a0e2c110624062a624a3d2ab4f4ccda16dd8 Mon Sep 17 00:00:00 2001 From: puxiao Date: Tue, 1 Jul 2025 15:00:06 +0800 Subject: [PATCH 05/12] =?UTF-8?q?Finish=20Task#6617=20=E6=99=BA=E6=85=A7?= =?UTF-8?q?=E5=86=85=E9=A5=B0&=E5=87=BA=E9=A3=8E=E5=8F=A3=E6=9D=A1?= =?UTF-8?q?=E7=A0=81=E8=A7=84=E5=88=99=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AirOutletCustSnNumberRuleStrategyService.java | 180 +++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java new file mode 100644 index 0000000..106e503 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java @@ -0,0 +1,180 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.numberrule; + +import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException; +import cn.estsh.i3plus.mes.pcn.api.iservice.busi.INumberRulePackAttributeStrategyService; +import cn.estsh.i3plus.platform.common.tool.TimeTool; +import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel; +import org.springframework.stereotype.Component; + +import java.text.DecimalFormat; +import java.util.*; + +/** + * @Description : 出风口条码 + * @Reference : + * @Author : puxiao + * @CreateDate : 2025/6/30 18:57 + * @Modify: + **/ +@Component +public class AirOutletCustSnNumberRuleStrategyService implements INumberRulePackAttributeStrategyService { + + + @Override + public GenSerialNoModel execute(GenSerialNoModel genSerialNoModel) { + if (null == genSerialNoModel) { + MesPcnException.throwBusiException("入参缺少[GenSerialNoModel]!"); + } + Date date = new Date(); + genSerialNoModel.setYear(getYearShort(date)); + genSerialNoModel.setMonth(getMonthShort(date)); + genSerialNoModel.setDay(getDayShort(date)); + genSerialNoModel.setVersionNo(getDayOfYear(date)); + return genSerialNoModel; + } + + + private String getYearShort(Date date) { + String yearShort = ""; + int year = Integer.parseInt(TimeTool.getYear(date)); + switch (year){ + case 2010: + yearShort = "A"; + break; + case 2011: + yearShort = "B"; + break; + case 2012: + yearShort = "C"; + break; + case 2013: + yearShort = "D"; + break; + case 2014: + yearShort = "E"; + break; + case 2015: + yearShort = "F"; + break; + case 2016: + yearShort = "G"; + break; + case 2017: + yearShort = "H"; + break; + case 2018: + yearShort = "J"; + break; + case 2019: + yearShort = "K"; + break; + case 2020: + yearShort = "L"; + break; + case 2021: + yearShort = "M"; + break; + case 2022: + yearShort = "N"; + break; + case 2023: + yearShort = "P"; + break; + case 2024: + yearShort = "R"; + break; + case 2025: + yearShort = "S"; + break; + case 2026: + yearShort = "T"; + break; + case 2027: + yearShort = "V"; + break; + case 2028: + yearShort = "W"; + break; + case 2029: + yearShort = "X"; + break; + case 2030: + yearShort = "Y"; + break; + case 2031: + yearShort = "1"; + break; + case 2032: + yearShort = "2"; + break; + case 2033: + yearShort = "3"; + break; + case 2034: + yearShort = "4"; + break; + case 2035: + yearShort = "5"; + break; + case 2036: + yearShort = "6"; + break; + case 2037: + yearShort = "7"; + break; + case 2038: + yearShort = "8"; + break; + case 2039: + yearShort = "9"; + break; + case 2040: + yearShort = "A"; + break; + default: + } + return yearShort; + } + + private String getMonthShort(Date date) { + String monthShort = ""; + int monthValue = Integer.parseInt(TimeTool.getMonth(date)); + switch (monthValue){ + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + monthShort = String.valueOf(monthValue); + break; + case 10: + monthShort = "0"; + break; + case 11: + monthShort = "A"; + break; + case 12: + monthShort = "B"; + break; + default: + } + return monthShort; + } + + private String getDayShort(Date date) { + return TimeTool.pareDateToString("dd",date); + } + + + private String getDayOfYear(Date date) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); + DecimalFormat df = new DecimalFormat("000"); + return df.format(dayOfYear); + } +} \ No newline at end of file From e9a6bcbc25dac2860c17e1440881a5f77728abcd Mon Sep 17 00:00:00 2001 From: puxiao Date: Tue, 1 Jul 2025 15:28:14 +0800 Subject: [PATCH 06/12] =?UTF-8?q?Revert=20"Finish=20Task#6617=20=E6=99=BA?= =?UTF-8?q?=E6=85=A7=E5=86=85=E9=A5=B0&=E5=87=BA=E9=A3=8E=E5=8F=A3?= =?UTF-8?q?=E6=9D=A1=E7=A0=81=E8=A7=84=E5=88=99=E9=9C=80=E6=B1=82"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit afe4a0e2 --- .../AirOutletCustSnNumberRuleStrategyService.java | 180 --------------------- 1 file changed, 180 deletions(-) delete mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java deleted file mode 100644 index 106e503..0000000 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/numberrule/AirOutletCustSnNumberRuleStrategyService.java +++ /dev/null @@ -1,180 +0,0 @@ -package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.numberrule; - -import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException; -import cn.estsh.i3plus.mes.pcn.api.iservice.busi.INumberRulePackAttributeStrategyService; -import cn.estsh.i3plus.platform.common.tool.TimeTool; -import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel; -import org.springframework.stereotype.Component; - -import java.text.DecimalFormat; -import java.util.*; - -/** - * @Description : 出风口条码 - * @Reference : - * @Author : puxiao - * @CreateDate : 2025/6/30 18:57 - * @Modify: - **/ -@Component -public class AirOutletCustSnNumberRuleStrategyService implements INumberRulePackAttributeStrategyService { - - - @Override - public GenSerialNoModel execute(GenSerialNoModel genSerialNoModel) { - if (null == genSerialNoModel) { - MesPcnException.throwBusiException("入参缺少[GenSerialNoModel]!"); - } - Date date = new Date(); - genSerialNoModel.setYear(getYearShort(date)); - genSerialNoModel.setMonth(getMonthShort(date)); - genSerialNoModel.setDay(getDayShort(date)); - genSerialNoModel.setVersionNo(getDayOfYear(date)); - return genSerialNoModel; - } - - - private String getYearShort(Date date) { - String yearShort = ""; - int year = Integer.parseInt(TimeTool.getYear(date)); - switch (year){ - case 2010: - yearShort = "A"; - break; - case 2011: - yearShort = "B"; - break; - case 2012: - yearShort = "C"; - break; - case 2013: - yearShort = "D"; - break; - case 2014: - yearShort = "E"; - break; - case 2015: - yearShort = "F"; - break; - case 2016: - yearShort = "G"; - break; - case 2017: - yearShort = "H"; - break; - case 2018: - yearShort = "J"; - break; - case 2019: - yearShort = "K"; - break; - case 2020: - yearShort = "L"; - break; - case 2021: - yearShort = "M"; - break; - case 2022: - yearShort = "N"; - break; - case 2023: - yearShort = "P"; - break; - case 2024: - yearShort = "R"; - break; - case 2025: - yearShort = "S"; - break; - case 2026: - yearShort = "T"; - break; - case 2027: - yearShort = "V"; - break; - case 2028: - yearShort = "W"; - break; - case 2029: - yearShort = "X"; - break; - case 2030: - yearShort = "Y"; - break; - case 2031: - yearShort = "1"; - break; - case 2032: - yearShort = "2"; - break; - case 2033: - yearShort = "3"; - break; - case 2034: - yearShort = "4"; - break; - case 2035: - yearShort = "5"; - break; - case 2036: - yearShort = "6"; - break; - case 2037: - yearShort = "7"; - break; - case 2038: - yearShort = "8"; - break; - case 2039: - yearShort = "9"; - break; - case 2040: - yearShort = "A"; - break; - default: - } - return yearShort; - } - - private String getMonthShort(Date date) { - String monthShort = ""; - int monthValue = Integer.parseInt(TimeTool.getMonth(date)); - switch (monthValue){ - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - monthShort = String.valueOf(monthValue); - break; - case 10: - monthShort = "0"; - break; - case 11: - monthShort = "A"; - break; - case 12: - monthShort = "B"; - break; - default: - } - return monthShort; - } - - private String getDayShort(Date date) { - return TimeTool.pareDateToString("dd",date); - } - - - private String getDayOfYear(Date date) { - Calendar calendar = Calendar.getInstance(); - calendar.setTime(date); - int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); - DecimalFormat df = new DecimalFormat("000"); - return df.format(dayOfYear); - } -} \ No newline at end of file From 1fc4f406c8dc37ad678ebae14c20e18701d949ea Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Wed, 2 Jul 2025 15:15:46 +0800 Subject: [PATCH 07/12] =?UTF-8?q?=E5=90=B8=E5=A1=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IMesProductionProcessContextStepService.java | 3 + .../step/MesStationMatchAssemblyStepService.java | 8 +- .../MesStationMatchProductSnInStepService.java | 89 ++++++++++++++++++++++ .../MesProductionProcessContextStepService.java | 10 ++- 4 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnInStepService.java diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionProcessContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionProcessContextStepService.java index 1a435c8..ea6656a 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionProcessContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionProcessContextStepService.java @@ -185,4 +185,7 @@ public interface IMesProductionProcessContextStepService { @ApiOperation(value = "处理设备站点") List dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode, List stationTypeList); + @ApiOperation(value = "搜集设备站点") + List dispatchEquipmentStationContext(List stationList, List stationTypeList); + } 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 a89a73f..94d604a 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 @@ -180,11 +180,9 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { } if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) { - if (!StringUtils.isEmpty(productionAssemblyContext.getAssemblySn())) { - productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue()); - productionAssemblyContext.setAssemblySn(null); - productionAssemblyContext.setMatchDatetime(null); - } + productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue()); + productionAssemblyContext.setAssemblySn(null); + productionAssemblyContext.setMatchDatetime(null); stepResult.isCompleted(false).msg(String.format("站点匹配装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getAssemblyPartNo())); break; } else { 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 new file mode 100644 index 0000000..7bda682 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesStationMatchProductSnInStepService.java @@ -0,0 +1,89 @@ +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.MesContainerPackageDetailContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext; +import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; +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.platform.common.tool.MathOperation; +import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +import cn.estsh.i3plus.pojo.mes.bean.MesStation; +import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter; +import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; +import cn.estsh.i3plus.pojo.mes.model.StationResultBean; +import cn.estsh.i3plus.pojo.mes.model.StepResult; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.text.SimpleDateFormat; +import java.util.*; +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())); + //搜集设备站点【原料站点&&混料站点】 + List stationList2PsIn = productionProcessContextStepService.dispatchEquipmentStationContext(stationList, + Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_10.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue()).collect(Collectors.toList())); + //搜集设备站点【混料站点&&成品站点&&可疑站点】 + List stationList2PsOut = productionProcessContextStepService.dispatchEquipmentStationContext(stationList, + Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.getValue()).collect(Collectors.toList())); + + if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点匹配装配件时验证设备未关联支持扣减的站点"); + + //保存站点用于缺料时进行上料绑定 + productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList); + + + + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点匹配装配件验证成功!"); + + } + +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java index 5bf6026..bf077e6 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/context/MesProductionProcessContextStepService.java @@ -705,8 +705,14 @@ public class MesProductionProcessContextStepService extends BaseStepService impl @Override public List dispatchEquipmentStationContext(StationRequestBean reqBean, String equipmentCode, List stationTypeList) { List stationList = dispatchEquipmentStationContext(reqBean, equipmentCode); - return CollectionUtils.isEmpty(stationList) ? null : - stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStationType()) && stationTypeList.contains(o.getStationType()))).collect(Collectors.toList()); + return dispatchEquipmentStationContext(stationList, stationTypeList); + } + + //搜集设备站点 + @Override + public List dispatchEquipmentStationContext(List stationList, List stationTypeList) { + if (CollectionUtils.isEmpty(stationList) || CollectionUtils.isEmpty(stationTypeList)) return stationList; + return stationList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getStationType()) && stationTypeList.contains(o.getStationType()))).collect(Collectors.toList()); } } From c180720114a9c0402d51c20bc074660fe15405ff Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Wed, 2 Jul 2025 17:48:53 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E5=90=B8=E5=A1=91=E6=89=A3=E6=96=99?= =?UTF-8?q?=E8=A3=85=E9=85=8D=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MesStationDeductionAssemblyStepService.java | 47 ++++++++++++------ .../step/MesStationMatchAssemblyStepService.java | 58 ++++++++++++++-------- 2 files changed, 68 insertions(+), 37 deletions(-) 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 12fd3b5..83812c4 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 @@ -18,6 +18,7 @@ import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; import cn.estsh.i3plus.pojo.mes.model.StationResultBean; import cn.estsh.i3plus.pojo.mes.model.StepResult; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import cn.estsh.impp.framework.boot.util.SpringContextsUtil; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -29,6 +30,7 @@ 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 : 站点扣减装配件工步 @@ -114,12 +116,18 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { Map remainQtyMap2Cache = new HashMap<>(); //执行容器装配件的缓存扣减 - dispatchStationDeductionAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, remainQtyMap2Cache); - - if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), stepResult.getMsg()); + Boolean isNeedSavePrc = dispatchStationDeductionAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, remainQtyMap2Cache); //保存上下文产品加工规则信息集合 - productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList); + if (isNeedSavePrc) { + productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList); + if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0) + ((MesAssemblyShowNosortStepService) SpringContextsUtil.getBean("mesAssemblyShowNosortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList); + else + ((MesAssemblyShowSortStepService) SpringContextsUtil.getBean("mesAssemblyShowSortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList, true, true); + } + + if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), stepResult.getMsg()); //重置原料条码的缓存库存 productionCustomContextStepService.dispatchContainerPackageDetailContext(reqBean.getOrganizeCode(), remainQtyMap2Cache); @@ -138,21 +146,27 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { } //执行容器装配件的缓存扣减 - private void dispatchStationDeductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, + private Boolean dispatchStationDeductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, List prodRuleContextList, Map remainQtyMap2Cache) { - + Boolean isNeedSavePrc = false; + List needFeedPartNoList = new ArrayList<>(); for (MesProdRuleContext prodRuleContext : prodRuleContextList) { if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getIsMatchContainer())) continue; - List productionAssemblyContextList = dispatchStationDeductionAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, remainQtyMap2Cache); - if (!stepResult.isCompleted()) break; - prodRuleContext.assemblyDataJson(productionAssemblyContextList); + if (dispatchStationDeductionAssembly(reqBean, resultBean, workCenter, prodRuleContext, remainQtyMap2Cache, needFeedPartNoList)) isNeedSavePrc = true; } - + if (!CollectionUtils.isEmpty(needFeedPartNoList)) { + stepResult.isCompleted(false) + .msg(String.format("站点匹配装配件时验证零件号%s当前缺料,请扫描上料条码!", + (needFeedPartNoList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList())).toString())); + } + return isNeedSavePrc; } //执行容器装配件的缓存扣减 - private List dispatchStationDeductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, - MesProdRuleContext prodRuleContext, Map remainQtyMap2Cache) { + private Boolean dispatchStationDeductionAssembly(StationRequestBean reqBean, StationResultBean resultBean, MesWorkCenter workCenter, + MesProdRuleContext prodRuleContext, Map remainQtyMap2Cache, List needFeedPartNoList) { + + Boolean isNeedSavePrc = false; List productionAssemblyContextList = prodRuleContext.getAssemblyDataContext(workCenter); for (MesProductionAssemblyContext productionAssemblyContext : productionAssemblyContextList) { @@ -214,17 +228,20 @@ public class MesStationDeductionAssemblyStepService extends BaseStepService { productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue()); productionAssemblyContext.setAssemblySn(null); productionAssemblyContext.setMatchDatetime(null); + isNeedSavePrc = true; } - stepResult.isCompleted(false).msg(String.format("站点扣减装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getAssemblyPartNo())); - break; + needFeedPartNoList.add(productionAssemblyContext.getPartNo()); } else { productionAssemblyContext.setAssemblySn(barCodeList.get(0)); productionAssemblyContext.setContainerSnData(JSONObject.toJSONString(deductionContextList)); + isNeedSavePrc = true; } } - return productionAssemblyContextList; + if (isNeedSavePrc) prodRuleContext.assemblyDataJson(productionAssemblyContextList); + + return isNeedSavePrc; } 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 94d604a..8f386b8 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 @@ -99,40 +99,49 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { Map stationMap2Lock = new HashMap<>(); //匹配装配件的工序用量 - dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, containerPackageDetailContextList, stationMap2Lock); + Boolean isNeedSavePrc = dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContextList, containerPackageDetailContextList, stationMap2Lock); + + //保存上下文产品加工规则信息集合 + if (isNeedSavePrc) { + productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList); + if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0) + ((MesAssemblyShowNosortStepService) SpringContextsUtil.getBean("mesAssemblyShowNosortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList); + else + ((MesAssemblyShowSortStepService) SpringContextsUtil.getBean("mesAssemblyShowSortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList, true, true); + } if (!stepResult.isCompleted()) return stepNonCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult.nextTriggerEvent(MesPcnExtConstWords.NEXT_TRIGGER_EVENT_FEEDING), stepResult.getMsg()); - //保存上下文产品加工规则信息集合 - productionDispatchContextStepService.dispatchProdRuleDataContext(reqBean, prodRuleContextList); //保存站点用于后面扣料业务中进行LOCK productionDispatchContextStepService.dispatchLockStationContext(reqBean, stationMap2Lock); - if (workCenter.getCenterType().compareTo(MesExtEnumUtil.WORK_CENTER_TYPE.NOSORT.getValue()) == 0) - ((MesAssemblyShowNosortStepService) SpringContextsUtil.getBean("mesAssemblyShowNosortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList); - else - ((MesAssemblyShowSortStepService) SpringContextsUtil.getBean("mesAssemblyShowSortStepService")).showProductionAssembly(reqBean, resultBean, workCenter, prodRuleContextList, true, true); - - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, "站点匹配装配件验证成功!"); } //匹配装配件的工序用量【遍历加工规则】 - private void dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, + private Boolean dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, List prodRuleContextList, List containerPackageDetailContextList, Map stationMap2Lock) { + Boolean isNeedSavePrc = false; + List needFeedPartNoList = new ArrayList<>(); for (MesProdRuleContext prodRuleContext : prodRuleContextList) { if (null == prodRuleContext || StringUtils.isEmpty(prodRuleContext.getIsMatchContainer())) continue; - List productionAssemblyContextList = dispatchStationMatchAssembly(reqBean, resultBean, stepResult, workCenter, prodRuleContext, containerPackageDetailContextList, stationMap2Lock); - if (!stepResult.isCompleted()) break; - prodRuleContext.assemblyDataJson(productionAssemblyContextList); + if (dispatchStationMatchAssembly(reqBean, resultBean, workCenter, prodRuleContext, containerPackageDetailContextList, stationMap2Lock, needFeedPartNoList)) isNeedSavePrc = true; + } + if (!CollectionUtils.isEmpty(needFeedPartNoList)) { + stepResult.isCompleted(false) + .msg(String.format("站点匹配装配件时验证零件号%s当前缺料,请扫描上料条码!", + (needFeedPartNoList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList())).toString())); } + return isNeedSavePrc; } //匹配装配件的工序用量【遍历装配件】 - private List dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, StepResult stepResult, MesWorkCenter workCenter, - MesProdRuleContext prodRuleContext, List containerPackageDetailContextList, - Map stationMap2Lock) { + private Boolean dispatchStationMatchAssembly(StationRequestBean reqBean, StationResultBean resultBean, MesWorkCenter workCenter, + MesProdRuleContext prodRuleContext, List containerPackageDetailContextList, + Map stationMap2Lock, List needFeedPartNoList) { + Boolean isNeedSavePrc = false; + List productionAssemblyContextList = prodRuleContext.getAssemblyDataContext(workCenter); for (MesProductionAssemblyContext productionAssemblyContext : productionAssemblyContextList) { if (null == productionAssemblyContext || productionAssemblyContext.getMatchType().compareTo(MesExtEnumUtil.ASSEMBLY_MATCH_TYPE.MATCH_TYPE_80.getValue()) != 0) continue; @@ -180,21 +189,26 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { } if (MathOperation.compareTo(unMatchQty, new Double(0)) > 0) { - productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue()); - productionAssemblyContext.setAssemblySn(null); - productionAssemblyContext.setMatchDatetime(null); - stepResult.isCompleted(false).msg(String.format("站点匹配装配件时验证零件号[%s]当前缺料,请扫描上料条码!", productionAssemblyContext.getAssemblyPartNo())); - break; + if (!StringUtils.isEmpty(productionAssemblyContext.getAssemblySn())) { + productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_30.getValue()); + productionAssemblyContext.setAssemblySn(null); + productionAssemblyContext.setMatchDatetime(null); + isNeedSavePrc = true; + } + needFeedPartNoList.add(productionAssemblyContext.getPartNo()); } else { productionAssemblyContext.setAssemblyStatus(MesExtEnumUtil.ASSEMBLY_STATUS.ASSEMBLY_STATUS_10.getValue()); productionAssemblyContext.setAssemblySn(barCodeList.get(0)); productionAssemblyContext.setMatchDatetime((new SimpleDateFormat(MesPcnExtConstWords.DATE_FORMAT_SSS)).format(new Date())); productionAssemblyContext.setContainerSnData(JSONObject.toJSONString(containerSnDataList)); + isNeedSavePrc = true; } } - return productionAssemblyContextList; + if (isNeedSavePrc) prodRuleContext.assemblyDataJson(productionAssemblyContextList); + + return isNeedSavePrc; } } From ce75150d145aef5fd5fd73ddc540bfd8bbce4a0d Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Wed, 2 Jul 2025 19:56:12 +0800 Subject: [PATCH 09/12] =?UTF-8?q?=E9=BE=99=E5=85=B475jph=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../step/MesSendUserDefinedCmdStepService.java | 8 ++-- ...ckCimSeresLastOrderShippingCodeStepService.java | 44 +++++++++------------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java index 60c3734..e491ef0 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesSendUserDefinedCmdStepService.java @@ -136,7 +136,7 @@ public class MesSendUserDefinedCmdStepService extends BaseStepService { MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); } else { this.sendMessage(reqBean, new StationResultBean().writeDbLog().checkRepeat(), - String.format("设备[%s]:初始化指令发送失败!原因:%s", cellEquipContext.getEquipmentName(), + String.format("设备[%s]:自定义指令发送失败!原因:%s", cellEquipContext.getEquipmentName(), JSONObject.toJSONString(equipVariableRwResult)), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); break; @@ -144,15 +144,15 @@ public class MesSendUserDefinedCmdStepService extends BaseStepService { } if (!equipVariableRwResult.getIsSuccessed() && equipVariableRwResult.getIsNoCfg()) { - stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("设备[%s]:初始化指令发送失败!原因:%s", + stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), String.format("设备[%s]:自定义指令发送失败!原因:%s", cellEquipContext.getEquipmentName(), equipVariableRwResult.getMessage())); } if (equipVariableRwResult.getIsSuccessed()) { - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("设备[%s]:初始化指令发送成功!", cellEquipContext.getEquipmentName())); + return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("设备[%s]:自定义指令发送成功!", cellEquipContext.getEquipmentName())); } - stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, String.format("设备[%s]:初始化指令发送失败!累计次数[%s]!原因:%s", cellEquipContext.getEquipmentName(), i, equipVariableRwResult.getMessage())); + stepNonCompleteAndSendMsg(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult, String.format("设备[%s]:自定义指令发送失败!累计次数[%s]!原因:%s", cellEquipContext.getEquipmentName(), i, equipVariableRwResult.getMessage())); //每失败一次 睡眠 if (i != maxRetryTimes) { diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java index 7799a77..0512bea 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesShippingCheckCimSeresLastOrderShippingCodeStepService.java @@ -1,27 +1,25 @@ 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.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.mes.pcn.serviceimpl.fsm.IStepService; import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; -import cn.estsh.i3plus.pojo.mes.model.StationKvBean; +import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue; 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.repository.seres.shipping.MesCimSeresLastOrderShippingCodeRepository; -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.StringUtils; -import java.util.List; - /** * @Description : 校验当前扫描的发运单是否为“末单” * @Reference : @@ -37,51 +35,45 @@ public class MesShippingCheckCimSeresLastOrderShippingCodeStepService extends Ba private IMesProductionProcessContextStepService productionProcessContextStepService; @Autowired - private IMesProductionCustomContextStepService productionCustomContextStepService; + private IMesProductionDispatchContextStepService productionDispatchContextStepService; @Autowired private MesCimSeresLastOrderShippingCodeRepository mesCimSeresLastOrderShippingCodeRepository; @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()); - } + if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage()); //存储生产过程上下文对象 productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext); - //扫描信息置空 - String scanInfo = reqBean.resetScanInfo(reqBean.getScanInfo()); - - //验证发运组信息是否有效 - List resultList = null; - - if (StringUtils.isEmpty(scanInfo)) { - stepSendGuideAndThrowEx(reqBean, - resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), - "[人工模式]请扫描发运单号!"); - } - - //发送工步内容 - productionCustomContextStepService.sendStepContextMessage(reqBean, scanInfo, MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN); + //获取上下文发运队列信息 + MesShippingQueue shippingQueue = productionDispatchContextStepService.getShippingQueueContext(reqBean); + if ((null == shippingQueue || StringUtils.isEmpty(shippingQueue.getRfidSn()))) + return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true, + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, "当前未获取到缓存中有效的发运队列,默认跳过发送空托盘!"); //判断当前扫描的发运单号是否是“末单” DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode()); - DdlPreparedPack.getStringEqualPack(scanInfo, "shippingCode", ddlPackBean); + DdlPreparedPack.getStringEqualPack(shippingQueue.getShippingCode(), MesPcnExtConstWords.SHIPPING_CODE, ddlPackBean); boolean exitByHql = mesCimSeresLastOrderShippingCodeRepository.isExitByHql(ddlPackBean); if (exitByHql) { + this.sendMessage(reqBean, resultBean.writeDbLog(), String.format("当前发运单号[%s]为末单,即将执行发送空托盘!", + shippingQueue.getShippingCode()), MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT); //当前发运单号为“末单”,则调用“向PLC点位发送自定义指令”工步向PLC点位发送用户自定义指令 return ((IStepService) SpringContextsUtil.getBean("mesSendUserDefinedCmdStepService")).executeInState(reqBean); }else { - return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), null, - String.format("当前扫描信息发运单号[%s]无须发送末单指令!", scanInfo)); + return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true, + MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, String.format("当前发运单号[%s]非末单,默认跳过发送空托盘!", shippingQueue.getShippingCode())); } } From 88bd632347e2460316dbb18d2d18e0d83ecf39e6 Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Wed, 2 Jul 2025 19:59:35 +0800 Subject: [PATCH 10/12] =?UTF-8?q?=E6=88=90=E9=83=BD=E6=A0=87=E7=AD=BE=20?= =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java index 5b7b2a7..29c3a75 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/print/strategy/ChengDuSplitFixCharPrintStrategy.java @@ -35,7 +35,7 @@ import java.io.IOException; import java.util.*; /** - * @Description : 装配目视单标签打印 + * @Description : 成都data Matrix 标签 * @Reference : * @Author : Castle * @CreateDate : 2024/6/17 16:43 From fbea1bb2f3dfd0ad19d58c7486e8238524aeb02c Mon Sep 17 00:00:00 2001 From: "jhforever.wang@estsh.com" Date: Thu, 3 Jul 2025 23:08:12 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IMesProductionDispatchContextStepService.java | 6 ++ .../step/MesStationMatchAssemblyStepService.java | 2 +- .../MesStationMatchProductSnInStepService.java | 70 ++++++++++++++++------ .../MesProductionDispatchContextStepService.java | 14 +++++ .../ext/mes/pcn/pojo/util/MesPcnExtConstWords.java | 3 + 5 files changed, 76 insertions(+), 19 deletions(-) diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionDispatchContextStepService.java index 5a4ecaa..2433bf5 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 @@ -277,4 +277,10 @@ 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-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 8f386b8..244315b 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 @@ -79,7 +79,7 @@ public class MesStationMatchAssemblyStepService extends BaseStepService { 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(), "站点匹配装配件时验证设备未关联支持扣减的站点"); + if (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点匹配装配件时验证设备未关联支持扣减的站点!"); //保存站点用于缺料时进行上料绑定 productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList); 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 index 7bda682..a8b9935 100644 --- 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 @@ -1,30 +1,26 @@ 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.MesContainerPackageDetailContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProdRuleContext; -import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionAssemblyContext; 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.platform.common.tool.MathOperation; -import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil; +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.bean.MesWorkCenter; import cn.estsh.i3plus.pojo.mes.model.StationRequestBean; import cn.estsh.i3plus.pojo.mes.model.StationResultBean; import cn.estsh.i3plus.pojo.mes.model.StepResult; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; -import cn.estsh.impp.framework.boot.util.SpringContextsUtil; -import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; -import java.text.SimpleDateFormat; -import java.util.*; +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; @@ -68,21 +64,59 @@ public class MesStationMatchProductSnInStepService extends BaseStepService { 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())); - //搜集设备站点【混料站点&&成品站点&&可疑站点】 - List stationList2PsOut = productionProcessContextStepService.dispatchEquipmentStationContext(stationList, - Stream.of(MesExtEnumUtil.STATION_TYPE.STATION_TYPE_40.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_30.getValue(), MesExtEnumUtil.STATION_TYPE.STATION_TYPE_50.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 (CollectionUtils.isEmpty(stationList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "站点匹配装配件时验证设备未关联支持扣减的站点"); + //验证【成品站点】是否存在【未关箱】的容器条码 + 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; - //保存站点用于缺料时进行上料绑定 - productionDispatchContextStepService.dispatchMatchStationContext(reqBean, stationList); + //验证【可疑站点】是否存在【未关箱】的容器条码 + 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, "站点匹配进料验证成功!"); + + } - 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/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 a1e84b6..31e9989 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 @@ -630,4 +630,18 @@ 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-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 040e5f7..c42d810 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 @@ -754,6 +754,9 @@ 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"; 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 12/12] =?UTF-8?q?=E5=8C=B9=E9=85=8D=E5=8E=9F=E6=96=99?= =?UTF-8?q?=E7=AB=99=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";