From 63ba72f5d65a3a4dcd56d9228582042448af61d7 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 26 十月 2026 19:09:47 +0800
Subject: [PATCH] feat(mdm): 统一物料分类管理并迁移至MDM模块
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java | 272 ++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 203 insertions(+), 69 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
index dd1a2e6..0ab3f9d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
@@ -2,17 +2,26 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.exception.ServiceException;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.mdm.api.category.MdmItemCategoryApi;
+import cn.iocoder.yudao.module.mdm.api.category.dto.MdmItemCategoryRespDTO;
+import cn.iocoder.yudao.module.mdm.api.category.dto.MdmItemCategorySaveReqDTO;
+import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeImportExcelVO;
+import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeImportRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
-import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemTypeMapper;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@@ -20,70 +29,91 @@
/**
* MES 鐗╂枡浜у搧鍒嗙被 Service 瀹炵幇绫�
*
- * @author 鑺嬮亾婧愮爜
+ * 鐗╂枡鍒嗙被宸茬粺涓�鐢� MDM 绠$悊锛屾暟鎹瓨鍌ㄥ湪 mdm_item_category 琛ㄣ��
+ * 鏈湇鍔′繚鐣� MES 鐨勫垎绫绘帴鍙o紝搴曞眰鍏ㄩ儴閫氳繃 {@link MdmItemCategoryApi} 璇诲啓 MDM 鍒嗙被銆�
+ *
+ * @author 瓒呯骇绠$悊鍛�
*/
@Service
@Validated
public class MesMdItemTypeServiceImpl implements MesMdItemTypeService {
- @Resource
- private MesMdItemTypeMapper itemTypeMapper;
+ /** MDM 鐗╂枡绫诲瀷锛氱墿鏂� */
+ private static final Integer MDM_ITEM_TYPE_MATERIAL = 1;
+ /** MDM 鐗╂枡绫诲瀷锛氫骇鍝� */
+ private static final Integer MDM_ITEM_TYPE_PRODUCT = 2;
+ /** MES 鐗╂枡/浜у搧鏍囪瘑锛氫骇鍝� */
+ private static final String ITEM_OR_PRODUCT_PRODUCT = "PRODUCT";
@Resource
- @Lazy // 寤惰繜鍔犺浇锛岄伩鍏嶅惊鐜緷璧�
+ private MdmItemCategoryApi mdmItemCategoryApi;
+
+ @Resource
+ @Lazy
private MesMdItemService itemService;
@Override
+ @Transactional(rollbackFor = Exception.class)
public Long createItemType(MesMdItemTypeSaveReqVO createReqVO) {
- // 鏍¢獙鏁版嵁
- validateItemTypeSaveData(createReqVO);
-
- // 鎻掑叆
- MesMdItemTypeDO itemType = BeanUtils.toBean(createReqVO, MesMdItemTypeDO.class);
- itemTypeMapper.insert(itemType);
- return itemType.getId();
+ // 鏍¢獙鐖跺垎绫�
+ validateParentItemType(createReqVO.getId(), createReqVO.getParentId());
+ // 鍐欏叆 MDM 鍒嗙被琛�
+ CommonResult<Long> result = mdmItemCategoryApi.createItemCategory(buildSaveDTO(createReqVO));
+ return result.getData();
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public void updateItemType(MesMdItemTypeSaveReqVO updateReqVO) {
// 鏍¢獙瀛樺湪
validateItemTypeExists(updateReqVO.getId());
- // 鏍¢獙鏁版嵁
- validateItemTypeSaveData(updateReqVO);
-
- // 鏇存柊
- MesMdItemTypeDO updateObj = BeanUtils.toBean(updateReqVO, MesMdItemTypeDO.class);
- itemTypeMapper.updateById(updateObj);
+ // 鏍¢獙鐖跺垎绫�
+ validateParentItemType(updateReqVO.getId(), updateReqVO.getParentId());
+ // 鏇存柊 MDM 鍒嗙被琛�
+ MdmItemCategorySaveReqDTO updateDTO = buildSaveDTO(updateReqVO);
+ updateDTO.setId(updateReqVO.getId());
+ mdmItemCategoryApi.updateItemCategory(updateDTO);
}
- private void validateItemTypeSaveData(MesMdItemTypeSaveReqVO reqVO) {
- // 鏍¢獙鐖跺垎绫荤紪鍙风殑鏈夋晥鎬�
- validateParentItemType(reqVO.getId(), reqVO.getParentId());
- // 鏍¢獙鍒嗙被鍚嶇О鐨勫敮涓�鎬�
- validateItemTypeNameUnique(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
- // 鏍¢獙鍒嗙被缂栫爜鐨勫敮涓�鎬�
- validateItemTypeCodeUnique(reqVO.getId(), reqVO.getParentId(), reqVO.getCode());
+ private MdmItemCategorySaveReqDTO buildSaveDTO(MesMdItemTypeSaveReqVO reqVO) {
+ MdmItemCategorySaveReqDTO dto = new MdmItemCategorySaveReqDTO();
+ dto.setParentId(ObjUtil.defaultIfNull(reqVO.getParentId(), MesMdItemTypeDO.PARENT_ID_ROOT));
+ dto.setCode(reqVO.getCode());
+ dto.setName(reqVO.getName());
+ dto.setItemOrProduct(reqVO.getItemOrProduct());
+ dto.setItemType(convertMdmItemType(reqVO.getItemOrProduct()));
+ dto.setSort(ObjUtil.defaultIfNull(reqVO.getSort(), 0));
+ dto.setStatus(ObjUtil.defaultIfNull(reqVO.getStatus(), CommonStatusEnum.ENABLE.getStatus()));
+ dto.setRemark(reqVO.getRemark());
+ return dto;
+ }
+
+ /**
+ * MES 鐗╂枡/浜у搧鏍囪瘑 -> MDM 鐗╂枡绫诲瀷
+ */
+ private Integer convertMdmItemType(String itemOrProduct) {
+ if (StrUtil.isBlank(itemOrProduct)) {
+ return null;
+ }
+ return ITEM_OR_PRODUCT_PRODUCT.equalsIgnoreCase(itemOrProduct)
+ ? MDM_ITEM_TYPE_PRODUCT : MDM_ITEM_TYPE_MATERIAL;
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public void deleteItemType(Long id) {
// 1.1 鏍¢獙瀛樺湪
validateItemTypeExists(id);
- // 1.2 鏍¢獙鏄惁鏈夊瓙鍒嗙被
- if (itemTypeMapper.selectCountByParentId(id) > 0) {
- throw exception(MD_ITEM_TYPE_EXITS_CHILDREN);
- }
- // 1.3 鏍¢獙鏄惁鏈夌墿鏂�
+ // 1.2 鏍¢獙鏄惁鏈夌墿鏂�
if (itemService.getItemCountByItemTypeId(id) > 0) {
throw exception(MD_ITEM_TYPE_EXITS_ITEM);
}
-
- // 2. 鍒犻櫎
- itemTypeMapper.deleteById(id);
+ // 2. 鍒犻櫎锛堝瓙鍒嗙被銆丮DM 鐗╂枡寮曠敤鐢� MDM 渚ф牎楠岋級
+ mdmItemCategoryApi.deleteItemCategory(id);
}
private void validateItemTypeExists(Long id) {
- if (itemTypeMapper.selectById(id) == null) {
+ if (getItemType(id) == null) {
throw exception(MD_ITEM_TYPE_NOT_EXISTS);
}
}
@@ -97,64 +127,51 @@
throw exception(MD_ITEM_TYPE_PARENT_ERROR);
}
// 2. 鐖跺垎绫讳笉瀛樺湪
- MesMdItemTypeDO parentItemType = itemTypeMapper.selectById(parentId);
+ MesMdItemTypeDO parentItemType = getItemType(parentId);
if (parentItemType == null) {
throw exception(MD_ITEM_TYPE_PARENT_NOT_EXITS);
}
// 3. 閫掑綊鏍¢獙鐖跺垎绫伙紝濡傛灉鐖跺垎绫绘槸鑷繁鐨勫瓙鍒嗙被锛屽垯鎶ラ敊锛岄伩鍏嶅舰鎴愮幆璺�
- if (id == null) { // id 涓虹┖锛岃鏄庢柊澧烇紝涓嶉渶瑕佽�冭檻鐜矾
+ if (id == null) {
return;
}
for (int i = 0; i < Short.MAX_VALUE; i++) {
- // 3.1 鏍¢獙鐜矾
parentId = parentItemType.getParentId();
if (Objects.equals(id, parentId)) {
throw exception(MD_ITEM_TYPE_PARENT_IS_CHILD);
}
- // 3.2 缁х画閫掑綊涓嬩竴绾х埗鍒嗙被
if (parentId == null || MesMdItemTypeDO.PARENT_ID_ROOT.equals(parentId)) {
break;
}
- parentItemType = itemTypeMapper.selectById(parentId);
+ parentItemType = getItemType(parentId);
if (parentItemType == null) {
break;
}
}
}
- private void validateItemTypeNameUnique(Long id, Long parentId, String name) {
- MesMdItemTypeDO itemType = itemTypeMapper.selectByParentIdAndName(parentId, name);
- if (itemType == null) {
- return;
- }
- if (ObjUtil.notEqual(itemType.getId(), id)) {
- throw exception(MD_ITEM_TYPE_NAME_DUPLICATE);
- }
- }
-
- private void validateItemTypeCodeUnique(Long id, Long parentId, String code) {
- MesMdItemTypeDO itemType = itemTypeMapper.selectByParentIdAndCode(parentId, code);
- if (itemType == null) {
- return;
- }
- if (ObjUtil.notEqual(itemType.getId(), id)) {
- throw exception(MD_ITEM_TYPE_CODE_DUPLICATE);
- }
- }
-
@Override
public MesMdItemTypeDO getItemType(Long id) {
- return itemTypeMapper.selectById(id);
+ CommonResult<MdmItemCategoryRespDTO> result = mdmItemCategoryApi.getItemCategory(id);
+ return result.isSuccess() ? convertToMesDO(result.getData()) : null;
}
@Override
public MesMdItemTypeDO getItemTypeByCode(String code) {
- return itemTypeMapper.selectByCode(code);
+ CommonResult<MdmItemCategoryRespDTO> result = mdmItemCategoryApi.getItemCategoryByCode(code);
+ return result.isSuccess() ? convertToMesDO(result.getData()) : null;
}
@Override
public List<MesMdItemTypeDO> getItemTypeList(MesMdItemTypeListReqVO listReqVO) {
- return itemTypeMapper.selectList(listReqVO);
+ List<MesMdItemTypeDO> list = getAllItemTypeList();
+ return list.stream()
+ .filter(itemType -> StrUtil.isBlank(listReqVO.getName())
+ || StrUtil.contains(itemType.getName(), listReqVO.getName()))
+ .filter(itemType -> listReqVO.getStatus() == null
+ || Objects.equals(listReqVO.getStatus(), itemType.getStatus()))
+ .sorted(Comparator.comparing(itemType -> ObjUtil.defaultIfNull(itemType.getSort(), 0)))
+ .toList();
}
@Override
@@ -162,21 +179,30 @@
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
- return itemTypeMapper.selectByIds(ids);
+ CommonResult<List<MdmItemCategoryRespDTO>> result = mdmItemCategoryApi.getItemCategoryList(ids);
+ return convertToMesDOList(result.isSuccess() ? result.getData() : null);
+ }
+
+ private List<MesMdItemTypeDO> getAllItemTypeList() {
+ CommonResult<List<MdmItemCategoryRespDTO>> result = mdmItemCategoryApi.getItemCategoryAllList();
+ return convertToMesDOList(result.isSuccess() ? result.getData() : null);
+ }
+
+ private List<MesMdItemTypeDO> convertToMesDOList(List<MdmItemCategoryRespDTO> list) {
+ if (CollUtil.isEmpty(list)) {
+ return new ArrayList<>();
+ }
+ return new ArrayList<>(list.stream().map(this::convertToMesDO).toList());
}
@Override
public List<MesMdItemTypeDO> getItemTypeChildrenList(Long parentId) {
- List<MesMdItemTypeDO> allList = itemTypeMapper.selectList(); // 鍒嗙被鎬婚噺灏忥紝鍏ㄩ噺鏌�
- // 閫掑綊鏀堕泦鎵�鏈夊瓙鍒嗙被
+ List<MesMdItemTypeDO> allList = getAllItemTypeList();
List<MesMdItemTypeDO> result = new ArrayList<>();
collectItemTypeChildren(result, parentId, allList);
return result;
}
- /**
- * 閫掑綊鏀堕泦鎵�鏈夊瓙鍒嗙被
- */
private void collectItemTypeChildren(List<MesMdItemTypeDO> result, Long parentId, List<MesMdItemTypeDO> allList) {
for (MesMdItemTypeDO itemType : allList) {
if (Objects.equals(itemType.getParentId(), parentId)) {
@@ -186,4 +212,112 @@
}
}
+ /**
+ * 杞崲 MDM 鍒嗙被 DTO 涓� MES DO
+ */
+ private MesMdItemTypeDO convertToMesDO(MdmItemCategoryRespDTO dto) {
+ if (dto == null) {
+ return null;
+ }
+ MesMdItemTypeDO mesDO = new MesMdItemTypeDO();
+ mesDO.setId(dto.getId());
+ mesDO.setCode(dto.getCode());
+ mesDO.setName(dto.getName());
+ mesDO.setParentId(dto.getParentId());
+ mesDO.setItemOrProduct(dto.getItemOrProduct());
+ mesDO.setSort(dto.getSort());
+ mesDO.setStatus(dto.getStatus());
+ mesDO.setRemark(dto.getRemark());
+ mesDO.setCreateTime(dto.getCreateTime());
+ return mesDO;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public MesMdItemTypeImportRespVO importItemTypeList(List<MesMdItemTypeImportExcelVO> importItemTypeList,
+ boolean updateSupport) {
+ // 1. 鏍¢獙闈炵┖
+ if (CollUtil.isEmpty(importItemTypeList)) {
+ throw exception(MD_ITEM_TYPE_IMPORT_LIST_IS_EMPTY);
+ }
+
+ // 2. 閫愯澶勭悊
+ MesMdItemTypeImportRespVO respVO = MesMdItemTypeImportRespVO.builder()
+ .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>())
+ .failureCodes(new LinkedHashMap<>()).build();
+ List<MesMdItemTypeDO> allList = getAllItemTypeList();
+ AtomicInteger index = new AtomicInteger(1);
+ importItemTypeList.forEach(importItem -> {
+ int currentIndex = index.getAndIncrement();
+ String key = StrUtil.blankToDefault(importItem.getCode(), "绗� " + currentIndex + " 琛�");
+ if (StrUtil.isBlank(importItem.getCode())) {
+ respVO.getFailureCodes().put(key, "鍒嗙被缂栫爜涓嶈兘涓虹┖");
+ return;
+ }
+ if (StrUtil.isBlank(importItem.getName())) {
+ respVO.getFailureCodes().put(key, "鍒嗙被鍚嶇О涓嶈兘涓虹┖");
+ return;
+ }
+ if (StrUtil.isBlank(importItem.getItemOrProduct())) {
+ respVO.getFailureCodes().put(key, "鐗╂枡/浜у搧鏍囪瘑涓嶈兘涓虹┖");
+ return;
+ }
+ // 2.1 瑙f瀽鐖跺垎绫伙紙涓虹┖鍒欓粯璁や负鏍瑰垎绫伙級
+ Long parentId = MesMdItemTypeDO.PARENT_ID_ROOT;
+ if (StrUtil.isNotBlank(importItem.getParentCode())) {
+ MesMdItemTypeDO parentItemType = allList.stream()
+ .filter(itemType -> Objects.equals(importItem.getParentCode(), itemType.getCode()))
+ .findFirst().orElse(null);
+ if (parentItemType == null) {
+ respVO.getFailureCodes().put(key, "鐖跺垎绫荤紪鐮乕" + importItem.getParentCode() + "]涓嶅瓨鍦�");
+ return;
+ }
+ parentId = parentItemType.getId();
+ }
+ // 2.2 鍒ゆ柇鏄惁瀛樺湪锛堝悓涓�鐖跺垎绫讳笅缂栫爜鍞竴锛�
+ Long finalParentId = parentId;
+ MesMdItemTypeDO existItemType = allList.stream()
+ .filter(itemType -> Objects.equals(finalParentId, itemType.getParentId())
+ && Objects.equals(importItem.getCode(), itemType.getCode()))
+ .findFirst().orElse(null);
+ try {
+ MdmItemCategorySaveReqDTO dto = new MdmItemCategorySaveReqDTO();
+ dto.setParentId(parentId);
+ dto.setCode(importItem.getCode());
+ dto.setName(importItem.getName());
+ dto.setItemOrProduct(importItem.getItemOrProduct());
+ dto.setItemType(convertMdmItemType(importItem.getItemOrProduct()));
+ dto.setSort(ObjUtil.defaultIfNull(importItem.getSort(), 0));
+ dto.setStatus(ObjUtil.defaultIfNull(importItem.getStatus(), CommonStatusEnum.ENABLE.getStatus()));
+ dto.setRemark(importItem.getRemark());
+ if (existItemType == null) {
+ // 2.2.1 鏂板
+ dto.setId(null);
+ Long id = mdmItemCategoryApi.createItemCategory(dto).getData();
+ MesMdItemTypeDO created = new MesMdItemTypeDO();
+ created.setId(id);
+ created.setParentId(parentId);
+ created.setCode(importItem.getCode());
+ created.setName(importItem.getName());
+ created.setItemOrProduct(importItem.getItemOrProduct());
+ created.setSort(dto.getSort());
+ created.setStatus(dto.getStatus());
+ created.setRemark(importItem.getRemark());
+ allList.add(created);
+ respVO.getCreateCodes().add(importItem.getCode());
+ } else if (updateSupport) {
+ // 2.2.2 鏇存柊
+ dto.setId(existItemType.getId());
+ mdmItemCategoryApi.updateItemCategory(dto);
+ respVO.getUpdateCodes().add(importItem.getCode());
+ } else {
+ respVO.getFailureCodes().put(key, "鍒嗙被缂栫爜宸插瓨鍦�");
+ }
+ } catch (ServiceException e) {
+ respVO.getFailureCodes().put(key, e.getMessage());
+ }
+ });
+ return respVO;
+ }
+
}
--
Gitblit v1.9.3