|
@@ -137,6 +137,168 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
|
|
|
return iotMainWorkOrderMapper.selectPage(pageReqVO);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public PageResult<IotMainWorkOrderRespVO> sortedMainWorkOrderPage(IotMainWorkOrderPageReqVO pageReqVO) {
|
|
|
+ // 查询 未执行 计划生成 的工单
|
|
|
+ IotMainWorkOrderPageReqVO reqVO = new IotMainWorkOrderPageReqVO();
|
|
|
+ reqVO.setResult(1);
|
|
|
+ reqVO.setType(1);
|
|
|
+ List<Long> workOrderIds = new ArrayList<>();
|
|
|
+ List<IotMainWorkOrderDO> workOrders = iotMainWorkOrderMapper.selectList(reqVO);
|
|
|
+ if (CollUtil.isNotEmpty(workOrders)) {
|
|
|
+ workOrders.forEach(order -> {
|
|
|
+ workOrderIds.add(order.getId());
|
|
|
+ });
|
|
|
+ }
|
|
|
+ List<IotMainWorkOrderBomDO> workOrderBomS = new ArrayList<>();
|
|
|
+ IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
|
|
|
+ if (CollUtil.isNotEmpty(workOrderIds)) {
|
|
|
+ bomReqVO.setWorkOrderIds(workOrderIds);
|
|
|
+ // 查询 未执行的计划生成的工单 的保养项明细
|
|
|
+ workOrderBomS= iotMainWorkOrderBomMapper.selectList(bomReqVO);
|
|
|
+ }
|
|
|
+ // 保养工单保养项明细中已经绑定的 多累计属性 名称
|
|
|
+ Set<String> boundedMultiAttrNames = new HashSet<>();
|
|
|
+ // 工单保养项中包含的设备id集合
|
|
|
+ Set<Long> deviceIds = new HashSet<>();
|
|
|
+ if (CollUtil.isNotEmpty(workOrderBomS)) {
|
|
|
+ // 查询所有保养计划 保养项 中已经绑定的 多个累计时长 公里数 属性名称值
|
|
|
+ workOrderBomS.forEach(bom -> {
|
|
|
+ if (StrUtil.isNotBlank(bom.getType())) {
|
|
|
+ // 累计公里数属性
|
|
|
+ boundedMultiAttrNames.add(bom.getType());
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(bom.getCode())) {
|
|
|
+ // 累计时长属性
|
|
|
+ boundedMultiAttrNames.add(bom.getCode());
|
|
|
+ }
|
|
|
+ if (ObjUtil.isNotEmpty(bom.getDeviceId())) {
|
|
|
+ deviceIds.add(bom.getDeviceId());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 查询 运行记录模板中包含多个累计 时长 公里数 属性的集合
|
|
|
+ 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));
|
|
|
+ // 以保养工单为维度 统计每个工单相关的保养项的最近保养距离 key保养工单id value保养工单下每个保养项的的最小保养距离集合
|
|
|
+ Map<Long, List<Map<String, Object>>> orderDistancePair = new HashMap<>();
|
|
|
+ // key保养工单id value设备保养工单明细下所有保养规则数据最小值
|
|
|
+ Map<Long, String> resultMap = new HashMap<>();
|
|
|
+
|
|
|
+ // 计算出每个保养工单明细的不同保养规则的保养距离最小值
|
|
|
+ if (CollUtil.isNotEmpty(workOrderBomS)) {
|
|
|
+ workOrderBomS.forEach(bom -> {
|
|
|
+ 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(); // 运行时间周期
|
|
|
+ runningTimeDistance = runningTimePeriod.subtract(totalRunTime.subtract(lastRunningTime));
|
|
|
+ }
|
|
|
+ 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(); // 运行里程周期
|
|
|
+ runningKiloDistance = runningKiloPeriod.subtract(totalMileage.subtract(lastRunningKilo));
|
|
|
+ }
|
|
|
+ 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));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 找出距离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.getWorkOrderId())) {
|
|
|
+ List<Map<String, Object>> tempDistances = orderDistancePair.get(bom.getWorkOrderId());
|
|
|
+ tempDistances.add(tempDistance);
|
|
|
+ orderDistancePair.put(bom.getWorkOrderId(), tempDistances);
|
|
|
+ } else {
|
|
|
+ List<Map<String, Object>> tempDistances = new ArrayList<>();
|
|
|
+ tempDistances.add(tempDistance);
|
|
|
+ orderDistancePair.put(bom.getWorkOrderId(), tempDistances);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 以 保养工单id 为维度 统计每个保养工单明细中 距离最近的保养数据
|
|
|
+ resultMap = findClosestToZero(orderDistancePair);
|
|
|
+ // 对集合 resultMap 中所有数据进行排序 按照 map 的value值 去除后面的 字符后 升序排列
|
|
|
+ // 排序后输出一个 List<Long> 类型的集合,排序对应上面的排序规则 集合中的元素是 保养工单id
|
|
|
+ List<Long> sortedWorkOrderIds = sortByNumericValue(resultMap);
|
|
|
+ // 查询所有设备列表 通过SQL形式 使用 FIELD 字段
|
|
|
+ IPage<IotMainWorkOrderRespVO> page = iotMainWorkOrderMapper.sortedMainWorkOrders(
|
|
|
+ new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO, sortedWorkOrderIds);
|
|
|
+ if (CollUtil.isNotEmpty(page.getRecords())) {
|
|
|
+ Map<Long, String> finalResultMap = resultMap;
|
|
|
+ page.getRecords().forEach(order -> {
|
|
|
+ if (finalResultMap.containsKey(order.getId())) {
|
|
|
+ order.setMainDistance(finalResultMap.get(order.getId()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return new PageResult<>(page.getRecords(), page.getTotal());
|
|
|
+ } catch (Exception exception) {
|
|
|
+ if (exception.getMessage().contains("Table does not exist")) {
|
|
|
+ return PageResult.empty();
|
|
|
+ }
|
|
|
+ throw exception;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public PageResult<IotDeviceRespVO> deviceMainDistances(IotMainWorkOrderPageReqVO pageReqVO) {
|
|
|
// 20250624 只查询保养计划中的设备 不查询保养工单表
|