wlzboy
2025-12-23 0a3eed02e78dfeeb7763a4b62992eefcd1f5a0ca
feat: 优化状态变更时实时推送
15个文件已修改
189 ■■■■ 已修改文件
app/pages/index.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/utils/taskValidator.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | 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 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/IDispatchOrdService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ITaskStatusPushService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | 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 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusPushServiceImpl.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusSyncServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskSyncUtilService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/pages/index.vue
@@ -243,6 +243,7 @@
import { getUnreadCount } from "@/api/message";
import { formatDateTime } from "@/utils/common";
import subscribeManager from "@/utils/subscribe";
import { checkTaskCanDepart } from "@/utils/taskValidator";
export default {
  data() {
@@ -613,16 +614,96 @@
    },
    // 处理任务操作
    handleTaskAction(task, action) {
    async handleTaskAction(task, action) {
      switch (action) {
        case "depart":
          // 出发 -> 状态变为出发中
          this.$modal
            .confirm("确定要出发吗?")
            .then(() => {
              this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
            })
            .catch(() => {});
          // 显示加载提示
          uni.showLoading({
            title: "检查任务状态...",
          });
          try {
            // 调用工具类检查任务是否可以出发(包含基本校验和冲突检查)
            const checkResult = await checkTaskCanDepart(task);
            uni.hideLoading();
            console.log("出发检查结果:", checkResult);
            console.log("valid:", checkResult.valid);
            console.log("conflicts:", checkResult.conflicts);
            if (!checkResult.valid) {
              // 校验失败,显示提示信息并提供跳转选项
              const conflicts = checkResult.conflicts || [];
              const conflictInfo = conflicts.length > 0 ? conflicts[0] : null;
              console.log("冲突信息:", conflictInfo);
              // 如果有冲突任务信息,提供跳转按钮
              if (conflictInfo && conflictInfo.taskId) {
                console.log(
                  "显示带跳转按钮的弹窗,任务ID:",
                  conflictInfo.taskId
                );
                const conflictTaskId = conflictInfo.taskId;
                const message =
                  checkResult.message || conflictInfo.message || "存在冲突任务";
                uni.showModal({
                  title: "提示",
                  content: message,
                  confirmText: "去处理",
                  cancelText: "知道了",
                  success: function (res) {
                    console.log("弹窗点击结果:", res);
                    if (res.confirm) {
                      // 用户点击"现在去处理",跳转到冲突任务详情页
                      console.log("准备跳转到任务详情页:", conflictTaskId);
                      uni.navigateTo({
                        url: `/pagesTask/detail?id=${conflictTaskId}`,
                      });
                    }
                  },
                  fail: function (err) {
                    console.error("显示弹窗失败:", err);
                  },
                });
              } else {
                // 没有冲突任务ID,只显示提示
                console.log("显示普通提示弹窗");
                uni.showModal({
                  title: "提示",
                  content: checkResult.message || "任务校验失败",
                  showCancel: false,
                  confirmText: "知道了",
                  fail: function (err) {
                    console.error("显示弹窗失败:", err);
                  },
                });
              }
              return;
            }
            // 所有检查通过,可以出发
            this.$modal
              .confirm("确定要出发吗?")
              .then(() => {
                this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
              })
              .catch(() => {});
          } catch (error) {
            uni.hideLoading();
            console.error("检查任务状态失败:", error);
            // 检查失败时,仍然允许出发
            this.$modal
              .confirm("检查任务状态失败,是否继续出发?")
              .then(() => {
                this.updateTaskStatus(task.taskId, "DEPARTING", "任务已出发");
              })
              .catch(() => {});
          }
          break;
        case "cancel":
app/utils/taskValidator.js
@@ -97,8 +97,8 @@
    }
  }
  // 检查是否为无效时间(1900年)
  if (task.plannedStartTime.startsWith('1900')) {
  // 检查是否为无效时间(1900年或1970年)
  if (task.plannedStartTime.startsWith('1900') || task.plannedStartTime.startsWith('1970')) {
    return {
      valid: false,
      message: '任务的转运时间无效',
ruoyi-admin/src/main/resources/application.yml
@@ -58,7 +58,7 @@
    basename: i18n/messages
  profiles:
    # 环境 dev|test|prod
    active: prod
    active: dev
  # 文件上传
  servlet:
    multipart:
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
@@ -103,7 +103,7 @@
        try
        {
            String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url;
            log.info("sendGet - {}", urlNameString);
//            log.info("sendGet - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept", "*/*");
@@ -116,7 +116,7 @@
            {
                result.append(line);
            }
            log.info("recv - {}", result);
//            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacySystemSyncTask.java
@@ -63,10 +63,10 @@
     * cron表达式: 0 0/10 * * * ? (每10分钟执行一次)
     */
    public void syncPendingTasks() {
        log.info("开始执行旧系统任务同步定时任务");
//        log.info("开始执行旧系统任务同步定时任务");
        try {
            int successCount = legacySystemSyncService.batchSyncPendingTasks();
            log.info("旧系统任务同步完成,成功同步: {} 个任务", successCount);
//            log.info("旧系统任务同步完成,成功同步: {} 个任务", successCount);
        } catch (Exception e) {
            log.error("旧系统任务同步异常", e);
        }
ruoyi-system/src/main/java/com/ruoyi/system/listener/TaskMessageListener.java
@@ -65,6 +65,9 @@
    @Autowired
    private ISysTaskAssigneeService taskAssigneeService;
    @Autowired
    private ITaskStatusPushService taskStatusPushService;
    @Async
    @EventListener
    public void handleTaskDispatchEvent(TaskDispatchSyncEvent event) {
@@ -436,7 +439,8 @@
    private void sendTaskStatusToLegacy(Long taskId) {
        try{
            taskStatusSyncService.syncTaskStatusFromLegacy(taskId);
            log.info("任务状态同步到旧系统开始 taskId:{}",taskId);
           taskStatusPushService.pushTaskStatusToLegacy(taskId);
        }catch (Exception e){
            log.error("任务状态同步到旧系统异常 taskId:{}",taskId, e);
        }
ruoyi-system/src/main/java/com/ruoyi/system/service/IDispatchOrdService.java
@@ -1,5 +1,7 @@
package com.ruoyi.system.service;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.system.domain.DictionaryCondition;
import com.ruoyi.system.domain.DispatchOrd;
@@ -10,6 +12,7 @@
 * 
 * @author ruoyi
 */
@DataSource(DataSourceType.SQLSERVER)
public interface IDispatchOrdService {
    /**
     * 根据服务订单ID查询调度订单
ruoyi-system/src/main/java/com/ruoyi/system/service/ITaskStatusPushService.java
@@ -1,5 +1,8 @@
package com.ruoyi.system.service;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
/**
 * 任务状态推送Service接口
 * 负责将新系统的任务状态推送到旧系统
@@ -7,6 +10,7 @@
 * @author ruoyi
 * @date 2024-01-16
 */
public interface ITaskStatusPushService {
    
    /**
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java
@@ -96,7 +96,7 @@
    @Override
    public int batchSyncPendingTasks() {
        if (!legacyConfig.isEnabled()) {
            log.info("旧系统同步已禁用");
//            log.info("旧系统同步已禁用");
            return 0;
        }
        
@@ -110,7 +110,7 @@
                List<SysTaskEmergency> pendingTasks = sysTaskEmergencyService.selectPendingSyncTasks(offset, pageSize);
                
                if (pendingTasks == null || pendingTasks.isEmpty()) {
                    log.info("没有更多需要同步的任务,offset: {}", offset);
//                    log.info("没有更多需要同步的任务,offset: {}", offset);
                    break; // 没有更多数据,退出循环
                }
                
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -619,7 +619,7 @@
                                List<Long> vehicleIds = new ArrayList<>();
                                vehicleIds.add(vehicleInfo.getVehicleId());
                                createTaskVo.setVehicleIds(vehicleIds);
                                log.debug("转运任务,ServiceOrdID:{} 通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}",serviceOrdID, vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
//                                log.debug("转运任务,ServiceOrdID:{} 通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}",serviceOrdID, vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
                            } else {
                                log.warn("转运任务,ServiceOrdID:{} 未找到对应的车辆信息: car_id={}, vehicle_no={}",serviceOrdID, carID, carLicense);
                            }
@@ -632,7 +632,7 @@
                            List<Long> vehicleIds = new ArrayList<>();
                            vehicleIds.add(vehicleInfo.getVehicleId());
                            createTaskVo.setVehicleIds(vehicleIds);
                            log.debug("通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
//                            log.debug("通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
                        } else {
                            log.warn("未找到对应的车辆信息: vehicle_no={}", carLicense);
                        }
@@ -829,7 +829,7 @@
                return String.join(",", diseaseIds);
            }
            
            log.info("查询到病情信息,服务单ID: {}, 病情数量: {}", serviceOrdID, diseaseIds != null ? diseaseIds.size() : 0);
//            log.info("查询到病情信息,服务单ID: {}, 病情数量: {}", serviceOrdID, diseaseIds != null ? diseaseIds.size() : 0);
            return null;
        } catch (Exception e) {
            log.error("查询病情信息异常,服务单ID: {}", serviceOrdID, e);
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysEmergencyTaskServiceImpl.java
@@ -327,7 +327,7 @@
            return;
        }
        
        log.info("更新转运任务 taskId:{}", existingInfo.getTaskId());
//        log.info("更新转运任务 taskId:{}", existingInfo.getTaskId());
        
        // 更新患者信息
        if (createVO.getPatient() != null) {
@@ -383,7 +383,7 @@
                        if (coords != null) {
                            existingInfo.setHospitalOutLongitude(BigDecimal.valueOf(coords.get("lng")));
                            existingInfo.setHospitalOutLatitude(BigDecimal.valueOf(coords.get("lat")));
                            log.info("转出医院GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
//                            log.info("转出医院GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                        }
                    } catch (Exception e) {
                        log.error("自动获取转出医院GPS坐标失败", e);
@@ -424,7 +424,7 @@
                        if (coords != null) {
                            existingInfo.setHospitalInLongitude(BigDecimal.valueOf(coords.get("lng")));
                            existingInfo.setHospitalInLatitude(BigDecimal.valueOf(coords.get("lat")));
                            log.info("转入医院GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
//                            log.info("转入医院GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                        }
                    } catch (Exception e) {
                        log.error("自动获取转入医院GPS坐标失败", e);
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -101,6 +101,10 @@
    @Autowired
    private ISysTaskVehicleService sysTaskVehicleService;
    @Autowired
    private ISysTaskAssigneeService assigneeService;
    @Override
    public Boolean dispatchSyncEvent(Long taskId) {
        SysTask task= sysTaskMapper.selectSysTaskByTaskId(taskId);
@@ -124,7 +128,7 @@
    public SysTask selectSysTaskByTaskId(Long taskId) {
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (task != null) {
            bindTaskAssign(task);
            // 加载急救转运扩展信息
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
@@ -139,6 +143,13 @@
        return task;
    }
    private void bindTaskAssign(SysTask task){
       List<SysTaskAssignee> assignees= assigneeService.getAssigneesByTaskId(task.getTaskId());
       if(assignees!=null && !assignees.isEmpty()) {
           task.setAssignees(assignees);
       }
    }
    /**
     * 查询任务管理列表
     * 
@@ -149,7 +160,7 @@
    public List<SysTask> selectSysTaskList(TaskQueryVO queryVO) {
        List<SysTask> tasks= sysTaskMapper.selectSysTaskList(queryVO);
        tasks.forEach(task -> {
            bindTaskAssign( task);
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId());
                task.setEmergencyInfo(emergencyInfo);
@@ -220,6 +231,7 @@
            if (task.getTaskCode() != null && task.getTaskCode().contains(taskCode)) {
                return true;
            }
            bindTaskAssign(task);
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType()) && task.getEmergencyInfo() != null) {
                String dispatchCode = task.getEmergencyInfo().getDispatchCode();
@@ -344,7 +356,6 @@
     * @return 结果
     */
    @Override
    @Transactional
    public int insertTask(TaskCreateVO createVO,Long serviceOrderId,Long dispatchOrderId, String serviceOrdNo, Long userId,String userName, Long deptId, Date createTime, Date updateTime) {
        SysTask task = new SysTask();
        if(createVO.getTaskCode()!=null){
@@ -446,10 +457,10 @@
    private void sendTaskAssigneeEvent(TaskCreateVO createVO,SysTask task,Long userId,String userName){
        List<Long> assigneeIds = createVO.getAssignees().stream()
                .map(assignee -> assignee.getUserId())
                .map(TaskCreateVO.AssigneeInfo::getUserId)
                .collect(Collectors.toList());
        List<String> assigneeNames = createVO.getAssignees().stream()
                .map(assignee -> assignee.getUserName())
                .map(TaskCreateVO.AssigneeInfo::getUserName)
                .collect(Collectors.toList());
        eventPublisher.publishEvent(new TaskAssignedEvent(
@@ -712,13 +723,6 @@
            task.setTaskCode(updateVO.getTaskCode());
        }
//        task.setDepartureLongitude(updateVO.getDepartureLongitude());
//        task.setDepartureLatitude(updateVO.getDepartureLatitude());
//        task.setDestinationLongitude(updateVO.getDestinationLongitude());
//        task.setDestinationLatitude(updateVO.getDestinationLatitude());
        Boolean modifyOutLongLat = false;
        // 自动获取出发地GPS坐标(如果地址变更且缺失坐标)
        if (task != null && updateVO.getDepartureAddress() != null
@@ -1190,7 +1194,7 @@
    public List<SysTask> selectMyTasks(Long userId) {
        List<SysTask> list = sysTaskMapper.selectMyTasks(userId);
        list.stream().forEach(task -> {
            bindTaskAssign(task);
            if(task.getTaskType().equals("EMERGENCY_TRANSFER")){
                task.setEmergencyInfo(sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId()));
            }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusPushServiceImpl.java
@@ -48,7 +48,6 @@
     * @return 是否推送成功
     */
    @Override
    @Transactional
    public boolean pushTaskStatusToLegacy(Long taskId) {
        if (!legacyConfig.isEnabled()) {
//            log.info("旧系统同步已禁用,跳过状态推送,任务ID: {}", taskId);
@@ -93,8 +92,8 @@
            // 转换为旧系统状态码
            Integer targetStatusCode = TaskStatusPushConverter.convertToLegacyStatus(newTaskStatus);
            if (targetStatusCode == null) {
//                log.debug("【新推旧】任务状态不需要推送到旧系统,任务ID: {}, 状态: {}",
//                    taskId, newTaskStatus.getInfo());
                log.debug("【新推旧】任务状态不需要推送到旧系统,任务ID: {}, 状态: {}",
                    taskId, newTaskStatus.getInfo());
                return false;
            }
            
@@ -120,12 +119,12 @@
            // 推送状态到旧系统
            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());
            }
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskStatusSyncServiceImpl.java
@@ -49,7 +49,6 @@
     * @return 是否同步成功
     */
    @Override
    @Transactional
    public boolean syncTaskStatusFromLegacy(Long taskId) {
        if (!legacyConfig.isEnabled()) {
            log.info("旧系统同步已禁用,跳过状态同步,任务ID: {}", taskId);
@@ -219,7 +218,6 @@
     * @param legacyStatus 旧系统状态码
     * @return 是否成功
     */
    @Transactional
    private boolean syncTaskStatusWithLegacyState(Long taskId, Integer legacyStatus) {
        try {
            // 查询任务信息
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TaskSyncUtilService.java
@@ -229,7 +229,7 @@
        params.put("ServiceOrdDepartureType", "1"); // 预约类型
        params.put("ConditionLevel", "0"); // 病重级别
        params.put("DirectionType", "0"); // 转运去向
        params.put("ServiceOrd_m", "1"); // 来源入口
        params.put("ServiceOrd_m", ""); // 来源入口
        params.put("FromHQ2_is", "0"); // 广州总部推送任务标记
        params.put("OrderPrice_Auto", "0"); // 订单自动报价参考值