浏览代码

pms 保养工单 功能优化

zhangcl 2 月之前
父节点
当前提交
278b0fda79

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

@@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -186,14 +187,18 @@ public class IotMainWorkOrderController {
         // 查询 各工单 明细保养项 的距离保养时间/里程/自然日期 包含多个保养项的 以最近到期时间为准
         IotMainWorkOrderBomPageReqVO reqVO = new IotMainWorkOrderBomPageReqVO();
         reqVO.setWorkOrderIds(convertListByFlatMap(distanceOrders, order -> Stream.of(order.getId())));
-        Map<Long, String> nearestDistances = iotMainWorkOrderBomService.mainWorkOrderNearestDistance(reqVO);
+        Map<Long, String> nearestDistances = new HashMap<>();
+        if (CollUtil.isNotEmpty(distanceOrders)) {
+            nearestDistances = iotMainWorkOrderBomService.mainWorkOrderNearestDistance(reqVO);
+        }
         // 2. 转换成 VO
+        Map<Long, String> finalNearestDistances = nearestDistances;
         return BeanUtils.toBean(orders, IotMainWorkOrderRespVO.class, orderVO -> {
             // 设置创建人、负责人名称
             MapUtils.findAndThen(userMap, NumberUtils.parseLong(orderVO.getResponsiblePerson()),
                     user -> orderVO.setResponsiblePersonName(user.getNickname()));
             // 距离保养时间/公里数/自然日
-            MapUtils.findAndThen(nearestDistances, orderVO.getId(),
+            MapUtils.findAndThen(finalNearestDistances, orderVO.getId(),
                     distance -> orderVO.setMainDistance(distance));
         });
     }

+ 4 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorder/vo/IotMainWorkOrderPageReqVO.java

@@ -89,4 +89,8 @@ public class IotMainWorkOrderPageReqVO extends PageParam {
      */
     @Schema(description = "设备id", example = "8684")
     private Long deviceId;
+    @Schema(description = "设备名称", example = "空压机")
+    private Long deviceName;
+    @Schema(description = "设备编码", example = "8684")
+    private Long deviceCode;
 }

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

@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorder.vo.IotMainWorkOrderPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
@@ -170,5 +171,6 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
     void updateBomSyncStatus(@Param("id") Long id);
 
 
-    IPage<IotDeviceRespVO> deviceDistances(IPage<IotDeviceRespVO> page, @Param("sortedDeviceIds") Collection<Long> sortedDeviceIds);
+    IPage<IotDeviceRespVO> deviceDistances(IPage<IotDeviceRespVO> page, @Param("reqVO") IotMainWorkOrderPageReqVO reqVO,
+                                           @Param("sortedDeviceIds") Collection<Long> sortedDeviceIds, @Param("deptIds") Collection<Long> deptIds);
 }

+ 24 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmainworkorder/IotMainWorkOrderMapper.java

@@ -47,6 +47,30 @@ public interface IotMainWorkOrderMapper extends BaseMapperX<IotMainWorkOrderDO>
                 .orderByDesc(IotMainWorkOrderDO::getId));
     }
 
+    default List<IotMainWorkOrderDO> selectList(IotMainWorkOrderPageReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<IotMainWorkOrderDO>()
+                .eqIfPresent(IotMainWorkOrderDO::getPlanId, reqVO.getPlanId())
+                .eqIfPresent(IotMainWorkOrderDO::getPlanSerialNumber, reqVO.getPlanSerialNumber())
+                .eqIfPresent(IotMainWorkOrderDO::getDeptId, reqVO.getDeptId())
+                .eqIfPresent(IotMainWorkOrderDO::getOrderNumber, reqVO.getOrderNumber())
+                .likeIfPresent(IotMainWorkOrderDO::getName, reqVO.getName())
+                .eqIfPresent(IotMainWorkOrderDO::getType, reqVO.getType())
+                .eqIfPresent(IotMainWorkOrderDO::getResponsiblePerson, reqVO.getResponsiblePerson())
+                .likeIfPresent(IotMainWorkOrderDO::getResponsiblePersonName, reqVO.getResponsiblePersonName())
+                .eqIfPresent(IotMainWorkOrderDO::getCost, reqVO.getCost())
+                .eqIfPresent(IotMainWorkOrderDO::getResult, reqVO.getResult())
+                .eqIfPresent(IotMainWorkOrderDO::getOtherCost, reqVO.getOtherCost())
+                .eqIfPresent(IotMainWorkOrderDO::getLaborCost, reqVO.getLaborCost())
+                .eqIfPresent(IotMainWorkOrderDO::getOutsourcingFlag, reqVO.getOutsourcingFlag())
+                .betweenIfPresent(IotMainWorkOrderDO::getActualStartTime, reqVO.getActualStartTime())
+                .betweenIfPresent(IotMainWorkOrderDO::getActualEndTime, reqVO.getActualEndTime())
+                .eqIfPresent(IotMainWorkOrderDO::getRemark, reqVO.getRemark())
+                .eqIfPresent(IotMainWorkOrderDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(IotMainWorkOrderDO::getProcessInstanceId, reqVO.getProcessInstanceId())
+                .eqIfPresent(IotMainWorkOrderDO::getAuditStatus, reqVO.getAuditStatus())
+                .betweenIfPresent(IotMainWorkOrderDO::getCreateTime, reqVO.getCreateTime()));
+    }
+
     default List<IotMainWorkOrderDO> theMaxOne(){
         return selectList(new LambdaQueryWrapperX<IotMainWorkOrderDO>().orderByDesc(IotMainWorkOrderDO::getId));
     }

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

@@ -30,6 +30,7 @@ import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
@@ -78,7 +79,18 @@ public class CreateMainWorkOrderJob implements JobHandler {
         IotDevicePersonPageReqVO devicePersonReqVO = new IotDevicePersonPageReqVO();
         devicePersonReqVO.setDeviceIds(deviceIds);
         List<IotDevicePersonDO> devicePersons = iotDevicePersonService.getPersonsByDeviceIds(devicePersonReqVO);
-
+        Map<Long, List<Long>> devicePersonPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(devicePersons)) {
+            devicePersonPair = devicePersons.stream()
+                    .filter(person -> person.getDeviceId() != null) // 过滤deviceId为null的记录
+                    .collect(Collectors.groupingBy(
+                            IotDevicePersonDO::getDeviceId, // 按deviceId分组
+                            Collectors.mapping(
+                                    IotDevicePersonDO::getPersonId, // 提取personId
+                                    Collectors.toList() // 收集为列表
+                            )
+                    ));
+        }
         // 查询保养计划明细中所有设备的累计运行里程、累计运行时间
         Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap = iotDeviceRunLogService.getDeviceRunLogMap(convertListByFlatMap(mainBomList,
                 bom -> Stream.of(bom.getDeviceId())));
@@ -141,11 +153,11 @@ public class CreateMainWorkOrderJob implements JobHandler {
                 tobeMainBomIds.add(bom.getBomNodeId());
             }
         });
+        // key保养计划id    value保养计划
         Map<Long, IotMaintenancePlanDO> maintenancePair = new HashMap<>();
         plans.forEach(plan -> {
             maintenancePair.put(plan.getId(), plan);
         });
-        System.out.println("保养计划集合中所有元素:" + maintenancePair.size());
         if (CollUtil.isNotEmpty(tobeMaintenanceBomList)) {
             // 如果有可以触发的保养项 查询保养工单明细中是否存在相同保养项 未填报完成的保养工单 如果有则不生成新的保养工单
             IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
@@ -194,12 +206,14 @@ public class CreateMainWorkOrderJob implements JobHandler {
                 }
             });
             // 以保养计划id对待保养工单分组 分组后便于生成 保养工单主表记录
+            // key保养计划id value待保养工单明细集合
             Map<Long, List<IotMainWorkOrderBomDO>> workOrderBomPair = new HashMap<>();
+            // 以设备为维度 统计每种设备对应的 保养项集合 key保养计划id+设备id value设备对应的保养项集合
+            Map<String, List<IotMainWorkOrderBomDO>> deviceBomPair = 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);
@@ -210,12 +224,28 @@ public class CreateMainWorkOrderJob implements JobHandler {
                         workOrderBomPair.put(workOrderBom.getWorkOrderId(), tempOrderBomS);
                     }
                 });
+                // 组装设备及对应的 保养项集合 map
+                workOrderBOMs.forEach(bom -> {
+                    String uniqueKey = bom.getWorkOrderId()+"-"+bom.getDeviceId();
+                    if (deviceBomPair.containsKey(uniqueKey)) {
+                        List<IotMainWorkOrderBomDO> tempOrderBomS = deviceBomPair.get(uniqueKey);
+                        tempOrderBomS.add(bom);
+                        deviceBomPair.put(uniqueKey, tempOrderBomS);
+                    } else {
+                        List<IotMainWorkOrderBomDO> tempOrderBomS = new ArrayList<>();
+                        tempOrderBomS.add(bom);
+                        deviceBomPair.put(uniqueKey, tempOrderBomS);
+                    }
+                });
+
+                // 按照 保养计划id+设备id 分组 每个"保养计划id+设备id" 生成一个工单
+                deviceBomPair.forEach((k,v) -> {
+
+                });
 
                 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());
@@ -245,7 +275,6 @@ public class CreateMainWorkOrderJob implements JobHandler {
                 iotMainWorkOrderBomService.batchAddOrderBOMs(finalWorkOrderBomS);
             }
         }
-        // 查询需要保养的node节点是否包含在正在执行的保养工单中
         return "创建成功";
     }
 }

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

@@ -34,6 +34,7 @@ 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.service.dept.DeptService;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -83,6 +84,8 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
     private IotMaintenanceBomMapper iotMaintenanceBomMapper;
     @Autowired
     private IotDeviceMapper iotDeviceMapper;
+    @Resource
+    private DeptService deptService;
 
     @Override
     public Long createIotMainWorkOrder(IotMainWorkOrderSaveReqVO createReqVO) {
@@ -134,7 +137,18 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
         // 所有保养计划 + 保养工单 明细中待保养的最近距离 里程/时间/自然日
         // 查询所有保养工单明细中所有设备的累计运行里程 累计运行时间 如果保养项有设置 里程/时间规则 可以计算保养距离
         IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
-        bomReqVO.setDeviceIds(null);
+        // 不查询 已执行 临时创建 的工单
+        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());
+            });
+        }
+        bomReqVO.setWorkOrderIds(workOrderIds);
         List<IotMainWorkOrderBomDO> workOrderBomS = iotMainWorkOrderBomMapper.selectList(bomReqVO);
         Set<Long> deviceIds = CollUtil.isEmpty(workOrderBomS)
                 ? Collections.emptySet()
@@ -217,8 +231,14 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
             // 排序后输出一个 List<Long> 类型的集合,排序对应上面的排序规则
             List<Long> sortedDeviceIds = sortByNumericValue(resultMap);
             try {
+                // 组织层级查询
+                Set<Long> ids = new HashSet<>();
+                if (Objects.nonNull(pageReqVO.getDeptId())) {
+                    ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
+                    ids.add(pageReqVO.getDeptId());
+                }
                 IPage<IotDeviceRespVO> page = iotDeviceMapper.deviceDistances(
-                        new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), sortedDeviceIds);
+                        new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO, sortedDeviceIds, ids);
                 // 处理当前分页数据 拼接上已经排序的 筛选出的设备保养项 最小保养距离
                 if (CollUtil.isNotEmpty(page.getRecords())) {
                     for (IotDeviceRespVO device : page.getRecords()) {

+ 12 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotDeviceMapper.xml

@@ -61,12 +61,24 @@
         WHERE mwoo.deleted = 0
         AND mwoo.`status` = 0
         AND rid.device_code IS NOT NULL
+        <if test="deptIds != null and deptIds.size &gt; 0">
+            AND rid.dept_id IN
+            <foreach collection="deptIds" index="index" item="key" open="(" separator="," close=")">
+                #{key}
+            </foreach>
+        </if>
         <if test="sortedDeviceIds != null and sortedDeviceIds.size &gt; 0">
             AND rid.id IN
             <foreach collection="sortedDeviceIds" index="index" item="key" open="(" separator="," close=")">
                 #{key}
             </foreach>
         </if>
+        <if test="reqVO.deviceName!=null and reqVO.deviceName!=''">
+            AND rid.device_name LIKE concat(concat("%",#{reqVO.deviceName}),"%")
+        </if>
+        <if test="reqVO.deviceCode!=null and reqVO.deviceCode!=''">
+            AND rid.device_code LIKE concat(concat("%",#{reqVO.deviceCode}),"%")
+        </if>
         GROUP BY mwoo.device_id
         ORDER BY FIELD(rid.id,
         <if test="sortedDeviceIds != null and sortedDeviceIds.size &gt; 0">