From 9bad721754fe8bbe2e5f459d0706e0fefac569f3 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期日, 20 九月 2026 09:05:41 +0800
Subject: [PATCH] feat(mes): 添加智能质检报告功能与AI导入能力
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicator/MesQcIndicatorServiceImpl.java | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 114 insertions(+), 2 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 10fa498..562b5bf 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
@@ -3,6 +3,7 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
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;
@@ -10,6 +11,7 @@
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;
@@ -19,8 +21,10 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@@ -43,6 +47,7 @@
// 鎻掑叆
MesQcIndicatorDO indicator = BeanUtils.toBean(createReqVO, MesQcIndicatorDO.class);
+ normalizeHierarchy(indicator);
indicatorMapper.insert(indicator);
return indicator.getId();
}
@@ -56,6 +61,7 @@
// 鏇存柊
MesQcIndicatorDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIndicatorDO.class);
+ normalizeHierarchy(updateObj);
indicatorMapper.updateById(updateObj);
}
@@ -63,6 +69,11 @@
public void deleteIndicator(Long id) {
// 鏍¢獙瀛樺湪
validateIndicatorExists(id);
+ // 绾ц仈鍒犻櫎瀛愰」锛氭寚鏍囧彧鏀寔涓ゅ眰锛屾寕鍦ㄥ畠涓嬮潰鐨勯兘鏄畠鐨勬槑缁嗛」锛岀埗鍒犱簡瀛愭棤澶勫彲鎸�
+ List<MesQcIndicatorDO> children = indicatorMapper.selectListByParentId(id);
+ if (CollUtil.isNotEmpty(children)) {
+ indicatorMapper.deleteByIds(convertList(children, MesQcIndicatorDO::getId));
+ }
// 鍒犻櫎
indicatorMapper.deleteById(id);
}
@@ -72,8 +83,100 @@
validateIndicatorCodeUnique(id, saveReqVO.getCode());
// 鏍¢獙鍚嶇О鍞竴
validateIndicatorNameUnique(id, saveReqVO.getName());
+ // 鏍¢獙灞傜骇褰掑睘锛堝彧鍏佽涓ゅ眰锛�
+ validateHierarchy(id, saveReqVO);
// 鏍¢獙缁撴灉鍊煎睘鎬�
- validateResultSpecification(saveReqVO.getResultType(), saveReqVO.getResultSpecification());
+ validateResultSpecification(saveReqVO.getItemType(), saveReqVO.getResultType(), saveReqVO.getResultSpecification());
+ }
+
+ /**
+ * 鏍¢獙灞傜骇褰掑睘銆傚彧鍏佽涓ゅ眰锛氬垎缁勯」蹇呴』椤剁骇锛屽綍鍏ラ」鍙寕鍒板垎缁勯」涓嬨��
+ * <p>
+ * 銆岀埗蹇呴』鏄垎缁勯」銆嶈繖鏉℃湰韬氨鎺愭浜嗙涓夊眰锛屾墍浠ヤ笉鍐嶅崟鐙啓涓�鏉°�岀埗蹇呴』椤剁骇銆嶇殑鏍¢獙銆�
+ * 鎸変笟鍔′紭鍏堢骇鍙姏绗竴澶勪笉婊¤冻锛岄伩鍏嶄竴娆℃姏澶氭潯璁╃敤鎴锋姄涓嶄綇閲嶇偣銆�
+ */
+ private void validateHierarchy(Long id, MesQcIndicatorSaveReqVO reqVO) {
+ Long parentId = ObjectUtils.defaultIfNull(reqVO.getParentId(), MesQcIndicatorDO.PARENT_ID_ROOT);
+ Integer itemType = ObjectUtils.defaultIfNull(reqVO.getItemType(), MesQcIndicatorItemTypeEnum.ENTRY.getType());
+ // 1. 鍒嗙粍椤瑰彧鑳介《绾�
+ if (MesQcIndicatorItemTypeEnum.isGroup(itemType) && !MesQcIndicatorDO.PARENT_ID_ROOT.equals(parentId)) {
+ throw new ServiceException(QC_INDICATOR_GROUP_CANNOT_NEST.getCode(),
+ String.format("鍒嗙粍椤筟%s]蹇呴』浣滀负椤剁骇鎸囨爣锛屼笉鑳芥寕鍒板叾瀹冩寚鏍囦笅锛堝綋鍓嶉�夋嫨浜嗙埗鎸囨爣[%s]锛夈��"
+ + "濡傞渶璋冩暣灞傜骇锛岃鎶娿�屾潯鐩被鍨嬨�嶆敼涓哄綍鍏ラ」鍚庡啀閫夋嫨鎵�灞炲垎缁勩��",
+ defaultStr(reqVO.getName()), nameOf(parentId)));
+ }
+ // 2. 鐖舵寚鏍囧繀椤诲瓨鍦ㄤ笖鏄垎缁勯」
+ if (!MesQcIndicatorDO.PARENT_ID_ROOT.equals(parentId)) {
+ if (Objects.equals(id, parentId)) {
+ throw exception(QC_INDICATOR_PARENT_SELF);
+ }
+ MesQcIndicatorDO parent = indicatorMapper.selectById(parentId);
+ if (parent == null) {
+ throw new ServiceException(QC_INDICATOR_PARENT_NOT_EXISTS.getCode(),
+ String.format("鎵�灞炲垎缁勪笉瀛樺湪锛堟寚鏍囩紪鍙� %d 鏌ユ棤姝ゆ寚鏍囷紝鍙兘宸茶鍒犻櫎锛夈�傝閲嶆柊閫夋嫨鎵�灞炲垎缁勶紝鎴栨竻绌鸿椤逛綔涓洪《绾ф寚鏍囥��",
+ parentId));
+ }
+ if (!MesQcIndicatorItemTypeEnum.isGroup(parent.getItemType())) {
+ throw new ServiceException(QC_INDICATOR_PARENT_NOT_GROUP.getCode(),
+ String.format("鎵�閫夌埗鎸囨爣[%s]涓嶆槸鍒嗙粍椤癸紙褰撳墠鏉$洰绫诲瀷涓篬%s]锛夛紝涓嶈兘浣滀负鎵�灞炲垎缁勩��"
+ + "璇锋敼閫変竴涓垎缁勯」锛屾垨鍏堝湪鎸囨爣鍒楄〃鎶奫%s]鐨勬潯鐩被鍨嬫敼涓哄垎缁勯」銆�",
+ defaultStr(parent.getName()), itemTypeNameOf(parent.getItemType()), defaultStr(parent.getName())));
+ }
+ }
+ // 3. 褰曞叆椤瑰繀椤绘湁缁撴灉鍊肩被鍨嬶紙鍒嗙粍椤规病鏈夌粨鏋滃�硷紝鐜扮綉鍒嗙粍琛� result_type 灏辨槸 NULL锛�
+ if (!MesQcIndicatorItemTypeEnum.isGroup(itemType) && reqVO.getResultType() == null) {
+ throw exception(QC_INDICATOR_RESULT_TYPE_REQUIRED);
+ }
+ // 4. 鑷繁宸茬粡鏈夊瓙椤规椂锛屼笉鑳藉啀琚埆浜烘敹缂栥�佷篃涓嶈兘鍙嶈繃鏉ュ彉鎴愬瓙椤�
+ if (id == null) {
+ return;
+ }
+ Long childCount = indicatorMapper.selectCountByParentId(id);
+ if (childCount <= 0) {
+ return;
+ }
+ if (!MesQcIndicatorDO.PARENT_ID_ROOT.equals(parentId)) {
+ throw new ServiceException(QC_INDICATOR_HAS_CHILDREN.getCode(),
+ String.format("鎸囨爣[%s]涓嬪凡鎸傛湁 %d 涓綍鍏ラ」锛屼笉鑳藉啀鎸傚埌鍏跺畠鍒嗙粍涓嬶紙鎸囨爣鍙敮鎸佷袱灞傦級銆�"
+ + "璇峰厛鍒犻櫎鎴栫Щ璧拌繖 %d 涓瓙椤癸紝鍐嶄慨鏀瑰畠鐨勬墍灞炲垎缁勩��",
+ defaultStr(reqVO.getName()), childCount, childCount));
+ }
+ if (!MesQcIndicatorItemTypeEnum.isGroup(itemType)) {
+ throw new ServiceException(QC_INDICATOR_HAS_CHILDREN.getCode(),
+ String.format("鎸囨爣[%s]涓嬪凡鎸傛湁 %d 涓綍鍏ラ」锛屼笉鑳藉啀鎶婂畠鐨勬潯鐩被鍨嬫敼涓哄綍鍏ラ」锛屽惁鍒欒繖浜涘瓙椤逛細澶卞幓鎵�灞炲垎缁勩��"
+ + "璇峰厛鍒犻櫎鎴栫Щ璧拌繖 %d 涓瓙椤癸紝鍐嶄慨鏀规潯鐩被鍨嬨��",
+ defaultStr(reqVO.getName()), childCount, childCount));
+ }
+ }
+
+ /**
+ * 钀藉簱鍓嶈ˉ榻愬眰绾у瓧娈碉細鍒嗙粍椤规竻绌虹粨鏋滃�硷紙鐜扮綉鍒嗙粍琛屾病鏈夌粨鏋滃�硷級锛屾帓搴忓彿鐣欑┖鍒欐帓鍒板悓绾ф湯灏�
+ */
+ private void normalizeHierarchy(MesQcIndicatorDO indicator) {
+ indicator.setParentId(ObjectUtils.defaultIfNull(indicator.getParentId(), MesQcIndicatorDO.PARENT_ID_ROOT));
+ indicator.setItemType(ObjectUtils.defaultIfNull(indicator.getItemType(), MesQcIndicatorItemTypeEnum.ENTRY.getType()));
+ if (MesQcIndicatorItemTypeEnum.isGroup(indicator.getItemType())) {
+ indicator.setResultType(null);
+ indicator.setResultSpecification(null);
+ }
+ if (indicator.getSortOrder() == null) {
+ Integer max = indicatorMapper.selectMaxSortOrder(indicator.getParentId());
+ indicator.setSortOrder((max == null ? 0 : max) + (MesQcIndicatorDO.PARENT_ID_ROOT.equals(indicator.getParentId()) ? 10 : 1));
+ }
+ }
+
+ private String nameOf(Long id) {
+ MesQcIndicatorDO indicator = id == null ? null : indicatorMapper.selectById(id);
+ return indicator == null ? String.valueOf(id) : defaultStr(indicator.getName());
+ }
+
+ private static String itemTypeNameOf(Integer itemType) {
+ return MesQcIndicatorItemTypeEnum.isGroup(itemType)
+ ? MesQcIndicatorItemTypeEnum.GROUP.getName() : MesQcIndicatorItemTypeEnum.ENTRY.getName();
+ }
+
+ private static String defaultStr(String value) {
+ return StrUtil.blankToDefault(value, "");
}
private void validateIndicatorExists(Long id) {
@@ -102,7 +205,11 @@
}
}
- private void validateResultSpecification(Integer resultType, String resultSpecification) {
+ private void validateResultSpecification(Integer itemType, Integer resultType, String resultSpecification) {
+ // 鍒嗙粍椤规病鏈夌粨鏋滃�硷紝钀藉簱鍓嶄細琚竻绌猴紝杩欓噷涓嶆牎楠�
+ if (MesQcIndicatorItemTypeEnum.isGroup(ObjectUtils.defaultIfNull(itemType, MesQcIndicatorItemTypeEnum.ENTRY.getType()))) {
+ return;
+ }
if (ObjectUtils.equalsAny(resultType, MesQcResultValueTypeEnum.FILE.getType(),
MesQcResultValueTypeEnum.DICT.getType())) {
if (StrUtil.isBlank(resultSpecification)) {
@@ -127,6 +234,11 @@
}
@Override
+ public List<MesQcIndicatorDO> getIndicatorGroupList() {
+ return indicatorMapper.selectListByItemType(MesQcIndicatorItemTypeEnum.GROUP.getType());
+ }
+
+ @Override
public List<MesQcIndicatorDO> getIndicatorList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
--
Gitblit v1.9.3