From f64efdb8a55bd4a7eb604e648ec0e25b4ea788a7 Mon Sep 17 00:00:00 2001 From: administrator Date: Fri, 21 Jun 2024 19:43:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=B6=E6=95=88=E6=80=A7=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pcn/api/busi/IMesProductionRecordService.java | 27 +++ .../busi/MesProductionRecordServiceImpl.java | 190 +++++++++++++++++++++ .../step/MesProductSnPrintStepService.java | 7 + 3 files changed, 224 insertions(+) create mode 100644 modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionRecordService.java create mode 100644 modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesProductionRecordServiceImpl.java diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionRecordService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionRecordService.java new file mode 100644 index 0000000..9c00857 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesProductionRecordService.java @@ -0,0 +1,27 @@ +package cn.estsh.i3plus.ext.mes.pcn.api.busi; + +import java.util.Map; + +/** + * @Description : 生产加工记录接口 + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/20 21:05 + * @Modify: + **/ +public interface IMesProductionRecordService { + + /** + * 校验条码加工记录时效性 + * @param sn 条码 用于查询生产加工记录 + * @param prodRuleNoSortId 用于获取时效性记录 + * @param dataSource 判断是否是装配件校验,如果是装配件校验,不仅需要校验主条码,也需要校验主条码的装配件时效性 + * + * MesExtEnumUtil.TIME_DATA_SOURCE + * DATA_SOURCE10(10, "排序加工规则"), + * DATA_SOURCE20(20, "非排序加工规则"), + * DATA_SOURCE30(30, "非排序装配件"); + * + */ + Map checkSnTimeliness(String sn, Long prodRuleNoSortId , String organizeCode , Integer dataSource ,Boolean isAssembly); +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesProductionRecordServiceImpl.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesProductionRecordServiceImpl.java new file mode 100644 index 0000000..aafd3e7 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesProductionRecordServiceImpl.java @@ -0,0 +1,190 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService; +import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; +import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.bean.MesProductionAssembly; +import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord; +import cn.estsh.i3plus.pojo.mes.bean.MesTimeEfficientCfg; +import cn.estsh.i3plus.pojo.mes.repository.MesProductionAssemblyRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesProductionRecordRepository; +import cn.estsh.i3plus.pojo.mes.repository.MesTimeEfficientCfgRepository; +import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description : + * @Reference : + * @Author : Castle + * @CreateDate : 2024/6/20 21:20 + * @Modify: + **/ +@Service +public class MesProductionRecordServiceImpl implements IMesProductionRecordService { + @Autowired + private MesTimeEfficientCfgRepository mesTimeEfficientCfgRao; + + @Autowired + private MesProductionRecordRepository mesProductionRecordRao; + + @Autowired + private MesProductionAssemblyRepository mesProductionAssemblyRao; + + /** + * 逻辑: + * 0.根据加工规则可以查询 主条码时效性规则 + * 1.校验主条码时效性 + * 1.1 查询条码的所有加工记录,条件 条码相等且工序不相等; 没有不需要校验,直接返回true + * 1.2 如果有前道工序,遍历时效性规则 + * 1.2.1 如果维护了零件号,则需要首先匹配零件号 相等,然后校验时间 和 时效性规则 + * 1.2.2 如果维护了工序,则需要校验生产记录中当前工序的主条码生成时间 与 时效性校验 + * 2.主条码装配件校验 + * 2.1 首先校验主条码规则--同上 + * 2.2 查找主条码的装配件条码(在装配件记录表中) + * 2.3 遍历获取道的装配件条码, 去校验装配件 的时效性,有零件 和 工序 两种情况 + * + * 可以根据如下timeDataSource + sourceId 可以查询 MES_TIME_EFFICIENT_CFG 需要校验的 时效性规则 + * DATA_SOURCE10(10, "排序加工规则"), + * DATA_SOURCE20(20, "非排序加工规则"), + * DATA_SOURCE30(30, "非排序装配件"); + * 排除未知的零件号生产记录 + * @param sn 条码 用于查询生产加工记录 + * @param sourceId 用于获取时效性记录 + * @param organizeCode + * @param isAssembly 如果是装配件需要查询装配记录 + * @return + */ + @Override + public Map checkSnTimeliness(String sn, Long sourceId ,String organizeCode ,Integer timeDataSource , Boolean isAssembly) { + Map resultMap = new HashMap<>(); + //校验成功 + resultMap.put("result", true); + //1.根据prodRuleNoSortId 获取 非排序加工规则的 时效性数据 --- 当前的条码需要完全匹配查询的规则 + DdlPackBean timelinessPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getNumEqualPack(sourceId,"sourceId",timelinessPackBean); + List timelinessList = mesTimeEfficientCfgRao.findByHqlWhere(timelinessPackBean); + + //2.如果timelinessList为空 且 非装配件校验 直接返回true + if (timelinessList.isEmpty() && !isAssembly){ + return resultMap; + } + //查询主条码的逻辑 + if (!isAssembly){ + //3.根据条码获取生产加工记录结果 + DdlPackBean recordPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(sn,"productSn",recordPackBean); + List recordList = mesProductionRecordRao.findByHqlWhere(recordPackBean); + boolean checkedResult = checkProductSn(recordList, timelinessList); + if (!checkedResult){ + resultMap.put("result", false); + return resultMap; + } + } + try { + if (isAssembly){ + Date now = new Date(); + for (MesTimeEfficientCfg timeliness : timelinessList) { + //需要查询装配件记录表 production_assembly mesProductionAssemblyRao + DdlPackBean assemblyPackBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(sn,"assemblySn",assemblyPackBean); + DdlPreparedPack.getStringEqualPack(timeliness.getCraftCode(),"craftCode",assemblyPackBean); + List productionAssemblyList = mesProductionAssemblyRao.findByHqlWhere(assemblyPackBean); + + MesProductionAssembly mesProductionAssembly = productionAssemblyList.get(0); + String productDateTimeStr = mesProductionAssembly.getCreateDatetime(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date productDateTime = sdf.parse(productDateTimeStr); + //时差 + int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000)); + } + } + } catch (ParseException e) { + throw new RuntimeException(e); + } + return resultMap; + } + + /** + * MATCH_RULE_10("10", "生产时间小于装配件有效期"), + * MATCH_RULE_20("20", "小于最小时差有效"), + * MATCH_RULE_30("30", "大于最小时差有效"), + * MATCH_RULE_40("40", "最大最小时差有效"), + * MATCH_RULE_50("50", "最大外或最小内有效"); + * 用于校验主条码时效性 + * 加工记录 和 时效性校验 + * + * 时效性规则 零件号可以为空 、工艺一定不为空 + * @param + * @return + */ + private boolean checkProductSn(List recordList,List timelinessList) { + try { + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + for (MesTimeEfficientCfg timeliness : timelinessList) { + List records = new ArrayList<>(); + //时效性规则 零件号不为空 + if (StringUtils.isNoneBlank(timeliness.getPartNo())){ + records = recordList.stream().filter(item -> item.getPartNo().equals(timeliness.getPartNo())).sorted(Comparator.comparing(MesProductionRecord::getCompleteDateTime)).collect(Collectors.toList()); + } + //时效性规则 工艺不为空时 + if (StringUtils.isNoneBlank(timeliness.getCraftCode())){ + records = recordList.stream().filter(item -> item.getCraftCode().equals(timeliness.getCraftCode())).sorted(Comparator.comparing(MesProductionRecord::getCompleteDateTime)).collect(Collectors.toList()); + } + + if (records.isEmpty()){ + return false; + } + //不为空 则 需要校验时效性 + MesProductionRecord record = records.get(0); + String completeDateTime = record.getCompleteDateTime(); + Date productDateTime = sdf.parse(completeDateTime); + //时差 + int minDiff = (int) ((now.getTime() - productDateTime.getTime())/(60 * 1000)); + if (!checkTimeliness(timeliness, minDiff)){ + return false; + } + } + + } catch (ParseException e) { + throw new RuntimeException(e); + } + return false; + } + + private boolean checkTimeliness(MesTimeEfficientCfg timeliness, int minDiff) { + String matchRule = timeliness.getMatchRule(); + Double minValue = timeliness.getMinValue(); + Double maxValue = timeliness.getMaxValue(); + if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_20.getValue().equals(matchRule)) { + //差值 大于等于最小值 + if (minDiff >= minValue){ + return false; + } + } else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_30.getValue().equals(matchRule)) { + // 差值 小于等于最大值 + if (minDiff <= minValue){ + return false; + } + } else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_40.getValue().equals(matchRule)) { + // 差值 在 最大值 最小值之间 + if (minDiff <= minValue || minDiff >= maxValue){ + return false; + } + } else if (MesExtEnumUtil.MATCH_RULE.MATCH_RULE_50.getValue().equals(matchRule)) { + // 差值 在 最小值之间 + if (minDiff >= minValue && maxValue <= minDiff){ + return false; + } + } + + return true; + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java index b4300a6..bcb583c 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/step/MesProductSnPrintStepService.java @@ -53,6 +53,8 @@ public class MesProductSnPrintStepService extends BaseStepService { * labelTemplateParamList: List> * } * + * 根据foreign找出加工规则对应的上下文,判断是否需要打印 + * */ String organizeCode = reqBean.getOrganizeCode(); StationResultBean resultBean = new StationResultBean(); @@ -67,6 +69,9 @@ public class MesProductSnPrintStepService extends BaseStepService { //2. 获取条码需要模板、模板代码、打印机 --- 循环遍历条码 封装数据 for (MesProductionPsOutContext sn : productionPsOutContextList) { String prodLabelTemplate = sn.getProdLabelTemplate(); + if (prodLabelTemplate == null) { + execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("零件号[%s]的模板代码[%s]的模板信息丢失,请配置!", sn.getPartNo(), prodLabelTemplate)); + } MesLabelTemplate labelTemplate; // 查模板代码 if (!labelTemplateMap.containsKey(prodLabelTemplate)) { @@ -120,6 +125,7 @@ public class MesProductSnPrintStepService extends BaseStepService { data.put("valueList", dataMaps); printData.add(data); } + //前端接收到busiTyep是customComponent,并且 dataType是file类型的消息,就需要打印后续消息里的数据,一个模板对应多个打印数据 resultBean.setBusiType(MesPcnEnumUtil.STATION_BUSI_TYPE.CUSTOM_COMPONENT.getValue()); resultBean.setDataType(MesPcnEnumUtil.STATION_DATA_TYPE.FILE.getValue()); @@ -127,6 +133,7 @@ public class MesProductSnPrintStepService extends BaseStepService { //3. 发送数据给到前端 this.sendMessage(reqBean, resultBean); + //todo 更新打印状态 return stepResult; }