فهرست منبع

pms 以公司为维度 统计所有超时保养的设备

zhangcl 4 روز پیش
والد
کامیت
7fe4a1ca16

+ 9 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorder/IotMainWorkOrderController.java

@@ -34,6 +34,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
@@ -158,6 +159,14 @@ public class IotMainWorkOrderController {
         return success(new PageResult<>(buildDeviceDistanceList(pageResult.getList()), pageResult.getTotal()));
     }
 
+    @GetMapping("/timeoutDeviceMainDistances")
+    @Operation(summary = "以公司为维度 统计所有超时保养的设备(保养里程 保养时长 保养自然日期)")
+    @PermitAll
+    public CommonResult<Map<String, Integer>> timeoutDeviceMainDistances(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
+        Map<String, Integer> deviceMainDistances = iotMainWorkOrderService.timeoutDeviceMainDistances(pageReqVO);
+        return success(deviceMainDistances);
+    }
+
     @GetMapping("/maintenanceSearch")
     @Operation(summary = "以设备为维度统计所有保养计划明细中最近的保养数据 里程/时间/自然日期 可能以设备BOM分组")
     @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/IotDeviceMapper.java

@@ -113,7 +113,7 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
     default List<IotDeviceDO> selectListAlone(IotDevicePageReqVO reqVO) {
         LambdaQueryWrapperX<IotDeviceDO> queryWrapper = new LambdaQueryWrapperX<>();
         queryWrapper
-                .inIfPresent(IotDeviceDO::getDeptId, reqVO.getDeviceIds())
+                .inIfPresent(IotDeviceDO::getId, reqVO.getDeviceIds())
                 .eqIfPresent(IotDeviceDO::getBrand, reqVO.getBrand())
                 .eqIfPresent(IotDeviceDO::getModel, reqVO.getModel())
                 .eqIfPresent(IotDeviceDO::getDeviceStatus, reqVO.getDeviceStatus())

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

@@ -83,6 +83,14 @@ public interface IotMainWorkOrderService {
      */
     PageResult<IotDeviceRespVO> deviceMainDistances(IotMainWorkOrderPageReqVO pageReqVO);
 
+    /**
+     * 以公司为维度 统计所有超时保养的设备(保养里程 保养时长 保养自然日期)
+     *
+     * @param pageReqVO 分页查询
+     * @return 保养工单分页
+     */
+    Map<String, Integer> timeoutDeviceMainDistances(IotMainWorkOrderPageReqVO pageReqVO);
+
     /**
      * 以设备为维度统计所有保养计划明细中最近的保养数据 里程/时间/自然日期 可能以设备BOM分组
      *

+ 315 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmainworkorder/IotMainWorkOrderServiceImpl.java

@@ -9,6 +9,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotlockstock.vo.IotLockStockPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmaintenancebom.vo.IotMaintenanceBomPageReqVO;
@@ -42,6 +43,8 @@ import cn.iocoder.yudao.module.pms.dal.redis.BizNoRedisDAO;
 import cn.iocoder.yudao.module.pms.service.IotDeviceService;
 import cn.iocoder.yudao.module.pms.service.iotdevicerunlog.IotDeviceRunLogService;
 import cn.iocoder.yudao.module.pms.service.iotmaintenancebom.IotMaintenanceBomService;
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
+import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -98,6 +101,8 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
     private DeptService deptService;
     @Resource
     private IotOutboundMapper iotOutboundMapper;
+    @Resource
+    private DeptMapper deptMapper;
 
     @Override
     public Long createIotMainWorkOrder(IotMainWorkOrderSaveReqVO createReqVO) {
@@ -660,6 +665,281 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
         }
     }
 
+
+    @Override
+    public Map<String, Integer> timeoutDeviceMainDistances(IotMainWorkOrderPageReqVO pageReqVO) {
+        // key公司级部门名称     value公司下所有保养超时的设备数量
+        Map<String, Integer> companyNameTimeoutDevices = new HashMap<>();
+        // 所有保养计划 明细中待保养的最近距离 里程/时间/自然日
+        DataPermissionUtils.executeIgnore(() -> {
+            List<IotMainWorkOrderBomDO> workOrderBomS = new ArrayList<>();
+            Set<Long> deviceIds = CollUtil.isEmpty(workOrderBomS)
+                    ? new HashSet<>()
+                    : workOrderBomS.stream()
+                    .map(IotMainWorkOrderBomDO::getDeviceId) // 获取 deviceId
+                    .filter(Objects::nonNull)      // 过滤非空值
+                    .collect(Collectors.toSet());  // 收集到 Set 中
+            Set<Long> orderDeviceIds = new HashSet<>();
+            orderDeviceIds.addAll(deviceIds);
+            // 查询保养计划明细中不包含 deviceIds 的设备id集合
+            List<IotMaintenanceBomDO> mainBomS = new ArrayList<>();
+            Set<Long> mainBomDeviceIds = new HashSet<>();
+            IotMaintenanceBomPageReqVO mainBomReqVO = new IotMaintenanceBomPageReqVO();
+            if (CollUtil.isNotEmpty(deviceIds)) {
+                mainBomReqVO.setDeviceIds(new ArrayList<>(deviceIds));
+                mainBomS = iotMaintenanceBomMapper.selectAlarmList(mainBomReqVO);
+            } else {
+                mainBomS = iotMaintenanceBomMapper.selectList(mainBomReqVO);
+            }
+            Set<String> boundedMultiAttrNames = new HashSet<>();
+            Set<Long> deviceCategoryIds = new HashSet<>();
+            Map<Long, Long> deviceCategoryPair = new HashMap<>();
+            if (CollUtil.isNotEmpty(mainBomS)) {
+                mainBomDeviceIds = CollUtil.isEmpty(mainBomS)
+                        ? Collections.emptySet()
+                        : mainBomS.stream()
+                        .map(IotMaintenanceBomDO::getDeviceId) // 获取 deviceId
+                        .filter(Objects::nonNull)      // 过滤非空值
+                        .collect(Collectors.toSet());  // 收集到 Set 中
+                // 查询所有保养计划 保养项 中已经绑定的 多个累计时长 公里数 属性名称值
+                mainBomS.forEach(bom -> {
+                    if (StrUtil.isNotBlank(bom.getType())) {
+                        // 累计公里数属性
+                        boundedMultiAttrNames.add(bom.getType());
+                    }
+                    if (StrUtil.isNotBlank(bom.getCode())) {
+                        // 累计时长属性
+                        boundedMultiAttrNames.add(bom.getCode());
+                    }
+                });
+                // 查询所有设备类别id
+                // 组装bom关联的设备信息
+                Map<Long, IotDeviceRespVO> deviceMap = iotDeviceService.getDeviceMap(convertListByFlatMap(mainBomS,
+                        bom -> Stream.of(bom.getDeviceId())));
+                if (CollUtil.isNotEmpty(deviceMap)) {
+                    deviceMap.forEach((k,v) -> {
+                        deviceCategoryIds.add(v.getAssetClass());
+                        deviceCategoryPair.put(k, v.getAssetClass());
+                    });
+                }
+            }
+            deviceIds.addAll(mainBomDeviceIds);
+            if (CollUtil.isEmpty(deviceIds)){
+                // 没有设备信息,返回空列表
+                return companyNameTimeoutDevices;
+            }
+            // 查询 运行记录模板中包含多个累计 时长 公里数 属性的集合
+            List<IotDeviceRunLogRespVO> multipleAccumulatedData = new ArrayList<>();
+            if (CollUtil.isNotEmpty(deviceIds) && CollUtil.isNotEmpty(boundedMultiAttrNames)) {
+                multipleAccumulatedData = iotDeviceRunLogService.multipleAccumulatedData(deviceIds, boundedMultiAttrNames);
+            }
+            // key(设备id-累计时长属性名称)    value时长属性累计时长数值
+            Map<String, BigDecimal> tempTotalRunDataPair = new HashMap<>();
+            if (CollUtil.isNotEmpty(multipleAccumulatedData)) {
+                multipleAccumulatedData.forEach(data -> {
+                    String uniqueKey = StrUtil.join("-", data.getDeviceId(), data.getPointName());
+                    tempTotalRunDataPair.put(uniqueKey, data.getTotalRunTime());
+                });
+            }
+
+            // 查询 运行记录模板中 正常的累计时长 公里数集合
+            // Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap = iotDeviceRunLogService.getDeviceRunLogMap(new ArrayList<>(deviceIds));
+            Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap =
+                    iotDeviceRunLogService.getDeviceRunLogMapAlone(new ArrayList<>(deviceIds), new ArrayList<>(deviceCategoryIds), deviceCategoryPair);
+            // 以设备为维度统计每个设备相关的保养项的最近保养距离 key设备id    value设备下每个保养项的的最小保养距离集合
+            Map<Long, List<Map<String, Object>>> orderDistancePair = new HashMap<>();
+            // 设备保养明细 key设备id  value设备保养工单明细下所有保养规则数据最小值
+            Map<Long, String> resultMap = new HashMap<>();
+            // 记录保养项的 提前量 key设备id-保养项id-距离保养值   value提前量
+            Map<String, BigDecimal> bomLeadPair = new HashMap<>();
+            if (CollUtil.isNotEmpty(mainBomS)) {
+                // 遍历保养计划明细 计算 保养计划中的设备 的最近的保养时间
+                for (IotMaintenanceBomDO bom : mainBomS) {
+                    BigDecimal runningTimeDistance = null;
+                    BigDecimal runningKiloDistance = null;
+                    BigDecimal naturalDateDistance = null;
+                    // 计算每个保养项 每个保养规则下的 距离保养时间 单位 小时
+                    if (ObjUtil.isNotEmpty(bom.getRunningTimeRule()) && 0 == bom.getRunningTimeRule()) {
+                        // 运行时间保养规则
+                        BigDecimal totalRunTime = BigDecimal.ZERO;
+                        if (deviceRunLogMap.containsKey(bom.getDeviceId())) {
+                            totalRunTime = deviceRunLogMap.get(bom.getDeviceId()).getTotalRunTime();
+                        } else {
+                            // 运行记录模板中包含多个累计时长 公里数类型的属性
+                            String uniqueKey = StrUtil.join("-", bom.getDeviceId(), bom.getCode());
+                            if (tempTotalRunDataPair.containsKey(uniqueKey)) {
+                                totalRunTime = tempTotalRunDataPair.get(uniqueKey);
+                            }
+                        }
+                        BigDecimal lastRunningTime = bom.getLastRunningTime();      // 上次保养运行时间
+                        BigDecimal runningTimePeriod = bom.getNextRunningTime();    // 运行时间周期
+                        BigDecimal timePeriodLead = bom.getTimePeriodLead();    // 运行时间周期提前量
+                        runningTimeDistance = runningTimePeriod.subtract(totalRunTime.subtract(lastRunningTime));
+                        String uniqueKey = StrUtil.join("-", bom.getDeviceId(), bom.getBomNodeId(), runningTimeDistance);
+                        bomLeadPair.put(uniqueKey, timePeriodLead);
+                    }
+                    if (ObjUtil.isNotEmpty(bom.getMileageRule()) && 0 == bom.getMileageRule()) {
+                        // 运行里程保养规则 累计运行里程规则 累计运行里程 >= (上次保养运行里程+运行里程周期-提前量)
+                        BigDecimal totalMileage = BigDecimal.ZERO;
+                        if (deviceRunLogMap.containsKey(bom.getDeviceId())) {
+                            totalMileage = deviceRunLogMap.get(bom.getDeviceId()).getTotalMileage();
+                        } else {
+                            // 运行记录模板中包含多个累计时长 公里数类型的属性
+                            String uniqueKey = StrUtil.join("-", bom.getDeviceId(), bom.getType());
+                            if (tempTotalRunDataPair.containsKey(uniqueKey)) {
+                                totalMileage = tempTotalRunDataPair.get(uniqueKey);
+                            }
+                        }
+                        BigDecimal lastRunningKilo = bom.getLastRunningKilometers();      // 上次保养运行里程
+                        BigDecimal runningKiloPeriod = bom.getNextRunningKilometers();    // 运行里程周期
+                        BigDecimal kiloCycleLead = bom.getKiloCycleLead();    // 运行里程周期提前量
+                        runningKiloDistance = runningKiloPeriod.subtract(totalMileage.subtract(lastRunningKilo));
+                        String uniqueKey = StrUtil.join("-", bom.getDeviceId(), bom.getBomNodeId(), runningKiloDistance);
+                        bomLeadPair.put(uniqueKey, kiloCycleLead);
+                    }
+                    if (ObjUtil.isNotEmpty(bom.getNaturalDateRule()) && 0 == bom.getNaturalDateRule()) {
+                        // 自然日期保养规则
+                        LocalDateTime lastNaturalDate = bom.getLastNaturalDate();      // 上次保养自然日期
+                        BigDecimal naturalDatePeriod = bom.getNextNaturalDate();        // 自然日周期
+                        BigDecimal natualDateLead = bom.getNaturalDatePeriodLead();    // 自然日周期提前量
+                        if (ObjUtil.isNotEmpty(lastNaturalDate) && ObjUtil.isNotEmpty(naturalDatePeriod) && ObjUtil.isNotEmpty(natualDateLead)) {
+                            // 计算有效天数 = 自然日周期 - 提前量
+                            long days = naturalDatePeriod.longValue(); // 转为长整型天数
+                            // 计算目标日期:上次保养日期 + 有效天数(注意:LocalDateTime加天数会自动处理日期进位)
+                            LocalDateTime targetDate = lastNaturalDate.plusDays(days);
+                            // 获取当前日期时间
+                            LocalDateTime now = LocalDateTime.now();
+                            // 计算日期差值(以天为单位)
+                            naturalDateDistance = new BigDecimal(ChronoUnit.DAYS.between(now, targetDate));
+                            String uniqueKey = StrUtil.join("-", bom.getDeviceId(), bom.getBomNodeId(), naturalDateDistance);
+                            bomLeadPair.put(uniqueKey, natualDateLead);
+                        }
+                    }
+                    // 找出距离0最近的数,作为工单的最近保养距离数据
+                    Object closet = chooseNearestDistance(runningTimeDistance, runningKiloDistance, naturalDateDistance);
+                    Map<String, Object> tempDistance = new HashMap<>();
+                    if (closet == runningTimeDistance) {
+                        tempDistance.put("H", closet);
+                    } else if (closet == runningKiloDistance) {
+                        tempDistance.put("KM", closet);
+                    } else if (closet == naturalDateDistance) {
+                        tempDistance.put("D", closet);
+                    }
+                    if (orderDistancePair.containsKey(bom.getDeviceId())) {
+                        List<Map<String, Object>> tempDistances = orderDistancePair.get(bom.getDeviceId());
+                        tempDistances.add(tempDistance);
+                        orderDistancePair.put(bom.getDeviceId(), tempDistances);
+                    } else {
+                        List<Map<String, Object>> tempDistances = new ArrayList<>();
+                        tempDistances.add(tempDistance);
+                        orderDistancePair.put(bom.getDeviceId(), tempDistances);
+                    }
+                }
+            }
+            // 以设备id 为维度 统计每个保养工单明细中 距离最近的保养数据
+            resultMap = findClosestToZero(orderDistancePair);
+            // 根据保养项规则应该生成保养工单的设备id集合
+            Set<Long> shouldWorkOrderFlags = new HashSet<>();
+            // 找出设备保养项距离保养最小值对应的 提前量
+            if (CollUtil.isNotEmpty(resultMap)) {
+                resultMap.forEach((k,v) -> {
+                    // k设备id    v距离保养最小值(带单位)
+                    // 去掉v中带的单位 310 D   -61.00 H
+                    String[] distanceStrs = v.split(" ");
+                    BigDecimal tempDistance = new BigDecimal(distanceStrs[0]);
+                    if (tempDistance.compareTo(BigDecimal.ZERO) < 0) {
+                        shouldWorkOrderFlags.add(k);
+                    }
+                    if (CollUtil.isNotEmpty(bomLeadPair)) {
+                        bomLeadPair.forEach((key,value) -> {
+                            // key设备id-保养项id-距离保养值   value提前量
+                            String[] uniqueKeyStrs = key.split("-");
+                            if (uniqueKeyStrs.length == 3) {
+                                if (String.valueOf(k).equals(uniqueKeyStrs[0]) && distanceStrs[0].equals(uniqueKeyStrs[2])
+                                        && tempDistance.compareTo(BigDecimal.ZERO)>=0 && tempDistance.compareTo(value)<=0 )  {
+                                    shouldWorkOrderFlags.add(k);
+                                }
+                            }
+                        });
+                    }
+                });
+            }
+            // 对集合 resultMap 中所有数据进行排序 按照 map 的value值 去除后面的 字符后 升序排列
+            // 排序后输出一个 List<Long> 类型的集合,排序对应上面的排序规则
+            // 筛选出所有 保养距离 小于0 的设备
+            List<Long> sortedDeviceIds = sortByNumericTimeoutValue(resultMap);
+            try {
+                // 查询所有公司级别的组织部门
+                Set<Long> parentIds = new HashSet<>();
+                parentIds.add(DeptDO.PARENT_ID_ROOT);
+                // 公司级部门
+                List<DeptDO> theFirstLevelDepts = deptMapper.selectListByParentId(parentIds);
+                AtomicReference<List<DeptDO>> theSecondLevelDepts = new AtomicReference<>(new ArrayList<>());
+                if (CollUtil.isNotEmpty(theFirstLevelDepts)) {
+                    theFirstLevelDepts.forEach(dept -> {
+                        parentIds.clear();
+                        parentIds.add(dept.getId());
+                        theSecondLevelDepts.set(deptMapper.selectListByParentId(parentIds));
+                    });
+                }
+                Map<Long, String> firstLevelDeptNamePair = new HashMap<>();
+                // key子部门id     value公司级部门id
+                Map<Long, Long> deptCompanyPair = new HashMap<>();
+                if (CollUtil.isNotEmpty(theSecondLevelDepts.get())) {
+                    AtomicReference<Set<Long>> ids = new AtomicReference<>(new HashSet<>());
+                    theSecondLevelDepts.get().forEach(dept -> {
+                        // 对部门名称进行 处理 去掉多语言部分
+                        String deptName = dept.getName();
+                        deptName = StrUtil.subBefore(deptName, "~~", false);
+                        firstLevelDeptNamePair.put(dept.getId(), deptName);
+                        // 查询每个公司下所有子部门 将子部门与公司建立对应关系
+                        ids.set(deptService.getChildDeptIdListFromCache(dept.getId()));
+                        ids.get().add(dept.getId());
+                        if (CollUtil.isNotEmpty(ids.get())) {
+                            ids.get().forEach(deptId -> {
+                                deptCompanyPair.put(deptId, dept.getId());
+                            });
+                        }
+                        ids.get().clear();;
+                    });
+                    // 查询 排序后的保养距离超时的 sortedDeviceIds 集合中 每个设备 对应的部门
+                    IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+                    deviceReqVO.setDeviceIds(sortedDeviceIds);
+                    List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
+                    // key公司级部门id     value公司下所有保养超时的设备数量
+                    Map<Long, Integer> companyTimeoutDevices = new HashMap<>();
+
+                    if (CollUtil.isNotEmpty(devices)) {
+                        devices.forEach(device -> {
+                            if (deptCompanyPair.containsKey(device.getDeptId())) {
+                                Long tempCompanyDeptId = deptCompanyPair.get(device.getDeptId());
+                                if (companyTimeoutDevices.containsKey(tempCompanyDeptId)) {
+                                    Integer tempCount = companyTimeoutDevices.get(tempCompanyDeptId);
+                                    companyTimeoutDevices.put(tempCompanyDeptId, ++tempCount);
+                                } else {
+                                    companyTimeoutDevices.put(tempCompanyDeptId, 1);
+                                }
+                            }
+                        });
+                        if (CollUtil.isNotEmpty(companyTimeoutDevices)) {
+                            companyTimeoutDevices.forEach((k,v) -> {
+                                // key公司级部门id     value公司下所有保养超时的设备数量
+                                if (firstLevelDeptNamePair.containsKey(k)) {
+                                    String companyName = firstLevelDeptNamePair.get(k);
+                                    companyNameTimeoutDevices.put(companyName, v);
+                                }
+                            });
+                        }
+                    }
+                }
+                return companyNameTimeoutDevices;
+            } catch (Exception exception) {
+                return new HashMap<>();
+            }
+        });
+        return companyNameTimeoutDevices;
+    }
+
     @Override
     public PageResult<IotDeviceRespVO> maintenanceSearch(IotMainWorkOrderPageReqVO pageReqVO) {
         // 所有保养计划 明细中待保养的最近距离 里程/时间/自然日
@@ -1064,6 +1344,41 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
                 .collect(Collectors.toList());
     }
 
+    /**
+     * 筛选出 保养距离 超时的所有设备
+     * 排序 Map<Long, String> 中的元素 删除 类似 D、 H、 KM 后进行升序排列
+     * @param map
+     * @return
+     */
+    private List<Long> sortByNumericTimeoutValue(Map<Long, String> map) {
+        return map.entrySet().stream()
+                .map(entry -> {
+                    String[] parts = entry.getValue().split("\\s+");
+                    if (parts.length < 2) {
+                        return new AbstractMap.SimpleEntry<>(entry.getKey(), Double.MAX_VALUE);
+                    }
+
+                    try {
+                        BigDecimal value = new BigDecimal(parts[0]);
+                        // 单位转换:H→天,KM/D保持不变
+                        if ("H".equals(parts[1])) {
+                            value = value.divide(BigDecimal.valueOf(24), 2, BigDecimal.ROUND_HALF_UP);
+                        }
+                        return new AbstractMap.SimpleEntry<>(entry.getKey(), value.doubleValue());
+                    } catch (NumberFormatException e) {
+                        return new AbstractMap.SimpleEntry<>(entry.getKey(), Double.MAX_VALUE);
+                    }
+                })
+                // 2. 过滤出转换后数值小于0的数据
+                .filter(entry -> entry.getValue() < 0)
+                .sorted(Comparator
+                        .<AbstractMap.SimpleEntry<Long, Double>>comparingDouble(AbstractMap.SimpleEntry::getValue) // 按转换值升序
+                        .thenComparingLong(AbstractMap.SimpleEntry::getKey) // 值相同时按键升序
+                )
+                .map(AbstractMap.SimpleEntry::getKey)
+                .collect(Collectors.toList());
+    }
+
     /**
      * 找出每个设备对应的bom保养项集合中 距离保养最短的 数据
      * @param orderDistancePair