ouyj hace 2 meses
padre
commit
f7aa362fe7

+ 16 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/mapper/GxtOrderHourMapper.java

@@ -29,4 +29,20 @@ public interface GxtOrderHourMapper
                                                      @Param("orderType") String orderType,
                                                      @Param("keyword") String keyword);
 
+    /**
+     * 查询维修工单挂起时长记录
+     * 
+     * @param orderId 工单ID
+     * @return 挂起时长记录数组 [开工前挂起秒数, 作业中挂起秒数, 夜间自动挂起秒数]
+     */
+    public int[] selectRepairOrderSuspensionTime(@Param("orderId") Long orderId);
+    
+    /**
+     * 查询维保工单挂起时长记录
+     * 
+     * @param orderId 工单ID
+     * @return 挂起时长记录数组 [开工前挂起秒数, 作业中挂起秒数, 夜间自动挂起秒数]
+     */
+    public int[] selectWorkOrderSuspensionTime(@Param("orderId") Long orderId);
+
 }

+ 215 - 147
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtOrderHourServiceImpl.java

@@ -929,174 +929,75 @@ public class GxtOrderHourServiceImpl implements IGxtOrderHourService {
         // 转换为小时
         return processingDuration / (1000.0 * 60 * 60);
     }
-    
+
     /**
      * 计算维修工单的挂起时长,分为开工前和开工后两部分
      * 维修工单挂起对应的actionType是approved,恢复对应的是resume
      * 自动挂起对应的actionType是auto_suspend,恢复对应的是auto_resume
-     * 
+     *
      * @param orderId 工单ID
      * @return 包含总挂起时长、开工前挂起时长、开工后挂起时长的数组,索引0为总时长,索引1为开工前时长,索引2为开工后时长(毫秒)
      */
     private long[] calculateRepairOrderSuspensionTime(Long orderId) {
-        GxtRepairOrder order = gxtRepairOrderService.selectGxtRepairOrderById(orderId);
-        List<GxtRepairOrderFlow> flows = gxtRepairOrderFlowMapper.selectGxtRepairOrderFlowListByOrderId(orderId);
-        Date realStartTime = order.getRealStartTime();
-        long totalSuspensionTime = 0;
-        long beforeStartSuspensionTime = 0;
-        long afterStartSuspensionTime = 0;
-        Date suspendTime = null;
-        GxtRepairOrderFlow suspendFlow = null;
-        // 按时间顺序处理流转记录
-        flows.sort((f1, f2) -> f1.getActionTime().compareTo(f2.getActionTime()));
+        // 从数据库中直接获取挂起时长记录
+        int[] suspensionRecord = gxtOrderHourMapper.selectRepairOrderSuspensionTime(orderId);
         
-        for (GxtRepairOrderFlow flow : flows) {
-            if ("approved".equals(flow.getActionType()) || "auto_suspend".equals(flow.getActionType())) {
-                suspendFlow = flow;
-                // 挂起时间
-                suspendTime = flow.getActionTime();
-            } else if (("resume".equals(flow.getActionType()) || "auto_resume".equals(flow.getActionType())) && suspendTime != null) {
-                // 恢复时间
-                long suspensionDuration = flow.getActionTime().getTime() - suspendTime.getTime();
-                //totalSuspensionTime += suspensionDuration;
-                
-                // 判断是开工前还是开工后挂起
-                Date realEndTime = order.getRealEndTime();
-                if (realStartTime != null && realEndTime != null) {
-                    // 计算实际有效的挂起时间段
-                    Date effectiveSuspendStart = suspendTime;
-                    Date effectiveSuspendEnd = flow.getActionTime();
-                    
-                    // 如果挂起时间早于开工时间
-                    if (suspendTime.before(realStartTime)) {
-                        // 挂起时间到开工时间这段时间算为开工前挂起
-                        Date overlapEnd = effectiveSuspendEnd.before(realStartTime) ? effectiveSuspendEnd : realStartTime;
-                        long beforeStartDuration = overlapEnd.getTime() - effectiveSuspendStart.getTime();
-                        if (beforeStartDuration > 0) {
-                            beforeStartSuspensionTime += beforeStartDuration;
-                        }
-                        
-                        // 剩余部分如果在开工后结束时间前,则算作开工后挂起
-                        if (effectiveSuspendEnd.after(realStartTime) && effectiveSuspendEnd.before(realEndTime)) {
-                            Date overlapStart = effectiveSuspendStart.after(realStartTime) ? effectiveSuspendStart : realStartTime;
-                            long afterStartDuration = effectiveSuspendEnd.getTime() - overlapStart.getTime();
-                            if (afterStartDuration > 0) {
-                                afterStartSuspensionTime += afterStartDuration;
-                            }
-                        }
-                    } else {
-                        // 挂起时间在开工时间之后
-                        if("auto_suspend".equals(suspendFlow.getActionType())){
-                            // 自动挂起仍然算作开工前挂起
-                            beforeStartSuspensionTime += suspensionDuration;
-                        } else {
-                            // 普通挂起,只计算在开工时间到结束时间范围内的部分
-                            if (effectiveSuspendStart.before(realEndTime)) {
-                                Date actualEnd = effectiveSuspendEnd.before(realEndTime) ? effectiveSuspendEnd : realEndTime;
-                                long validDuration = actualEnd.getTime() - effectiveSuspendStart.getTime();
-                                if (validDuration > 0) {
-                                    afterStartSuspensionTime += validDuration;
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    // 如果没有开工时间,默认全部算作开工前挂起
-                    beforeStartSuspensionTime += suspensionDuration;
-                }
-                
-                suspendTime = null; // 重置挂起时间
-                suspendFlow = null;
-            }
+        if (suspensionRecord != null && suspensionRecord.length >= 3) {
+            // 数据库存储的是秒,需要转换为毫秒
+            int beforeStartSeconds = suspensionRecord[0];  // 开工前挂起秒数
+            int inWorkSeconds = suspensionRecord[1];       // 作业中挂起秒数
+            int nightAutoSeconds = suspensionRecord[2];    // 夜间自动挂起秒数
+            
+            // 总挂起时长 = 开工前挂起 + 作业中挂起 + 夜间自动挂起
+            long totalSuspensionTime = (long)(beforeStartSeconds + inWorkSeconds + nightAutoSeconds) * 1000;
+            
+            // 开工前挂起时长 = 开工前挂起 + 夜间自动挂起(夜间自动挂起也算作开工前)
+            long beforeStartSuspensionTime = (long)(beforeStartSeconds + nightAutoSeconds) * 1000;
+            
+            // 开工后挂起时长 = 作业中挂起
+            long afterStartSuspensionTime = (long)inWorkSeconds * 1000;
+            
+            return new long[]{totalSuspensionTime, beforeStartSuspensionTime, afterStartSuspensionTime};
+        } else {
+            // 如果没有找到记录,返回默认值
+            return new long[]{0L, 0L, 0L};
         }
-        totalSuspensionTime = beforeStartSuspensionTime + afterStartSuspensionTime;
-        return new long[]{totalSuspensionTime, beforeStartSuspensionTime, afterStartSuspensionTime};
     }
-    
+
     /**
      * 计算维保工单的挂起时长,分为开工前和开工后两部分
      * 维保工单挂起对应的actionType是approved,恢复对应的是restart
      * 自动挂起对应的actionType是auto_suspend,恢复对应的是auto_resume
-     * 
+     *
      * @param orderId 工单ID
      * @return 包含总挂起时长、开工前挂起时长、开工后挂起时长的数组,索引0为总时长,索引1为开工前时长,索引2为开工后时长(毫秒)
      */
     private long[] calculateWorkOrderSuspensionTime(Long orderId) {
-        GxtWorkOrder order = gxtWorkOrderService.selectGxtWorkOrderById(orderId);
-        List<GxtWorkOrderFlow> flows = gxtWorkOrderFlowMapper.selectGxtWorkOrderFlowByOrderId(orderId);
-        Date realStartTime = order.getRealStartTime();
-        long totalSuspensionTime = 0;
-        long beforeStartSuspensionTime = 0;
-        long afterStartSuspensionTime = 0;
-        Date suspendTime = null;
-        GxtWorkOrderFlow suspendFlow = null;
-
-        // 按时间顺序处理流转记录
-        flows.sort((f1, f2) -> f1.getActionTime().compareTo(f2.getActionTime()));
-
-        for (GxtWorkOrderFlow flow : flows) {
-            if ("approved".equals(flow.getActionType()) || "auto_suspend".equals(flow.getActionType())) {
-                suspendFlow = flow;
-                // 挂起时间
-                suspendTime = flow.getActionTime();
-            } else if (("resume".equals(flow.getActionType()) || "auto_resume".equals(flow.getActionType())) && suspendTime != null) {
-                // 恢复时间
-                long suspensionDuration = flow.getActionTime().getTime() - suspendTime.getTime();
-                //totalSuspensionTime += suspensionDuration;
-                
-                // 判断是开工前还是开工后挂起
-                Date realEndTime = order.getRealEndTime();
-                if (realStartTime != null && realEndTime != null) {
-                    // 计算实际有效的挂起时间段
-                    Date effectiveSuspendStart = suspendTime;
-                    Date effectiveSuspendEnd = flow.getActionTime();
-                    
-                    // 如果挂起时间早于开工时间
-                    if (suspendTime.before(realStartTime)) {
-                        // 挂起时间到开工时间这段时间算为开工前挂起
-                        Date overlapEnd = effectiveSuspendEnd.before(realStartTime) ? effectiveSuspendEnd : realStartTime;
-                        long beforeStartDuration = overlapEnd.getTime() - effectiveSuspendStart.getTime();
-                        if (beforeStartDuration > 0) {
-                            beforeStartSuspensionTime += beforeStartDuration;
-                        }
-                        
-                        // 剩余部分如果在开工后结束时间前,则算作开工后挂起
-                        if (effectiveSuspendEnd.after(realStartTime) && effectiveSuspendEnd.before(realEndTime)) {
-                            Date overlapStart = effectiveSuspendStart.after(realStartTime) ? effectiveSuspendStart : realStartTime;
-                            long afterStartDuration = effectiveSuspendEnd.getTime() - overlapStart.getTime();
-                            if (afterStartDuration > 0) {
-                                afterStartSuspensionTime += afterStartDuration;
-                            }
-                        }
-                    } else {
-                        // 挂起时间在开工时间之后
-                        if("auto_suspend".equals(suspendFlow.getActionType())){
-                            // 自动挂起仍然算作开工前挂起
-                            beforeStartSuspensionTime += suspensionDuration;
-                        } else {
-                            // 普通挂起,只计算在开工时间到结束时间范围内的部分
-                            if (effectiveSuspendStart.before(realEndTime)) {
-                                Date actualEnd = effectiveSuspendEnd.before(realEndTime) ? effectiveSuspendEnd : realEndTime;
-                                long validDuration = actualEnd.getTime() - effectiveSuspendStart.getTime();
-                                if (validDuration > 0) {
-                                    afterStartSuspensionTime += validDuration;
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    // 如果没有开工时间,默认全部算作开工前挂起
-                    beforeStartSuspensionTime += suspensionDuration;
-                }
-                
-                suspendTime = null; // 重置挂起时间
-                suspendFlow = null;
-            }
+        // 从数据库中直接获取挂起时长记录
+        int[] suspensionRecord = gxtOrderHourMapper.selectWorkOrderSuspensionTime(orderId);
+        
+        if (suspensionRecord != null && suspensionRecord.length >= 3) {
+            // 数据库存储的是秒,需要转换为毫秒
+            int beforeStartSeconds = suspensionRecord[0];  // 开工前挂起秒数
+            int inWorkSeconds = suspensionRecord[1];       // 作业中挂起秒数
+            int nightAutoSeconds = suspensionRecord[2];    // 夜间自动挂起秒数
+            
+            // 总挂起时长 = 开工前挂起 + 作业中挂起 + 夜间自动挂起
+            long totalSuspensionTime = (long)(beforeStartSeconds + inWorkSeconds + nightAutoSeconds) * 1000;
+            
+            // 开工前挂起时长 = 开工前挂起 + 夜间自动挂起(夜间自动挂起也算作开工前)
+            long beforeStartSuspensionTime = (long)(beforeStartSeconds + nightAutoSeconds) * 1000;
+            
+            // 开工后挂起时长 = 作业中挂起
+            long afterStartSuspensionTime = (long)inWorkSeconds * 1000;
+            
+            return new long[]{totalSuspensionTime, beforeStartSuspensionTime, afterStartSuspensionTime};
+        } else {
+            // 如果没有找到记录,返回默认值
+            return new long[]{0L, 0L, 0L};
         }
-        totalSuspensionTime = beforeStartSuspensionTime + afterStartSuspensionTime;
-        return new long[]{totalSuspensionTime, beforeStartSuspensionTime, afterStartSuspensionTime};
     }
-    
+
     /**
      * 计算工单详情中的各个时长(用于前端展示)
      * 
@@ -1413,4 +1314,171 @@ public class GxtOrderHourServiceImpl implements IGxtOrderHourService {
 
         return statistics;
     }
+
+    /**
+     * 计算维修工单的挂起时长,分为开工前和开工后两部分
+     * 维修工单挂起对应的actionType是approved,恢复对应的是resume
+     * 自动挂起对应的actionType是auto_suspend,恢复对应的是auto_resume
+     *
+     * @param orderId 工单ID
+     * @return 包含总挂起时长、开工前挂起时长、开工后挂起时长的数组,索引0为总时长,索引1为开工前时长,索引2为开工后时长(毫秒)
+     */
+    private long[] calculateRepairOrderSuspensionTimeV0(Long orderId) {
+        GxtRepairOrder order = gxtRepairOrderService.selectGxtRepairOrderById(orderId);
+        List<GxtRepairOrderFlow> flows = gxtRepairOrderFlowMapper.selectGxtRepairOrderFlowListByOrderId(orderId);
+        Date realStartTime = order.getRealStartTime();
+        long totalSuspensionTime = 0;
+        long beforeStartSuspensionTime = 0;
+        long afterStartSuspensionTime = 0;
+        Date suspendTime = null;
+        GxtRepairOrderFlow suspendFlow = null;
+        // 按时间顺序处理流转记录
+        flows.sort((f1, f2) -> f1.getActionTime().compareTo(f2.getActionTime()));
+
+        for (GxtRepairOrderFlow flow : flows) {
+            if ("approved".equals(flow.getActionType()) || "auto_suspend".equals(flow.getActionType())) {
+                suspendFlow = flow;
+                // 挂起时间
+                suspendTime = flow.getActionTime();
+            } else if (("resume".equals(flow.getActionType()) || "auto_resume".equals(flow.getActionType())) && suspendTime != null) {
+                // 恢复时间
+                long suspensionDuration = flow.getActionTime().getTime() - suspendTime.getTime();
+                //totalSuspensionTime += suspensionDuration;
+
+                // 判断是开工前还是开工后挂起
+                Date realEndTime = order.getRealEndTime();
+                if (realStartTime != null && realEndTime != null) {
+                    // 计算实际有效的挂起时间段
+                    Date effectiveSuspendStart = suspendTime;
+                    Date effectiveSuspendEnd = flow.getActionTime();
+
+                    // 如果挂起时间早于开工时间
+                    if (suspendTime.before(realStartTime)) {
+                        // 挂起时间到开工时间这段时间算为开工前挂起
+                        Date overlapEnd = effectiveSuspendEnd.before(realStartTime) ? effectiveSuspendEnd : realStartTime;
+                        long beforeStartDuration = overlapEnd.getTime() - effectiveSuspendStart.getTime();
+                        if (beforeStartDuration > 0) {
+                            beforeStartSuspensionTime += beforeStartDuration;
+                        }
+
+                        // 剩余部分如果在开工后结束时间前,则算作开工后挂起
+                        if (effectiveSuspendEnd.after(realStartTime) && effectiveSuspendEnd.before(realEndTime)) {
+                            Date overlapStart = effectiveSuspendStart.after(realStartTime) ? effectiveSuspendStart : realStartTime;
+                            long afterStartDuration = effectiveSuspendEnd.getTime() - overlapStart.getTime();
+                            if (afterStartDuration > 0) {
+                                afterStartSuspensionTime += afterStartDuration;
+                            }
+                        }
+                    } else {
+                        // 挂起时间在开工时间之后
+                        if("auto_suspend".equals(suspendFlow.getActionType())){
+                            // 自动挂起仍然算作开工前挂起
+                            beforeStartSuspensionTime += suspensionDuration;
+                        } else {
+                            // 普通挂起,只计算在开工时间到结束时间范围内的部分
+                            if (effectiveSuspendStart.before(realEndTime)) {
+                                Date actualEnd = effectiveSuspendEnd.before(realEndTime) ? effectiveSuspendEnd : realEndTime;
+                                long validDuration = actualEnd.getTime() - effectiveSuspendStart.getTime();
+                                if (validDuration > 0) {
+                                    afterStartSuspensionTime += validDuration;
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    // 如果没有开工时间,默认全部算作开工前挂起
+                    beforeStartSuspensionTime += suspensionDuration;
+                }
+
+                suspendTime = null; // 重置挂起时间
+                suspendFlow = null;
+            }
+        }
+        totalSuspensionTime = beforeStartSuspensionTime + afterStartSuspensionTime;
+        return new long[]{totalSuspensionTime, beforeStartSuspensionTime, afterStartSuspensionTime};
+    }
+
+    /**
+     * 计算维保工单的挂起时长,分为开工前和开工后两部分
+     * 维保工单挂起对应的actionType是approved,恢复对应的是restart
+     * 自动挂起对应的actionType是auto_suspend,恢复对应的是auto_resume
+     *
+     * @param orderId 工单ID
+     * @return 包含总挂起时长、开工前挂起时长、开工后挂起时长的数组,索引0为总时长,索引1为开工前时长,索引2为开工后时长(毫秒)
+     */
+    private long[] calculateWorkOrderSuspensionTimeV0(Long orderId) {
+        GxtWorkOrder order = gxtWorkOrderService.selectGxtWorkOrderById(orderId);
+        List<GxtWorkOrderFlow> flows = gxtWorkOrderFlowMapper.selectGxtWorkOrderFlowByOrderId(orderId);
+        Date realStartTime = order.getRealStartTime();
+        long totalSuspensionTime = 0;
+        long beforeStartSuspensionTime = 0;
+        long afterStartSuspensionTime = 0;
+        Date suspendTime = null;
+        GxtWorkOrderFlow suspendFlow = null;
+
+        // 按时间顺序处理流转记录
+        flows.sort((f1, f2) -> f1.getActionTime().compareTo(f2.getActionTime()));
+
+        for (GxtWorkOrderFlow flow : flows) {
+            if ("approved".equals(flow.getActionType()) || "auto_suspend".equals(flow.getActionType())) {
+                suspendFlow = flow;
+                // 挂起时间
+                suspendTime = flow.getActionTime();
+            } else if (("resume".equals(flow.getActionType()) || "auto_resume".equals(flow.getActionType())) && suspendTime != null) {
+                // 恢复时间
+                long suspensionDuration = flow.getActionTime().getTime() - suspendTime.getTime();
+                //totalSuspensionTime += suspensionDuration;
+
+                // 判断是开工前还是开工后挂起
+                Date realEndTime = order.getRealEndTime();
+                if (realStartTime != null && realEndTime != null) {
+                    // 计算实际有效的挂起时间段
+                    Date effectiveSuspendStart = suspendTime;
+                    Date effectiveSuspendEnd = flow.getActionTime();
+
+                    // 如果挂起时间早于开工时间
+                    if (suspendTime.before(realStartTime)) {
+                        // 挂起时间到开工时间这段时间算为开工前挂起
+                        Date overlapEnd = effectiveSuspendEnd.before(realStartTime) ? effectiveSuspendEnd : realStartTime;
+                        long beforeStartDuration = overlapEnd.getTime() - effectiveSuspendStart.getTime();
+                        if (beforeStartDuration > 0) {
+                            beforeStartSuspensionTime += beforeStartDuration;
+                        }
+
+                        // 剩余部分如果在开工后结束时间前,则算作开工后挂起
+                        if (effectiveSuspendEnd.after(realStartTime) && effectiveSuspendEnd.before(realEndTime)) {
+                            Date overlapStart = effectiveSuspendStart.after(realStartTime) ? effectiveSuspendStart : realStartTime;
+                            long afterStartDuration = effectiveSuspendEnd.getTime() - overlapStart.getTime();
+                            if (afterStartDuration > 0) {
+                                afterStartSuspensionTime += afterStartDuration;
+                            }
+                        }
+                    } else {
+                        // 挂起时间在开工时间之后
+                        if("auto_suspend".equals(suspendFlow.getActionType())){
+                            // 自动挂起仍然算作开工前挂起
+                            beforeStartSuspensionTime += suspensionDuration;
+                        } else {
+                            // 普通挂起,只计算在开工时间到结束时间范围内的部分
+                            if (effectiveSuspendStart.before(realEndTime)) {
+                                Date actualEnd = effectiveSuspendEnd.before(realEndTime) ? effectiveSuspendEnd : realEndTime;
+                                long validDuration = actualEnd.getTime() - effectiveSuspendStart.getTime();
+                                if (validDuration > 0) {
+                                    afterStartSuspensionTime += validDuration;
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    // 如果没有开工时间,默认全部算作开工前挂起
+                    beforeStartSuspensionTime += suspensionDuration;
+                }
+
+                suspendTime = null; // 重置挂起时间
+                suspendFlow = null;
+            }
+        }
+        totalSuspensionTime = beforeStartSuspensionTime + afterStartSuspensionTime;
+        return new long[]{totalSuspensionTime, beforeStartSuspensionTime, afterStartSuspensionTime};
+    }
 }

+ 20 - 0
ygtx-gxt/src/main/resources/mapper/gxt/GxtOrderHourMapper.xml

@@ -234,5 +234,25 @@
         </where>
         ORDER BY create_time DESC
     </select>
+    
+    <!-- 查询维修工单挂起时长记录 -->
+    <select id="selectRepairOrderSuspensionTime" resultType="int">
+        SELECT 
+            COALESCE(total_before_start_suspend_seconds, 0) as beforeStartSeconds,
+            COALESCE(total_in_work_suspend_seconds, 0) as inWorkSeconds,
+            COALESCE(total_night_auto_suspend_seconds, 0) as nightAutoSeconds
+        FROM gxt_repair_order_flow_records_next 
+        WHERE order_id = #{orderId}
+    </select>
+    
+    <!-- 查询维保工单挂起时长记录 -->
+    <select id="selectWorkOrderSuspensionTime" resultType="int">
+        SELECT 
+            COALESCE(total_before_start_suspend_seconds, 0) as beforeStartSeconds,
+            COALESCE(total_in_work_suspend_seconds, 0) as inWorkSeconds,
+            COALESCE(total_night_auto_suspend_seconds, 0) as nightAutoSeconds
+        FROM gxt_work_order_flow_records_next 
+        WHERE order_id = #{orderId}
+    </select>
 
 </mapper>