wlzboy
2025-12-06 847a7773ef1a8ad418c6934d35b5f205a97c04d0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -2,15 +2,13 @@
import java.io.*;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.*;
import java.util.stream.Collectors;
import java.net.HttpURLConnection;
import java.net.URL;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.utils.TaskCodeGenerator;
import com.ruoyi.common.config.ImageUrlConfig;
@@ -31,15 +29,13 @@
import com.ruoyi.system.domain.SysTaskEmergency;
import com.ruoyi.system.domain.SysTaskWelfare;
import com.ruoyi.system.domain.SysTaskAssignee;
import com.ruoyi.system.domain.vo.TaskQueryVO;
import com.ruoyi.system.domain.vo.TaskCreateVO;
import com.ruoyi.system.domain.vo.TaskUpdateVO;
import com.ruoyi.system.domain.vo.TaskStatisticsVO;
import com.ruoyi.system.domain.enums.TaskStatus;
import com.ruoyi.system.domain.VehicleInfo;
import com.ruoyi.system.service.ISysTaskService;
import com.ruoyi.system.service.ILegacySystemSyncService;
import com.ruoyi.system.service.ISysTaskEmergencyService;
import com.ruoyi.system.service.ITaskAttachmentSyncService;
import com.ruoyi.system.service.IMapService;
import com.ruoyi.system.event.TaskCreatedEvent;
import com.ruoyi.system.event.TaskAssignedEvent;
import com.ruoyi.system.event.TaskStatusChangedEvent;
@@ -87,6 +83,9 @@
    private ILegacySystemSyncService legacySystemSyncService;
    
    @Autowired
    private ISysTaskEmergencyService sysTaskEmergencyService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    @Autowired
@@ -97,6 +96,9 @@
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired(required = false)
    private IMapService mapService;
    /**
     * 查询任务管理
@@ -142,6 +144,7 @@
    @Override
    @Transactional
    public int insertSysTask(TaskCreateVO createVO) {
        String username = SecurityUtils.getUsername();
        SysTask task = new SysTask();
        task.setTaskCode(generateTaskCode());
        task.setTaskType(createVO.getTaskType());
@@ -153,9 +156,9 @@
        task.setCreatorId(SecurityUtils.getUserId());
        // 优先使用前端传入的部门ID,如果没有则使用当前用户的部门ID
        task.setDeptId(createVO.getDeptId() != null ? createVO.getDeptId() : SecurityUtils.getDeptId());
        task.setCreateBy(SecurityUtils.getUsername());
        task.setCreateBy(username);
        task.setCreateTime(DateUtils.getNowDate());
        task.setUpdateBy(SecurityUtils.getUsername());
        task.setUpdateBy(username);
        task.setUpdateTime(DateUtils.getNowDate());
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
@@ -206,6 +209,44 @@
            task.setEstimatedDistance(createVO.getDistance());
        }
        
        // 自动获取出发地GPS坐标(如果缺失)
        if (task.getDepartureAddress() != null &&
            (task.getDepartureLongitude() == null || task.getDepartureLatitude() == null) &&
            mapService != null) {
            try {
                Map<String, Double> coords = mapService.geocoding(
                    task.getDepartureAddress(),
                    extractCityFromAddress(task.getDepartureAddress())
                );
                if (coords != null) {
                    task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
                    log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取出发地GPS坐标失败", e);
            }
        }
        // 自动获取目的地GPS坐标(如果缺失)
        if (task.getDestinationAddress() != null &&
            (task.getDestinationLongitude() == null || task.getDestinationLatitude() == null) &&
            mapService != null) {
            try {
                Map<String, Double> coords = mapService.geocoding(
                    task.getDestinationAddress(),
                    extractCityFromAddress(task.getDestinationAddress())
                );
                if (coords != null) {
                    task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
                    log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取目的地GPS坐标失败", e);
            }
        }
        int result = sysTaskMapper.insertSysTask(task);
        
        // 保存车辆关联信息
@@ -215,11 +256,11 @@
                taskVehicle.setTaskId(task.getTaskId());
                taskVehicle.setVehicleId(vehicleId);
                taskVehicle.setAssignTime(DateUtils.getNowDate());
                taskVehicle.setAssignBy(SecurityUtils.getUsername());
                taskVehicle.setAssignBy(username);
                taskVehicle.setStatus("ASSIGNED");
                taskVehicle.setCreateBy(SecurityUtils.getUsername());
                taskVehicle.setCreateBy(username);
                taskVehicle.setCreateTime(DateUtils.getNowDate());
                taskVehicle.setUpdateBy(SecurityUtils.getUsername());
                taskVehicle.setUpdateBy(username);
                taskVehicle.setUpdateTime(DateUtils.getNowDate());
                
                sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
@@ -228,17 +269,17 @@
        
        // 保存执行人员信息(包含角色类型)
        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
            saveTaskAssignees(task.getTaskId(), createVO.getAssignees());
            saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),username);
        }
        
        // 保存急救转运扩展信息
        if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) {
            saveEmergencyInfo(task.getTaskId(), createVO);
            saveEmergencyInfo(task.getTaskId(),username, createVO,null,null,null);
        }
        
        // 保存福祉车扩展信息
        if (result > 0 && "WELFARE".equals(createVO.getTaskType())) {
            saveWelfareInfo(task.getTaskId(), createVO);
            saveWelfareInfo(task.getTaskId(),SecurityUtils.getUsername(), createVO);
        }
        
        // 记录操作日志
@@ -296,6 +337,208 @@
    }
    /**
     * 新增任务管理(允许从外部传入用户信息、部门信息和时间信息)
     *
     * @param createVO 任务创建对象
     * @param userId 用户ID
     * @param deptId 部门ID
     * @param createTime 创建时间
     * @param updateTime 更新时间
     * @return 结果
     */
    @Override
    @Transactional
    public int insertTask(TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId, String serviceOrdNo, Long userId,String userName, Long deptId, Date createTime, Date updateTime) {
        SysTask task = new SysTask();
        if(createVO.getTaskCode()!=null){
            task.setTaskCode(createVO.getTaskCode());
        }else{
            task.setTaskCode(generateTaskCode());
        }
        task.setTaskType(createVO.getTaskType());
        task.setTaskStatus(TaskStatus.PENDING.getCode());
        task.setTaskDescription(createVO.getTaskDescription());
        task.setPlannedStartTime(createVO.getPlannedStartTime());
        task.setPlannedEndTime(createVO.getPlannedEndTime());
        task.setActualStartTime(createVO.getActualStartTime());
        task.setActualEndTime(createVO.getActualEndTime());
        task.setAssigneeId(createVO.getAssigneeId());
        // 使用外部传入的用户ID和部门ID
        task.setCreatorId(userId);
        task.setDeptId(deptId);
        task.setCreateBy(userName);
        // 使用外部传入的创建时间和更新时间
        task.setCreateTime(createTime);
        task.setUpdateTime(updateTime);
        task.setUpdateBy(userName);
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        // 设置通用地址和坐标信息
        if (createVO.getDepartureAddress() != null) {
            task.setDepartureAddress(createVO.getDepartureAddress());
        }
        if (createVO.getDestinationAddress() != null) {
            task.setDestinationAddress(createVO.getDestinationAddress());
        }
        if (createVO.getDepartureLongitude() != null) {
            task.setDepartureLongitude(createVO.getDepartureLongitude());
        }
        if (createVO.getDepartureLatitude() != null) {
            task.setDepartureLatitude(createVO.getDepartureLatitude());
        }
        if (createVO.getDestinationLongitude() != null) {
            task.setDestinationLongitude(createVO.getDestinationLongitude());
        }
        if (createVO.getDestinationLatitude() != null) {
            task.setDestinationLatitude(createVO.getDestinationLatitude());
        }
        if (createVO.getEstimatedDistance() != null) {
            task.setEstimatedDistance(createVO.getEstimatedDistance());
        }
        // 设置急救转运特定信息
        if (createVO.getTransferTime() != null) {
            task.setPlannedStartTime(createVO.getTransferTime());
        }
        if (createVO.getTransferDistance() != null) {
            task.setEstimatedDistance(createVO.getTransferDistance());
        }
        // 设置福祉车特定信息
        if (createVO.getPlannedStartTime() != null) {
            task.setPlannedStartTime(createVO.getPlannedStartTime());
        }
        if (createVO.getStartAddress() != null) {
            task.setDepartureAddress(createVO.getStartAddress());
        }
        if (createVO.getEndAddress() != null) {
            task.setDestinationAddress(createVO.getEndAddress());
        }
        // 设置福祉车公里数
        if (createVO.getDistance() != null) {
            task.setEstimatedDistance(createVO.getDistance());
        }
        // 自动获取出发地GPS坐标(如果缺失)
        if (task.getDepartureAddress() != null &&
            (task.getDepartureLongitude() == null || task.getDepartureLatitude() == null) &&
            mapService != null) {
            try {
                Map<String, Double> coords = mapService.geocoding(
                    task.getDepartureAddress(),
                    extractCityFromAddress(task.getDepartureAddress())
                );
                if (coords != null) {
                    task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
                    log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取出发地GPS坐标失败", e);
            }
        }
        // 自动获取目的地GPS坐标(如果缺失)
        if (task.getDestinationAddress() != null &&
            (task.getDestinationLongitude() == null || task.getDestinationLatitude() == null) &&
            mapService != null) {
            try {
                Map<String, Double> coords = mapService.geocoding(
                    task.getDestinationAddress(),
                    extractCityFromAddress(task.getDestinationAddress())
                );
                if (coords != null) {
                    task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
                    log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取目的地GPS坐标失败", e);
            }
        }
        int result = sysTaskMapper.insertSysTask(task);
        // 保存车辆关联信息
        if (result > 0 && createVO.getVehicleIds() != null && !createVO.getVehicleIds().isEmpty()) {
            for (Long vehicleId : createVO.getVehicleIds()) {
                SysTaskVehicle taskVehicle = new SysTaskVehicle();
                taskVehicle.setTaskId(task.getTaskId());
                taskVehicle.setVehicleId(vehicleId);
                taskVehicle.setAssignTime(updateTime);
                taskVehicle.setAssignBy(userName);
                taskVehicle.setStatus("ASSIGNED");
                taskVehicle.setCreateBy(userName);
                taskVehicle.setCreateTime(createTime);
                taskVehicle.setUpdateBy(userName);
                taskVehicle.setUpdateTime(updateTime);
                sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
            }
        }
        // 保存执行人员信息(包含角色类型)
        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
            saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),userName);
        }
        // 保存急救转运扩展信息
        if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) {
            saveEmergencyInfo(task.getTaskId(),userName, createVO, serviceOrderId, dispatchOrderId, serviceOrdNo);
        }
        // 保存福祉车扩展信息
        if (result > 0 && "WELFARE".equals(createVO.getTaskType())) {
            saveWelfareInfo(task.getTaskId(),userName, createVO);
        }
        // 记录操作日志
        if (result > 0) {
            recordTaskLog(task.getTaskId(), "CREATE", "创建任务", null,
                         "任务类型:" + createVO.getTaskType(), userId, userName);
        }
        // 发布任务创建事件
        if (result > 0) {
            eventPublisher.publishEvent(new TaskCreatedEvent(
                this,
                task.getTaskId(),
                task.getTaskCode(),
                task.getTaskType(),
                userId,
                userName
            ));
        }
        // 发布任务分配事件
        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
            List<Long> assigneeIds = createVO.getAssignees().stream()
                .map(assignee -> assignee.getUserId())
                .collect(Collectors.toList());
            List<String> assigneeNames = createVO.getAssignees().stream()
                .map(assignee -> assignee.getUserName())
                .collect(Collectors.toList());
            eventPublisher.publishEvent(new TaskAssignedEvent(
                this,
                task.getTaskId(),
                task.getTaskCode(),
                assigneeIds,
                assigneeNames,
                userId,
                userName
            ));
        }
        return result;
    }
    /**
     * 修改任务管理
     * 
     * @param updateVO 任务更新对象
@@ -303,38 +546,401 @@
     */
    @Override
    @Transactional
    public int updateSysTask(TaskUpdateVO updateVO) {
    public int updateSysTask(TaskUpdateVO updateVO, Boolean updateFromLegacy) {
        SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(updateVO.getTaskId());
        if (oldTask == null) {
            throw new RuntimeException("任务不存在");
        }
        String userName = SecurityUtils.getUsername();
        
        SysTask task = new SysTask();
        task.setTaskId(updateVO.getTaskId());
        task.setTaskDescription(updateVO.getTaskDescription());
        task.setPlannedStartTime(updateVO.getPlannedStartTime());
        task.setPlannedEndTime(updateVO.getPlannedEndTime());
        task.setAssigneeId(updateVO.getAssigneeId());
        task.setUpdateBy(userName);
        task.setUpdateTime(updateVO.getUpdateTime() != null ? updateVO.getUpdateTime() : DateUtils.getNowDate());
        task.setRemark(updateVO.getRemark());
        // 设置通用地址和坐标信息
        task.setDepartureAddress(updateVO.getDepartureAddress());
        task.setDestinationAddress(updateVO.getDestinationAddress());
        task.setDepartureLongitude(updateVO.getDepartureLongitude());
        task.setDepartureLatitude(updateVO.getDepartureLatitude());
        task.setDestinationLongitude(updateVO.getDestinationLongitude());
        task.setDestinationLatitude(updateVO.getDestinationLatitude());
        task.setPlannedStartTime(updateVO.getPlannedStartTime());
        task.setPlannedEndTime(updateVO.getPlannedEndTime());
        task.setAssigneeId(updateVO.getAssigneeId());
        task.setUpdateBy(SecurityUtils.getUsername());
        task.setUpdateTime(DateUtils.getNowDate());
        task.setRemark(updateVO.getRemark());
        
        // 重新计算预计公里数
        calculateEstimatedDistance(task);
        // 设置预计距离
        if (updateVO.getEstimatedDistance() != null) {
            task.setEstimatedDistance(updateVO.getEstimatedDistance());
        } else if (updateVO.getTransferDistance() != null) {
            // 兼容急救转运字段
            task.setEstimatedDistance(updateVO.getTransferDistance());
        } else if (updateVO.getDistance() != null) {
            // 兼容福祉车字段
            task.setEstimatedDistance(updateVO.getDistance());
        }
        
        // 如果更新了部门ID
        if (updateVO.getDeptId() != null) {
            task.setDeptId(updateVO.getDeptId());
        }
        // 如果更新了任务编号
        if (updateVO.getTaskCode() != null) {
            task.setTaskCode(updateVO.getTaskCode());
        }
        // 自动获取出发地GPS坐标(如果更新了地址但缺失坐标)
        if (updateVO.getDepartureAddress() != null &&
            (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null) &&
            mapService != null) {
            if (!updateVO.getDepartureAddress().equals(oldTask.getDepartureAddress())) {
                try {
                    Map<String, Double> coords = mapService.geocoding(
                        updateVO.getDepartureAddress(),
                        extractCityFromAddress(updateVO.getDepartureAddress())
                    );
                    if (coords != null) {
                        task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
                        task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
                        log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                    }
                } catch (Exception e) {
                    log.error("自动获取出发地GPS坐标失败", e);
                }
            }
        }
        // 自动获取目的地GPS坐标(如果更新了地址但缺失坐标)
        if (updateVO.getDestinationAddress() != null &&
            (updateVO.getDestinationLongitude() == null || updateVO.getDestinationLatitude() == null) &&
            mapService != null) {
            if (!updateVO.getDestinationAddress().equals(oldTask.getDestinationAddress())) {
                try {
                    Map<String, Double> coords = mapService.geocoding(
                        updateVO.getDestinationAddress(),
                        extractCityFromAddress(updateVO.getDestinationAddress())
                    );
                    if (coords != null) {
                        task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
                        task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
                        log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                    }
                } catch (Exception e) {
                    log.error("自动获取目的地GPS坐标失败", e);
                }
            }
        }
        // 用于跟踪是否需要重新同步(车辆、人员、地址、成交价变更)
        boolean needResync = true;
        int result = sysTaskMapper.updateSysTask(task);
        // 更新车辆关联
        if (result > 0 && updateVO.getVehicleIds() != null && !updateVO.getVehicleIds().isEmpty()) {
            // 查询现有的车辆关联
            List<SysTaskVehicle> existingVehicles = sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(updateVO.getTaskId());
            List<Long> existingVehicleIds = existingVehicles.stream()
                .map(SysTaskVehicle::getVehicleId)
                .collect(Collectors.toList());
            // 比较新旧车辆ID列表,判断是否有变化
            boolean vehiclesChanged = !new HashSet<>(existingVehicleIds).equals(new HashSet<>(updateVO.getVehicleIds()));
            // 只有车辆发生变化时才更新
            if (vehiclesChanged) {
                // 删除旧的车辆关联
                sysTaskVehicleMapper.deleteSysTaskVehicleByTaskId(updateVO.getTaskId());
                // 添加新的车辆关联
                Date now = DateUtils.getNowDate();
                String currentUser = userName;
                for (Long vehicleId : updateVO.getVehicleIds()) {
                    SysTaskVehicle taskVehicle = new SysTaskVehicle();
                    taskVehicle.setTaskId(updateVO.getTaskId());
                    taskVehicle.setVehicleId(vehicleId);
                    taskVehicle.setAssignTime(now);
                    taskVehicle.setAssignBy(currentUser);
                    taskVehicle.setCreateTime(now);
                    sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
                }
                // 标记需要重新同步(车辆变更)
                needResync = true;
            }
        }
        // 更新执行人员(检测人员变更)
        if (result > 0 && updateVO.getAssignees() != null) {
            // 查询现有的执行人员
            List<SysTaskAssignee> existingAssignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(updateVO.getTaskId());
            List<Long> existingAssigneeIds = existingAssignees.stream()
                .map(SysTaskAssignee::getUserId)
                .collect(Collectors.toList());
            List<Long> newAssigneeIds = updateVO.getAssignees().stream()
                .map(TaskCreateVO.AssigneeInfo::getUserId)
                .collect(Collectors.toList());
            // 比较新旧执行人员ID列表,判断是否有变化
            boolean assigneesChanged = !new HashSet<>(existingAssigneeIds).equals(new HashSet<>(newAssigneeIds));
            // 只有执行人员发生变化时才更新
            if (assigneesChanged) {
                // 删除旧的执行人员关联
                sysTaskAssigneeMapper.deleteSysTaskAssigneeByTaskId(updateVO.getTaskId());
                // 添加新的执行人员关联
                if (!updateVO.getAssignees().isEmpty()) {
                    saveTaskAssignees(updateVO.getTaskId(), updateVO.getAssignees(), userName);
                }
                // 标记需要重新同步(人员变更)
                needResync = true;
            }
        }
        // 更新急救转运扩展信息(检测地址和成交价变更)
        if (result > 0 && "EMERGENCY_TRANSFER".equals(oldTask.getTaskType())) {
            // 获取旧的急救转运信息
            SysTaskEmergency oldEmergency = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(updateVO.getTaskId());
            // 检测转出医院地址变更
            boolean hospitalOutAddressChanged = false;
            if (updateVO.getHospitalOut() != null && updateVO.getHospitalOut().getAddress() != null
                && oldEmergency != null
                && !updateVO.getHospitalOut().getAddress().equals(oldEmergency.getHospitalOutAddress())) {
                hospitalOutAddressChanged = true;
            }
            // 检测转入医院地址变更
            boolean hospitalInAddressChanged = false;
            if (updateVO.getHospitalIn() != null && updateVO.getHospitalIn().getAddress() != null
                && oldEmergency != null
                && !updateVO.getHospitalIn().getAddress().equals(oldEmergency.getHospitalInAddress())) {
                hospitalInAddressChanged = true;
            }
            // 检测成交价变更
            boolean transferPriceChanged = false;
            if (updateVO.getPrice() != null
                && oldEmergency != null
                && oldEmergency.getTransferPrice() != null
                && updateVO.getPrice().compareTo(oldEmergency.getTransferPrice()) != 0) {
                transferPriceChanged = true;
            }
            ;
            // 更新急救转运信息
            if (updateVO.getHospitalOut() != null || updateVO.getHospitalIn() != null || updateVO.getPatient() != null) {
                updateEmergencyInfoFromCreateVO(updateVO.getTaskId(), updateVO, userName);
            }
            // 如果地址或成交价发生变更,标记需要重新同步
            if (hospitalOutAddressChanged || hospitalInAddressChanged || transferPriceChanged) {
                needResync = true;
            }
        }
        // 更新福祉车扩展信息
        if (result > 0 && "WELFARE".equals(oldTask.getTaskType())) {
            if (updateVO.getPassenger() != null || updateVO.getStartAddress() != null || updateVO.getEndAddress() != null) {
                updateWelfareInfoFromCreateVO(updateVO.getTaskId(), updateVO, userName);
            }
        }
        // 如果是急救转运任务且有变更,标记需要重新同步
        if (result > 0 && "EMERGENCY_TRANSFER".equals(oldTask.getTaskType()) && needResync && !updateFromLegacy) {
            try {
                sysTaskEmergencyService.markNeedResync(updateVO.getTaskId());
            } catch (Exception e) {
                // 标记失败不影响主流程
            }
        }
        
        // 记录操作日志
        if (result > 0) {
            recordTaskLog(updateVO.getTaskId(), "UPDATE", "更新任务",
                         buildTaskDescription(oldTask), buildTaskDescription(task),
                         SecurityUtils.getUserId(), SecurityUtils.getUsername());
            recordTaskLog(updateVO.getTaskId(), "UPDATE", "更新任务",
                buildTaskDescription(oldTask), buildTaskDescription(task),
                SecurityUtils.getUserId(), userName);
        }
        return result;
    }
    /**
     * 更新任务(用于旧系统同步)
     *
     * @param updateVO 任务更新对象
     * @param serviceOrderId 旧系统服务单ID
     * @param dispatchOrderId 旧系统调度单ID
     * @param serviceOrdNo 旧系统服务单编号
     * @param userId 用户ID
     * @param userName 用户名
     * @param deptId 部门ID
     * @param createTime 创建时间
     * @param updateTime 更新时间
     * @return 结果
     */
    @Override
    public int updateTask(TaskUpdateVO updateVO, String serviceOrderId, String dispatchOrderId, String serviceOrdNo,
                         Long userId, String userName, Long deptId, Date createTime, Date updateTime) {
        // 通过旧系统服务单ID查找任务
        SysTaskEmergency taskEmergency = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(Long.parseLong(serviceOrderId));
        Long taskId = taskEmergency.getTaskId();
        updateVO.setTaskId(taskId);
        SysTask task = new SysTask();
        task.setTaskId(taskId);
        task.setTaskDescription(updateVO.getTaskDescription());
        task.setPlannedStartTime(updateVO.getPlannedStartTime());
        task.setPlannedEndTime(updateVO.getPlannedEndTime());
        task.setAssigneeId(updateVO.getAssigneeId());
        task.setUpdateBy(userName);
        task.setUpdateTime(DateUtils.getNowDate());
        task.setRemark(updateVO.getRemark());
        // 设置地址和坐标信息
        task.setDepartureAddress(updateVO.getDepartureAddress());
        task.setDestinationAddress(updateVO.getDestinationAddress());
        task.setDepartureLongitude(updateVO.getDepartureLongitude());
        task.setDepartureLatitude(updateVO.getDepartureLatitude());
        task.setDestinationLongitude(updateVO.getDestinationLongitude());
        task.setDestinationLatitude(updateVO.getDestinationLatitude());
        // 如果更新了部门ID
        if (updateVO.getDeptId() != null) {
            task.setDeptId(updateVO.getDeptId());
        }
        // 如果更新了任务编号
        if (updateVO.getTaskCode() != null) {
            task.setTaskCode(updateVO.getTaskCode());
        }
        // 获取旧任务信息,用于判断地址是否变更
        SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(taskId);
        // 自动获取出发地GPS坐标(如果地址变更且缺失坐标)
        if (oldTask != null && updateVO.getDepartureAddress() != null
            && !updateVO.getDepartureAddress().equals(oldTask.getDepartureAddress())
            && (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null)
            && mapService != null) {
            try {
                Map<String, Double> coords = mapService.geocoding(
                    updateVO.getDepartureAddress(),
                    extractCityFromAddress(updateVO.getDepartureAddress())
                );
                if (coords != null) {
                    task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
                    log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取出发地GPS坐标失败", e);
            }
        }
        // 自动获取目的地GPS坐标(如果地址变更且缺失坐标)
        if (oldTask != null && updateVO.getDestinationAddress() != null
            && !updateVO.getDestinationAddress().equals(oldTask.getDestinationAddress())
            && (updateVO.getDestinationLongitude() == null || updateVO.getDestinationLatitude() == null)
            && mapService != null) {
            try {
                Map<String, Double> coords = mapService.geocoding(
                    updateVO.getDestinationAddress(),
                    extractCityFromAddress(updateVO.getDestinationAddress())
                );
                if (coords != null) {
                    task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
                    task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
                    log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取目的地GPS坐标失败", e);
            }
        }
        int result = sysTaskMapper.updateSysTask(task);
        // 更新车辆关联
        if (result > 0 && updateVO.getVehicleIds() != null && !updateVO.getVehicleIds().isEmpty()) {
            // 查询现有的车辆关联
            List<SysTaskVehicle> existingVehicles = sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId);
            List<Long> existingVehicleIds = existingVehicles.stream()
                .map(SysTaskVehicle::getVehicleId)
                .collect(Collectors.toList());
            // 比较新旧车辆ID列表,判断是否有变化
            boolean vehiclesChanged = !new HashSet<>(existingVehicleIds).equals(new HashSet<>(updateVO.getVehicleIds()));
            // 只有车辆发生变化时才更新
            if (vehiclesChanged) {
                // 删除旧的车辆关联
                sysTaskVehicleMapper.deleteSysTaskVehicleByTaskId(taskId);
                // 添加新的车辆关联
                Date now = DateUtils.getNowDate();
                for (Long vehicleId : updateVO.getVehicleIds()) {
                    SysTaskVehicle taskVehicle = new SysTaskVehicle();
                    taskVehicle.setTaskId(taskId);
                    taskVehicle.setVehicleId(vehicleId);
                    taskVehicle.setAssignTime(now);
                    taskVehicle.setAssignBy(userName);
                    taskVehicle.setCreateTime(now);
                    sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
                }
            }
        }
        // 更新执行人员(检测人员变更)
        if (result > 0 && updateVO.getAssignees() != null) {
            // 查询现有的执行人员
            List<SysTaskAssignee> existingAssignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
            List<Long> existingAssigneeIds = existingAssignees.stream()
                .map(SysTaskAssignee::getUserId)
                .collect(Collectors.toList());
            List<Long> newAssigneeIds = updateVO.getAssignees().stream()
                .map(TaskCreateVO.AssigneeInfo::getUserId)
                .collect(Collectors.toList());
            // 比较新旧执行人员ID列表,判断是否有变化
            boolean assigneesChanged = !new HashSet<>(existingAssigneeIds).equals(new HashSet<>(newAssigneeIds));
            // 只有执行人员发生变化时才更新
            if (assigneesChanged) {
                // 删除旧的执行人员关联
                sysTaskAssigneeMapper.deleteSysTaskAssigneeByTaskId(taskId);
                // 添加新的执行人员关联
                if (!updateVO.getAssignees().isEmpty()) {
                    saveTaskAssignees(taskId, updateVO.getAssignees(), userName);
                }
            }
        }
        // 更新急救转运扩展信息
        if (result > 0) {
            // 更新旧系统ID
            if (serviceOrderId != null) {
                taskEmergency.setLegacyServiceOrdId(Long.parseLong(serviceOrderId));
            }
            if (dispatchOrderId != null) {
                taskEmergency.setLegacyDispatchOrdId(Long.parseLong(dispatchOrderId));
            }
            if (serviceOrdNo != null) {
                taskEmergency.setLegacyServiceOrdNo(serviceOrdNo);
            }
            // 使用TaskCreateVO的字段来更新急救转运信息
            if (updateVO.getHospitalOut() != null || updateVO.getHospitalIn() != null || updateVO.getPatient() != null) {
                updateEmergencyInfoFromCreateVO(taskId, updateVO, userName);
            }
        }
        
        return result;
@@ -418,7 +1024,6 @@
     * @return 结果
     */
    @Override
    @Transactional
    public int changeTaskStatus(Long taskId, TaskStatus newStatus, String remark) {
        return changeTaskStatusWithLocation(taskId, newStatus, remark, null);
    }
@@ -433,7 +1038,6 @@
     * @return 结果
     */
    @Override
    @Transactional
    public int changeTaskStatusWithLocation(Long taskId, TaskStatus newStatus, String remark, SysTaskLog locationLog) {
        SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (oldTask == null) {
@@ -485,7 +1089,10 @@
                    .map(SysTaskAssignee::getUserId)
                    .collect(Collectors.toList());
            }
            Long userId=SecurityUtils.getUserId();
            Double lng=locationLog==null?null: locationLog.getLongitude();
            Double lat=locationLog==null?null: locationLog.getLatitude();
            String address=locationLog==null?null: locationLog.getLocationAddress();
            eventPublisher.publishEvent(new TaskStatusChangedEvent(
                this,
                oldTask.getTaskId(),
@@ -495,7 +1102,11 @@
                oldTaskStatus.getInfo(),
                newStatus.getInfo(),
                assigneeIds,
                oldTask.getCreatorId()
                oldTask.getCreatorId(),
                userId,
                    lng, lat,
                    address
            ));
        }
        
@@ -538,7 +1149,7 @@
                recordTaskLog(taskId, "UPDATE", "上传附件", null, 
                             "上传文件:" + file.getOriginalFilename() + "(分类:" + categoryDesc + ")", 
                             SecurityUtils.getUserId(), SecurityUtils.getUsername());
            }
            
@@ -598,7 +1209,7 @@
                recordTaskLog(taskId, "UPDATE", "上传附件", null, 
                             "通过微信上传文件:" + fileName + "(分类:" + categoryDesc + ")", 
                             SecurityUtils.getUserId(), SecurityUtils.getUsername());
            }
            
@@ -751,7 +1362,7 @@
     */
    @Override
    @Transactional
    public int assignVehicleToTask(Long taskId, Long vehicleId, String remark) {
    public int assignVehicleToTask(Long taskId, Long vehicleId, String remark,Long userId,String userName) {
        // 检查是否已经分配
        int exists = sysTaskVehicleMapper.checkTaskVehicleExists(taskId, vehicleId);
        if (exists > 0) {
@@ -762,7 +1373,7 @@
        taskVehicle.setTaskId(taskId);
        taskVehicle.setVehicleId(vehicleId);
        taskVehicle.setAssignTime(DateUtils.getNowDate());
        taskVehicle.setAssignBy(SecurityUtils.getUsername());
        taskVehicle.setAssignBy(userName);
        taskVehicle.setStatus("ASSIGNED");
        taskVehicle.setRemark(remark);
        
@@ -772,7 +1383,7 @@
        if (result > 0) {
            recordTaskLog(taskId, "ASSIGN", "分配车辆", null, 
                         "分配车辆ID:" + vehicleId + ",备注:" + remark, 
                         SecurityUtils.getUserId(), SecurityUtils.getUsername());
                         userId, userName);
        }
        
        return result;
@@ -810,10 +1421,10 @@
     */
    @Override
    @Transactional
    public int assignMultipleVehiclesToTask(Long taskId, List<Long> vehicleIds, String remark) {
    public int assignMultipleVehiclesToTask(Long taskId, List<Long> vehicleIds, String remark,Long userId,String userName) {
        List<SysTaskVehicle> taskVehicles = new ArrayList<>();
        Date now = DateUtils.getNowDate();
        String assignBy = SecurityUtils.getUsername();
        String assignBy = userName;
        
        for (Long vehicleId : vehicleIds) {
            // 检查是否已经分配
@@ -839,7 +1450,7 @@
        if (result > 0) {
            recordTaskLog(taskId, "ASSIGN", "批量分配车辆", null, 
                         "分配车辆数量:" + result + ",备注:" + remark, 
                         SecurityUtils.getUserId(), SecurityUtils.getUsername());
                         userId,userName);
        }
        
        return result;
@@ -947,6 +1558,8 @@
            task.setAttachments(attachments);
            // 查询操作日志
            task.setOperationLogs(sysTaskLogMapper.selectSysTaskLogByTaskId(taskId));
            // 查询执行人员列表
            task.setAssignees(sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId));
            // 加载急救转运扩展信息
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
@@ -961,6 +1574,82 @@
        return task;
    }
    /**
     * 检查车辆是否有正在进行中的任务
     * 正在进行中的任务是指状态不为:PENDING(待处理)、COMPLETED(已完成)、CANCELLED(已取消)的任务
     *
     * @param vehicleId 车辆ID
     * @return 正在进行中的任务列表
     */
    @Override
    public List<SysTask> checkVehicleActiveTasks(Long vehicleId) {
        return sysTaskMapper.selectActiveTasksByVehicleId(vehicleId);
    }
    /**
     * 检查任务是否已关联旧系统服务单ID
     *
     * @param taskId 任务ID
     * @return true-已关联,false-未关联
     */
    @Override
    public boolean hasLegacyServiceOrdId(Long taskId) {
        // 只有急救转运任务才有旧系统ID
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (task != null && "EMERGENCY_TRANSFER".equals(task.getTaskType())) {
            SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
            return emergencyInfo != null && emergencyInfo.getLegacyServiceOrdId() != null;
        }
        return false;
    }
    /**
     * 检查任务是否已关联旧系统调度单ID
     *
     * @param taskId 任务ID
     * @return true-已关联,false-未关联
     */
    @Override
    public boolean hasLegacyDispatchOrdId(Long taskId) {
        // 只有急救转运任务才有旧系统ID
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (task != null && "EMERGENCY_TRANSFER".equals(task.getTaskType())) {
            SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
            return emergencyInfo != null && emergencyInfo.getLegacyDispatchOrdId() != null;
        }
        return false;
    }
    /**
     * 根据旧系统服务单ID检查是否存在任务
     *
     * @param legacyServiceOrdId 旧系统服务单ID
     * @return true-存在,false-不存在
     */
    @Override
    public boolean existsByLegacyServiceOrdId(Long legacyServiceOrdId) {
        if (legacyServiceOrdId == null) {
            return false;
        }
        SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(legacyServiceOrdId);
        return emergencyInfo != null;
    }
    /**
     * 根据旧系统调度单ID检查是否存在任务
     *
     * @param legacyDispatchOrdId 旧系统调度单ID
     * @return true-存在,false-不存在
     */
    @Override
    public boolean existsByLegacyDispatchOrdId(Long legacyDispatchOrdId) {
        if (legacyDispatchOrdId == null) {
            return false;
        }
        SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectByLegacyDispatchOrdId(legacyDispatchOrdId);
        return emergencyInfo != null;
    }
    @Autowired
    private TaskCodeGenerator taskCodeGenerator;
    
@@ -971,6 +1660,30 @@
     */
    private String generateTaskCode() {
        return taskCodeGenerator.generateTaskCode();
    }
    /**
     * 从地址中提取城市名称(用于地图地理编码)
     *
     * @param address 地址
     * @return 城市名称
     */
    private String extractCityFromAddress(String address) {
        if (address == null || address.trim().isEmpty()) {
            return null;
        }
        // 常见城市名列表
        String[] cities = {"广州", "深圳", "东莞", "佛山", "珠海", "惠州", "中山", "江门", "湛江", "肇庆", "清远", "韶关", "梅州", "河源", "潮州", "揭阳", "汕头", "汕尾", "云浮", "阳江","北京","上海","天津"};
        for (String city : cities) {
            if (address.contains(city)) {
                return city;
            }
        }
        return null;
    }
    /**
@@ -1093,14 +1806,14 @@
     * @param taskId 任务ID
     * @param assignees 执行人员信息列表
     */
    private void saveTaskAssignees(Long taskId, java.util.List<TaskCreateVO.AssigneeInfo> assignees) {
    private void saveTaskAssignees(Long taskId, java.util.List<TaskCreateVO.AssigneeInfo> assignees,String userName) {
        if (assignees == null || assignees.isEmpty()) {
            return;
        }
        
        java.util.List<SysTaskAssignee> taskAssignees = new java.util.ArrayList<>();
        Date now = DateUtils.getNowDate();
        String currentUser = SecurityUtils.getUsername();
        String currentUser = userName;
        
        for (int i = 0; i < assignees.size(); i++) {
            TaskCreateVO.AssigneeInfo assigneeInfo = assignees.get(i);
@@ -1133,7 +1846,7 @@
     * @param taskId 任务ID
     * @param createVO 任务创建对象
     */
    private void saveEmergencyInfo(Long taskId, TaskCreateVO createVO) {
    private void saveEmergencyInfo(Long taskId,String createUserName, TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId, String serviceOrdNo) {
        SysTaskEmergency emergencyInfo = new SysTaskEmergency();
        emergencyInfo.setTaskId(taskId);
        
@@ -1155,8 +1868,27 @@
            emergencyInfo.setHospitalOutDepartmentId(createVO.getHospitalOut().getDepartmentId());
            emergencyInfo.setHospitalOutBedNumber(createVO.getHospitalOut().getBedNumber());
            emergencyInfo.setHospitalOutAddress(createVO.getHospitalOut().getAddress());
            emergencyInfo.setHospitalOutLongitude(createVO.getHospitalOut().getLongitude());
            emergencyInfo.setHospitalOutLatitude(createVO.getHospitalOut().getLatitude());
            // GPS坐标:优先使用前端传入的,否则后端自动获取
            if (createVO.getHospitalOut().getLongitude() != null && createVO.getHospitalOut().getLatitude() != null) {
                emergencyInfo.setHospitalOutLongitude(createVO.getHospitalOut().getLongitude());
                emergencyInfo.setHospitalOutLatitude(createVO.getHospitalOut().getLatitude());
            } else if (mapService != null && createVO.getHospitalOut().getAddress() != null) {
                // 后端自动获取GPS坐标
                try {
                    Map<String, Double> coords = mapService.geocoding(
                        createVO.getHospitalOut().getAddress(),
                        extractCityFromAddress(createVO.getHospitalOut().getAddress())
                    );
                    if (coords != null) {
                        emergencyInfo.setHospitalOutLongitude(BigDecimal.valueOf(coords.get("lng")));
                        emergencyInfo.setHospitalOutLatitude(BigDecimal.valueOf(coords.get("lat")));
                        log.info("转出医院GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                    }
                } catch (Exception e) {
                    log.error("自动获取转出医院GPS坐标失败", e);
                }
            }
        }
        
        // 设置转入医院信息
@@ -1167,8 +1899,27 @@
            emergencyInfo.setHospitalInDepartmentId(createVO.getHospitalIn().getDepartmentId());
            emergencyInfo.setHospitalInBedNumber(createVO.getHospitalIn().getBedNumber());
            emergencyInfo.setHospitalInAddress(createVO.getHospitalIn().getAddress());
            emergencyInfo.setHospitalInLongitude(createVO.getHospitalIn().getLongitude());
            emergencyInfo.setHospitalInLatitude(createVO.getHospitalIn().getLatitude());
            // GPS坐标:优先使用前端传入的,否则后端自动获取
            if (createVO.getHospitalIn().getLongitude() != null && createVO.getHospitalIn().getLatitude() != null) {
                emergencyInfo.setHospitalInLongitude(createVO.getHospitalIn().getLongitude());
                emergencyInfo.setHospitalInLatitude(createVO.getHospitalIn().getLatitude());
            } else if (mapService != null && createVO.getHospitalIn().getAddress() != null) {
                // 后端自动获取GPS坐标
                try {
                    Map<String, Double> coords = mapService.geocoding(
                        createVO.getHospitalIn().getAddress(),
                        extractCityFromAddress(createVO.getHospitalIn().getAddress())
                    );
                    if (coords != null) {
                        emergencyInfo.setHospitalInLongitude(BigDecimal.valueOf(coords.get("lng")));
                        emergencyInfo.setHospitalInLatitude(BigDecimal.valueOf(coords.get("lat")));
                        log.info("转入医院GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                    }
                } catch (Exception e) {
                    log.error("自动获取转入医院GPS坐标失败", e);
                    }
                }
        }
        
        // 设置费用信息
@@ -1188,14 +1939,252 @@
                .collect(Collectors.joining(","));
            emergencyInfo.setDiseaseIds(diseaseIdsStr);
        }
        if(serviceOrderId!=null){
            emergencyInfo.setLegacyServiceOrdId(Long.parseLong(serviceOrderId));
            emergencyInfo.setSyncStatus(2);
            emergencyInfo.setSyncTime(new Date());
            emergencyInfo.setSyncErrorMsg("旧系统同步过来");
        }
        if(dispatchOrderId!=null){
            emergencyInfo.setLegacyDispatchOrdId(Long.parseLong(dispatchOrderId));
            emergencyInfo.setDispatchSyncStatus(2);
            emergencyInfo.setDispatchSyncTime(new Date());
            emergencyInfo.setDispatchSyncErrorMsg("旧系统同步过来");
        }
        if(serviceOrdNo!=null){
            emergencyInfo.setLegacyServiceOrdNo(serviceOrdNo);
        }
        // 系统字段
        emergencyInfo.setCreateTime(DateUtils.getNowDate());
        emergencyInfo.setUpdateTime(DateUtils.getNowDate());
        emergencyInfo.setCreateBy(SecurityUtils.getUsername());
        emergencyInfo.setUpdateBy(SecurityUtils.getUsername());
        emergencyInfo.setCreateBy(createUserName);
        emergencyInfo.setUpdateBy(createUserName);
        
        sysTaskEmergencyMapper.insertSysTaskEmergency(emergencyInfo);
    }
    /**
     * 从 TaskCreateVO 更新急救转运任务扩展信息
     *
     * @param taskId 任务ID
     * @param createVO 任务创建/更新对象
     * @param userName 操作人名
     */
    private void updateEmergencyInfoFromCreateVO(Long taskId, TaskCreateVO createVO, String userName) {
        // 查询现有的扩展信息
        SysTaskEmergency existingInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
        if (existingInfo == null) {
            // 如果不存在,则创建新的
            existingInfo = new SysTaskEmergency();
            existingInfo.setTaskId(taskId);
            existingInfo.setCreateTime(DateUtils.getNowDate());
            existingInfo.setCreateBy(userName);
        }
        // 更新患者信息
        if (createVO.getPatient() != null) {
            if (createVO.getPatient().getContact() != null) {
                existingInfo.setPatientContact(createVO.getPatient().getContact());
            }
            if (createVO.getPatient().getPhone() != null) {
                existingInfo.setPatientPhone(createVO.getPatient().getPhone());
            }
            if (createVO.getPatient().getName() != null) {
                existingInfo.setPatientName(createVO.getPatient().getName());
            }
            if (createVO.getPatient().getGender() != null) {
                existingInfo.setPatientGender(createVO.getPatient().getGender());
            }
            if (createVO.getPatient().getIdCard() != null) {
                existingInfo.setPatientIdCard(createVO.getPatient().getIdCard());
            }
            if (createVO.getPatient().getCondition() != null) {
                existingInfo.setPatientCondition(createVO.getPatient().getCondition());
            }
        }
        // 更新转出医院信息
        if (createVO.getHospitalOut() != null) {
            if (createVO.getHospitalOut().getId() != null) {
                existingInfo.setHospitalOutId(createVO.getHospitalOut().getId());
            }
            if (createVO.getHospitalOut().getName() != null) {
                existingInfo.setHospitalOutName(createVO.getHospitalOut().getName());
            }
            if (createVO.getHospitalOut().getDepartment() != null) {
                existingInfo.setHospitalOutDepartment(createVO.getHospitalOut().getDepartment());
            }
            if (createVO.getHospitalOut().getDepartmentId() != null) {
                existingInfo.setHospitalOutDepartmentId(createVO.getHospitalOut().getDepartmentId());
            }
            if (createVO.getHospitalOut().getBedNumber() != null) {
                existingInfo.setHospitalOutBedNumber(createVO.getHospitalOut().getBedNumber());
            }
            if (createVO.getHospitalOut().getAddress() != null && !createVO.getHospitalOut().getAddress().equals(existingInfo.getHospitalOutAddress())) {
                existingInfo.setHospitalOutAddress(createVO.getHospitalOut().getAddress());
                // 如枟更新了地址但没有GPS坐标,后端自动获取
                if (createVO.getHospitalOut().getLongitude() == null && createVO.getHospitalOut().getLatitude() == null && mapService != null) {
                    try {
                        Map<String, Double> coords = mapService.geocoding(
                            createVO.getHospitalOut().getAddress(),
                            extractCityFromAddress(createVO.getHospitalOut().getAddress())
                        );
                        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"));
                        }
                    } catch (Exception e) {
                        log.error("自动获取转出医院GPS坐标失败", e);
                    }
                }
            }
        }
        // 更新转入医院信息
        if (createVO.getHospitalIn() != null) {
            if (createVO.getHospitalIn().getId() != null) {
                existingInfo.setHospitalInId(createVO.getHospitalIn().getId());
            }
            if (createVO.getHospitalIn().getName() != null) {
                existingInfo.setHospitalInName(createVO.getHospitalIn().getName());
            }
            if (createVO.getHospitalIn().getDepartment() != null) {
                existingInfo.setHospitalInDepartment(createVO.getHospitalIn().getDepartment());
            }
            if (createVO.getHospitalIn().getDepartmentId() != null) {
                existingInfo.setHospitalInDepartmentId(createVO.getHospitalIn().getDepartmentId());
            }
            if (createVO.getHospitalIn().getBedNumber() != null) {
                existingInfo.setHospitalInBedNumber(createVO.getHospitalIn().getBedNumber());
            }
            if (createVO.getHospitalIn().getAddress() != null && !createVO.getHospitalIn().getAddress().equals(existingInfo.getHospitalInAddress())) {
                existingInfo.setHospitalInAddress(createVO.getHospitalIn().getAddress());
                // 如果更新了地址但没有GPS坐标,后端自动获取
                if (createVO.getHospitalIn().getLongitude() == null && createVO.getHospitalIn().getLatitude() == null && mapService != null) {
                    try {
                        Map<String, Double> coords = mapService.geocoding(
                            createVO.getHospitalIn().getAddress(),
                            extractCityFromAddress(createVO.getHospitalIn().getAddress())
                        );
                        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"));
                        }
                    } catch (Exception e) {
                        log.error("自动获取转入医院GPS坐标失败", e);
                    }
                }
            }
        }
        // 更新费用信息
        if (createVO.getTransferDistance() != null) {
            existingInfo.setTransferDistance(createVO.getTransferDistance());
        }
        if (createVO.getPrice() != null) {
            existingInfo.setTransferPrice(createVO.getPrice());
        }
        // 更新单据类型ID
        if (createVO.getDocumentTypeId() != null) {
            existingInfo.setDocumentTypeId(createVO.getDocumentTypeId());
        }
        // 更新任务类型ID
        if (createVO.getTaskTypeId() != null) {
            existingInfo.setTaskTypeId(createVO.getTaskTypeId());
        }
        // 更新病情ID列表
        if (createVO.getDiseaseIds() != null && !createVO.getDiseaseIds().isEmpty()) {
            String diseaseIdsStr = createVO.getDiseaseIds().stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));
            existingInfo.setDiseaseIds(diseaseIdsStr);
        }
        // 系统字段
        existingInfo.setUpdateTime(DateUtils.getNowDate());
        existingInfo.setUpdateBy(userName);
        // 执行更新
        sysTaskEmergencyMapper.updateSysTaskEmergency(existingInfo);
    }
    /**
     * 从 TaskCreateVO 更新福祉车任务扩展信息
     *
     * @param taskId 任务ID
     * @param createVO 任务创建/更新对象
     * @param userName 操作人名
     */
    private void updateWelfareInfoFromCreateVO(Long taskId, TaskCreateVO createVO, String userName) {
        // 查询现有的扩展信息
        SysTaskWelfare existingInfo = sysTaskWelfareMapper.selectSysTaskWelfareByTaskId(taskId);
        if (existingInfo == null) {
            // 如果不存在,则创建新的
            existingInfo = new SysTaskWelfare();
            existingInfo.setTaskId(taskId);
            existingInfo.setCreateTime(DateUtils.getNowDate());
            existingInfo.setCreateBy(userName);
        }
        // 更新乘客信息
        if (createVO.getPassenger() != null) {
            if (createVO.getPassenger().getContact() != null) {
                existingInfo.setPassengerContact(createVO.getPassenger().getContact());
            }
            if (createVO.getPassenger().getPhone() != null) {
                existingInfo.setPassengerPhone(createVO.getPassenger().getPhone());
            }
        }
        // 更新地址信息
        if (createVO.getStartAddress() != null) {
            existingInfo.setPickupAddress(createVO.getStartAddress());
        }
        if (createVO.getEndAddress() != null) {
            existingInfo.setDestinationAddress(createVO.getEndAddress());
        }
        // 更新GPS坐标
        if (createVO.getDepartureLongitude() != null) {
            existingInfo.setPickupLongitude(createVO.getDepartureLongitude());
        }
        if (createVO.getDepartureLatitude() != null) {
            existingInfo.setPickupLatitude(createVO.getDepartureLatitude());
        }
        if (createVO.getDestinationLongitude() != null) {
            existingInfo.setDestinationLongitude(createVO.getDestinationLongitude());
        }
        if (createVO.getDestinationLatitude() != null) {
            existingInfo.setDestinationLatitude(createVO.getDestinationLatitude());
        }
        // 更新距离和费用
        if (createVO.getDistance() != null) {
            existingInfo.setServiceDistance(createVO.getDistance());
        } else if (createVO.getEstimatedDistance() != null) {
            existingInfo.setServiceDistance(createVO.getEstimatedDistance());
        }
        if (createVO.getPrice() != null) {
            existingInfo.setServicePrice(createVO.getPrice());
        }
        // 系统字段
        existingInfo.setUpdateTime(DateUtils.getNowDate());
        existingInfo.setUpdateBy(userName);
        // 执行更新
        sysTaskWelfareMapper.updateSysTaskWelfare(existingInfo);
    }
    /**
@@ -1204,7 +2193,7 @@
     * @param taskId 任务ID
     * @param createVO 任务创建对象
     */
    private void saveWelfareInfo(Long taskId, TaskCreateVO createVO) {
    private void saveWelfareInfo(Long taskId,String userName, TaskCreateVO createVO) {
        SysTaskWelfare welfareInfo = new SysTaskWelfare();
        welfareInfo.setTaskId(taskId);
        
@@ -1233,8 +2222,8 @@
        // 系统字段
        welfareInfo.setCreateTime(DateUtils.getNowDate());
        welfareInfo.setUpdateTime(DateUtils.getNowDate());
        welfareInfo.setCreateBy(SecurityUtils.getUsername());
        welfareInfo.setUpdateBy(SecurityUtils.getUsername());
        welfareInfo.setCreateBy(userName);
        welfareInfo.setUpdateBy(userName);
        
        sysTaskWelfareMapper.insertSysTaskWelfare(welfareInfo);
    }
@@ -1278,5 +2267,89 @@
        }
    }
    
    /**
     * 检查任务是否可以出发
     * 检查:
     * 1. 车辆是否有未完成的任务
     * 2. 执行人员是否有未完成的任务
     *
     * @param taskId 任务ID
     * @return AjaxResult 校验结果
     */
    @Override
    public com.ruoyi.common.core.domain.AjaxResult checkTaskCanDepart(Long taskId) {
        // 获取任务详情
        SysTask task = this.getTaskDetail(taskId);
        if (task == null) {
            return com.ruoyi.common.core.domain.AjaxResult.error("任务不存在");
        }
        List<Map<String, Object>> conflicts = new ArrayList<>();
        // 1. 检查车辆是否有未完成的任务
        List<SysTaskVehicle> taskVehicles = task.getAssignedVehicles();
        if (taskVehicles != null && !taskVehicles.isEmpty()) {
            for (SysTaskVehicle taskVehicle : taskVehicles) {
                Long vehicleId = taskVehicle.getVehicleId();
                List<SysTask> vehicleActiveTasks = this.checkVehicleActiveTasks(vehicleId);
                // 过滤掉当前任务本身
                vehicleActiveTasks = vehicleActiveTasks.stream()
                    .filter(t -> !t.getTaskId().equals(taskId))
                    .collect(Collectors.toList());
                if (!vehicleActiveTasks.isEmpty()) {
                    for (SysTask activeTask : vehicleActiveTasks) {
                        Map<String, Object> conflict = new HashMap<>();
                        conflict.put("type", "vehicle");
                        conflict.put("vehicleNo", taskVehicle.getVehicleNo());
                        conflict.put("taskId", activeTask.getTaskId());
                        conflict.put("taskCode", activeTask.getTaskCode());
                        conflict.put("taskStatus", activeTask.getTaskStatus());
                        conflict.put("message", String.format("车辆 %s 尚有未完成的任务 %s,请先完成",
                            taskVehicle.getVehicleNo(), activeTask.getTaskCode()));
                        conflicts.add(conflict);
                    }
                }
            }
        }
        // 2. 检查执行人员是否有未完成的任务
        List<SysTaskAssignee> assignees = task.getAssignees();
        if (assignees != null && !assignees.isEmpty()) {
            for (SysTaskAssignee assignee : assignees) {
                Long userId = assignee.getUserId();
                // 查询该执行人的所有正在进行中的任务(排除PENDING、COMPLETED、CANCELLED)
                List<SysTask> userActiveTasks = this.selectMyTasks(userId).stream()
                    .filter(t -> !TaskStatus.PENDING.getCode().equals(t.getTaskStatus())
                              && !TaskStatus.COMPLETED.getCode().equals(t.getTaskStatus())
                              && !TaskStatus.CANCELLED.getCode().equals(t.getTaskStatus())
                              && !t.getTaskId().equals(taskId)) // 过滤掉当前任务
                    .collect(Collectors.toList());
                if (!userActiveTasks.isEmpty()) {
                    for (SysTask activeTask : userActiveTasks) {
                        Map<String, Object> conflict = new HashMap<>();
                        conflict.put("type", "assignee");
                        conflict.put("userName", assignee.getUserName());
                        conflict.put("taskId", activeTask.getTaskId());
                        conflict.put("taskCode", activeTask.getTaskCode());
                        conflict.put("taskStatus", activeTask.getTaskStatus());
                        conflict.put("message", String.format("执行人 %s 尚有正在进行中的任务 %s,请先完成",
                            assignee.getUserName(), activeTask.getTaskCode()));
                        conflicts.add(conflict);
                    }
                }
            }
        }
        // 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("valid", conflicts.isEmpty());
        result.put("conflicts", conflicts);
        return com.ruoyi.common.core.domain.AjaxResult.success(result);
    }
   
}