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

pms 按保养规则生成保养工单 修复重复生成保养工单的问题。

zhangcl 2 сар өмнө
parent
commit
75a3b899f5

+ 8 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorderbom/vo/IotMainWorkOrderBomPageReqVO.java

@@ -9,6 +9,7 @@ import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
@@ -145,4 +146,11 @@ public class IotMainWorkOrderBomPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "设备id列表")
+    private List<Long> deviceIds;
+    @Schema(description = "设备bom节点id列表")
+    private List<Long> bomNodeIds;
 }

+ 2 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmainworkorderbom/IotMainWorkOrderBomMapper.java

@@ -69,6 +69,7 @@ public interface IotMainWorkOrderBomMapper extends BaseMapperX<IotMainWorkOrderB
                 .eqIfPresent(IotMainWorkOrderBomDO::getWorkOrderId, reqVO.getWorkOrderId())
                 .eqIfPresent(IotMainWorkOrderBomDO::getDeviceCategoryId, reqVO.getDeviceCategoryId())
                 .eqIfPresent(IotMainWorkOrderBomDO::getDeviceId, reqVO.getDeviceId())
+                .inIfPresent(IotMainWorkOrderBomDO::getDeviceId, reqVO.getDeviceIds())
                 .eqIfPresent(IotMainWorkOrderBomDO::getRule, reqVO.getRule())
                 .eqIfPresent(IotMainWorkOrderBomDO::getMileageRule, reqVO.getMileageRule())
                 .eqIfPresent(IotMainWorkOrderBomDO::getNaturalDateRule, reqVO.getNaturalDateRule())
@@ -91,6 +92,7 @@ public interface IotMainWorkOrderBomMapper extends BaseMapperX<IotMainWorkOrderB
                 .eqIfPresent(IotMainWorkOrderBomDO::getNaturalDatePeriod, reqVO.getNaturalDatePeriod())
                 .eqIfPresent(IotMainWorkOrderBomDO::getNaturalDatePeriodLead, reqVO.getNaturalDatePeriodLead())
                 .eqIfPresent(IotMainWorkOrderBomDO::getBomNodeId, reqVO.getBomNodeId())
+                .inIfPresent(IotMainWorkOrderBomDO::getBomNodeId, reqVO.getBomNodeIds())
                 .likeIfPresent(IotMainWorkOrderBomDO::getName, reqVO.getName())
                 .eqIfPresent(IotMainWorkOrderBomDO::getCode, reqVO.getCode())
                 .eqIfPresent(IotMainWorkOrderBomDO::getParentId, reqVO.getParentId())

+ 108 - 56
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/mainworkorder/CreateMainWorkOrderJob.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdeviceperson.vo.IotDevicePersonPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmaintenancebom.vo.IotMaintenanceBomPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.maintenance.vo.IotMaintenancePlanPageReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdeviceperson.IotDevicePersonDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmaintenancebom.IotMaintenanceBomDO;
@@ -27,10 +28,7 @@ import org.springframework.stereotype.Component;
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Stream;
 
@@ -85,14 +83,19 @@ public class CreateMainWorkOrderJob implements JobHandler {
         Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap = iotDeviceRunLogService.getDeviceRunLogMap(convertListByFlatMap(mainBomList,
                 bom -> Stream.of(bom.getDeviceId())));
         List<IotMaintenanceBomDO> tobeMaintenanceBomList = new ArrayList<>();
-                // 遍历保养计划明细 根据保养项规则 筛选出当前满足保养项规则的 明细记录
+        // 触发保养规则的设备id 集合
+        List<Long> tobeMainDeviceIds = new ArrayList<>();
+        // 触发保养规则的设备bom节点id 集合
+        List<Long> tobeMainBomIds = new ArrayList<>();
+        // 遍历保养计划明细 根据保养项规则 筛选出当前满足保养项规则的 明细记录
         mainBomList.forEach(bom -> {
+            boolean runningTimeArrive = false;
+            boolean runningKiloArrive = false;
+            boolean naturalDateArrive = false;
+            // 只有维护了累计运行时间、累计运行里程 运行记录的设备才能触发 里程周期 时间周期 保养规则
             if (deviceRunLogMap.containsKey(bom.getDeviceId())) {
                 BigDecimal totalRunTime = deviceRunLogMap.get(bom.getDeviceId()).getTotalRunTime();
                 BigDecimal totalMileage = deviceRunLogMap.get(bom.getDeviceId()).getTotalMileage();
-                boolean runningTimeArrive = false;
-                boolean runningKiloArrive = false;
-                boolean naturalDateArrive = false;
                 if (0 == bom.getRunningTimeRule()) {
                     // 累计运行时间规则   累计运行时间 >= (上次保养运行时间+运行时间周期-提前量)
                     BigDecimal lastRunningTime = bom.getLastRunningTime();      // 上次保养运行时间
@@ -112,6 +115,8 @@ public class CreateMainWorkOrderJob implements JobHandler {
                     }
 
                 }
+            } else {
+                // 没有维护 累计运行时间、累计运行里程 运行记录的设备 可以触发 自然日周期 保养规则
                 if (0 == bom.getNaturalDateRule()) {
                     // 自然日期规则  当前日期 >= (上次保养自然日期+自然日周期-提前量)
                     LocalDateTime lastNaturalDate = bom.getLastNaturalDate();      // 上次保养自然日期
@@ -128,70 +133,117 @@ public class CreateMainWorkOrderJob implements JobHandler {
                         naturalDateArrive = now.isAfter(targetDate) || now.isEqual(targetDate);
                     }
                 }
-                if (runningTimeArrive || runningKiloArrive || naturalDateArrive) {
-                    // 3个保养规则中有任何一个规则达到条件即触发 保养
-                    tobeMaintenanceBomList.add(bom);
-                }
+            }
+            if (runningTimeArrive || runningKiloArrive || naturalDateArrive) {
+                // 3个保养规则中有任何一个规则达到条件即触发 保养
+                tobeMaintenanceBomList.add(bom);
+                tobeMainDeviceIds.add(bom.getDeviceId());
+                tobeMainBomIds.add(bom.getBomNodeId());
             }
         });
-
-        Map<String, IotMaintenancePlanDO> maintenancePair = new HashMap<>();
+        Map<Long, IotMaintenancePlanDO> maintenancePair = new HashMap<>();
         plans.forEach(plan -> {
-            maintenancePair.put(plan.getSerialNumber(), plan);
+            maintenancePair.put(plan.getId(), plan);
         });
-        Map<Long, Long> workOrderIdPair = new HashMap<>();
+        System.out.println("保养计划集合中所有元素:" + maintenancePair.size());
         if (CollUtil.isNotEmpty(tobeMaintenanceBomList)) {
+            // 如果有可以触发的保养项 查询保养工单明细中是否存在相同保养项 未填报完成的保养工单 如果有则不生成新的保养工单
+            IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
+            bomReqVO.setDeviceIds(tobeMainDeviceIds);
+            bomReqVO.setBomNodeIds(tobeMainBomIds);
+            bomReqVO.setStatus(0);
+            List<IotMainWorkOrderBomDO> workOrderBomS = iotMainWorkOrderBomService.getIotMainWorkOrderBomList(bomReqVO);
+            Set<Long> existDeviceIds = new HashSet<>();
+            Set<Long> existBomNodeIds = new HashSet<>();
+            if (CollUtil.isNotEmpty(workOrderBomS)) {
+                workOrderBomS.forEach(bom -> {
+                    existDeviceIds.add(bom.getDeviceId());
+                    existBomNodeIds.add(bom.getBomNodeId());
+                });
+            }
             // 暂时使用以保养计划为维度,生成保养工单
             // 查询最新的保养工单id
             AtomicReference<Long> theMaxId = new AtomicReference<>(iotMainWorkOrderService.theMaxId());
             List<IotMainWorkOrderDO> workOrders = new ArrayList<>();
             List<IotMainWorkOrderBomDO> workOrderBOMs = new ArrayList<>();
-            // 组装工单集合
-            maintenancePair.forEach((k,v) ->{
-                IotMainWorkOrderDO workOrder = new IotMainWorkOrderDO();
-                theMaxId.getAndSet(theMaxId.get() + 1);
-                workOrder.setId(theMaxId.get());
-                workOrder.setDeptId(v.getDeptId());
-                workOrder.setPlanId(v.getId());
-                workOrder.setOrderNumber(iotMainWorkOrderService.createWorkOrderNumber());
-                workOrder.setName(v.getName() + " 工单");
-                workOrder.setType(1);   // 计划生成
-                workOrder.setResult(1); // 待执行
-                workOrder.setResponsiblePerson(v.getResponsiblePerson());
-                workOrder.setAuditStatus(FailureAuditStatusEnum.DRAFT.getStatus());
-                workOrder.setCreator(v.getResponsiblePerson());
-                workOrders.add(workOrder);
-                workOrderIdPair.put(v.getId(), theMaxId.get());
-            });
             // 组装 工单明细 集合
             // 根据保养计划明细中的 保养项的保养规则 生成保养工单明细
-            // 查询保养计划明细中设备累计运行时间、累计运行里程
             tobeMaintenanceBomList.forEach(bom -> {
-                IotMainWorkOrderBomDO workOrderBom = new IotMainWorkOrderBomDO();
-                workOrderBom.setWorkOrderId(workOrderIdPair.get(bom.getPlanId()));
-                workOrderBom.setDeviceCategoryId(bom.getDeviceCategoryId());
-                workOrderBom.setDeviceId(bom.getDeviceId());
-                workOrderBom.setMileageRule(bom.getMileageRule());
-                workOrderBom.setRunningTimeRule(bom.getRunningTimeRule());
-                workOrderBom.setNaturalDateRule(bom.getNaturalDateRule());
-                workOrderBom.setLastRunningTime(bom.getLastRunningTime());
-                workOrderBom.setNextRunningTime(bom.getNextRunningTime());
-                workOrderBom.setTimePeriodLead(bom.getTimePeriodLead());
-                workOrderBom.setLastRunningKilometers(bom.getLastRunningKilometers());
-                workOrderBom.setNextRunningKilometers(bom.getNextRunningKilometers());
-                workOrderBom.setKiloCycleLead(bom.getKiloCycleLead());
-                workOrderBom.setLastNaturalDate(bom.getLastNaturalDate());
-                workOrderBom.setNextNaturalDate(bom.getNextNaturalDate());
-                workOrderBom.setNaturalDatePeriodLead(bom.getNaturalDatePeriodLead());
-                workOrderBom.setBomNodeId(bom.getBomNodeId());
-                workOrderBom.setName(bom.getName());
-                workOrderBom.setCode(bom.getCode());
-                workOrderBOMs.add(workOrderBom);
+                if (!(existDeviceIds.contains(bom.getDeviceId()) && existBomNodeIds.contains(bom.getBomNodeId()))) {
+                    // 当前保养项存在 未填报完成的保养工单 不能生成新工单
+                    IotMainWorkOrderBomDO workOrderBom = new IotMainWorkOrderBomDO();
+                    workOrderBom.setWorkOrderId(bom.getPlanId());   // 以保养计划planId当作保养工单明细分组的标识
+                    workOrderBom.setDeviceCategoryId(bom.getDeviceCategoryId());
+                    workOrderBom.setDeviceId(bom.getDeviceId());
+                    workOrderBom.setMileageRule(bom.getMileageRule());
+                    workOrderBom.setRunningTimeRule(bom.getRunningTimeRule());
+                    workOrderBom.setNaturalDateRule(bom.getNaturalDateRule());
+                    workOrderBom.setLastRunningTime(bom.getLastRunningTime());
+                    workOrderBom.setNextRunningTime(bom.getNextRunningTime());
+                    workOrderBom.setTimePeriodLead(bom.getTimePeriodLead());
+                    workOrderBom.setLastRunningKilometers(bom.getLastRunningKilometers());
+                    workOrderBom.setNextRunningKilometers(bom.getNextRunningKilometers());
+                    workOrderBom.setKiloCycleLead(bom.getKiloCycleLead());
+                    workOrderBom.setLastNaturalDate(bom.getLastNaturalDate());
+                    workOrderBom.setNextNaturalDate(bom.getNextNaturalDate());
+                    workOrderBom.setNaturalDatePeriodLead(bom.getNaturalDatePeriodLead());
+                    workOrderBom.setBomNodeId(bom.getBomNodeId());
+                    workOrderBom.setName(bom.getName());
+                    workOrderBom.setCode(bom.getCode());
+                    workOrderBOMs.add(workOrderBom);
+                }
             });
+            // 以保养计划id对待保养工单分组 分组后便于生成 保养工单主表记录
+            Map<Long, List<IotMainWorkOrderBomDO>> workOrderBomPair = new HashMap<>();
+            // 最终使用的保养工单明细 设置了保养工单主表id
+            List<IotMainWorkOrderBomDO> finalWorkOrderBomS = new ArrayList<>();
+            if (CollUtil.isNotEmpty(workOrderBOMs)) {
+                workOrderBOMs.forEach(workOrderBom -> {
+                    System.out.println("保养工单明细中保留的临时保养计划id:" + workOrderBom.getWorkOrderId());
+                    if (workOrderBomPair.containsKey(workOrderBom.getWorkOrderId())) {
+                        List<IotMainWorkOrderBomDO> tempOrderBomS = workOrderBomPair.get(workOrderBom.getWorkOrderId());
+                        tempOrderBomS.add(workOrderBom);
+                        workOrderBomPair.put(workOrderBom.getWorkOrderId(), tempOrderBomS);
+                    } else {
+                        List<IotMainWorkOrderBomDO> tempOrderBomS = new ArrayList<>();
+                        tempOrderBomS.add(workOrderBom);
+                        workOrderBomPair.put(workOrderBom.getWorkOrderId(), tempOrderBomS);
+                    }
+                });
+
+                workOrderBomPair.forEach((k,v) -> {
+                    // k保养计划id   v已经触发的保养工单明细
+                    // 根据每个保养计划生成一个保养工单
+                    IotMaintenancePlanDO plan = maintenancePair.get(k);
+                    System.out.println("保养计划id:" + k);
+                    IotMainWorkOrderDO workOrder = new IotMainWorkOrderDO();
+                    theMaxId.getAndSet(theMaxId.get() + 1);
+                    workOrder.setId(theMaxId.get());
+                    workOrder.setDeptId(plan.getDeptId());
+                    workOrder.setPlanId(plan.getId());
+                    workOrder.setOrderNumber(iotMainWorkOrderService.createWorkOrderNumber());
+                    workOrder.setName(plan.getName() + " 工单");
+                    workOrder.setType(1);   // 计划生成
+                    workOrder.setResult(1); // 待执行
+                    workOrder.setResponsiblePerson(plan.getResponsiblePerson());
+                    workOrder.setAuditStatus(FailureAuditStatusEnum.DRAFT.getStatus());
+                    workOrder.setCreator(plan.getResponsiblePerson());
+                    workOrders.add(workOrder);
+                    // 2. 处理关联的BOM明细
+                    final long workOrderId = workOrder.getId(); // 获取当前工单ID
+                    v.forEach(bom -> bom.setWorkOrderId(workOrderId)); // 设置明细关联ID
+                    // 3. 添加到最终集合
+                    finalWorkOrderBomS.addAll(v);
+                });
+            }
             // 批量新增 保养工单记录
-            iotMainWorkOrderService.batchAddOrders(workOrders);
+            if (CollUtil.isNotEmpty(workOrders)) {
+                iotMainWorkOrderService.batchAddOrders(workOrders);
+            }
             // 批量新增 保养工单明细
-            iotMainWorkOrderBomService.batchAddOrderBOMs(workOrderBOMs);
+            if (CollUtil.isNotEmpty(finalWorkOrderBomS)) {
+                iotMainWorkOrderBomService.batchAddOrderBOMs(finalWorkOrderBomS);
+            }
         }
         // 查询需要保养的node节点是否包含在正在执行的保养工单中
         return "创建成功";

+ 0 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmainworkorderbom/IotMainWorkOrderBomService.java

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.pms.service.iotmainworkorderbom;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomSaveReqVO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbom.IotMainWorkOrderBomDO;
 
 import javax.validation.Valid;