package com.chinaztt.mes.quality.utils; import cn.hutool.core.util.BooleanUtil; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.chinaztt.mes.quality.dto.ApplyDTO; import com.chinaztt.mes.quality.dto.ApplyPartDTO; import com.chinaztt.mes.quality.dto.MoTestStandardDTO; import com.chinaztt.mes.quality.entity.Apply; import com.chinaztt.mes.quality.entity.QualityTestApplyRule; import com.chinaztt.mes.quality.mapper.ApplyPartMapper; import com.chinaztt.mes.quality.mapper.QualityTestApplyRuleMapper; import com.chinaztt.mes.quality.mapper.TestStandardMapper; import com.chinaztt.mes.quality.state.standard.constant.InspectionTypeStringValues; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; /** * @Description : 检测申请规则工具类 * @ClassName : TestApplyRuleUtils * @Author : sll * @Date: 2022-08-22 15:28 */ @Service @AllArgsConstructor public class TestApplyRuleUtils { private ApplyPartMapper applyPartMapper; private QualityTestApplyRuleMapper qualityTestApplyRuleMapper; private TestStandardMapper testStandardMapper; /** * 根据检测申请规则配置数据自动矫正工作台的自动报检 * * @param applyDTO * @return */ public ApplyDTO adjustApplyDTO(ApplyDTO applyDTO) { if (CollectionUtils.isEmpty(applyDTO.getApplyPartList())) { throw new RuntimeException("申请材料明细为空"); } // 约束报检类型 if (StringUtils.isBlank(applyDTO.getApplyType())) { throw new RuntimeException("检测申请类型为空 -> 系统无法处理"); } else { switch (applyDTO.getApplyType()) { case Apply.FIRST_APPLY: // 首检 break; case Apply.OUTPUT_APPLY: // 尾检 break; case Apply.LOCAL_APPLY: // 库存报检 throw new RuntimeException("【库存报检】-> 系统该业务路径暂时无法处理"); case Apply.ERP_APPLY: // ERP报检 throw new RuntimeException("【ERP报检】 -> 系统该业务路径暂时无法处理"); case Apply.ONSITE_APPLY: // 巡检 throw new RuntimeException("【巡检】 -> 系统该业务路径暂时无法处理"); case Apply.BACK_APPLY: // 退货报检 throw new RuntimeException("【退货报检】 -> 系统该业务路径暂时无法处理"); case Apply.PRODUCT_APPLY: // 成品检 throw new RuntimeException("【成品检】 -> 为系统自动触发 -> 必须经过过程检测方可触发"); case Apply.BATCHFIRST_APPLY: // 批次首检 throw new RuntimeException("【批次首检】 -> 系统该业务已废弃"); case Apply.PROCESS_APPLY: // 工序检 break; default: throw new RuntimeException("检测申请类型 = 【" + applyDTO.getApplyType() + "】非法"); } } HashSet operationNos = new HashSet(); for (ApplyPartDTO applyPartDTO : applyDTO.getApplyPartList()) { if (null == applyPartDTO.getSystemNo() || applyPartDTO.getSystemNo().equals("")) { throw new RuntimeException("产出系统编号 = 【" + applyPartDTO.getSystemNo() + "】异常"); } operationNos.add(applyPartMapper.selectOperationNoBySystemNo(applyPartDTO.getSystemNo()));// 根据产出系统编号获取对应的工序编号 } if (null == operationNos || operationNos.size() == 0) { throw new RuntimeException("数据异常 -> 根据查出系统编号无法获取工序编号"); } if (operationNos.size() != 1) { throw new RuntimeException("系统不支持一个检测申请单据中对应多个不同工序的申请材料"); } // 根据工序编号读检测申请规则配置表(这里的长度必定是1) List qualityTestApplyRuleList = new ArrayList<>(); for (String operationNo : operationNos) { qualityTestApplyRuleList = qualityTestApplyRuleMapper.selectList(Wrappers.lambdaQuery().eq(QualityTestApplyRule::getOperationNo, operationNo)); } if (CollectionUtils.isEmpty(qualityTestApplyRuleList)) { applyDTO.setAutoCreateApplyDoor(true); return applyDTO;// 没有单独配置,则按原路径走 } else { // 存在配置,则需校验检测申请规则配置是否合规 applyRuleCheck(qualityTestApplyRuleList); for (QualityTestApplyRule qualityTestApplyRule : qualityTestApplyRuleList) { if (qualityTestApplyRule.getInspectionType().equals(applyDTO.getApplyType())) { applyDTO.setAutoCreateApplyDoor(true); return applyDTO;// 存在与发起类型相同的检测申请配置,则按原路径走 } } // 如果申请是首检,且不在配置中,则不进行自动矫正(工作台的固定机制是配置自动报检后会自动发送首检和尾检的检测申请) if (applyDTO.getApplyType().equals(Apply.FIRST_APPLY)) { applyDTO.setAutoCreateApplyDoor(false); return applyDTO; } // 存在配置,但是不存在请求的检测申请类型,则进行自动矫正 // 自动矫正的检测申请类型优先级:首检 > 尾检 > 工序检 > 成品检(目前系统只支持这4种检测类型) List rules = qualityTestApplyRuleList.stream().map(o -> o.getInspectionType()).collect(Collectors.toList()); if (rules.containsAll(Collections.singleton(Apply.FIRST_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.FIRST_APPLY); return applyDTO; } else if (rules.containsAll(Collections.singleton(Apply.OUTPUT_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.OUTPUT_APPLY); return applyDTO; } else if (rules.containsAll(Collections.singleton(Apply.PROCESS_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.PROCESS_APPLY); return applyDTO; } else if (rules.containsAll(Collections.singleton(Apply.PRODUCT_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.PRODUCT_APPLY); return applyDTO; } else { applyDTO.setAutoCreateApplyDoor(false); return applyDTO; } } } /** * 根据检测申请规则配置数据自动矫正工作台的自动报检 * * @param applyDTO * @return */ public ApplyDTO adjustApplyDTONew(ApplyDTO applyDTO) { if (CollectionUtils.isEmpty(applyDTO.getApplyPartList())) { throw new RuntimeException("申请材料明细为空"); } // 约束报检类型 if (StringUtils.isBlank(applyDTO.getApplyType())) { throw new RuntimeException("检测申请类型为空 -> 系统无法处理"); } else { switch (applyDTO.getApplyType()) { case Apply.FIRST_APPLY: // 首检 break; case Apply.OUTPUT_APPLY: // 尾检 break; case Apply.LOCAL_APPLY: // 库存报检 throw new RuntimeException("【库存报检】-> 系统该业务路径暂时无法处理"); case Apply.ERP_APPLY: // ERP报检 throw new RuntimeException("【ERP报检】 -> 系统该业务路径暂时无法处理"); case Apply.ONSITE_APPLY: // 巡检 throw new RuntimeException("【巡检】 -> 系统该业务路径暂时无法处理"); case Apply.BACK_APPLY: // 退货报检 throw new RuntimeException("【退货报检】 -> 系统该业务路径暂时无法处理"); case Apply.PRODUCT_APPLY: // 成品检 break; case Apply.BATCHFIRST_APPLY: // 批次首检 throw new RuntimeException("【批次首检】 -> 系统该业务已废弃"); case Apply.PROCESS_APPLY: // 工序检 break; default: throw new RuntimeException("检测申请类型 = 【" + applyDTO.getApplyType() + "】非法"); } } List totalTestStandardList = new ArrayList<>(); for (ApplyPartDTO applyPartDTO : applyDTO.getApplyPartList()) { if (null == applyPartDTO.getSystemNo() || applyPartDTO.getSystemNo().equals("")) { throw new RuntimeException("产出系统编号 = 【" + applyPartDTO.getSystemNo() + "】异常"); } // 找出对应车间订单的检测标准配置 List testStandardList = testStandardMapper.selectMoTestStandardDTOList(applyPartDTO.getSystemNo()); if (CollectionUtils.isEmpty(testStandardList)) { throw new RuntimeException("数据异常 -> 车间订单未绑定检测标准"); } if (!BooleanUtil.isTrue(testStandardList.get(0).getInspection())) { continue; } if (BooleanUtil.isTrue(testStandardList.get(0).getInspection()) && StringUtils.isBlank(testStandardList.get(0).getInspectionType())){ throw new RuntimeException("数据异常 -> 检测标准未配置检测类型"); } totalTestStandardList.addAll(testStandardList); } if (CollectionUtils.isEmpty(totalTestStandardList)) { applyDTO.setAutoCreateApplyDoor(false); return applyDTO; } Long check = totalTestStandardList.stream().map(MoTestStandardDTO::getMoRoutingOperationId).distinct().count(); if (check > 1) { throw new RuntimeException("数据异常 -> 一个检测申请单据中对应多个不同工序的申请材料"); } applyRuleCheckNew(totalTestStandardList); for (MoTestStandardDTO qualityTestApplyRule : totalTestStandardList) { if (qualityTestApplyRule.getInspectionType().equals(applyDTO.getApplyType())) { applyDTO.setAutoCreateApplyDoor(true); return applyDTO;// 存在与发起类型相同的检测申请配置,则按原路径走 } } // 如果申请是首检,且不在配置中,则不进行自动矫正(工作台的固定机制是配置自动报检后会自动发送首检和尾检的检测申请) if (applyDTO.getApplyType().equals(Apply.FIRST_APPLY)) { applyDTO.setAutoCreateApplyDoor(false); return applyDTO; } // 存在配置,但是不存在请求的检测申请类型,则进行自动矫正 // 自动矫正的检测申请类型优先级:首检 > 尾检 > 工序检 > 成品检(目前系统只支持这4种检测类型) List rules = totalTestStandardList.stream().map(o -> o.getInspectionType()).collect(Collectors.toList()); if (rules.containsAll(Collections.singleton(Apply.FIRST_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.FIRST_APPLY); return applyDTO; } else if (rules.containsAll(Collections.singleton(Apply.OUTPUT_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.OUTPUT_APPLY); return applyDTO; } else if (rules.containsAll(Collections.singleton(Apply.PROCESS_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.PROCESS_APPLY); return applyDTO; } else if (rules.containsAll(Collections.singleton(Apply.PRODUCT_APPLY))) { applyDTO.setAutoCreateApplyDoor(true); applyDTO.setApplyType(Apply.PRODUCT_APPLY); return applyDTO; } else { applyDTO.setAutoCreateApplyDoor(false); return applyDTO; } } /** * 判断检测申请规则是否合规 * * @param totalTestStandardList 规则列表 */ private void applyRuleCheckNew(List totalTestStandardList) { /** * 合规配置如下: * 配置1:首检、尾检 * 配置2:首检、尾检、成品检 * 配置3:工序检 * 配置4:工序检、成品检 * 配置5:成品检 */ Set rules = new HashSet<>(); for (MoTestStandardDTO moTestStandardDTO : totalTestStandardList) { rules.add(moTestStandardDTO.getInspectionType()); } Boolean door = true; if (rules.size() == 1) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_03).containsAll(rules)) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_05).containsAll(rules)) { door = false; } } } else if (rules.size() == 3) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_02).containsAll(rules)) { door = false; } } else if (rules.size() == 2) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_01).containsAll(rules)) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_04).containsAll(rules)) { door = false; } } } else { door = false; } if (!door) { throw new RuntimeException("车间订单工序 = 【" + totalTestStandardList.get(0).getOperationName() + "】绑定的检测标准的检测申请规则配置不合规"); } } /** * 判断检测申请规则是否合规 * * @param qualityTestApplyRuleList 规则列表 */ public void applyRuleCheck(List qualityTestApplyRuleList) { /** * 合规配置如下: * 配置1:首检、尾检 * 配置2:首检、尾检、成品检 * 配置3:工序检 * 配置4:工序检、成品检 */ List rules = new ArrayList<>(); for (QualityTestApplyRule qualityTestApplyRule : qualityTestApplyRuleList) { rules.add(qualityTestApplyRule.getInspectionType()); } Boolean door = true; if (qualityTestApplyRuleList.size() == 1) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_03).containsAll(rules)) { door = false; } } else if (qualityTestApplyRuleList.size() == 3) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_02).containsAll(rules)) { door = false; } } else if (qualityTestApplyRuleList.size() == 2) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_01).containsAll(rules)) { if (!Arrays.asList(InspectionTypeStringValues.TEST_RULE_CONFIG_04).containsAll(rules)) { door = false; } } } else { door = false; } if (!door) { throw new RuntimeException("工序编号 = 【" + qualityTestApplyRuleList.get(0).getOperationNo() + "】检测申请规则配置不合规"); } } /** * 根据工序编号校验检测申请配置规则是否合规 * * @param operationNo 工序编号 */ public void applyRulesCheckByOprationNo(String operationNo) { if (StringUtils.isBlank(operationNo)) { throw new RuntimeException("工序编号 = 【" + operationNo + "】异常"); } List qualityTestApplyRuleList = qualityTestApplyRuleMapper.selectList(Wrappers.lambdaQuery().eq(QualityTestApplyRule::getOperationNo, operationNo)); applyRuleCheck(qualityTestApplyRuleList); } /** * 剔除掉相同批次号相同检测类型已存在的申请材料 * * @param applyType * @param applyPartDTOList */ public void removeAlExistObj(String applyType, List applyPartDTOList) { if (CollectionUtils.isNotEmpty(applyPartDTOList)) { Iterator iterator = applyPartDTOList.iterator(); while (iterator.hasNext()) { ApplyPartDTO applyPartDTO = iterator.next(); if (applyPartMapper.isAutoApplyPartExist(applyType, applyPartDTO.getSystemNo()) > 0) { iterator.remove(); } } } /* if (CollectionUtils.isNotEmpty(applyPartDTOList)) { for (int i = applyPartDTOList.size() - 1; i >= 0; i--) { // 工作台那边传过来的申请材料只有system_no if (applyPartMapper.isAutoApplyPartExist(applyType, applyPartDTOList.get(i).getSystemNo()) > 0) { applyPartDTOList.remove(i);// 剔除 } } }*/ } /** * 根据系统编号获取检测申请类型 * 应用场景,矫正工作台进行【尾检】业务操作时的检测申请类型 * * @param systemNo 产出系统编号 * @return 矫正后的检测申请类型 */ public String getApplyTypeBySystemNo(String systemNo) { if (null == systemNo) { throw new RuntimeException("产出系统编号 = 【" + systemNo + "】 --> 传参异常"); } ApplyDTO applyDTO = new ApplyDTO(); List applyPartDTOList = new ArrayList<>(); ApplyPartDTO applyPartDTO = new ApplyPartDTO(); applyPartDTO.setSystemNo(systemNo); applyPartDTOList.add(applyPartDTO); applyDTO.setApplyPartList(applyPartDTOList); applyDTO.setApplyType(Apply.OUTPUT_APPLY);// 设置成尾检,然后对其进行矫正 adjustApplyDTONew(applyDTO); return applyDTO.getApplyType(); } public void applyRulesCheckBySystemNo(String systemNo) { if (StringUtils.isBlank(systemNo)) { throw new RuntimeException("系统编号 = 【" + systemNo + "】异常"); } List testStandardList = testStandardMapper.selectMoTestStandardDTOList(systemNo); applyRuleCheckNew(testStandardList); } }