Эх сурвалжийг харах

pms 新建的设备分类 拷贝设备分类BOM及物料

zhangcl 4 өдөр өмнө
parent
commit
c99c1b8549

+ 8 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/IotBomController.java

@@ -68,6 +68,14 @@ public class IotBomController {
         return success(true);
     }
 
+    @PutMapping("/copyCategoryBom")
+    @Operation(summary = "拷贝已有设备分类的BOM")
+    @PreAuthorize("@ss.hasPermission('rq:iot-bom:create')")
+    public CommonResult<Boolean> copyCategoryBom(@Valid @RequestBody IotBomSaveReqVO updateReqVO) {
+        iotBomService.copyCategoryBom(updateReqVO);
+        return success(true);
+    }
+
     @PutMapping("/updateAlone")
     @Operation(summary = "更新PMS BOM 关系 只同步没有BOM的设备")
     @PreAuthorize("@ss.hasPermission('rq:iot-bom:update')")

+ 5 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/vo/IotBomSaveReqVO.java

@@ -48,4 +48,9 @@ public class IotBomSaveReqVO {
     @Schema(description = "版本")
     private Integer version;
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "被拷贝设备分类id", example = "23419")
+    private Long toDeviceCategoryId;
 }

+ 17 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotbom/IotBomMapper.java

@@ -10,7 +10,9 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotbom.IotBomDO;
+import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.Collection;
 import java.util.List;
@@ -71,4 +73,19 @@ public interface IotBomMapper extends BaseMapperX<IotBomDO> {
                 .eq(IotBomDO::getLeafFlag, 1)
                 .like(IotBomDO::getType, "2"));
     }
+
+    /**
+     * 删除指定 deviceCategoryId 集合的 设备分类BOM
+     *
+     * @param deviceCategoryIds 设备分类id集合
+     * @return 删除条数
+     */
+    @Delete("<script>" +
+            "DELETE FROM rq_iot_bom " +
+            "WHERE device_category_id IN " +
+            "<foreach collection=\"deviceCategoryIds\" item=\"id\" open=\"(\" separator=\",\" close=\")\">" +
+            "#{id}" +
+            "</foreach>" +
+            "</script>")
+    Integer deleteByDeviceCategoryIds(@Param("deviceCategoryIds") List<Long> deviceCategoryIds);
 }

+ 16 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotcommonbommaterial/IotCommonBomMaterialMapper.java

@@ -10,7 +10,9 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotC
 import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotcommonbommaterial.IotCommonBomMaterialDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmaterial.IotMaterialDO;
+import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -53,4 +55,18 @@ public interface IotCommonBomMaterialMapper extends BaseMapperX<IotCommonBomMate
         return selectJoinList(IotCommonBomMaterialDO.class, query);
     }
 
+    /**
+     * 删除指定 deviceCategoryId 集合的设备分类BOM 挂载的物料
+     *
+     * @param deviceCategoryIds 设备分类id集合
+     * @return 删除条数
+     */
+    @Delete("<script>" +
+            "DELETE FROM rq_iot_common_bom_material " +
+            "WHERE device_category_id IN " +
+            "<foreach collection=\"deviceCategoryIds\" item=\"id\" open=\"(\" separator=\",\" close=\")\">" +
+            "#{id}" +
+            "</foreach>" +
+            "</script>")
+    Integer deleteByDeviceCategoryIds(@Param("deviceCategoryIds") List<Long> deviceCategoryIds);
 }

+ 8 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotbom/IotBomService.java

@@ -115,4 +115,12 @@ public interface IotBomService {
      * @return bom 信息数组
      */
     void syncDeviceBomAndMaterials(Long deviceCategoryId);
+
+    /**
+     * 将设备分类A的BOM树 拷贝到 设备分类B的BOM树
+     *
+     * @param updateReqVO 设备分类A-id  设备分类B-ID
+     * @return
+     */
+    void copyCategoryBom(IotBomSaveReqVO updateReqVO);
 }

+ 107 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotbom/IotBomServiceImpl.java

@@ -37,6 +37,7 @@ import java.util.stream.Stream;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
 import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_BOM_NOT_EXISTS;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_PRODUCT_CLASSIFY_NOT_EXISTS;
 
 /**
  * PMS BOM 关系 Service 实现类
@@ -181,6 +182,57 @@ public class IotBomServiceImpl implements IotBomService {
         }
     }
 
+    @Override
+    public void copyCategoryBom(IotBomSaveReqVO updateReqVO) {
+        // 校验 被拷贝的设备分类ID 与
+        if (ObjUtil.isEmpty(updateReqVO.getDeviceCategoryId()) || ObjUtil.isEmpty(updateReqVO.getToDeviceCategoryId())) {
+            throw exception(IOT_PRODUCT_CLASSIFY_NOT_EXISTS);
+        }
+        // 查询 deviceCategoryId 下关联的BOM
+        List<IotBomDO> existBomList = deviceCategoryBom(updateReqVO.getDeviceCategoryId());
+        if (CollUtil.isEmpty(existBomList)) {
+            throw exception(IOT_BOM_NOT_EXISTS);
+        }
+        // 3. 构建树形结构并获取层级顺序
+        List<IotBomDO> orderedBomS = buildHierarchyOrder(existBomList);
+        // 当前设备分类下所有bom节点id
+        List<Long> bomIds = convertListByFlatMap(orderedBomS, bom -> Stream.of(bom.getId()));
+        IotCommonBomMaterialSaveReqVO saveReqVO = new IotCommonBomMaterialSaveReqVO();
+        saveReqVO.setBomNodeIds(bomIds);
+        List<IotCommonBomMaterialDO> bomMaterials = iotCommonBomMaterialMapper.selectList(saveReqVO);
+        Map<Long, List<IotCommonBomMaterialDO>> bomNodeMaterialMap = bomMaterials.stream()
+                .collect(Collectors.groupingBy(
+                        IotCommonBomMaterialDO::getBomNodeId,  // 分组键:提取 bomNodeId
+                        Collectors.toList()                      // 分组值:保存为列表
+                ));
+
+        // 新 bom 列表
+        List<IotBomDO> resultCategoryBomList = new ArrayList<>();
+        // 新 bom 关联物料列表
+        List<IotCommonBomMaterialDO> bomMaterialList = new ArrayList<>();
+        // 4. 生成ID映射关系
+        Map<Long, Long> idMapping = new LinkedHashMap<>();
+        orderedBomS.forEach(bom -> idMapping.put(bom.getId(), IdGenerator.nextId()));
+        // 5. 转换目标对象
+        List<IotBomDO> targetBoms = convertCategoryBoms(orderedBomS, updateReqVO.getToDeviceCategoryId(), idMapping);
+        // 转换 bom关联的物料 目标对象
+        List<IotCommonBomMaterialDO> targetCommonBomMaterials = convertCategoryBomMaterials(idMapping,
+                updateReqVO.getToDeviceCategoryId(), bomNodeMaterialMap);
+        resultCategoryBomList.addAll(targetBoms);
+        bomMaterialList.addAll(targetCommonBomMaterials);
+        // 先删除已有的 新 设备分类id 下的BOM 及关联的设备
+        List<Long> deviceCategoryIds = new ArrayList<>();
+        deviceCategoryIds.add(updateReqVO.getToDeviceCategoryId());
+        iotBomMapper.deleteByDeviceCategoryIds(deviceCategoryIds);
+        iotCommonBomMaterialMapper.deleteByDeviceCategoryIds(deviceCategoryIds);
+        if (CollUtil.isNotEmpty(resultCategoryBomList)) {
+            iotBomMapper.insertBatch(resultCategoryBomList);
+            if (CollUtil.isNotEmpty(bomMaterialList)) {
+                iotCommonBomMaterialMapper.insertBatch(bomMaterialList);
+            }
+        }
+    }
+
     /**
      * 将设备分类BOM及bom节点挂载的物料同步到 设备bom
      */
@@ -399,6 +451,35 @@ public class IotBomServiceImpl implements IotBomService {
         return targetDeviceMaterials;
     }
 
+    /**
+     * 拷贝已有设备分类BOM 转换目标对象
+     * @param
+     * @param idMapping
+     * @return
+     */
+    private List<IotCommonBomMaterialDO> convertCategoryBomMaterials(Map<Long, Long> idMapping, Long deviceCategoryId,
+                                                          Map<Long, List<IotCommonBomMaterialDO>> bomNodeMaterialMap) {
+        List<IotCommonBomMaterialDO> targetDeviceMaterials = new ArrayList<>();
+        bomNodeMaterialMap.forEach((k,v) -> {
+            // k bomNodeId    v bomNodeId关联的物料集合
+            // 获取 bomNodeId 对应的 设备分类bom nodeId
+            Long deviceBomNodeId = idMapping.get(k);
+            v.forEach(bomMaterial -> {
+                IotCommonBomMaterialDO commonBomMaterial = new IotCommonBomMaterialDO();
+                commonBomMaterial.setDeviceCategoryId(deviceCategoryId);
+                commonBomMaterial.setBomNodeId(deviceBomNodeId);
+                commonBomMaterial.setName(bomMaterial.getName());
+                commonBomMaterial.setCode(bomMaterial.getCode());
+                commonBomMaterial.setQuantity(bomMaterial.getQuantity());
+                commonBomMaterial.setMaterialId(bomMaterial.getMaterialId());
+                commonBomMaterial.setCreator(bomMaterial.getCreator());
+                commonBomMaterial.setCreateTime(LocalDateTime.now());
+                targetDeviceMaterials.add(commonBomMaterial);
+            });
+        });
+        return targetDeviceMaterials;
+    }
+
     /**
      * 转换目标对象
      * @param orderedBoms
@@ -427,6 +508,32 @@ public class IotBomServiceImpl implements IotBomService {
         return targetBoms;
     }
 
+    /**
+     * 拷贝已有的设备分类的BOM
+     * @param orderedBoms
+     * @param idMapping
+     * @return
+     */
+    private List<IotBomDO> convertCategoryBoms(List<IotBomDO> orderedBoms, Long deviceCategoryId, Map<Long, Long> idMapping) {
+        List<IotBomDO> targetBoms = new ArrayList<>();
+        for (IotBomDO source : orderedBoms) {
+            IotBomDO target = new IotBomDO();
+
+            // 基础字段拷贝
+            BeanUtils.copyProperties(source, target);
+            target.setDeviceCategoryId(deviceCategoryId);
+            // ID映射处理
+            target.setId(idMapping.get(source.getId()));
+            target.setParentId(idMapping.getOrDefault(source.getParentId(), 0L));
+
+            target.setCreateTime(LocalDateTime.now());
+            target.setUpdateTime(LocalDateTime.now());
+
+            targetBoms.add(target);
+        }
+        return targetBoms;
+    }
+
     /**
      * 拷贝设备分类bom时构建层级结构
      * @param sourceBoms