From 7a681887e5a8e1aab49acc886974d354c69a280e Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 17 九月 2026 13:10:38 +0800
Subject: [PATCH] feat(mes): 新增质检指标分组树和平行测量功能

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicator/MesQcIndicatorServiceImpl.java |   78 +++++++++++++++++++++++++++++++++------
 1 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicator/MesQcIndicatorServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicator/MesQcIndicatorServiceImpl.java
index c3c6819..0e306f5 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicator/MesQcIndicatorServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicator/MesQcIndicatorServiceImpl.java
@@ -6,10 +6,12 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.indicator.vo.MesQcIndicatorPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.indicator.vo.MesQcIndicatorSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.indicator.MesQcIndicatorMapper;
+import cn.iocoder.yudao.module.mes.enums.qc.MesQcIndicatorItemTypeEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcResultValueTypeEnum;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
@@ -27,7 +29,7 @@
 /**
  * MES 璐ㄦ鎸囨爣 Service 瀹炵幇绫�
  *
- * @author 鑺嬮亾婧愮爜
+ * @author 瓒呯骇绠$悊鍛�
  */
 @Service
 @Validated
@@ -38,6 +40,8 @@
 
     @Override
     public Long createIndicator(MesQcIndicatorSaveReqVO createReqVO) {
+        // 瑙勮寖鍖栧眰绾у瓧娈�
+        normalizeHierarchyFields(createReqVO);
         // 鏍¢獙鐩稿叧鍙傛暟
         validateIndicatorSaveData(null, createReqVO);
 
@@ -51,6 +55,8 @@
     public void updateIndicator(MesQcIndicatorSaveReqVO updateReqVO) {
         // 鏍¢獙瀛樺湪
         validateIndicatorExists(updateReqVO.getId());
+        // 瑙勮寖鍖栧眰绾у瓧娈�
+        normalizeHierarchyFields(updateReqVO);
         // 鏍¢獙鐩稿叧鍙傛暟
         validateIndicatorSaveData(updateReqVO.getId(), updateReqVO);
 
@@ -62,24 +68,72 @@
     @Override
     public void deleteIndicator(Long id) {
         // 鏍¢獙瀛樺湪
-        validateIndicatorExists(id);
+        MesQcIndicatorDO indicator = validateIndicatorExists(id);
+        // 鏍¢獙鏃犲瓙椤�
+        Long childCount = indicatorMapper.selectCount(new LambdaQueryWrapperX<MesQcIndicatorDO>()
+                .eq(MesQcIndicatorDO::getParentId, id));
+        if (childCount != null && childCount > 0) {
+            throw exception(QC_INDICATOR_EXISTS_CHILDREN, indicator.getName());
+        }
         // 鍒犻櫎
         indicatorMapper.deleteById(id);
+    }
+
+    private void normalizeHierarchyFields(MesQcIndicatorSaveReqVO saveReqVO) {
+        if (saveReqVO.getParentId() == null) {
+            saveReqVO.setParentId(0L);
+        }
+        if (saveReqVO.getItemType() == null) {
+            saveReqVO.setItemType(MesQcIndicatorItemTypeEnum.RECORD.getType());
+        }
+        if (saveReqVO.getSortOrder() == null) {
+            saveReqVO.setSortOrder(0);
+        }
     }
 
     private void validateIndicatorSaveData(Long id, MesQcIndicatorSaveReqVO saveReqVO) {
         // 鏍¢獙缂栫爜鍞竴
         validateIndicatorCodeUnique(id, saveReqVO.getCode());
-        // 鏍¢獙鍚嶇О鍞竴
-        validateIndicatorNameUnique(id, saveReqVO.getName());
+        // 鏍¢獙鍚屽眰绾у悕绉板敮涓�锛堜笉鍚屽垎缁勪笅鍏佽鍚屽悕鍙傛暟琛岋紝濡�"璇曟牱浣撶НV/mL"锛�
+        validateIndicatorNameUnique(id, saveReqVO.getName(), saveReqVO.getParentId());
+        // 鏍¢獙灞傜骇鍚堟硶鎬э紙鐖堕」瀛樺湪銆佺埗椤逛负鍒嗙粍椤广�佹渶澶氫袱绾э級
+        validateIndicatorHierarchy(id, saveReqVO);
+        // 褰曞叆椤瑰繀椤绘寚瀹氱粨鏋滃�肩被鍨�
+        if (ObjUtil.notEqual(MesQcIndicatorItemTypeEnum.GROUP.getType(), saveReqVO.getItemType())
+                && saveReqVO.getResultType() == null) {
+            throw exception(QC_INDICATOR_RESULT_TYPE_REQUIRED);
+        }
         // 鏍¢獙缁撴灉鍊煎睘鎬�
         validateResultSpecification(saveReqVO.getResultType(), saveReqVO.getResultSpecification());
     }
 
-    private void validateIndicatorExists(Long id) {
-        if (indicatorMapper.selectById(id) == null) {
+    private void validateIndicatorHierarchy(Long id, MesQcIndicatorSaveReqVO saveReqVO) {
+        Long parentId = saveReqVO.getParentId();
+        if (parentId == null || parentId == 0L) {
+            return;
+        }
+        if (ObjUtil.equal(parentId, id)) {
+            throw exception(QC_INDICATOR_PARENT_NOT_GROUP, saveReqVO.getName());
+        }
+        MesQcIndicatorDO parent = indicatorMapper.selectById(parentId);
+        if (parent == null) {
             throw exception(QC_INDICATOR_NOT_EXISTS);
         }
+        if (ObjUtil.notEqual(MesQcIndicatorItemTypeEnum.GROUP.getType(), parent.getItemType())) {
+            throw exception(QC_INDICATOR_PARENT_NOT_GROUP, parent.getName());
+        }
+        // 浠呭厑璁镐袱绾э細鐖跺垎缁勬湰韬繀椤绘槸椤剁骇
+        if (ObjUtil.defaultIfNull(parent.getParentId(), 0L) != 0L) {
+            throw exception(QC_INDICATOR_PARENT_LEVEL_EXCEEDED, parent.getName());
+        }
+    }
+
+    private MesQcIndicatorDO validateIndicatorExists(Long id) {
+        MesQcIndicatorDO indicator = indicatorMapper.selectById(id);
+        if (indicator == null) {
+            throw exception(QC_INDICATOR_NOT_EXISTS);
+        }
+        return indicator;
     }
 
     private void validateIndicatorCodeUnique(Long id, String code) {
@@ -92,12 +146,12 @@
         }
     }
 
-    private void validateIndicatorNameUnique(Long id, String name) {
-        MesQcIndicatorDO indicator = indicatorMapper.selectByName(name);
-        if (indicator == null) {
-            return;
-        }
-        if (ObjUtil.notEqual(indicator.getId(), id)) {
+    private void validateIndicatorNameUnique(Long id, String name, Long parentId) {
+        Long count = indicatorMapper.selectCount(new LambdaQueryWrapperX<MesQcIndicatorDO>()
+                .eq(MesQcIndicatorDO::getName, name)
+                .eq(MesQcIndicatorDO::getParentId, ObjUtil.defaultIfNull(parentId, 0L))
+                .ne(id != null, MesQcIndicatorDO::getId, id));
+        if (count != null && count > 0) {
             throw exception(QC_INDICATOR_NAME_DUPLICATE);
         }
     }

--
Gitblit v1.9.3