wlzboy
2025-12-23 355dda1f90c70ab04c4517688da37d1a4236f112
fix:优化保存
21个文件已修改
300 ■■■■■ 已修改文件
app/pages/index.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/task/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pagesTask/detail.vue 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/BigDecimalUtil.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/listener/TaskMessageListener.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysEmergencyTaskServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskAssigneeServiceImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusPushServiceImpl.java 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusSyncServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/utils/TaskStatusPushConverter.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/index.vue
@@ -510,7 +510,9 @@
                startLocation: task.departureAddress || task.startLocation || "未设置",
                endLocation: task.destinationAddress || task.endLocation || "未设置",
                startTime: task.plannedStartTime
                  ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                  ? (task.plannedStartTime.startsWith('1900') || task.plannedStartTime.startsWith('1970')
                    ? '未分配时间'
                    : formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm"))
                  : "未设置",
                assignee: task.assigneeName || "未分配",
                taskNo: task.taskCode || "未知编号",
app/pages/task/index.vue
@@ -168,7 +168,7 @@
              <!-- 任务编号和开始时间在同一行显示,但分开一些 -->
              <view class="task-code-row">
                <text class="task-code">{{ task.showTaskCode }}</text>
                <text class="task-time">出发时间:{{ task.startTime }}</text>
                <text class="task-time">{{ task.startTime }}</text>
              </view>
              <!-- 任务详细信息 -->
@@ -457,7 +457,9 @@
                task.destinationAddress || task.endLocation || "未设置"
              ),
              startTime: task.plannedStartTime
                ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                ? (task.plannedStartTime.startsWith('1900') || task.plannedStartTime.startsWith('1970')
                  ? '未分配时间'
                  : formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm"))
                : "未设置",
              assignee: task.assigneeName || "未分配",
            };
@@ -569,7 +571,9 @@
                task.destinationAddress || task.endLocation || "未设置"
              ),
              startTime: task.plannedStartTime
                ? formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm")
                ? (task.plannedStartTime.startsWith('1900') || task.plannedStartTime.startsWith('1970')
                  ? '未分配时间'
                  : formatDateTime(task.plannedStartTime, "YYYY-MM-DD HH:mm"))
                : "未设置",
              assignee: task.assigneeName || "未分配",
            };
app/pagesTask/detail.vue
@@ -535,9 +535,9 @@
          return '未设置'
        }
        const formatted = formatDateTime(this.taskDetail.plannedStartTime, 'YYYY-MM-DD HH:mm')
        // 如果年份是1900,表示无效日期,显示为未设置
        if (formatted && formatted.startsWith('1900')) {
          return '未设置'
        // 如果年份是1900或1970,表示无效日期,显示为未分配时间
        if (formatted && (formatted.startsWith('1900') || formatted.startsWith('1970'))) {
          return '未分配时间'
        }
        return formatted
      },
@@ -547,9 +547,9 @@
          return '未设置'
        }
        const formatted = formatDateTime(this.taskDetail.plannedEndTime, 'YYYY-MM-DD HH:mm')
        // 如果年份是1900,表示无效日期,显示为未设置
        if (formatted && formatted.startsWith('1900')) {
          return '未设置'
        // 如果年份是1900或1970,表示无效日期,显示为未分配时间
        if (formatted && (formatted.startsWith('1900') || formatted.startsWith('1970'))) {
          return '未分配时间'
        }
        return formatted
      },
@@ -559,9 +559,9 @@
          return '未设置'
        }
        const formatted = formatDateTime(this.taskDetail.actualStartTime, 'YYYY-MM-DD HH:mm')
        // 如果年份是1900,表示无效日期,显示为未设置
        if (formatted && formatted.startsWith('1900')) {
          return '未设置'
        // 如果年份是1900或1970,表示无效日期,显示为未分配时间
        if (formatted && (formatted.startsWith('1900') || formatted.startsWith('1970'))) {
          return '未分配时间'
        }
        return formatted
      },
@@ -571,9 +571,9 @@
          return '未设置'
        }
        const formatted = formatDateTime(this.taskDetail.actualEndTime, 'YYYY-MM-DD HH:mm')
        // 如果年份是1900,表示无效日期,显示为未设置
        if (formatted && formatted.startsWith('1900')) {
          return '未设置'
        // 如果年份是1900或1970,表示无效日期,显示为未分配时间
        if (formatted && (formatted.startsWith('1900') || formatted.startsWith('1970'))) {
          return '未分配时间'
        }
        return formatted
      }
ruoyi-admin/src/main/resources/application.yml
@@ -58,7 +58,7 @@
    basename: i18n/messages
  profiles:
    # 环境 dev|test|prod
    active: dev
    active: prod
  # 文件上传
  servlet:
    multipart:
ruoyi-common/src/main/java/com/ruoyi/common/utils/BigDecimalUtil.java
@@ -6,4 +6,60 @@
    public static Boolean isZero(BigDecimal bigDecimal) {
        return bigDecimal.compareTo(BigDecimal.ZERO) == 0;
    }
public static Boolean izBigZero(BigDecimal bigDecimal) {
    return bigDecimal != null && bigDecimal.compareTo(BigDecimal.ZERO) > 0;
}
        /**
         * 判断 num1 是否等于 num2
         */
        public static boolean equals(BigDecimal num1, BigDecimal num2) {
            if (num1 == null || num2 == null) {
                return false; // 或根据业务抛空指针异常
            }
            return num1.compareTo(num2) == 0;
        }
        /**
         * 判断 num1 是否大于 num2
         */
        public static boolean greaterThan(BigDecimal num1, BigDecimal num2) {
            if (num1 == null || num2 == null) {
                return false;
            }
            return num1.compareTo(num2) > 0;
        }
        /**
         * 判断 num1 是否大于等于 num2
         */
        public static boolean greaterThanOrEqual(BigDecimal num1, BigDecimal num2) {
            if (num1 == null || num2 == null) {
                return false;
            }
            return num1.compareTo(num2) >= 0;
        }
        /**
         * 判断 num1 是否小于 num2
         */
        public static boolean lessThan(BigDecimal num1, BigDecimal num2) {
            if (num1 == null || num2 == null) {
                return false;
            }
            return num1.compareTo(num2) < 0;
        }
        /**
         * 判断 num1 是否小于等于 num2
         */
        public static boolean lessThanOrEqual(BigDecimal num1, BigDecimal num2) {
            if (num1 == null || num2 == null) {
                return false;
            }
            return num1.compareTo(num2) <= 0;
        }
}
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java
@@ -123,10 +123,10 @@
     * cron表达式: 0 0/5 * * * ? (每5分钟执行一次)
     */
    public void syncTaskStatusFromLegacy() {
        log.info("开始执行任务状态同步定时任务(从旧系统到新系统)");
//        log.info("开始执行任务状态同步定时任务(从旧系统到新系统)");
        try {
            int successCount = taskStatusSyncService.batchSyncTaskStatusFromLegacy();
            log.info("任务状态同步完成,成功同步: {} 个任务", successCount);
//            log.info("任务状态同步完成,成功同步: {} 个任务", successCount);
        } catch (Exception e) {
            log.error("任务状态同步异常", e);
        }
ruoyi-system/src/main/java/com/ruoyi/system/listener/TaskMessageListener.java
@@ -418,6 +418,8 @@
        return content.toString();
    }
    @Autowired
    private ITaskStatusSyncService taskStatusSyncService;
    /**
     * 监听任务状态变更事件
     * 
@@ -426,10 +428,27 @@
    @Async
    @EventListener
    public void handleTaskStatusChangedEvent(TaskStatusChangedEvent event) {
        sendTaskStatusToLocal(event);
        sendTaskStatusToLegacy(event.getTaskId());
    }
    private void sendTaskStatusToLegacy(Long taskId) {
        try{
            taskStatusSyncService.syncTaskStatusFromLegacy(taskId);
        }catch (Exception e){
            log.error("任务状态同步到旧系统异常 taskId:{}",taskId, e);
        }
    }
    private  void sendTaskStatusToLocal(TaskStatusChangedEvent event) {
        try {
            log.info("收到任务状态变更事件,任务ID:{},旧状态:{},新状态:{}", 
                    event.getTaskId(), event.getOldStatus(), event.getNewStatus());
            //发起状态同步
            // 构建状态变更内容
            String statusContent = getStatusChangeContent(event.getNewStatus(), event.getNewStatusDesc());
            
ruoyi-system/src/main/java/com/ruoyi/system/service/IVehicleInfoService.java
@@ -15,6 +15,7 @@
     */
    public VehicleInfo selectVehicleInfoById(Long vehicleId);
    public VehicleInfo selectVehicleInfoByCarId(Integer carId);
    /**
     * 通过车牌号查询车辆信息
     * 
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -477,8 +477,8 @@
               createTaskVo.setServiceOrdVIP("0");
           }
           Integer FromHQ2_is = MapValueUtils.getIntegerValue(order, "FromHQ2_is");
           if(IntegerUtil.isNotEmpty(FromHQ2_is)){
           Integer FromHQ_is = MapValueUtils.getIntegerValue(order, "FromHQ_is");
           if(IntegerUtil.isNotEmpty(FromHQ_is)){
               createTaskVo.setFromHQ2_is("1");
           }else{
               createTaskVo.setFromHQ2_is("0");
@@ -598,7 +598,7 @@
                String carLicense = legacyTransferSyncMapper.selectCarLicenseByCarID(carID);
                if (StringUtils.isNotEmpty(carLicense)) {
                    // 根据车牌号查询新系统中的车辆ID
                    log.info("转运任务,ServiceOrdID:{},车辆车牌:{}",serviceOrdID,carLicense);
//                    log.info("转运任务,ServiceOrdID:{},车辆车牌:{}",serviceOrdID,carLicense);
//                    log.debug("车辆车牌号: {}", carLicense);
                    
                    // 首先尝试通过VehicleInfoMapper查询车辆信息
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysEmergencyTaskServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.system.service.impl;
import com.ruoyi.common.utils.BigDecimalUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysTask;
@@ -433,7 +434,7 @@
        }
        
        // 更新费用信息
        if (createVO.getDistance() != null) {
        if (createVO.getDistance() != null && BigDecimalUtil.izBigZero(createVO.getDistance())) {
            existingInfo.setTransferDistance(createVO.getDistance());
        }
        if (createVO.getPrice() != null) {
@@ -480,6 +481,7 @@
        existingInfo.setServiceOrdVip(createVO.getServiceOrdVIP());
        existingInfo.setFromHq2Is(createVO.getFromHQ2_is());
        // 执行更新
        sysTaskEmergencyMapper.updateSysTaskEmergency(existingInfo);
    }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskAssigneeServiceImpl.java
@@ -74,7 +74,9 @@
            return false;
        }
        try {
            List<Long> newAssigneeIds = newAssignees.stream().map(TaskCreateVO.AssigneeInfo::getUserId).collect(Collectors.toList());
            //过滤分配人不要出现重复
            List<Long> newAssigneeIds = newAssignees.stream().map(TaskCreateVO.AssigneeInfo::getUserId).distinct().collect(Collectors.toList());
            // 查询现有的执行人员
            List<SysTaskAssignee> existingAssignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
@@ -83,11 +85,17 @@
            List<Long> assigneesToDelete = existingAssignees.stream().map(SysTaskAssignee::getUserId)
                    .filter(id -> !newAssigneeIds.contains(id))
                    .collect(Collectors.toList());
            Map<Long, TaskCreateVO.AssigneeInfo> addedAssignees = new HashMap<>();
            for(TaskCreateVO.AssigneeInfo assigneeInfo:newAssignees){
                Long userId = assigneeInfo.getUserId();
                if(!existingAssigneeIds.contains(userId) && !addedAssignees.containsKey(userId)){
                    addedAssignees.put(userId, assigneeInfo);
                }
            }
            // 找出需要添加的执行人(在新列表中存在但在数据库中不存在)
            List<TaskCreateVO.AssigneeInfo> assigneesToAdd = newAssignees.stream()
                    .filter(assignee -> !existingAssigneeIds.contains(assignee.getUserId()))
                    .collect(Collectors.toList());
            List<TaskCreateVO.AssigneeInfo> assigneesToAdd = new ArrayList<>(addedAssignees.values());
            //我们要对assigneesToAdd进行去重处理,对userId进行去重
            boolean hasChanges = !assigneesToDelete.isEmpty() || !assigneesToAdd.isEmpty();
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -267,7 +267,6 @@
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
//        task.setIsHeadPush(isTaskHeaderPush(userId,task.getDeptId())?"1":"0");
        
        // 设置地址和坐标信息
        setAddressAndCoordinatesFromVO(task, createVO);
@@ -372,15 +371,6 @@
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
//        Boolean isHeadPush=this.isTaskHeaderPush(userId, deptId);
//        if(isHeadPush){
//            task.setIsHeadPush("1");
//        }else{
//            task.setIsHeadPush("0");
//        }
        // 设置地址和坐标信息
        setAddressAndCoordinatesFromVO(task, createVO);
        // 设置任务类型特定信息(注:insertTask使用plannedStartTime而非serviceTime)
@@ -480,7 +470,6 @@
     * @return 结果
     */
    @Override
    @Transactional
    public int updateSysTask(TaskUpdateVO updateVO, Boolean updateFromLegacy) {
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(updateVO.getTaskId());
        if (task == null) {
@@ -520,7 +509,7 @@
        }
        Boolean hasSetDepartureFlag=false;
        //设置总部推送
//        task.setIsHeadPush(this.isTaskHeaderPush(task.getCreatorId(), task.getDeptId())?"1":"0");
        // 自动获取出发地GPS坐标(如果更新了地址但缺失坐标)
        if (updateVO.getDepartureAddress() != null && 
            (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null) && 
@@ -820,7 +809,8 @@
            Boolean hasEmergencyInfo = updateVO.getHospitalOut() != null || updateVO.getHospitalIn() != null || updateVO.getPatient() != null
                    || updateVO.getPrice() != null || updateVO.getDistance() != null;
//            Boolean isHeadPush=isTaskHeaderPush(task.getCreatorId(),task.getDeptId());
//            updateVO.setFromHQ2_is(isHeadPush?"1":"0");
            // 使用TaskCreateVO的字段来更新急救转运信息
            if (hasEmergencyInfo) {
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusPushServiceImpl.java
@@ -51,13 +51,13 @@
    @Transactional
    public boolean pushTaskStatusToLegacy(Long taskId) {
        if (!legacyConfig.isEnabled()) {
            log.info("旧系统同步已禁用,跳过状态推送,任务ID: {}", taskId);
//            log.info("旧系统同步已禁用,跳过状态推送,任务ID: {}", taskId);
            return false;
        }
        
        try {
            // 查询任务信息
            log.debug("【新推旧】查询任务ID: {}", taskId);
//            log.debug("【新推旧】查询任务ID: {}", taskId);
            SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
            if (task == null) {
                log.error("【新推旧】任务不存在,任务ID: {}", taskId);
@@ -66,7 +66,7 @@
            
            // 只推送急救转运任务
            if (!"EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                log.info("非急救转运任务,跳过状态推送,任务ID: {}", taskId);
//                log.info("非急救转运任务,跳过状态推送,任务ID: {}", taskId);
                return false;
            }
            
@@ -93,8 +93,8 @@
            // 转换为旧系统状态码
            Integer targetStatusCode = TaskStatusPushConverter.convertToLegacyStatus(newTaskStatus);
            if (targetStatusCode == null) {
                log.debug("【新推旧】任务状态不需要推送到旧系统,任务ID: {}, 状态: {}",
                    taskId, newTaskStatus.getInfo());
//                log.debug("【新推旧】任务状态不需要推送到旧系统,任务ID: {}, 状态: {}",
//                    taskId, newTaskStatus.getInfo());
                return false;
            }
            
@@ -110,22 +110,22 @@
            // 判断是否需要更新(包含防止状态倒退的检查)
            // 如果旧系统状态已经 >= 新系统要推送的状态,说明旧系统状态更新,新系统落后,不应该推送
            if (!TaskStatusPushConverter.shouldUpdateLegacyStatus(targetStatusCode, currentLegacyStatus)) {
                log.info("【新推旧】新系统状态落后或等于旧系统状态,跳过推送,任务ID: {}, 新系统状态: {} ({}→{}), 旧系统状态: {} ({})",
                    taskId,
                    task.getTaskStatus(), newTaskStatus.getInfo(), targetStatusCode,
                    currentLegacyStatus, TaskStatusPushConverter.getLegacyStatusDescription(currentLegacyStatus));
//                log.info("【新推旧】新系统状态落后或等于旧系统状态,跳过推送,任务ID: {}, 新系统状态: {} ({}→{}), 旧系统状态: {} ({})",
//                    taskId,
//                    task.getTaskStatus(), newTaskStatus.getInfo(), targetStatusCode,
//                    currentLegacyStatus, TaskStatusPushConverter.getLegacyStatusDescription(currentLegacyStatus));
                return true; // 返回true,因为这不算失败,只是不需要推送
            }
            
            // 推送状态到旧系统
            boolean result = updateLegacyTaskStatus(emergency.getLegacyDispatchOrdId(), targetStatusCode);
            
            if (result) {
                log.info("【新推旧】任务状态推送成功,任务ID: {}, DispatchOrdID: {}, 旧状态: {} ({}), 新状态: {} ({})",
                    taskId, emergency.getLegacyDispatchOrdId(),
                    currentLegacyStatus, TaskStatusPushConverter.getLegacyStatusDescription(currentLegacyStatus),
                    targetStatusCode, TaskStatusPushConverter.getLegacyStatusDescription(targetStatusCode));
            } else {
            if (!result) {
//                log.info("【新推旧】任务状态推送成功,任务ID: {}, DispatchOrdID: {}, 旧状态: {} ({}), 新状态: {} ({})",
//                    taskId, emergency.getLegacyDispatchOrdId(),
//                    currentLegacyStatus, TaskStatusPushConverter.getLegacyStatusDescription(currentLegacyStatus),
//                    targetStatusCode, TaskStatusPushConverter.getLegacyStatusDescription(targetStatusCode));
//            } else {
                log.error("【新推旧】任务状态推送失败,任务ID: {}, DispatchOrdID: {}",
                    taskId, emergency.getLegacyDispatchOrdId());
            }
@@ -161,11 +161,11 @@
                List<SysTaskEmergency> syncedTasks = sysTaskEmergencyService.selectSyncedTasksForStatusUpdate(offset, pageSize);
                
                if (syncedTasks == null || syncedTasks.isEmpty()) {
                    log.info("【新推旧】没有更多需要推送状态的任务,offset: {}", offset);
//                    log.info("【新推旧】没有更多需要推送状态的任务,offset: {}", offset);
                    break; // 没有更多数据,退出循环
                }
                
                log.info("【新推旧】开始推送状态第 {} 页,任务数量: {}", (offset / pageSize) + 1, syncedTasks.size());
//                log.info("【新推旧】开始推送状态第 {} 页,任务数量: {}", (offset / pageSize) + 1, syncedTasks.size());
                
                int pageSuccessCount = 0;
                for (SysTaskEmergency emergency : syncedTasks) {
@@ -179,25 +179,25 @@
                        Thread.sleep(200); // 每个请求间隔0.2秒
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        log.warn("【新推旧】推送状态被中断");
//                        log.warn("【新推旧】推送状态被中断");
                        return totalSuccessCount + pageSuccessCount;
                    }
                }
                
                totalSuccessCount += pageSuccessCount;
                log.info("状态第 {} 页推送完成,总数: {}, 成功: {}",
                    (offset / pageSize) + 1, syncedTasks.size(), pageSuccessCount);
//                log.info("状态第 {} 页推送完成,总数: {}, 成功: {}",
//                    (offset / pageSize) + 1, syncedTasks.size(), pageSuccessCount);
                
                // 如果本页数据少于每页大小,说明已经是最后一页
                if (syncedTasks.size() < pageSize) {
                    log.info("【新推旧】已到达最后一页,状态推送结束");
//                    log.info("【新推旧】已到达最后一页,状态推送结束");
                    break;
                }
                
                offset += pageSize; // 下一页
            }
            
            log.info("【新推旧】批量推送任务状态完成,总成功数: {}", totalSuccessCount);
//            log.info("【新推旧】批量推送任务状态完成,总成功数: {}", totalSuccessCount);
            return totalSuccessCount;
            
        } catch (Exception e) {
@@ -217,13 +217,13 @@
        try {
            // 直接通过Service调用Mapper更新SQL Server数据库
            int rows = dispatchOrdService.updateDispatchOrdState(dispatchOrdId, statusCode);
            log.debug("更新旧系统状态,DispatchOrdID: {}, StateInt: {}", dispatchOrdId, statusCode);
//            log.debug("更新旧系统状态,DispatchOrdID: {}, StateInt: {}", dispatchOrdId, statusCode);
            if (rows > 0) {
                log.debug("更新旧系统状态成功,DispatchOrdID: {}, StateInt: {}",
                    dispatchOrdId, statusCode);
//                log.debug("更新旧系统状态成功,DispatchOrdID: {}, StateInt: {}",
//                    dispatchOrdId, statusCode);
                return true;
            } else {
                log.warn("更新旧系统状态失败,未找到对应调度单,DispatchOrdID: {}", dispatchOrdId);
//                log.warn("更新旧系统状态失败,未找到对应调度单,DispatchOrdID: {}", dispatchOrdId);
                return false;
            }
            
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusSyncServiceImpl.java
@@ -108,7 +108,7 @@
    @Override
    public int batchSyncTaskStatusFromLegacy() {
        if (!legacyConfig.isEnabled()) {
            log.info("旧系统同步已禁用");
//            log.info("旧系统同步已禁用");
            return 0;
        }
        
@@ -122,11 +122,11 @@
                List<SysTaskEmergency> syncedTasks = sysTaskEmergencyService.selectSyncedTasksForStatusUpdate(offset, pageSize);
                
                if (syncedTasks == null || syncedTasks.isEmpty()) {
                    log.info("没有更多需要同步状态的任务,offset: {}", offset);
//                    log.info("没有更多需要同步状态的任务,offset: {}", offset);
                    break; // 没有更多数据,退出循环
                }
                
                log.info("开始同步状态第 {} 页,任务数量: {}", (offset / pageSize) + 1, syncedTasks.size());
//                log.info("开始同步状态第 {} 页,任务数量: {}", (offset / pageSize) + 1, syncedTasks.size());
                
                // 2. 提取调度单ID列表
                List<Long> dispatchOrdIDs = new ArrayList<>();
@@ -141,7 +141,7 @@
                }
                
                if (dispatchOrdIDs.isEmpty()) {
                    log.warn("本页没有有效的调度单ID");
//                    log.warn("本页没有有效的调度单ID");
                    offset += pageSize;
                    continue;
                }
@@ -178,7 +178,7 @@
                    // 获取旧系统状态
                    Integer legacyStatus = dispatchIdToStateMap.get(dispatchOrdId);
                    if (legacyStatus == null) {
                        log.warn("未找到调度单状态,DispatchOrdID: {}", dispatchOrdId);
//                        log.warn("未找到调度单状态,DispatchOrdID: {}", dispatchOrdId);
                        continue;
                    }
                    
@@ -190,19 +190,19 @@
                }
                
                totalSuccessCount += pageSuccessCount;
                log.info("状态第 {} 页同步完成,总数: {}, 成功: {}",
                    (offset / pageSize) + 1, syncedTasks.size(), pageSuccessCount);
//                log.info("状态第 {} 页同步完成,总数: {}, 成功: {}",
//                    (offset / pageSize) + 1, syncedTasks.size(), pageSuccessCount);
//
                // 如果本页数据少于每页大小,说明已经是最后一页
                if (syncedTasks.size() < pageSize) {
                    log.info("已到达最后一页,状态同步结束");
//                    log.info("已到达最后一页,状态同步结束");
                    break;
                }
                
                offset += pageSize; // 下一页
            }
            
            log.info("批量同步任务状态完成,总成功数: {}", totalSuccessCount);
//            log.info("批量同步任务状态完成,总成功数: {}", totalSuccessCount);
            return totalSuccessCount;
            
        } catch (Exception e) {
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleInfoServiceImpl.java
@@ -47,6 +47,11 @@
        return vehicleInfoMapper.selectVehicleInfoWithDeptsById(vehicleId);
    }
    @Override
    public VehicleInfo selectVehicleInfoByCarId(Integer carId) {
        return vehicleInfoMapper.selectVehicleInfoByCarId(carId);
    }
    /**
     * 查询车辆信息(包含多分公司关联)
     * 
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleMileageStatsServiceImpl.java
@@ -473,9 +473,9 @@
            List<TaskTimeInterval> taskIntervals = vehicleMileageStatsMapper.selectTaskTimeIntervals(vehicleId, dayStart, dayEnd);
            Integer taskCount = taskIntervals != null ? taskIntervals.size() : 0;
            logger.info("车辆ID: {} 在日期: {} 有 {} 个任务", vehicleId, statDate, taskCount);
//            logger.info("车辆ID: {} 在日期: {} 有 {} 个任务", vehicleId, statDate, taskCount);
            List<VehicleGpsSegmentMileage> mileages = this.getTaskDistanceMileage(vehicleId, dayStart, dayEnd).stream().filter(e -> e.getSegmentDistance() != null && e.getSegmentDistance().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
            logger.info("车辆ID: {} 在日期: {} 有 {} 个分段里程数据", vehicleId, statDate, mileages.size());
//            logger.info("车辆ID: {} 在日期: {} 有 {} 个分段里程数据", vehicleId, statDate, mileages.size());
            Integer totalGpsPoints = mileages != null ? mileages.stream()
                .filter(segment -> segment.getGpsPointCount() != null)
                .mapToInt(VehicleGpsSegmentMileage::getGpsPointCount)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java
@@ -46,7 +46,9 @@
    @Autowired
    private VehicleInfoMapper vehicleInfoMapper;
    private VehicleInfo findVehicleByCarId(Integer carId){
        return vehicleInfoService.selectVehicleInfoByCarId(carId);
    }
    /**
     * 同步车辆数据到MySQL
     * 
@@ -87,6 +89,11 @@
                    // 查询车辆是否存在
                    VehicleInfo existingVehicle = findVehicleByPlateNumber(plateNumber);
                    if(existingVehicle==null){
                        existingVehicle = findVehicleByCarId(vehicleDTO.getCarId());
                    }
                    // 解析所有分公司ID(CarOrdClass可能包含多个编码,如:HB,TI)
                    List<VehicleDept> vehicleDepts = parseVehicleDepts(vehicleDTO.getCarOrdClass());
@@ -215,6 +222,9 @@
        return license;
    }
    private VehicleInfo findByCarId(Integer carId){
        return vehicleInfoService.selectVehicleInfoByCarId(carId);
    }
    /**
     * 根据车牌号查找车辆(模糊匹配)
     * 
ruoyi-system/src/main/java/com/ruoyi/system/utils/TaskStatusPushConverter.java
@@ -40,7 +40,7 @@
            case PENDING:        // 待处理 - 不同步
            case ARRIVED:        // 已到达 - 不同步
            default:
                log.debug("新系统状态不需要同步到旧系统: {}", taskStatus.getInfo());
//                log.debug("新系统状态不需要同步到旧系统: {}", taskStatus.getInfo());
                return null;
        }
    }
@@ -55,18 +55,18 @@
     */
    public static boolean shouldUpdateLegacyStatus(Integer newStatusCode, Integer oldStatusCode) {
        if (newStatusCode == null || oldStatusCode == null) {
            log.warn("状态码为空,跳过更新,新状态码: {}, 旧状态码: {}", newStatusCode, oldStatusCode);
//            log.warn("状态码为空,跳过更新,新状态码: {}, 旧状态码: {}", newStatusCode, oldStatusCode);
            return false;
        }
        
        // 防止状态倒退:旧系统状态 >= 新系统要推送的状态时,不更新
        // 原因:可能是旧系统已经处理了更新的状态,而新系统由于时间差还没有同步到
        if (oldStatusCode >= newStatusCode) {
            log.info("旧系统状态({}) >= 新系统目标状态({}),跳过推送,防止状态倒退," +
                "旧系统: {} ({}), 新系统目标: {} ({})",
                oldStatusCode, newStatusCode,
                oldStatusCode, getLegacyStatusDescription(oldStatusCode),
                newStatusCode, getLegacyStatusDescription(newStatusCode));
//            log.info("旧系统状态({}) >= 新系统目标状态({}),跳过推送,防止状态倒退," +
//                "旧系统: {} ({}), 新系统目标: {} ({})",
//                oldStatusCode, newStatusCode,
//                oldStatusCode, getLegacyStatusDescription(oldStatusCode),
//                newStatusCode, getLegacyStatusDescription(newStatusCode));
            return false;
        }
        
@@ -74,17 +74,17 @@
        if (oldStatusCode >= 8) {
            // 旧系统已经是完成态(8,9,10),不应该被任何中间状态覆盖
            if (newStatusCode < 8) {
                log.warn("旧系统已是终态({})(:{}),拒绝推送中间状态({})(:{})",
                    oldStatusCode, getLegacyStatusDescription(oldStatusCode),
                    newStatusCode, getLegacyStatusDescription(newStatusCode));
//                log.warn("旧系统已是终态({})(:{}),拒绝推送中间状态({})(:{})",
//                    oldStatusCode, getLegacyStatusDescription(oldStatusCode),
//                    newStatusCode, getLegacyStatusDescription(newStatusCode));
                return false;
            }
        }
        
        log.debug("允许推送状态,旧系统: {} ({}), 新系统目标: {} ({})",
            oldStatusCode, getLegacyStatusDescription(oldStatusCode),
            newStatusCode, getLegacyStatusDescription(newStatusCode));
//        log.debug("允许推送状态,旧系统: {} ({}), 新系统目标: {} ({})",
//            oldStatusCode, getLegacyStatusDescription(oldStatusCode),
//            newStatusCode, getLegacyStatusDescription(newStatusCode));
//
        return true;
    }
    
ruoyi-system/src/main/resources/mapper/system/LegacyTransferSyncMapper.xml
@@ -47,7 +47,7 @@
        <result property="DispatchOrdNo" column="DispatchOrdNo" />
        <result property="DispatchOrdClass" column="DispatchOrdClass" />
        <result property="ServiceOrdVIP" column="ServiceOrdVIP" />
        <result property="FromHQ2_is" column="FromHQ2_is" />
        <result property="FromHQ_is" column="FromHQ_is" />
        <result property="DispatchOrd_NS_Time" column="DispatchOrd_NS_Time" />
    </resultMap>
@@ -65,7 +65,7 @@
            a.ServiceOrdID,
            a.Old_ServiceOrdID_TXT,
            a.ServiceOrdNo,
            a.FromHQ2_is,
            a.FromHQ_is,
            a.ServiceOrdVIP,
            a.ServiceOrdTraVia,
            a.ServiceOrdApptDate,
@@ -119,7 +119,7 @@
            a.ServiceOrdID,
            a.Old_ServiceOrdID_TXT,
            a.ServiceOrdTraVia,
             a.FromHQ2_is,
            a.FromHQ_is,
            a.ServiceOrdVIP,
            a.ServiceOrdNo,
            a.ServiceOrdApptDate,
@@ -171,7 +171,7 @@
        SELECT
        a.ServiceOrdID,
        a.Old_ServiceOrdID_TXT,
        a.FromHQ2_is,
        a.FromHQ_is,
        a.ServiceOrdVIP,
        a.ServiceOrdTraVia,
        a.ServiceOrdNo,
ruoyi-system/src/main/resources/mapper/system/SysTaskMapper.xml
@@ -265,7 +265,6 @@
            <if test="creatorId != null">#{creatorId},</if>
            <if test="assigneeId != null">#{assigneeId},</if>
            <if test="deptId != null">#{deptId},</if>
            <if test="isHeadPush != null">#{isHeadPush},</if>
            <if test="createTime != null">#{createTime},</if>
            now(),
            <if test="createBy != null">#{createBy},</if>
ruoyi-system/src/main/resources/mapper/system/VehicleGpsSegmentMileageMapper.xml
@@ -62,7 +62,11 @@
    </select>
    <select id="selectSegmentsByDateRange" resultMap="VehicleGpsSegmentMileageResult">
        <include refid="selectVehicleGpsSegmentMileageVo"/>
        SELECT segment_id, vehicle_id, vehicle_no, segment_start_time, segment_end_time,
        start_longitude, start_latitude, end_longitude, end_latitude,
        segment_distance, gps_point_count, task_id, task_code
        FROM tb_vehicle_gps_segment_mileage
        WHERE vehicle_id = #{vehicleId}
          AND segment_start_time &lt;= #{endDate}
          AND segment_end_time &gt;= #{startDate}