From b3e9e6eb29afce516d893f17c7c99ae3dd2be4f5 Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期四, 12 三月 2026 18:39:05 +0800
Subject: [PATCH] 处理缺卡问题

---
 xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/ClockInScheduleTask.java |  113 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/ClockInScheduleTask.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/ClockInScheduleTask.java
index 3edaa8b..9dd7fff 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/ClockInScheduleTask.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/ClockInScheduleTask.java
@@ -2,15 +2,21 @@
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
+import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient;
+import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient;
 import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
 import com.xiaopeng.api.model.maintenance.XpClockIn;
 import com.xiaopeng.api.model.maintenance.XpSchedulingDetail;
+import com.xiaopeng.api.model.maintenance.XpShift;
+import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
+import com.xiaopeng.common.core.utils.DateUtils;
 import com.xiaopeng.maintenance.mapper.XpClockInMapper;
 import com.xiaopeng.maintenance.mapper.XpTaskMapper;
 import com.xiaopeng.maintenance.mapper.XpTaskRuleMapper;
 import com.xiaopeng.maintenance.mapper.XpTaskRuleRoleMapper;
 import com.xiaopeng.maintenance.service.IXpClockInService;
 import com.xiaopeng.maintenance.service.IXpSchedulingDetailService;
+import com.xiaopeng.maintenance.service.IXpShiftService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +25,8 @@
 import org.springframework.util.CollectionUtils;
 
 import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -40,7 +48,10 @@
     private IXpClockInService xpClockInService;
     @Autowired
     private IXpSchedulingDetailService xpSchedulingDetailService;
-
+    @Autowired
+    private XpFleetOperationsClient xpFleetOperationsClient;
+    @Autowired
+    private IXpShiftService xpShiftService;
 
     /**
      * 每5分钟执行一次
@@ -49,20 +60,100 @@
     public void clockInScheduleTask() {
         log.info("========== 开始执行打卡检查 ==========");
         try {
-
-            // 查询上班卡在今天的
-            List<XpSchedulingDetail> clockInPlanList = xpSchedulingDetailService.list(Wrappers.lambdaQuery(XpSchedulingDetail.class)
-                    .likeRight(XpSchedulingDetail::getPlanTime, LocalDate.now()));
-            if(!CollectionUtils.isEmpty(clockInPlanList)){
-                List<Long> fleetIds = clockInPlanList.stream().map(XpSchedulingDetail::getFleetId).collect(Collectors.toList());
-                // 查询所有车队
-
-            }
-
             // 查询下班卡在今天的
             List<XpSchedulingDetail> clockOutPlanList = xpSchedulingDetailService.list(Wrappers.lambdaQuery(XpSchedulingDetail.class)
                     .likeRight(XpSchedulingDetail::getPlanTime, LocalDate.now()));
 
+            if(!CollectionUtils.isEmpty(clockOutPlanList)){
+                List<Long> fleetIds = clockOutPlanList.stream().map(XpSchedulingDetail::getFleetId).collect(Collectors.toList());
+                // 查询所有车队的绑定人员
+                List<XpFleetOperations> xpFleetOperations = xpFleetOperationsClient.getOperationsIdsByFleetIds(fleetIds).getData();
+                // 查询班次
+                List<Long> shiftIds = clockOutPlanList.stream().map(XpSchedulingDetail::getShiftId).collect(Collectors.toList());
+                List<XpShift> xpShifts = xpShiftService.list(Wrappers.lambdaQuery(XpShift.class)
+                        .eq(XpShift::getId, shiftIds));
+                log.info("========== 查询到{}个车队 ==========", xpFleetOperations.size());
+                if(!CollectionUtils.isEmpty(xpShifts) && !CollectionUtils.isEmpty(xpFleetOperations)){
+                    // 处理上班卡缺卡情况
+                    // 过滤当前时间在班次下班打卡时间之后的数据   今日已过下班的班次
+                    List<XpShift> shiftList = xpShifts.stream().filter(xpShift ->
+                            DateUtils.stringToLocalDateTime(LocalDate.now() + " " + xpShift.getEndTime() + ":00").isBefore(LocalDateTime.now())).collect(Collectors.toList());
+                    List<Long> ids = shiftList.stream().map(XpShift::getId).collect(Collectors.toList());
+                    if(!CollectionUtils.isEmpty(ids)){
+                        log.info("========== 进入上班过期的班次 ==========");
+                        // 获取过期当前班次的排班明细  覆盖
+                        List<XpSchedulingDetail> clockOutPlans = clockOutPlanList.stream().filter(xpSchedulingDetail -> ids.contains(xpSchedulingDetail.getShiftId())).collect(Collectors.toList());
+                        List<Long> fleetIdIn = clockOutPlans.stream().map(XpSchedulingDetail::getFleetId).collect(Collectors.toList());
+                        List<Long> operationsUserIds = xpFleetOperations.stream().filter(x -> fleetIdIn.contains(x.getFleetId()))
+                                .map(XpFleetOperations::getOperationsUserId).distinct().collect(Collectors.toList());
+                        // 批量查询人员打卡信息
+                        List<XpClockIn> clockInList = xpClockInService.list(Wrappers.lambdaQuery(XpClockIn.class)
+                                .eq(XpClockIn::getAppUserId, operationsUserIds));
+                        // 判断有哪些人员没有打卡信息
+                        List<Long> noClockInUserIds = operationsUserIds.stream().filter(id -> clockInList.stream().noneMatch(clockIn -> clockIn.getAppUserId().equals(id))).collect(Collectors.toList());
+                        if(!CollectionUtils.isEmpty(noClockInUserIds)){
+                            log.info("========== 获取到{}个人员没有打卡信息 ==========", noClockInUserIds.size());
+                            // 添加上班缺卡信息
+                            List<XpClockIn> noClockInList = new ArrayList<>();
+                            for (Long noClockInUserId : noClockInUserIds) {
+                                // 通过用户id找到车队id
+                                List<XpFleetOperations> operations = xpFleetOperations.stream().filter(x -> x.getOperationsUserId().equals(noClockInUserId)).collect(Collectors.toList());
+                                if(!CollectionUtils.isEmpty(operations)){
+                                    Long fleetId = operations.get(0).getFleetId();
+                                    // 通过车队id和已过期的班次获取排班明细
+                                    List<XpSchedulingDetail> clockOutPlanExpiredList = clockOutPlanList.stream()
+                                            .filter(xpSchedulingDetail -> xpSchedulingDetail.getFleetId().equals(fleetId)
+                                                    && ids.contains(xpSchedulingDetail.getShiftId())).collect(Collectors.toList());
+                                    if(!CollectionUtils.isEmpty(clockOutPlanExpiredList)){
+                                        Long shiftId = clockOutPlanExpiredList.get(0).getShiftId();
+                                        XpClockIn xpClockIn = new XpClockIn();
+                                        xpClockIn.setAppUserId(noClockInUserId);
+                                        xpClockIn.setClockInTime(LocalDateTime.now());
+                                        xpClockIn.setClockInResult(3);
+                                        xpClockIn.setShiftId(shiftId);
+                                        noClockInList.add(xpClockIn);
+                                    }
+                                }
+                            }
+                            if (!CollectionUtils.isEmpty(noClockInList)){
+                                log.info("添加上班缺卡信息:{}", noClockInList);
+                                xpClockInService.saveOrUpdateBatch(noClockInList);
+                            }
+                        }
+                    }
+
+                    // 处理下班卡缺卡情况
+                    // 过滤当前时间在班次下班打卡时间之后5小时的数据   今日已过下班打卡时间5小时后的班次
+                    List<XpShift> shiftListFive = xpShifts.stream().filter(xpShift ->
+                            DateUtils.stringToLocalDateTime(LocalDate.now() + " " + xpShift.getEndTime() + ":00").plusHours(5).isBefore(LocalDateTime.now())).collect(Collectors.toList());
+                    List<Long> fiveIds = shiftListFive.stream().map(XpShift::getId).collect(Collectors.toList());
+                    if(!CollectionUtils.isEmpty(fiveIds)){
+                        log.info("========== 进入下班过期的班次 ==========");
+                        // 获取过期当前班次的排班明细  覆盖
+                        List<XpSchedulingDetail> fiveClockOutPlans = clockOutPlanList.stream().filter(xpSchedulingDetail -> fiveIds.contains(xpSchedulingDetail.getShiftId())).collect(Collectors.toList());
+                        List<Long> fiveFleetIdIn = fiveClockOutPlans.stream().map(XpSchedulingDetail::getFleetId).collect(Collectors.toList());
+                        // 查询所有车队的绑定人员
+                        if(!CollectionUtils.isEmpty(xpFleetOperations)){
+                            List<Long> operationsUserIdsFive = xpFleetOperations.stream().filter(x -> fiveFleetIdIn.contains(x.getFleetId()))
+                                    .map(XpFleetOperations::getOperationsUserId).distinct().collect(Collectors.toList());
+                            // 批量查询人员打卡信息
+                            List<XpClockIn> clockInListFive = xpClockInService.list(Wrappers.lambdaQuery(XpClockIn.class)
+                                    .eq(XpClockIn::getAppUserId, operationsUserIdsFive)
+                                    .isNull(XpClockIn::getClockOutTime));
+                            log.info("========== 获取到{}个人员没有下班打卡信息 ==========", clockInListFive.size());
+                            if(!CollectionUtils.isEmpty(clockInListFive)){
+                                for (XpClockIn xpClockIn : clockInListFive) {
+                                    xpClockIn.setClockOutTime(LocalDateTime.now());
+                                    xpClockIn.setClockOutResult(3);
+                                }
+                                xpClockInService.updateBatchById(clockInListFive);
+                                log.info("========== 修改为下班缺卡 ==========");
+                            }
+                        }
+                    }
+                }
+            }
+
         } catch (Exception e) {
             log.error("执行打卡检查任务执行失败", e);
         }

--
Gitblit v1.7.1