Bladeren bron

pms BOM清单列表返回树型结构

zhangcl 1 dag geleden
bovenliggende
commit
5ebc36847b

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

@@ -158,6 +158,14 @@ public class IotBomController {
         }));
     }
 
+    @GetMapping("/listTree")
+    @Operation(summary = "获取 Bom树 分页 列表")
+    @PreAuthorize("@ss.hasPermission('rq:iot-bom:query')")
+    public CommonResult<PageResult<IotBomRespVO>> getBomTreeList(@Valid IotBomListReqVO reqVO) {
+        PageResult<IotBomRespVO> pageResult = iotBomService.getBomTreePage(reqVO);
+        return success(pageResult);
+    }
+
     @GetMapping(value = {"/list-all-simple", "/simple-list"})
     @Operation(summary = "获取Bom精简信息列表", description = "只包含被开启的Bom节点,主要用于前端的下拉选项")
     public CommonResult<List<IotBomSimpleRespVO>> getSimpleBomList(IotBomListReqVO reqVO) {

+ 2 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/vo/IotBomListReqVO.java

@@ -1,11 +1,12 @@
 package cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo;
 
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 @Schema(description = "管理后台 - Bom树 列表 Request VO")
 @Data
-public class IotBomListReqVO {
+public class IotBomListReqVO extends PageParam {
 
     @Schema(description = "部门名称,模糊匹配", example = "pms")
     private String name;

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

@@ -90,4 +90,7 @@ public class IotBomRespVO {
     @Schema(description = "所属设备分类名称", example = "空压机")
     @ExcelProperty("所属设备分类")
     private String deviceCategoryName;
+
+    @Schema(description = "子BOM列表 递归树层级")
+    private List<IotBomRespVO> children;
 }

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmaintenancebom/IotMaintenanceBomController.java

@@ -258,6 +258,7 @@ public class IotMaintenanceBomController {
         Map<String, BigDecimal> tempTotalMileagePair = new HashMap<>();
         // 查询指定设备 指定 多累计属性名称 的设备运行记录数据集合数据
         if (CollUtil.isNotEmpty(deviceIds) && CollUtil.isNotEmpty(multiPointNames)) {
+            // TODO 修改成查询 max_run_log 表
             multipleAccumulatedData = iotDeviceRunLogService.multipleAccumulatedData(deviceIds, multiPointNames, null);
         }
         if (CollUtil.isNotEmpty(multipleAccumulatedData)) {

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

@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomListReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotbom.IotBomDO;
 
@@ -72,6 +73,14 @@ public interface IotBomService {
      */
     List<IotBomDO> getBomList(IotBomListReqVO reqVO);
 
+    /**
+     * 获得PMS BOM树列表 分页树根节点
+     *
+     * @param reqVO 编号
+     * @return BOM列表
+     */
+    PageResult<IotBomRespVO> getBomTreePage(IotBomListReqVO reqVO);
+
     /**
      * 获得PMS 设备关联-BOM 关系分页
      *

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

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomListReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomSaveReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialSaveReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicebom.vo.IotDeviceBomListReqVO;
@@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotmaintenancebom.vo.IotMain
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotProductClassifyDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotbom.IotBomDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotcommonbommaterial.IotCommonBomMaterialDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicebom.IotDeviceBomDO;
@@ -405,6 +407,72 @@ public class IotBomServiceImpl implements IotBomService {
         return list;
     }
 
+    @Override
+    public PageResult<IotBomRespVO> getBomTreePage(IotBomListReqVO reqVO) {
+        // 1. 查询所有符合条件的BOM节点(原逻辑)
+        Set<Long> deviceCategoryIds = new HashSet<>();
+        if (Objects.nonNull(reqVO.getDeviceCategoryId())) {
+            deviceCategoryIds = iotProductClassifyService.getChildIotProductClassifyList(reqVO.getDeviceCategoryId());
+            deviceCategoryIds.add(reqVO.getDeviceCategoryId());
+        }
+        List<IotBomDO> allNodes = iotBomMapper.selectList(reqVO, deviceCategoryIds);
+        if (CollUtil.isEmpty(allNodes)) {
+            return PageResult.empty();
+        }
+
+        // 2. 查询物料数量
+        List<Long> bomNodeIds = allNodes.stream().map(IotBomDO::getId).collect(Collectors.toList());
+        IotCommonBomMaterialSaveReqVO materialReq = new IotCommonBomMaterialSaveReqVO();
+        materialReq.setBomNodeIds(bomNodeIds);
+        List<IotCommonBomMaterialDO> materials = iotCommonBomMaterialMapper.selectList1(materialReq);
+        Map<Long, Integer> materialCountMap = materials.stream()
+                .collect(Collectors.groupingBy(IotCommonBomMaterialDO::getBomNodeId, Collectors.summingInt(x -> 1)));
+
+        // 3. 查询设备分类名称(保持原有逻辑)
+        Map<Long, IotProductClassifyDO> deviceCategoryMap = iotProductClassifyService.getIotProductClassifyMap(
+                allNodes.stream().map(IotBomDO::getDeviceCategoryId).distinct().collect(Collectors.toList()));
+
+        // 4. DO -> VO 并填充扩展字段
+        List<IotBomRespVO> allVoList = allNodes.stream().map(bom -> {
+            IotBomRespVO vo = BeanUtils.toBean(bom, IotBomRespVO.class);
+            vo.setMaterials(materialCountMap.getOrDefault(bom.getId(), 0));
+            Optional.ofNullable(bom.getDeviceCategoryId())
+                    .map(deviceCategoryMap::get)
+                    .ifPresent(c -> vo.setDeviceCategoryName(c.getName()));
+            return vo;
+        }).collect(Collectors.toList());
+
+        // 5. 构建树结构(按 parent_id 分组)
+        Map<Long, List<IotBomRespVO>> parentIdMap = allVoList.stream()
+                .filter(vo -> vo.getParentId() != null)      // 防御 null,正常 parent_id 均有值
+                .collect(Collectors.groupingBy(IotBomRespVO::getParentId));
+
+        allVoList.forEach(vo -> {
+            List<IotBomRespVO> children = parentIdMap.getOrDefault(vo.getId(), Collections.emptyList());
+            children.sort(Comparator.comparingInt(IotBomRespVO::getSort)); // 子节点按 sort 升序
+            vo.setChildren(children);
+        });
+
+        // 6. 提取顶级节点(parentId == 0 视为顶级,同时兼容 null)
+        List<IotBomRespVO> rootNodes = allVoList.stream()
+                .filter(vo -> vo.getParentId() != null && vo.getParentId() == 0)
+                .sorted(Comparator.comparingInt(IotBomRespVO::getSort))
+                .collect(Collectors.toList());
+
+        // 7. 对顶级节点进行内存分页
+        int total = rootNodes.size();
+        int pageNo = reqVO.getPageNo();
+        int pageSize = reqVO.getPageSize();
+        int fromIndex = (pageNo - 1) * pageSize;
+        int toIndex = Math.min(fromIndex + pageSize, total);
+        if (fromIndex >= total) {
+            return new PageResult<>(Collections.emptyList(), (long) total);
+        }
+        List<IotBomRespVO> pageRoots = rootNodes.subList(fromIndex, toIndex);
+
+        return new PageResult<>(pageRoots, (long) total);
+    }
+
     @Override
     public PageResult<IotBomDO> deviceAssociateBomPage(IotBomPageReqVO pageReqVO) {
         return iotBomMapper.deviceAssociateBomPage(pageReqVO);