فهرست منبع

pms 按保养规则生成保养工单

zhangcl 3 ماه پیش
والد
کامیت
cd33819992

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

@@ -172,6 +172,6 @@ public class IotTobeMaintenanceBomRespVO {
     /**
      * 新生成的保养工单id
      */
-    @Schema(description = "需要根据自然日周期保养")
+    @Schema(description = "保养工单id")
     private Long workOrderId;
 }

+ 16 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/maintenance/IotMaintenancePlanMapper.java

@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.maintenance.vo.IotMaintenanc
 import cn.iocoder.yudao.module.pms.dal.dataobject.maintenance.IotMaintenancePlanDO;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -18,8 +19,22 @@ import java.util.List;
 @Mapper
 public interface IotMaintenancePlanMapper extends BaseMapperX<IotMaintenancePlanDO> {
 
-    default PageResult<IotMaintenancePlanDO> selectPage(IotMaintenancePlanPageReqVO reqVO) {
+    default PageResult<IotMaintenancePlanDO> selectPage(IotMaintenancePlanPageReqVO reqVO, Collection<Long> ids) {
         return selectPage(reqVO, new LambdaQueryWrapperX<IotMaintenancePlanDO>()
+                .eqIfPresent(IotMaintenancePlanDO::getDeptId, reqVO.getDeptId())
+                .eqIfPresent(IotMaintenancePlanDO::getSerialNumber, reqVO.getSerialNumber())
+                .likeIfPresent(IotMaintenancePlanDO::getName, reqVO.getName())
+                .eqIfPresent(IotMaintenancePlanDO::getResponsiblePerson, reqVO.getResponsiblePerson())
+                .likeIfPresent(IotMaintenancePlanDO::getResponsiblePersonName, reqVO.getResponsiblePersonName())
+                .eqIfPresent(IotMaintenancePlanDO::getRemark, reqVO.getRemark())
+                .eqIfPresent(IotMaintenancePlanDO::getStatus, reqVO.getStatus())
+                .betweenIfPresent(IotMaintenancePlanDO::getCreateTime, reqVO.getCreateTime())
+                .inIfPresent(IotMaintenancePlanDO::getDeptId, ids)
+                .orderByDesc(IotMaintenancePlanDO::getId));
+    }
+
+    default List<IotMaintenancePlanDO> selectList(IotMaintenancePlanPageReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<IotMaintenancePlanDO>()
                 .eqIfPresent(IotMaintenancePlanDO::getDeptId, reqVO.getDeptId())
                 .eqIfPresent(IotMaintenancePlanDO::getSerialNumber, reqVO.getSerialNumber())
                 .likeIfPresent(IotMaintenancePlanDO::getName, reqVO.getName())
@@ -35,6 +50,5 @@ public interface IotMaintenancePlanMapper extends BaseMapperX<IotMaintenancePlan
         return selectOne(IotMaintenancePlanDO::getSerialNumber, no);
     }
 
-
     List<IotTobeMaintenanceBomRespVO> toBeMaintenanceDeviceBOMs();
 }

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

@@ -1,15 +1,22 @@
 package cn.iocoder.yudao.module.pms.job.mainworkorder;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
 import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
-import cn.iocoder.yudao.module.pms.controller.admin.iotmaintenancebom.vo.IotTobeMaintenanceBomRespVO;
+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.maintenance.vo.IotMaintenancePlanPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdeviceperson.IotDevicePersonDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmaintenancebom.IotMaintenanceBomDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbom.IotMainWorkOrderBomDO;
-import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDetailMapper;
-import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderMapper;
-import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectPlanMapper;
+import cn.iocoder.yudao.module.pms.dal.dataobject.maintenance.IotMaintenancePlanDO;
 import cn.iocoder.yudao.module.pms.enums.common.FailureAuditStatusEnum;
+import cn.iocoder.yudao.module.pms.service.iotdeviceperson.IotDevicePersonService;
+import cn.iocoder.yudao.module.pms.service.iotdevicerunlog.IotDeviceRunLogService;
+import cn.iocoder.yudao.module.pms.service.iotmaintenancebom.IotMaintenanceBomService;
 import cn.iocoder.yudao.module.pms.service.iotmainworkorder.IotMainWorkOrderService;
 import cn.iocoder.yudao.module.pms.service.iotmainworkorderbom.IotMainWorkOrderBomService;
 import cn.iocoder.yudao.module.pms.service.maintenance.IotMaintenancePlanService;
@@ -18,21 +25,26 @@ import org.springframework.beans.factory.annotation.Autowired;
 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.concurrent.atomic.AtomicReference;
+import java.util.stream.Stream;
+
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
 
 @Component
 @Slf4j
 public class CreateMainWorkOrderJob implements JobHandler {
     @Resource
-    private IotInspectPlanMapper iotInspectPlanMapper;
+    private IotDevicePersonService iotDevicePersonService;
     @Resource
-    private IotInspectOrderMapper iotInspectOrderMapper;
+    private IotMaintenanceBomService iotMaintenanceBomService;
     @Autowired
-    private IotInspectOrderDetailMapper iotInspectOrderDetailMapper;
+    private IotDeviceRunLogService iotDeviceRunLogService;
 
     @Resource
     private IotMaintenancePlanService iotMaintenancePlanService;
@@ -44,15 +56,91 @@ public class CreateMainWorkOrderJob implements JobHandler {
     @Override
     @TenantJob
     public String execute(String param) throws Exception {
-        // 查询所有的 在保养规则周期内的 设备-bom 关联信息
-        List<IotTobeMaintenanceBomRespVO> tobeMaintenanceBomRespVOS = iotMaintenancePlanService.toBeMaintenanceDeviceBOMs();
+        // 查询所有 保养计划明细
+        IotMaintenanceBomPageReqVO reqVO = new IotMaintenanceBomPageReqVO();
+        List<IotMaintenanceBomDO> mainBomList = iotMaintenanceBomService.getIotMainPlanBomList(reqVO);
+        // 查询所有保养计划 保养工单会复制保养计划的部分信息
+        IotMaintenancePlanPageReqVO planReqVO = new IotMaintenancePlanPageReqVO();
+        List<IotMaintenancePlanDO> plans = iotMaintenancePlanService.maintenancePlans(planReqVO);
+        if (CollUtil.isEmpty(plans)) {
+            return "没有待保养项";
+        }
+        if (CollUtil.isEmpty(mainBomList)) {
+            return "没有待保养项";
+        }
+        List<Long> deviceIds = new ArrayList<>();
+        mainBomList.forEach(bom -> {
+            // 查询保养计划明细中所有设备id
+            deviceIds.add(bom.getDeviceId());
+        });
+        if (CollUtil.isEmpty(deviceIds)) {
+            return "没有设备信息";
+        }
+        // 查询所有设备的责任人
+        IotDevicePersonPageReqVO devicePersonReqVO = new IotDevicePersonPageReqVO();
+        devicePersonReqVO.setDeviceIds(deviceIds);
+        List<IotDevicePersonDO> devicePersons = iotDevicePersonService.getPersonsByDeviceIds(devicePersonReqVO);
 
-        Map<String, IotTobeMaintenanceBomRespVO> maintenancePair = new HashMap<>();
-        Map<String, Long> workOrderIdPair = new HashMap<>();
-        if (CollUtil.isNotEmpty(tobeMaintenanceBomRespVOS)) {
-            tobeMaintenanceBomRespVOS.forEach(maintenance -> {
-                maintenancePair.put(maintenance.getSerialNumber(), maintenance);
-            });
+        // 查询保养计划明细中所有设备的累计运行里程、累计运行时间
+        Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap = iotDeviceRunLogService.getDeviceRunLogMap(convertListByFlatMap(mainBomList,
+                bom -> Stream.of(bom.getDeviceId())));
+        List<IotMaintenanceBomDO> tobeMaintenanceBomList = new ArrayList<>();
+                // 遍历保养计划明细 根据保养项规则 筛选出当前满足保养项规则的 明细记录
+        mainBomList.forEach(bom -> {
+            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();      // 上次保养运行时间
+                    BigDecimal runningTimePeriod = bom.getNextRunningTime();    // 运行时间周期
+                    BigDecimal timePeriodLead = bom.getTimePeriodLead();    // 运行时间周期提前量
+                    if (totalRunTime.compareTo(lastRunningTime.add(runningTimePeriod).subtract(timePeriodLead)) >= 0) {
+                        runningTimeArrive = true;
+                    }
+                }
+                if (0 == bom.getMileageRule()) {
+                    // 累计运行里程规则 累计运行里程 >= (上次保养运行里程+运行里程周期-提前量)
+                    BigDecimal lastRunningKilo = bom.getLastRunningKilometers();      // 上次保养运行里程
+                    BigDecimal runningKiloPeriod = bom.getNextRunningKilometers();    // 运行里程周期
+                    BigDecimal kiloCycleLead = bom.getKiloCycleLead();    // 运行里程周期提前量
+                    if (totalMileage.compareTo(lastRunningKilo.add(runningKiloPeriod).subtract(kiloCycleLead)) >= 0) {
+                        runningKiloArrive = true;
+                    }
+
+                }
+                if (0 == bom.getNaturalDateRule()) {
+                    // 自然日期规则  当前日期 >= (上次保养自然日期+自然日周期-提前量)
+                    LocalDateTime lastNaturalDate = bom.getLastNaturalDate();      // 上次保养自然日期
+                    BigDecimal naturalDatePeriod = bom.getNextNaturalDate();        // 自然日周期
+                    BigDecimal natualDateLead = bom.getNaturalDatePeriodLead();    // 自然日周期提前量
+                    if (ObjUtil.isNotEmpty(lastNaturalDate) && ObjUtil.isNotEmpty(lastNaturalDate) && ObjUtil.isNotEmpty(lastNaturalDate)) {
+                        // 计算有效天数 = 自然日周期 - 提前量
+                        long days = naturalDatePeriod.subtract(natualDateLead).longValue(); // 转为长整型天数
+                        // 计算目标日期:上次保养日期 + 有效天数(注意:LocalDateTime加天数会自动处理日期进位)
+                        LocalDateTime targetDate = lastNaturalDate.plusDays(days);
+                        // 获取当前日期时间(可根据需求调整为指定时区,如:ZoneId.systemDefault())
+                        LocalDateTime now = LocalDateTime.now();
+                        // 判断当前时间是否大于等于目标日期
+                        naturalDateArrive = now.isAfter(targetDate) || now.isEqual(targetDate);
+                    }
+                }
+                if (runningTimeArrive || runningKiloArrive || naturalDateArrive) {
+                    // 3个保养规则中有任何一个规则达到条件即触发 保养
+                    tobeMaintenanceBomList.add(bom);
+                }
+            }
+        });
+
+        Map<String, IotMaintenancePlanDO> maintenancePair = new HashMap<>();
+        plans.forEach(plan -> {
+            maintenancePair.put(plan.getSerialNumber(), plan);
+        });
+        Map<Long, Long> workOrderIdPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(tobeMaintenanceBomList)) {
             // 暂时使用以保养计划为维度,生成保养工单
             // 查询最新的保养工单id
             AtomicReference<Long> theMaxId = new AtomicReference<>(iotMainWorkOrderService.theMaxId());
@@ -66,35 +154,38 @@ public class CreateMainWorkOrderJob implements JobHandler {
                 workOrder.setDeptId(v.getDeptId());
                 workOrder.setPlanId(v.getId());
                 workOrder.setOrderNumber(iotMainWorkOrderService.createWorkOrderNumber());
-                workOrder.setName(v.getPlanName());
+                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(k, theMaxId.get());
+                workOrderIdPair.put(v.getId(), theMaxId.get());
             });
             // 组装 工单明细 集合
-            tobeMaintenanceBomRespVOS.forEach(maintenance -> {
+            // 根据保养计划明细中的 保养项的保养规则 生成保养工单明细
+            // 查询保养计划明细中设备累计运行时间、累计运行里程
+            tobeMaintenanceBomList.forEach(bom -> {
                 IotMainWorkOrderBomDO workOrderBom = new IotMainWorkOrderBomDO();
-                workOrderBom.setWorkOrderId(workOrderIdPair.get(maintenance.getSerialNumber()));
-                workOrderBom.setDeviceCategoryId(maintenance.getDeviceCategoryId());
-                workOrderBom.setDeviceId(maintenance.getDeviceId());
-                workOrderBom.setMileageRule(maintenance.getMileageRule());
-                workOrderBom.setRunningTimeRule(maintenance.getRunningTimeRule());
-                workOrderBom.setNaturalDateRule(maintenance.getNaturalDateRule());
-                workOrderBom.setLastRunningTime(maintenance.getLastRunningTime());
-                workOrderBom.setNextRunningTime(maintenance.getNextRunningTime());
-                workOrderBom.setTimePeriodLead(maintenance.getTimePeriodLead());
-                workOrderBom.setLastRunningKilometers(maintenance.getLastRunningKilometers());
-                workOrderBom.setNextRunningKilometers(maintenance.getNextRunningKilometers());
-                workOrderBom.setKiloCycleLead(maintenance.getKiloCycleLead());
-                workOrderBom.setLastNaturalDate(maintenance.getLastNaturalDate());
-                workOrderBom.setNextNaturalDate(maintenance.getNextNaturalDate());
-                workOrderBom.setNaturalDatePeriodLead(maintenance.getNaturalDatePeriodLead());
-                workOrderBom.setBomNodeId(maintenance.getBomNodeId());
-                workOrderBom.setName(maintenance.getNodeName());
-                workOrderBom.setCode(maintenance.getCode());
+                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);
             });
             // 批量新增 保养工单记录

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

@@ -55,6 +55,14 @@ public interface IotMaintenancePlanService {
      */
     PageResult<IotMaintenancePlanDO> getIotMaintenancePlanPage(IotMaintenancePlanPageReqVO pageReqVO);
 
+    /**
+     * 获得保养计划分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 保养计划分页
+     */
+    List<IotMaintenancePlanDO> maintenancePlans(IotMaintenancePlanPageReqVO pageReqVO);
+
     /**
      * 获取待保养的设备-bom关联信息
      *

+ 14 - 3
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/maintenance/IotMaintenancePlanServiceImpl.java

@@ -13,13 +13,13 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.maintenance.IotMaintenancePlan
 import cn.iocoder.yudao.module.pms.dal.mysql.iotmaintenancebom.IotMaintenanceBomMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.maintenance.IotMaintenancePlanMapper;
 import cn.iocoder.yudao.module.pms.dal.redis.BizNoRedisDAO;
+import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -41,6 +41,8 @@ public class IotMaintenancePlanServiceImpl implements IotMaintenancePlanService
     private IotMaintenanceBomMapper iotMaintenanceBomMapper;
     @Resource
     private BizNoRedisDAO bizNoRedisDAO;
+    @Resource
+    private DeptService deptService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -107,8 +109,17 @@ public class IotMaintenancePlanServiceImpl implements IotMaintenancePlanService
     @Override
     public PageResult<IotMaintenancePlanDO> getIotMaintenancePlanPage(IotMaintenancePlanPageReqVO pageReqVO) {
         // 查询当前部门及子部门下所有数据
+        Set<Long> ids = new HashSet<>();
+        if (Objects.nonNull(pageReqVO.getDeptId())) {
+            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
+            ids.add(pageReqVO.getDeptId());
+        }
+        return iotMaintenancePlanMapper.selectPage(pageReqVO, ids);
+    }
 
-        return iotMaintenancePlanMapper.selectPage(pageReqVO);
+    @Override
+    public List<IotMaintenancePlanDO> maintenancePlans(IotMaintenancePlanPageReqVO pageReqVO) {
+        return iotMaintenancePlanMapper.selectList(pageReqVO);
     }
 
     @Override

+ 5 - 10
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotDeviceRunLogMapper.xml

@@ -10,21 +10,16 @@
      -->
     <select id="distinctDevices"
             resultType="cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO">
-        SELECT
-            l.device_id,
-            l.total_run_time,
-            l.total_mileage,
-            l.time
-        FROM
-            rq_iot_device_run_log l
-            RIGHT JOIN ( SELECT device_id, MAX( time ) AS latest_time, MAX( id ) AS max_id FROM rq_iot_device_run_log GROUP BY device_id ) AS latest ON l.device_id = latest.device_id
-            AND l.id = latest.max_id
+        SELECT device_id, MAX(total_run_time) AS total_run_time, MAX(total_mileage) AS total_mileage
+        FROM rq_iot_device_run_log
+        WHERE deleted = 0
         <if test="deviceIds != null and deviceIds.size &gt; 0">
-            AND latest.device_id IN
+            AND device_id IN
             <foreach collection="deviceIds" index="index" item="key" open="(" separator="," close=")">
                 #{key}
             </foreach>
         </if>
+        GROUP BY device_id
     </select>
 
 </mapper>