From a55609fe5bc430f213264487fb0ebcad68a582ac Mon Sep 17 00:00:00 2001 From: fengyuan_yang <1976974459@qq.com> Date: Sun, 20 Sep 2026 15:38:48 +0800 Subject: [PATCH] =?UTF-8?q?2026-09-20=20iqc=E4=BB=BB=E5=8A=A1=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=88=80=E6=A8=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/pms/data/QcFAIRecordData.java | 15 ++ .../heai/modules/pms/data/QcTemplateData.java | 2 +- .../com/heai/modules/pms/mapper/QcMapper.java | 8 +- .../pms/service/Impl/QcServiceImpl.java | 218 +++++++++++------- src/main/resources/mapper/pms/QcMapper.xml | 25 +- 5 files changed, 182 insertions(+), 86 deletions(-) diff --git a/src/main/java/com/heai/modules/pms/data/QcFAIRecordData.java b/src/main/java/com/heai/modules/pms/data/QcFAIRecordData.java index 24620f2..8a0b1b6 100644 --- a/src/main/java/com/heai/modules/pms/data/QcFAIRecordData.java +++ b/src/main/java/com/heai/modules/pms/data/QcFAIRecordData.java @@ -247,6 +247,21 @@ public class QcFAIRecordData extends QueryPage { private String submissionType; + /** + * 审核时是否触发QMS上机检验任务单 + */ + private Boolean triggerMachineInspect; + + /** + * 新生成的检验单号(外观审核生成上机单时使用) + */ + private String newInspectionNo; + + /** + * 来源检验单号(上机单绑定的外观单) + */ + private String sourceInspectionNo; + private String type; private String invdefinetype; diff --git a/src/main/java/com/heai/modules/pms/data/QcTemplateData.java b/src/main/java/com/heai/modules/pms/data/QcTemplateData.java index 339082e..a0e593c 100644 --- a/src/main/java/com/heai/modules/pms/data/QcTemplateData.java +++ b/src/main/java/com/heai/modules/pms/data/QcTemplateData.java @@ -137,7 +137,7 @@ public class QcTemplateData extends QueryPage { */ private String updateByDesc; /** - * IPQC检验方式 + * 检验方式(IPQC / IQC) */ private String ipqcInspectionMethod; diff --git a/src/main/java/com/heai/modules/pms/mapper/QcMapper.java b/src/main/java/com/heai/modules/pms/mapper/QcMapper.java index e9e0651..55a5772 100644 --- a/src/main/java/com/heai/modules/pms/mapper/QcMapper.java +++ b/src/main/java/com/heai/modules/pms/mapper/QcMapper.java @@ -265,7 +265,7 @@ public interface QcMapper { List selectFAIBasicData(); - List selectPartAttributeByPartNo(String site, String buNo, String partNo, String attributeType, String inspectionTypeNo, String supplierNo); + List selectPartAttributeByPartNo(@Param("site") String site, @Param("buNo") String buNo, @Param("partNo") String partNo, @Param("attributeType") String attributeType, @Param("inspectionTypeNo") String inspectionTypeNo, @Param("supplierNo") String supplierNo, @Param("ipqcInspectionMethod") String ipqcInspectionMethod); void saveFAIRecord(QcFAIRecordData data); @@ -287,6 +287,12 @@ public interface QcMapper { void saveIQCRecord(QcFAIRecordData qcFAIRecordData); + /** + * 由外观检验单复制生成上机检验单主表 + * 需先执行:ALTER TABLE qc_iqc_record ADD source_inspection_no VARCHAR(50) NULL; + */ + int copyIQCRecordForMachineInspect(QcFAIRecordData data); + void saveSQCRecord(QcFAIRecordData qcFAIRecordData); IPage qcIPQCInspectionSearch(Page qcFAIRecordDataPage,@Param("query") QcFAIRecordData data); diff --git a/src/main/java/com/heai/modules/pms/service/Impl/QcServiceImpl.java b/src/main/java/com/heai/modules/pms/service/Impl/QcServiceImpl.java index ff2c8ec..b99aac5 100644 --- a/src/main/java/com/heai/modules/pms/service/Impl/QcServiceImpl.java +++ b/src/main/java/com/heai/modules/pms/service/Impl/QcServiceImpl.java @@ -3068,12 +3068,16 @@ public class QcServiceImpl implements QcService { // 明细记录信息赋值 String partNo = recordData.getPartNo(); String attributeType1 = "A"; + String inspectionMethod = resolveIqcInspectionMethod(recordData); // 优先按partNo走模板匹配(与 selectTemplateByPartNo 逻辑保持一致) recordData.setInspectionTypeNo(qcFAIRecordData.getInspectionTypeNo()); - List partAttribute = qcMapper.selectTemplateByPartNoForOverLoad(recordData); - // 兼容老逻辑:未匹配到时回退到属性模板 + List partAttribute = null; + if (StringUtils.isBlank(inspectionMethod)) { + partAttribute = qcMapper.selectTemplateByPartNoForOverLoad(recordData); + } + // 兼容老逻辑:未匹配到时回退到属性模板;有检验方式时直接按检验方式匹配 if (partAttribute == null || partAttribute.isEmpty()) { - partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, qcFAIRecordData.getInspectionTypeNo(), supplierNo); + partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, qcFAIRecordData.getInspectionTypeNo(), supplierNo, inspectionMethod); } if (partAttribute != null && !partAttribute.isEmpty()) { // 检验周期 @@ -3127,7 +3131,7 @@ public class QcServiceImpl implements QcService { String familyId = qcMapper.selectFamilyIdByPartNo(partNo,recordData.getSite()); String attributeType2 = "B"; // 获取该类别属性下维护的IQC检验模板 - List familyAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), familyId, attributeType2, qcFAIRecordData.getInspectionTypeNo(), supplierNo); + List familyAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), familyId, attributeType2, qcFAIRecordData.getInspectionTypeNo(), supplierNo, inspectionMethod); if (!familyAttribute.isEmpty()) { // 获取检验周期 if (familyAttribute.get(0).getInspectionCycle() != null) { @@ -3260,7 +3264,7 @@ public class QcServiceImpl implements QcService { List partAttribute = qcMapper.selectTemplateByPartNoForOverLoad(recordData); if (partAttribute == null || partAttribute.isEmpty()) { - partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, masterData.getInspectionTypeNo(), supplierNo); + partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, masterData.getInspectionTypeNo(), supplierNo, null); } if (partAttribute != null && !partAttribute.isEmpty()) { return partAttribute; @@ -3268,7 +3272,7 @@ public class QcServiceImpl implements QcService { String familyId = qcMapper.selectFamilyIdByPartNo(partNo, recordData.getSite()); String attributeType2 = "B"; - List familyAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), familyId, attributeType2, masterData.getInspectionTypeNo(), supplierNo); + List familyAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), familyId, attributeType2, masterData.getInspectionTypeNo(), supplierNo, null); return familyAttribute == null ? new ArrayList<>() : familyAttribute; } @@ -3607,7 +3611,7 @@ public class QcServiceImpl implements QcService { String partNo = recordData.getPartNo(); String attributeType1 = "A"; - List partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, qcFAIRecordData.getInspectionTypeNo(), supplierNo); + List partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, qcFAIRecordData.getInspectionTypeNo(), supplierNo, null); if (!partAttribute.isEmpty()) { if (partAttribute.get(0).getInspectionCycle() != null) { qcFAIRecordData.setInspectionCycle(partAttribute.get(0).getInspectionCycle()); @@ -3990,6 +3994,7 @@ public class QcServiceImpl implements QcService { @Transactional public void saveIQCSubmitResult(QcFAIRecordData data) { SysUserEntity currentUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); + boolean triggerMachineInspect = Boolean.TRUE.equals(data.getTriggerMachineInspect()); for (QcFAIRecordData recordData : data.getSubmitList()) { // 修改主记录标识为已提交 qcMapper.updateIQCMasterSubmitFlag(recordData); @@ -3998,86 +4003,133 @@ public class QcServiceImpl implements QcService { // 修改子明细记录标识为已提交 qcMapper.updateIQCSubDetailSubmitFlag(recordData); - // 判断检验结论是否合格 - /*if ("合格".equals(recordData.getInspectionResult()) || "让步接收".equals(recordData.getDisposalMeasures()) || "挑选使用".equals(recordData.getDisposalMeasures())) { - // 根据 site、po_orderNo、po_itemNo 从 view_po_order 中查出数据 - List poOrderData = qcMapper.queryDataFromViewPoOrder(recordData); - if (!poOrderData.isEmpty() && poOrderData.get(0) != null) { - // 修改order_qty为送检数量 - // orderQty取值改为批次合格数 -- 2025-02-10 - poOrderData.get(0).setOrderQty(recordData.getBatchQualifiedQty() == null ? recordData.getRollQty().toString() : recordData.getBatchQualifiedQty().toString()); - poOrderData.get(0).setInspectionNo(recordData.getInspectionNo()); - poOrderData.get(0).setBatchNo(recordData.getBatchNo()); - poOrderData.get(0).setProductionDate(recordData.getProductionDate()); - poOrderData.get(0).setExpirationWarningDate(recordData.getExpirationWarningDate()); - poOrderData.get(0).setExpirationDate(recordData.getExpirationDate()); - // 获取物料的 control_mes - List partInformationList = qcMapper.getPartInformation(recordData); - if (partInformationList.isEmpty()) { - throw new RuntimeException("未查到该物料数据!"); - } - // control_mes 为 Y 的插入task表 - if ("G".equals(partInformationList.get(0).getControlMes())) { - // 获取接口时间 - String interfaceDate = getInterfaceDate(recordData.getSite()); - Date dateByParten = DateUtils.getStringToDate(interfaceDate, "yyyy-MM-dd"); - //获取当前时间 - String stringNow = DateUtils.getStringNow(); - String stringDate = DateUtils.getStringDate(dateByParten); - //获取收发类别 - List rdstyleList = qcMapper.getInterfaceRdStyleData("采购入库"); - if (rdstyleList.isEmpty()) { - throw new RuntimeException("获取收发类别失败!"); - } - String cdepcode = ""; - if ("4".equals(recordData.getSite())){ - cdepcode = "100"; - } - HardtagPurchaseInStorageCountData inStorageCountData = new HardtagPurchaseInStorageCountData(recordData.getSite(), recordData.getInspectionNo(), stringNow, data.getUpdateBy(), "0", toacc, stringDate, - poOrderData.get(0).getOrderNo(), partInformationList.get(0).getDefaultWarehouseId(), rdstyleList.get(0).getCrdcode(), recordData.getInspectionNo(), DateUtils.getStringDate(dateByParten), "1", "", - "1", poOrderData.get(0).getItemNo(), recordData.getPartNo(), recordData.getRollQty().doubleValue(), poOrderData.get(0).getCitemCode(), stringNow, "采购订单"); - inStorageCountData.setTransType("采购材料订单入库"); - inStorageCountData.setCdepcode(cdepcode); - //批量添加汇总数据 - int i = qcMapper.insertHardtagPurchaseInStorageData(inStorageCountData); - - //生成Transheader - HardtagTransHeaderData inData = new HardtagTransHeaderData(recordData.getInspectionNo(),recordData.getSite(),partInformationList.get(0).getDefaultWarehouseId(),dateByParten,"CRT","采购材料订单入库",data.getUpdateBy(), - data.getUpdateBy(),0,0,"*","D","N","N",new Date(), - "N",poOrderData.get(0).getOrderNo(),"Y","已录入",partInformationList.get(0).getDefaultWarehouseId(),"1","","", - "","",""); - inData.setCountId(i); - inData.setRemark("采购订单入库"); - //保存transHeader数据 - qcMapper.batchSaveHrdtagTransHeader(inData); - - HardtagTransDetailData hardtagTransDetailData = new HardtagTransDetailData(recordData.getInspectionNo(), recordData.getSite(), 1, recordData.getPartNo(), "", recordData.getRollQty(), "+", poOrderData.get(0).getOrderNo(), "0", poOrderData.get(0).getCitemCode()); - //保存transDetail数据 - qcMapper.batchSaveHardtagTransDetail(hardtagTransDetailData); - } else { - // 向收货任务表里添加数据 - qcMapper.saveReceivingTask(poOrderData.get(0)); - } - } else { - throw new RuntimeException("未查询到采购订单!"); - } - } - // 发送邮件 - if ("不合格".equals(recordData.getInspectionResult())) { - try { - List list = qcMapper.iqcDetailSearch(recordData); - recordData.setItemList(list); - sendMailIQC(recordData, "IQC"); - } catch (Exception e) { - logger.info(e.getMessage()); - } - }*/ - if (StringUtils.isNotBlank(recordData.getRefInfo1()) && StringUtils.isNotBlank(recordData.getRefInfo2())){ + if (triggerMachineInspect && shouldGenerateMachineInspectTask(recordData)) { + generateIQCMachineInspectTask(recordData); + } else if (StringUtils.isNotBlank(recordData.getRefInfo1()) && StringUtils.isNotBlank(recordData.getRefInfo2())) { inspectService.inspectForQMS(recordData.getSite(), recordData.getRefInfo1(), Integer.parseInt(recordData.getRefInfo2()), "submit", getQmsInspectResult(recordData), recordData.getInspectionRemark(), currentUser.getUsername()); } } } + private boolean shouldGenerateMachineInspectTask(QcFAIRecordData recordData) { + if (recordData == null) { + return false; + } + String type = recordData.getSubmissionType(); + return "合格".equals(recordData.getInspectionResult()) + && ("刀模进货检验-外观".equals(type) || "刀模维修检验-外观".equals(type)); + } + + private String toMachineInspectType(String appearanceType) { + if ("刀模进货检验-外观".equals(appearanceType)) { + return "刀模进货检验-上机"; + } + if ("刀模维修检验-外观".equals(appearanceType)) { + return "刀模维修检验-上机"; + } + return null; + } + + private String resolveIqcInspectionMethod(QcFAIRecordData recordData) { + String type = recordData == null ? null : recordData.getSubmissionType(); + if ("材料进货检验".equals(type) + || "刀模进货检验-外观".equals(type) + || "刀模进货检验-上机".equals(type) + || "刀模维修检验-外观".equals(type) + || "刀模维修检验-上机".equals(type)) { + return type; + } + return null; + } + + /** + * 外观合格审核后生成对应的上机检验任务单 + */ + private void generateIQCMachineInspectTask(QcFAIRecordData appearanceRecord) { + String machineType = toMachineInspectType(appearanceRecord.getSubmissionType()); + if (StringUtils.isBlank(machineType)) { + return; + } + String newInspectionNo = "IQC" + qcMapper.selectIQCInspectionNo(appearanceRecord); + + QcFAIRecordData copyParam = new QcFAIRecordData(); + copyParam.setSite(appearanceRecord.getSite()); + copyParam.setBuNo(appearanceRecord.getBuNo()); + copyParam.setInspectionNo(appearanceRecord.getInspectionNo()); + copyParam.setNewInspectionNo(newInspectionNo); + copyParam.setSubmissionType(machineType); + int copied = qcMapper.copyIQCRecordForMachineInspect(copyParam); + if (copied <= 0) { + throw new RuntimeException("复制外观检验单失败,无法生成上机检验任务单 {" + appearanceRecord.getInspectionNo() + "} !"); + } + + QcFAIRecordData machineRecord = new QcFAIRecordData(); + machineRecord.setSite(appearanceRecord.getSite()); + machineRecord.setBuNo(appearanceRecord.getBuNo()); + machineRecord.setInspectionNo(newInspectionNo); + machineRecord.setInspectionTypeNo(StringUtils.defaultIfBlank(appearanceRecord.getInspectionTypeNo(), "105")); + machineRecord.setPartNo(appearanceRecord.getPartNo()); + machineRecord.setPartDesc(appearanceRecord.getPartDesc()); + machineRecord.setRollQty(appearanceRecord.getRollQty()); + machineRecord.setSupplierNo(StringUtils.defaultString(appearanceRecord.getSupplierNo(), "")); + machineRecord.setActionDate(null); + if (appearanceRecord.getRollCount() == null) { + appearanceRecord.setRollCount(appearanceRecord.getRollQty()); + } + fillIQCDetailsByInspectionMethod(appearanceRecord, machineRecord, machineType); + } + + /** + * 参考 iqcRecordOverLoad 生成明细,并按检验方式匹配属性模板 + */ + private void fillIQCDetailsByInspectionMethod(QcFAIRecordData sourceRecord, QcFAIRecordData machineRecord, String inspectionMethod) { + String supplierNo = StringUtils.defaultString(sourceRecord.getSupplierNo(), ""); + String partNo = sourceRecord.getPartNo(); + String inspectionTypeNo = machineRecord.getInspectionTypeNo(); + + List templates = selectIqcTemplatesForMachineInspect(sourceRecord, partNo, inspectionTypeNo, supplierNo, inspectionMethod); + // 按供应商匹配不到时,去掉供应商条件再查一次(仅审核生成上机单使用) + if ((templates == null || templates.isEmpty()) && StringUtils.isNotBlank(supplierNo)) { + templates = selectIqcTemplatesForMachineInspect(sourceRecord, partNo, inspectionTypeNo, null, inspectionMethod); + } + if (templates == null || templates.isEmpty()) { + throw new RuntimeException("未找到检验方式为【" + inspectionMethod + "】的IQC属性模板,无法生成上机检验任务单 {" + sourceRecord.getInspectionNo() + "} !"); + } + + applySamplingFromTemplate(machineRecord, sourceRecord, templates.get(0)); + for (QcFAIRecordData template : templates) { + QcFAIRecordData detailData = new QcFAIRecordData(); + detailData.setSite(sourceRecord.getSite()); + detailData.setBuNo(sourceRecord.getBuNo()); + detailData.setInspectionNo(machineRecord.getInspectionNo()); + detailData.setTemplateId(template.getTemplateId()); + detailData.setSamplingLevelNo(template.getSamplingLevelNo()); + detailData.setSamplingLevelDesc(template.getSamplingLevelDesc()); + detailData.setSamplingProgrammeNo(template.getSamplingProgrammeNo()); + detailData.setSamplingProgrammeDesc(template.getSamplingProgrammeDesc()); + detailData.setAql(template.getAql()); + detailData.setAc(template.getAc()); + detailData.setRe(template.getRe()); + detailData.setSamplingQty(machineRecord.getSamplingQty()); + detailData.setPartNo(partNo); + qcMapper.saveIQCDetailedRecordByTemplate(detailData); + } + qcMapper.updateIQCRecord(machineRecord); + } + + private List selectIqcTemplatesForMachineInspect(QcFAIRecordData sourceRecord, String partNo, String inspectionTypeNo, String supplierNo, String inspectionMethod) { + List templates = qcMapper.selectPartAttributeByPartNo( + sourceRecord.getSite(), sourceRecord.getBuNo(), partNo, "A", inspectionTypeNo, supplierNo, inspectionMethod); + if (templates == null || templates.isEmpty()) { + String familyId = qcMapper.selectFamilyIdByPartNo(partNo, sourceRecord.getSite()); + if (StringUtils.isNotBlank(familyId)) { + templates = qcMapper.selectPartAttributeByPartNo( + sourceRecord.getSite(), sourceRecord.getBuNo(), familyId, "B", inspectionTypeNo, supplierNo, inspectionMethod); + } + } + return templates; + } + /** * 取消审核 */ @@ -6055,7 +6107,7 @@ public class QcServiceImpl implements QcService { qcFAIRecordData.setRollQty(recordData.getRollQty()); String partNo = recordData.getPartNo(); String attributeType1 = "A"; - List partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, qcFAIRecordData.getInspectionTypeNo(), ""); + List partAttribute = qcMapper.selectPartAttributeByPartNo(recordData.getSite(), recordData.getBuNo(), partNo, attributeType1, qcFAIRecordData.getInspectionTypeNo(), "", null); if (!partAttribute.isEmpty()) { if (partAttribute.get(0).getInspectionCycle() != null) { qcFAIRecordData.setInspectionCycle(partAttribute.get(0).getInspectionCycle()); diff --git a/src/main/resources/mapper/pms/QcMapper.xml b/src/main/resources/mapper/pms/QcMapper.xml index a1b3429..aa6244f 100644 --- a/src/main/resources/mapper/pms/QcMapper.xml +++ b/src/main/resources/mapper/pms/QcMapper.xml @@ -1823,7 +1823,12 @@ AND qat.attribute_no = #{partNo} AND qat.attribute_type = #{attributeType} AND qt.inspection_type_no = #{inspectionTypeNo} - AND qat.manufacturer_id = #{supplierNo} + + AND qat.manufacturer_id = #{supplierNo} + + + AND qat.ipqc_inspection_method = #{ipqcInspectionMethod} + @@ -2574,6 +2579,24 @@ #{partNo}, #{rollQty}, #{samplingQty,jdbcType=DECIMAL}, #{ssrId}, #{seqNo}, #{batchRollNo}, #{specialRequirements}, #{workCenterNo}, #{rollNo}, #{umId},#{refInfo1},#{refInfo2}) + + + INSERT INTO qc_iqc_record + (inspection_no, site, bu_no, state, create_date, inspection_type_no, inspection_cycle, + part_no, part_desc, roll_qty, sampling_qty, roll_no, supplier_no, po_orderNo, po_itemNo, + roll_count, submission_remark, submission_type, batch_no, production_date, expiration_warning_date, + expiration_date, receipt_no, receipt_item_no, ref_info1, ref_info2, ref_info3, ref_info4, ref_info5, + submit_flag, detail_flag, source_inspection_no) + SELECT + #{newInspectionNo}, site, bu_no, '未开始', getDate(), inspection_type_no, inspection_cycle, + part_no, part_desc, roll_qty, sampling_qty, roll_no, supplier_no, po_orderNo, po_itemNo, + roll_count, submission_remark, #{submissionType}, batch_no, production_date, expiration_warning_date, + expiration_date, receipt_no, receipt_item_no, ref_info1, ref_info2, ref_info3, ref_info4, ref_info5, + 'N', 'N', inspection_no + FROM qc_iqc_record + WHERE inspection_no = #{inspectionNo} AND site = #{site} AND bu_no = #{buNo} + + INSERT INTO qc_sqc_record (inspection_no, site, bu_no, state, task_date, inspection_type_no, inspection_cycle, order_no, operation_desc, resource_id,