wlzboy
1 天以前 08f95b2f159b56fa3bd4f4b348855989de8aa456
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -7,19 +7,20 @@
import java.net.HttpURLConnection;
import java.net.URL;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.event.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.TaskCodeGenerator;
import com.ruoyi.common.config.ImageUrlConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.GpsDistanceUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.domain.SysTask;
@@ -31,15 +32,6 @@
import com.ruoyi.system.domain.SysTaskAssignee;
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.service.ISysConfigService;
import com.ruoyi.system.event.TaskCreatedEvent;
import com.ruoyi.system.event.TaskAssignedEvent;
import com.ruoyi.system.event.TaskStatusChangedEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -60,9 +52,6 @@
    private SysTaskMapper sysTaskMapper;
    
    @Autowired
    private SysTaskVehicleMapper sysTaskVehicleMapper;
    @Autowired
    private SysTaskAttachmentMapper sysTaskAttachmentMapper;
    
    @Autowired
@@ -72,19 +61,13 @@
    private SysTaskEmergencyMapper sysTaskEmergencyMapper;
    
    @Autowired
    private SysTaskWelfareMapper sysTaskWelfareMapper;
    @Autowired
    private SysTaskAssigneeMapper sysTaskAssigneeMapper;
    
    @Autowired
    private VehicleInfoMapper vehicleInfoMapper;
    @Autowired(required = false)
    private ILegacySystemSyncService legacySystemSyncService;
    
    @Autowired
    private ISysTaskEmergencyService sysTaskEmergencyService;
    private ISysEmergencyTaskService sysEmergencyTaskService;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
@@ -92,11 +75,16 @@
    @Autowired
    private ImageUrlConfig imageUrlConfig;
    
    @Autowired(required = false)
    private ITaskAttachmentSyncService taskAttachmentSyncService;
    @Autowired
    private ISysTaskAttachmentService sysTaskAttachmentService;
    @Autowired
    private SysUserMapper sysUserMapper;
    private ISysDeptService deptService;
    @Autowired
    private ISysUserService userService;
    @Autowired(required = false)
    private IMapService mapService;
@@ -104,6 +92,28 @@
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private ISysTaskAssigneeService sysTaskAssigneeService;
    @Autowired
    private ISysWelfareTaskService sysWelfareTaskService;
    @Autowired
    private ISysTaskVehicleService sysTaskVehicleService;
    @Override
    public Boolean dispatchSyncEvent(Long taskId) {
        SysTask task= sysTaskMapper.selectSysTaskByTaskId(taskId);
        SysUser user= userService.selectUserById(task.getCreatorId());
        Integer oaUser=user.getOaUserId();
        SysTaskEmergency emergency = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
        eventPublisher.publishEvent(new TaskDispatchSyncEvent(this, taskId, task.getTaskCode(),emergency.getLegacyServiceOrdId(), emergency.getLegacyDispatchOrdId(),oaUser));
        return true;
    }
    private Long getBranchCompanyId(Long userId) {
       return userService.getBranchCompanyIdByUserId(userId);
    }
    /**
     * 查询任务管理
     * 
@@ -114,6 +124,7 @@
    public SysTask selectSysTaskByTaskId(Long taskId) {
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (task != null) {
            // 加载急救转运扩展信息
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId);
@@ -121,7 +132,7 @@
            }
            // 加载福祉车扩展信息
            else if ("WELFARE".equals(task.getTaskType())) {
                SysTaskWelfare welfareInfo = sysTaskWelfareMapper.selectSysTaskWelfareByTaskId(taskId);
                SysTaskWelfare welfareInfo = sysWelfareTaskService.getWelfareInfoByTaskId(taskId);
                task.setWelfareInfo(welfareInfo);
            }
        }
@@ -136,7 +147,90 @@
     */
    @Override
    public List<SysTask> selectSysTaskList(TaskQueryVO queryVO) {
        return sysTaskMapper.selectSysTaskList(queryVO);
        List<SysTask> tasks= sysTaskMapper.selectSysTaskList(queryVO);
        tasks.forEach(task -> {
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId());
                task.setEmergencyInfo(emergencyInfo);
            }
        });
        return tasks;
    }
    /**
     * 设置任务是总部推送的标记
     * @param taskCreatorId 任务创建人的用户ID
     * @param taskDeptId 任务中的归属机构ID
     */
    @Override
    public Boolean isTaskHeaderPush(Long taskCreatorId,Long taskDeptId){
        if(LongUtil.isEmpty(taskCreatorId))return false;
        if(LongUtil.isEmpty(taskDeptId))return false ;
        Long createrDeptId = getBranchCompanyId(taskCreatorId);
        if(createrDeptId !=null && !taskDeptId.equals(createrDeptId) && createrDeptId.equals(DeptUtil.GUANGZHOU_DEPT_ID)){
            //广州总部推送的任务
           return true;
        }else{
            return false;
        }
    }
    /**
     * 根据任务编号、调度单编号或服务单编号查询任务列表
     *
     * @param queryVO 任务查询对象
     * @param taskCode 任务编号
     * @return 任务管理集合
     */
    @Override
    public List<SysTask> selectSysTaskListByMultiCode(TaskQueryVO queryVO, String taskCode) {
        // Create a new query object without the taskCode filter
        TaskQueryVO newQuery = new TaskQueryVO();
        // Copy all properties except taskCode
        try {
            org.springframework.beans.BeanUtils.copyProperties(queryVO, newQuery, "taskCode");
        } catch (Exception e) {
            // If copy fails, manually copy the important fields
            newQuery.setTaskType(queryVO.getTaskType());
            newQuery.setTaskStatus(queryVO.getTaskStatus());
            newQuery.setVehicleNo(queryVO.getVehicleNo());
            newQuery.setCreatorId(queryVO.getCreatorId());
            newQuery.setAssigneeId(queryVO.getAssigneeId());
            newQuery.setDeptId(queryVO.getDeptId());
            newQuery.setDeptIds(queryVO.getDeptIds());
            newQuery.setPlannedStartTimeBegin(queryVO.getPlannedStartTimeBegin());
            newQuery.setPlannedStartTimeEnd(queryVO.getPlannedStartTimeEnd());
            newQuery.setPlannedEndTimeBegin(queryVO.getPlannedEndTimeBegin());
            newQuery.setPlannedEndTimeEnd(queryVO.getPlannedEndTimeEnd());
            newQuery.setOverdue(queryVO.getOverdue());
        }
        // Get all tasks matching the other criteria
        List<SysTask> allTasks = sysTaskMapper.selectSysTaskList(newQuery);
        allTasks.stream().forEach(task -> {
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) {
                SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId());
                task.setEmergencyInfo(emergencyInfo);
            }
        });
        return allTasks.stream().filter(task -> {
            if (task.getTaskCode() != null && task.getTaskCode().contains(taskCode)) {
                return true;
            }
            if ("EMERGENCY_TRANSFER".equals(task.getTaskType()) && task.getEmergencyInfo() != null) {
                String dispatchCode = task.getEmergencyInfo().getDispatchCode();
                String serviceCode = task.getEmergencyInfo().getServiceCode();
                return (dispatchCode != null && dispatchCode.contains(taskCode)) ||
                        (serviceCode != null && serviceCode.contains(taskCode));
            }
            return false;
        }).collect(Collectors.toList());
    }
    /**
@@ -149,6 +243,11 @@
    @Transactional
    public int insertSysTask(TaskCreateVO createVO) {
        String username = SecurityUtils.getUsername();
        Long userId = SecurityUtils.getUserId();
        if(userId==null || userId==0){
            log.error("insertSysTask 用户ID为空 userName:{}",username);
            return 0;
        }
        SysTask task = new SysTask();
        task.setTaskCode(generateTaskCode());
        task.setTaskType(createVO.getTaskType());
@@ -157,7 +256,7 @@
        task.setPlannedStartTime(createVO.getPlannedStartTime());
        task.setPlannedEndTime(createVO.getPlannedEndTime());
        task.setAssigneeId(createVO.getAssigneeId());
        task.setCreatorId(SecurityUtils.getUserId());
        task.setCreatorId(userId);
        // 优先使用前端传入的部门ID,如果没有则使用当前用户的部门ID
        task.setDeptId(createVO.getDeptId() != null ? createVO.getDeptId() : SecurityUtils.getDeptId());
        task.setCreateBy(username);
@@ -166,124 +265,36 @@
        task.setUpdateTime(DateUtils.getNowDate());
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        task.setIsHeadPush(isTaskHeaderPush(userId,task.getDeptId())?"1":"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.getServiceTime() != null) {
            task.setPlannedStartTime(createVO.getServiceTime());
        }
        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);
            }
        }
        // 设置地址和坐标信息
        setAddressAndCoordinatesFromVO(task, createVO);
        // 设置任务类型特定信息
        setTaskTypeSpecificInfo(task, createVO);
        // 自动填充缺失的GPS坐标
        autoFillMissingGpsCoordinates(task);
        
        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(DateUtils.getNowDate());
                taskVehicle.setAssignBy(username);
                taskVehicle.setStatus("ASSIGNED");
                taskVehicle.setCreateBy(username);
                taskVehicle.setCreateTime(DateUtils.getNowDate());
                taskVehicle.setUpdateBy(username);
                taskVehicle.setUpdateTime(DateUtils.getNowDate());
                sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
            }
            sysTaskVehicleService.saveTaskVehicles(task.getTaskId(), createVO.getVehicleIds(), username);
        }
        
        // 保存执行人员信息(包含角色类型)
        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
            saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),username);
            sysTaskAssigneeService.saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),username);
        }
        
        // 保存急救转运扩展信息
        if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) {
            saveEmergencyInfo(task.getTaskId(),username, createVO,null,null,null);
            sysEmergencyTaskService.saveEmergencyInfo(task.getTaskId(), username, createVO, null, null, null);
        }
        
        // 保存福祉车扩展信息
        if (result > 0 && "WELFARE".equals(createVO.getTaskType())) {
            saveWelfareInfo(task.getTaskId(),SecurityUtils.getUsername(), createVO);
            sysWelfareTaskService.saveWelfareInfo(task.getTaskId(), SecurityUtils.getUsername(), createVO);
        }
        
        // 记录操作日志
@@ -304,25 +315,7 @@
            ));
        }
        
        // 发布任务分配事件
        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,
                SecurityUtils.getUserId(),
                SecurityUtils.getUsername()
            ));
        }
        
        // 异步同步急救转运任务到旧系统
        if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType()) && legacySystemSyncService != null) {
@@ -352,7 +345,7 @@
     */
    @Override
    @Transactional
    public int insertTask(TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId, String serviceOrdNo, Long userId,String userName, Long deptId, Date createTime, Date updateTime) {
    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){
            task.setTaskCode(createVO.getTaskCode());
@@ -378,40 +371,24 @@
        task.setRemark(createVO.getRemark());
        task.setDelFlag("0");
        Boolean isHeadPush=this.isTaskHeaderPush(userId, deptId);
        if(isHeadPush){
            task.setIsHeadPush("1");
        }else{
            task.setIsHeadPush("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());
        }
        // 设置急救转运特定信息
        // 设置地址和坐标信息
        setAddressAndCoordinatesFromVO(task, createVO);
        // 设置任务类型特定信息(注:insertTask使用plannedStartTime而非serviceTime)
        if (createVO.getTransferTime() != null) {
            task.setPlannedStartTime(createVO.getTransferTime());
        }
        if (createVO.getTransferDistance() != null) {
            task.setEstimatedDistance(createVO.getTransferDistance());
        }
        // 设置福祉车特定信息
        if (createVO.getPlannedStartTime() != null) {
            task.setPlannedStartTime(createVO.getPlannedStartTime());
        }
@@ -421,82 +398,33 @@
        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);
            }
        }
        // 自动填充缺失的GPS坐标
        autoFillMissingGpsCoordinates(task);
        
        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);
            }
            sysTaskVehicleService.saveTaskVehicles(task.getTaskId(), createVO.getVehicleIds(), userName,
                updateTime, createTime, updateTime);
        }
        
        // 保存执行人员信息(包含角色类型)
        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
            saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),userName);
            sysTaskAssigneeService.saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),userName);
        }
        
        // 保存急救转运扩展信息
        if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) {
            saveEmergencyInfo(task.getTaskId(),userName, createVO, serviceOrderId, dispatchOrderId, serviceOrdNo);
            sysEmergencyTaskService.saveEmergencyInfo(task.getTaskId(), userName, createVO, serviceOrderId, dispatchOrderId, serviceOrdNo);
        }
        
        // 保存福祉车扩展信息
        if (result > 0 && "WELFARE".equals(createVO.getTaskType())) {
            saveWelfareInfo(task.getTaskId(),userName, createVO);
            sysWelfareTaskService.saveWelfareInfo(task.getTaskId(), userName, createVO);
        }
        
        // 记录操作日志
@@ -517,16 +445,23 @@
            ));
        }
        
        // 发布任务分配事件
        if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) {
            List<Long> assigneeIds = createVO.getAssignees().stream()
        if(result>0) {
            this.sendEmeryTaskProcess(task, dispatchOrderId);
        }
        return result;
    }
    private void sendTaskAssigneeEvent(TaskCreateVO createVO,SysTask task,Long userId,String userName){
        List<Long> assigneeIds = createVO.getAssignees().stream()
                .map(assignee -> assignee.getUserId())
                .collect(Collectors.toList());
            List<String> assigneeNames = createVO.getAssignees().stream()
        List<String> assigneeNames = createVO.getAssignees().stream()
                .map(assignee -> assignee.getUserName())
                .collect(Collectors.toList());
            eventPublisher.publishEvent(new TaskAssignedEvent(
        eventPublisher.publishEvent(new TaskAssignedEvent(
                this,
                task.getTaskId(),
                task.getTaskCode(),
@@ -534,12 +469,7 @@
                assigneeNames,
                userId,
                userName
            ));
        }
        return result;
        ));
    }
    /**
@@ -555,6 +485,7 @@
        if (oldTask == null) {
            throw new RuntimeException("任务不存在");
        }
        Long userId = SecurityUtils.getUserId();
        String userName = SecurityUtils.getUsername();
        
        SysTask task = new SysTask();
@@ -566,6 +497,8 @@
        task.setUpdateBy(userName);
        task.setUpdateTime(updateVO.getUpdateTime() != null ? updateVO.getUpdateTime() : DateUtils.getNowDate());
        task.setRemark(updateVO.getRemark());
        
        // 设置通用地址和坐标信息
        task.setDepartureAddress(updateVO.getDepartureAddress());
@@ -589,13 +522,16 @@
        // 如果更新了部门ID
        if (updateVO.getDeptId() != null) {
            task.setDeptId(updateVO.getDeptId());
        }else{
            task.setDeptId(oldTask.getDeptId());
        }
        
        // 如果更新了任务编号
        if (updateVO.getTaskCode() != null) {
            task.setTaskCode(updateVO.getTaskCode());
        }
        //设置总部推送
        task.setIsHeadPush(this.isTaskHeaderPush(oldTask.getCreatorId(), task.getDeptId())?"1":"0");
        // 自动获取出发地GPS坐标(如果更新了地址但缺失坐标)
        if (updateVO.getDepartureAddress() != null && 
            (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null) && 
@@ -609,7 +545,7 @@
                    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"));
//                        log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                    }
                } catch (Exception e) {
                    log.error("自动获取出发地GPS坐标失败", e);
@@ -630,12 +566,17 @@
                    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"));
//                        log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                    }
                } catch (Exception e) {
                    log.error("自动获取目的地GPS坐标失败", e);
                }
            }
        }
        if(updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty()){
           TaskCreateVO.AssigneeInfo assigneeInfo= updateVO.getAssignees().get(0);
            task.setAssigneeId(assigneeInfo.getUserId());
            task.setAssigneeName(assigneeInfo.getUserName());
        }
        // 用于跟踪是否需要重新同步(车辆、人员、地址、成交价变更)
        boolean needResync = true;
@@ -645,33 +586,9 @@
        
        // 更新车辆关联
        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()));
            // 只有车辆发生变化时才更新
            boolean vehiclesChanged = sysTaskVehicleService.updateTaskVehicles(
                updateVO.getTaskId(), updateVO.getVehicleIds(), userName);
            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;
            }
@@ -679,100 +596,49 @@
        
        // 更新执行人员(检测人员变更)
        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));
            // 只有执行人员发生变化时才更新
            boolean assigneesChanged = sysTaskAssigneeService.updateTaskAssignees(
                updateVO.getTaskId(), updateVO.getAssignees(), userName);
            if (assigneesChanged) {
                // 删除旧的执行人员关联
                sysTaskAssigneeMapper.deleteSysTaskAssigneeByTaskId(updateVO.getTaskId());
                // 添加新的执行人员关联
                if (!updateVO.getAssignees().isEmpty()) {
                    saveTaskAssignees(updateVO.getTaskId(), updateVO.getAssignees(), userName);
                }
                // 标记需要重新同步(人员变更)
                needResync = true;
            }
        }
        Long dispatchOrderId=0L;
        // 更新急救转运扩展信息(检测地址和成交价变更)
        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;
            }
            sysEmergencyTaskService.updateEmergencyInfoFromUpdateVO(oldEmergency, updateVO, userName);
          dispatchOrderId=  oldEmergency.getLegacyDispatchOrdId();
            sysEmergencyTaskService.markNeedResyncIfNecessary(updateVO.getTaskId(), oldTask, updateVO, updateFromLegacy);
        }
        
        // 更新福祉车扩展信息
        if (result > 0 && "WELFARE".equals(oldTask.getTaskType())) {
            if (updateVO.getPassenger() != null || updateVO.getStartAddress() != null || updateVO.getEndAddress() != null) {
                updateWelfareInfoFromCreateVO(updateVO.getTaskId(), updateVO, userName);
                sysWelfareTaskService.updateWelfareInfo(updateVO.getTaskId(), updateVO, userName);
            }
        }
        
        // 如果是急救转运任务且有变更,标记需要重新同步
        if (result > 0 && "EMERGENCY_TRANSFER".equals(oldTask.getTaskType()) && needResync && !updateFromLegacy) {
            try {
                sysTaskEmergencyService.markNeedResync(updateVO.getTaskId());
            } catch (Exception e) {
                // 标记失败不影响主流程
            }
            sysEmergencyTaskService.markNeedResyncIfNecessary(updateVO.getTaskId(), oldTask, updateVO, updateFromLegacy);
        }
        
        // 记录操作日志
        if (result > 0) {
            recordTaskLog(updateVO.getTaskId(), "UPDATE", "更新任务",
                buildTaskDescription(oldTask), buildTaskDescription(task),
                SecurityUtils.getUserId(), userName);
                userId, userName);
        }
        if(result > 0 && oldTask.getTaskStatus().equals(TaskStatus.PENDING.getCode())
                && updateVO.getAssignees() != null
                && !updateVO.getAssignees().isEmpty()
                && LongUtil.isNotEmpty(dispatchOrderId)){
            this.sendTaskAssigneeEvent(updateVO,oldTask,userId,userName);
        }
        return result;
    }
@@ -791,31 +657,47 @@
     * @return 结果
     */
    @Override
    public int updateTask(TaskUpdateVO updateVO, String serviceOrderId, String dispatchOrderId, String serviceOrdNo,
    public int updateTask(TaskUpdateVO updateVO, Long serviceOrderId, Long dispatchOrderId, String serviceOrdNo,
                         Long userId, String userName, Long deptId, Date createTime, Date updateTime) {
//        log.info("开始更新任务 ServiceOrdID: {} , dispatchOrdId:{}", serviceOrderId,dispatchOrderId);
        // 通过旧系统服务单ID查找任务
        SysTaskEmergency taskEmergency = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(Long.parseLong(serviceOrderId));
        // 获取旧任务信息,用于判断地址是否变更
        SysTaskEmergency taskEmergency = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(serviceOrderId);
        Long taskId = taskEmergency.getTaskId();
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        updateVO.setTaskId(taskId);
        SysTask task = new SysTask();
        task.setTaskId(taskId);
        if(updateVO.getTaskStatus()!=null){
            task.setTaskStatus(updateVO.getTaskStatus());
        }
        task.setTaskDescription(updateVO.getTaskDescription());
        task.setPlannedStartTime(updateVO.getPlannedStartTime());
        task.setPlannedEndTime(updateVO.getPlannedEndTime());
        task.setAssigneeId(updateVO.getAssigneeId());
        if(updateVO.getActualStartTime() != null) {
            task.setActualStartTime(updateVO.getActualStartTime());
        }
        if(updateVO.getActualEndTime() != null) {
            task.setActualEndTime(updateVO.getActualEndTime());
        }
        if(deptId!=null){
            task.setDeptId(deptId);
        }
//        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());
        if(updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty()){
            TaskCreateVO.AssigneeInfo assigneeInfo= updateVO.getAssignees().get(0);
            task.setAssigneeId(assigneeInfo.getUserId());
            task.setAssigneeName(assigneeInfo.getUserName());
        }
        // 如果更新了部门ID
        if (updateVO.getDeptId() != null) {
            task.setDeptId(updateVO.getDeptId());
@@ -825,13 +707,18 @@
        if (updateVO.getTaskCode() != null) {
            task.setTaskCode(updateVO.getTaskCode());
        }
        // 获取旧任务信息,用于判断地址是否变更
        SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(taskId);
//        task.setDepartureLongitude(updateVO.getDepartureLongitude());
//        task.setDepartureLatitude(updateVO.getDepartureLatitude());
//        task.setDestinationLongitude(updateVO.getDestinationLongitude());
//        task.setDestinationLatitude(updateVO.getDestinationLatitude());
        Boolean modifyOutLongLat = false;
        // 自动获取出发地GPS坐标(如果地址变更且缺失坐标)
        if (oldTask != null && updateVO.getDepartureAddress() != null
            && !updateVO.getDepartureAddress().equals(oldTask.getDepartureAddress())
        if (task != null && updateVO.getDepartureAddress() != null
            && !updateVO.getDepartureAddress().equals(task.getDepartureAddress())
            && (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null)
            && mapService != null) {
            try {
@@ -842,16 +729,23 @@
                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"));
                    modifyOutLongLat = true;
//                    log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取出发地GPS坐标失败", e);
            }
        }
        task.setDepartureAddress(updateVO.getDepartureAddress());
        if(!modifyOutLongLat){
            task.setDepartureLongitude(updateVO.getDepartureLongitude());
            task.setDepartureLatitude(updateVO.getDepartureLatitude());
        }
        Boolean modifyInLongLat = false;
        // 自动获取目的地GPS坐标(如果地址变更且缺失坐标)
        if (oldTask != null && updateVO.getDestinationAddress() != null
            && !updateVO.getDestinationAddress().equals(oldTask.getDestinationAddress())
        if (task != null && updateVO.getDestinationAddress() != null
            && !updateVO.getDestinationAddress().equals(task.getDestinationAddress())
            && (updateVO.getDestinationLongitude() == null || updateVO.getDestinationLatitude() == null)
            && mapService != null) {
            try {
@@ -862,94 +756,88 @@
                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"));
                    modifyInLongLat = true;
//                    log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
                }
            } catch (Exception e) {
                log.error("自动获取目的地GPS坐标失败", e);
            }
        }
        task.setDestinationAddress(updateVO.getDestinationAddress());
        if(!modifyInLongLat){
            task.setDestinationLongitude(updateVO.getDestinationLongitude());
            task.setDestinationLatitude(updateVO.getDestinationLatitude());
        }
        
        int result = sysTaskMapper.updateSysTask(task);
//        log.info("更新转运任务,ServiceOrdID:{},dispatchOrderId:{},result:{}",serviceOrderId,dispatchOrderId,result);
//        log.info("更新任务车辆 ServiceOrdID: {} , dispatchOrdId:{},VehicleIds:{}", serviceOrderId,dispatchOrderId,updateVO.getVehicleIds());
        // 更新车辆关联
        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);
                }
            }
//            log.info("更新车辆关联 ServiceOrdID:{},dispatchOrderId:{}",serviceOrderId,dispatchOrderId);
            sysTaskVehicleService.updateTaskVehicles(taskId, updateVO.getVehicleIds(), userName);
        }
        Boolean hasAssignee = updateVO.getAssigneeId() != null && !updateVO.getAssignees().isEmpty() ;
//        log.info("更新转运任务,ServiceOrdID:{},dispatchOrderId:{},result:{}, hasAssignee:{}",serviceOrderId,dispatchOrderId,result,hasAssignee);
        // 更新执行人员(检测人员变更)
        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 && hasAssignee) {
//            log.info("更新执行人员 ServiceOrdID:{},dispatchOrderId:{}",serviceOrderId,dispatchOrderId);
            sysTaskAssigneeService.updateTaskAssignees(taskId, updateVO.getAssignees(), userName);
        }
        // 更新急救转运扩展信息
        if (result > 0) {
            // 更新旧系统ID
            if (serviceOrderId != null) {
                taskEmergency.setLegacyServiceOrdId(Long.parseLong(serviceOrderId));
            }
            if (dispatchOrderId != null) {
                taskEmergency.setLegacyDispatchOrdId(Long.parseLong(dispatchOrderId));
            taskEmergency.setLegacyServiceOrdId(serviceOrderId);
            if (LongUtil.isNotEmpty(dispatchOrderId)) {
                taskEmergency.setLegacyDispatchOrdId(dispatchOrderId);
                taskEmergency.setDispatchSyncStatus(2);
                taskEmergency.setDispatchSyncTime(new Date());
                taskEmergency.setDispatchSyncErrorMsg("旧系统同步过来");
            }
            if (serviceOrdNo != null) {
                taskEmergency.setLegacyServiceOrdNo(serviceOrdNo);
            }
            taskEmergency.setUpdateTime(DateUtils.getNowDate());
            Boolean hasEmergencyInfo = updateVO.getHospitalOut() != null || updateVO.getHospitalIn() != null || updateVO.getPatient() != null;
            // 使用TaskCreateVO的字段来更新急救转运信息
            if (updateVO.getHospitalOut() != null || updateVO.getHospitalIn() != null || updateVO.getPatient() != null) {
                updateEmergencyInfoFromCreateVO(taskId, updateVO, userName);
            if (hasEmergencyInfo) {
                sysEmergencyTaskService.updateEmergencyInfoFromCreateVO(taskEmergency, updateVO, userName);
            }
           SysTaskEmergency emergency= sysEmergencyTaskService.selectSysTaskEmergencyByTaskId(taskId);
            dispatchOrderId = emergency.getLegacyDispatchOrdId();
        }
        if(updateVO.getTaskStatus()!=null
                && updateVO.getTaskStatus().equals(TaskStatus.PENDING.getCode())
                && updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty()
                && LongUtil.isNotEmpty(dispatchOrderId)){
            this.sendTaskAssigneeEvent(updateVO,task,userId,userName);
        }
        return result;
    }
    private void sendEmeryTaskProcess(SysTask task,Long dispatchOrderId){
        Long taskId = task.getTaskId();
        String taskCode = task.getShowTaskCode();
        if(task.getTaskStatus()!=null && task.getTaskStatus().equals(TaskStatus.PENDING.getCode())){
            //如果没有分配人员,且没有调度单,不是广州总公司的就需要发送通知跟进
            if(LongUtil.isEmpty(dispatchOrderId)){
                if(!task.getDeptId().equals(DeptUtil.GUANGZHOU_DEPT_ID) && (task.getAssignees()==null  || task.getAssignees().isEmpty())){
                    //发送通知
                    eventPublisher.publishEvent(new TaskOnlyServerOrderSyncEvent(this, taskId, taskCode));
                }
            }
        }
    }
    /**
     * 批量删除任务管理
     * 
@@ -1128,39 +1016,7 @@
    @Override
    @Transactional
    public Long uploadAttachment(Long taskId, MultipartFile file, String category) {
        try {
            // 上传文件,返回相对路径(如:/task/2025/01/15/xxx.jpg)
            String fileName = category+"_"+System.currentTimeMillis()+"_"+file.getOriginalFilename();
            fileName=saveLocalPath(fileName,file.getInputStream());
            SysTaskAttachment attachment = new SysTaskAttachment();
            attachment.setTaskId(taskId);
            attachment.setFileName(file.getOriginalFilename());
            // 保存相对路径,不包含 baseDir
            attachment.setFilePath(fileName);
            attachment.setFileSize(file.getSize());
            attachment.setFileType(getFileType(file.getOriginalFilename()));
            attachment.setAttachmentCategory(category);
            attachment.setUploadTime(DateUtils.getNowDate());
            attachment.setUploadBy(SecurityUtils.getUsername());
            Long result = sysTaskAttachmentMapper.insertSysTaskAttachment(attachment);
            // 记录操作日志
            if (result > 0) {
                String categoryDesc = getCategoryDesc(category);
                recordTaskLog(taskId, "UPDATE", "上传附件", null,
                             "上传文件:" + file.getOriginalFilename() + "(分类:" + categoryDesc + ")",
                             SecurityUtils.getUserId(), SecurityUtils.getUsername());
            }
            return attachment.getAttachmentId();
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败:" + e.getMessage());
        }
        return sysTaskAttachmentService.uploadAttachment(taskId, file, category);
    }
    
    /**
@@ -1175,132 +1031,9 @@
    @Override
    @Transactional
    public Long uploadAttachmentFromWechat(Long taskId, String accessToken, String mediaId, String category) {
        try {
            // 从微信服务器下载文件
            String wechatUrl = String.format(
                "https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s",
                accessToken, mediaId
            );
            byte[] fileBytes = downloadFromUrl(wechatUrl);
            if (fileBytes == null || fileBytes.length == 0) {
                throw new RuntimeException("从微信下载文件失败");
            }
            // 生成文件名(使用mediaId作为文件名的一部分)
            String fileName = "wx_" + mediaId.substring(0, Math.min(20, mediaId.length())) + "_" + System.currentTimeMillis() + ".jpg";
            // 保存到本地
            String relativeFilePath = saveLocalPath(fileName, fileBytes);
            // 保存附件记录
            SysTaskAttachment attachment = new SysTaskAttachment();
            attachment.setTaskId(taskId);
            attachment.setFileName(fileName);
            // 保存相对路径
            attachment.setFilePath(relativeFilePath);
            attachment.setFileSize((long) fileBytes.length);
            attachment.setFileType("jpg");
            attachment.setAttachmentCategory(category);
            attachment.setUploadTime(DateUtils.getNowDate());
            attachment.setUploadBy(SecurityUtils.getUsername());
            Long result = sysTaskAttachmentMapper.insertSysTaskAttachment(attachment);
            // 记录操作日志
            if (result > 0) {
                String categoryDesc = getCategoryDesc(category);
                recordTaskLog(taskId, "UPDATE", "上传附件", null,
                             "通过微信上传文件:" + fileName + "(分类:" + categoryDesc + ")",
                             SecurityUtils.getUserId(), SecurityUtils.getUsername());
            }
            return attachment.getAttachmentId();
        } catch (Exception e) {
            throw new RuntimeException("从微信上传文件失败:" + e.getMessage());
        }
        return sysTaskAttachmentService.uploadAttachmentFromWechat(taskId, accessToken, mediaId, category);
    }
    private static String saveLocalPath(String fileName, byte[] fileBytes) throws IOException {
        String baseDir = FileUploadUtils.getDefaultBaseDir();
        String datePath = DateUtils.datePath();
        String uploadDir = baseDir + "/task/" + datePath;
        // 创建目录
        File uploadPath = new File(uploadDir);
        if (!uploadPath.exists()) {
            uploadPath.mkdirs();
        }
        // 保存文件
        String filePath = uploadDir + "/" + fileName;
        File file = new File(filePath);
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(fileBytes);
        }
        // 生成相对路径(不包含baseDir)
        String relativeFilePath = "/task/" + datePath + "/" + fileName;
        return relativeFilePath;
    }
    private String saveLocalPath(String fileName,InputStream stream){
        String baseDir = FileUploadUtils.getDefaultBaseDir();
        String datePath = DateUtils.datePath();
        String uploadDir = baseDir + "/task/" + datePath;
        // 创建目录
        File uploadPath = new File(uploadDir);
        if (!uploadPath.exists()) {
            uploadPath.mkdirs();
        }
        // 保存文件
        String filePath = uploadDir + "/" + fileName;
       //将inputstream写入文件
        try (OutputStream os = new FileOutputStream(filePath)) {
            byte[] buffer = new byte[1024]; // 缓冲区,减少 IO 次数
            int bytesRead;
            // 循环读取输入流中的数据,写入输出流
            while ((bytesRead = stream.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.flush(); // 强制刷新缓冲区,确保数据写入文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 生成相对路径(不包含baseDir)
        String relativeFilePath = "/task/" + datePath + "/" + fileName;
        return relativeFilePath;
    }
    /**
     * 从 URL 下载文件
     */
    private byte[] downloadFromUrl(String fileUrl) throws IOException {
        URL url = new URL(fileUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(30000);
        try (InputStream inputStream = connection.getInputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            return outputStream.toByteArray();
        } finally {
            connection.disconnect();
        }
    }
    /**
     * 删除任务附件
@@ -1311,28 +1044,7 @@
    @Override
    @Transactional
    public int deleteAttachment(Long attachmentId) {
        SysTaskAttachment attachment = sysTaskAttachmentMapper.selectSysTaskAttachmentByAttachmentId(attachmentId);
        if (attachment == null) {
            throw new RuntimeException("附件不存在");
        }
        // 删除物理文件
        try {
            FileUtils.deleteFile(attachment.getFilePath());
        } catch (Exception e) {
            // 忽略文件删除失败
        }
        int result = sysTaskAttachmentMapper.deleteSysTaskAttachmentByAttachmentId(attachmentId);
        // 记录操作日志
        if (result > 0) {
            recordTaskLog(attachment.getTaskId(), "UPDATE", "删除附件",
                         "删除文件:" + attachment.getFileName(), null,
                         SecurityUtils.getUserId(), SecurityUtils.getUsername());
        }
        return result;
        return sysTaskAttachmentService.deleteAttachment(attachmentId);
    }
    
    /**
@@ -1343,17 +1055,12 @@
     */
    @Override
    public SysTaskAttachment getAttachmentById(Long attachmentId) {
        SysTaskAttachment attachment = sysTaskAttachmentMapper.selectSysTaskAttachmentByAttachmentId(attachmentId);
        if (attachment != null) {
            // 拼接完整URL
            buildAttachmentUrl(attachment);
        }
        return attachment;
        return sysTaskAttachmentService.getAttachmentById(attachmentId);
    }
    @Override
    public List<SysTaskAttachment> getAttachmentsByTaskId(Long taskId) {
        return sysTaskAttachmentMapper.selectSysTaskAttachmentByTaskId(taskId);
        return sysTaskAttachmentService.getAttachmentsByTaskId(taskId);
    }
    /**
@@ -1367,21 +1074,7 @@
    @Override
    @Transactional
    public int assignVehicleToTask(Long taskId, Long vehicleId, String remark,Long userId,String userName) {
        // 检查是否已经分配
        int exists = sysTaskVehicleMapper.checkTaskVehicleExists(taskId, vehicleId);
        if (exists > 0) {
            throw new RuntimeException("车辆已经分配给该任务");
        }
        SysTaskVehicle taskVehicle = new SysTaskVehicle();
        taskVehicle.setTaskId(taskId);
        taskVehicle.setVehicleId(vehicleId);
        taskVehicle.setAssignTime(DateUtils.getNowDate());
        taskVehicle.setAssignBy(userName);
        taskVehicle.setStatus("ASSIGNED");
        taskVehicle.setRemark(remark);
        int result = sysTaskVehicleMapper.insertSysTaskVehicle(taskVehicle);
        int result = sysTaskVehicleService.assignVehicleToTask(taskId, vehicleId, remark, userId, userName);
        
        // 记录操作日志
        if (result > 0) {
@@ -1403,7 +1096,7 @@
    @Override
    @Transactional
    public int unassignVehicleFromTask(Long taskId, Long vehicleId) {
        int result = sysTaskVehicleMapper.deleteSysTaskVehicleByTaskIdAndVehicleId(taskId, vehicleId);
        int result = sysTaskVehicleService.unassignVehicleFromTask(taskId, vehicleId);
        
        // 记录操作日志
        if (result > 0) {
@@ -1426,35 +1119,13 @@
    @Override
    @Transactional
    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 = userName;
        for (Long vehicleId : vehicleIds) {
            // 检查是否已经分配
            int exists = sysTaskVehicleMapper.checkTaskVehicleExists(taskId, vehicleId);
            if (exists == 0) {
                SysTaskVehicle taskVehicle = new SysTaskVehicle();
                taskVehicle.setTaskId(taskId);
                taskVehicle.setVehicleId(vehicleId);
                taskVehicle.setAssignTime(now);
                taskVehicle.setAssignBy(assignBy);
                taskVehicle.setStatus("ASSIGNED");
                taskVehicle.setRemark(remark);
                taskVehicles.add(taskVehicle);
            }
        }
        int result = 0;
        if (!taskVehicles.isEmpty()) {
            result = sysTaskVehicleMapper.batchInsertSysTaskVehicle(taskVehicles);
        }
        int result = sysTaskVehicleService.assignMultipleVehiclesToTask(taskId, vehicleIds, remark, userId, userName);
        
        // 记录操作日志
        if (result > 0) {
            recordTaskLog(taskId, "ASSIGN", "批量分配车辆", null, 
                         "分配车辆数量:" + result + ",备注:" + remark, 
                         userId,userName);
                         userId, userName);
        }
        
        return result;
@@ -1468,7 +1139,7 @@
     */
    @Override
    public List<SysTaskVehicle> getTaskVehicles(Long taskId) {
        return sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId);
        return sysTaskVehicleService.getTaskVehicles(taskId);
    }
    /**
@@ -1480,34 +1151,7 @@
     */
    @Override
    public List<SysTaskVehicle> getAvailableVehicles(Long deptId, String taskType) {
        List<SysTaskVehicle> availableVehicles = new ArrayList<>();
        try {
            // 查询所有状态为正常的车辆(不限制部门)
            VehicleInfo queryParam = new VehicleInfo();
            queryParam.setStatus("0"); // 0表示正常状态
            // 不设置deptId,查询所有部门的车辆
            queryParam.setDeptId(deptId);
            List<VehicleInfo> vehicles = vehicleInfoMapper.selectVehicleInfoList(queryParam);
            // 转换为SysTaskVehicle对象
            for (VehicleInfo vehicle : vehicles) {
                SysTaskVehicle taskVehicle = new SysTaskVehicle();
                taskVehicle.setVehicleId(vehicle.getVehicleId());
                taskVehicle.setVehicleNo(vehicle.getVehicleNo());
                taskVehicle.setVehicleType(vehicle.getVehicleType());
                taskVehicle.setVehicleBrand(vehicle.getVehicleBrand());
                taskVehicle.setVehicleModel(vehicle.getVehicleModel());
                taskVehicle.setDeptName(vehicle.getDeptName()); // 添加部门名称
                availableVehicles.add(taskVehicle);
            }
        } catch (Exception e) {
            // 如果查询失败,记录日志并返回空列表
            System.err.println("查询可用车辆失败: " + e.getMessage());
        }
        return availableVehicles;
        return sysTaskVehicleService.getAvailableVehicles(deptId, taskType);
    }
    /**
@@ -1538,7 +1182,14 @@
     */
    @Override
    public List<SysTask> selectMyTasks(Long userId) {
        return sysTaskMapper.selectMyTasks(userId);
        List<SysTask> list = sysTaskMapper.selectMyTasks(userId);
        list.stream().forEach(task -> {
            if(task.getTaskType().equals("EMERGENCY_TRANSFER")){
                task.setEmergencyInfo(sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId()));
            }
        });
        return list;
    }
    /**
@@ -1552,14 +1203,9 @@
        SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
        if (task != null) {
            // 查询关联车辆
            task.setAssignedVehicles(sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId));
            // 查询附件
            List<SysTaskAttachment> attachments = sysTaskAttachmentMapper.selectSysTaskAttachmentByTaskId(taskId);
            // 为每个附件拼接完整URL
            if (attachments != null && !attachments.isEmpty()) {
                attachments.forEach(this::buildAttachmentUrl);
            }
            task.setAttachments(attachments);
            task.setAssignedVehicles(sysTaskVehicleService.getTaskVehicles(taskId));
            // 查询附件(已自动拼接完整URL)
            task.setAttachments(sysTaskAttachmentService.getAttachmentsByTaskId(taskId));
            // 查询操作日志
            task.setOperationLogs(sysTaskLogMapper.selectSysTaskLogByTaskId(taskId));
            // 查询执行人员列表
@@ -1571,7 +1217,7 @@
            }
            // 加载福祉车扩展信息
            else if ("WELFARE".equals(task.getTaskType())) {
                SysTaskWelfare welfareInfo = sysTaskWelfareMapper.selectSysTaskWelfareByTaskId(taskId);
                SysTaskWelfare welfareInfo = sysWelfareTaskService.getWelfareInfoByTaskId(taskId);
                task.setWelfareInfo(welfareInfo);
            }
        }
@@ -1598,13 +1244,7 @@
     */
    @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;
        return sysEmergencyTaskService.hasLegacyServiceOrdId(taskId);
    }
    /**
@@ -1615,13 +1255,7 @@
     */
    @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;
        return sysEmergencyTaskService.hasLegacyDispatchOrdId(taskId);
    }
    /**
@@ -1632,11 +1266,7 @@
     */
    @Override
    public boolean existsByLegacyServiceOrdId(Long legacyServiceOrdId) {
        if (legacyServiceOrdId == null) {
            return false;
        }
        SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectByLegacyServiceOrdId(legacyServiceOrdId);
        return emergencyInfo != null;
        return sysEmergencyTaskService.existsByLegacyServiceOrdId(legacyServiceOrdId);
    }
    /**
@@ -1647,11 +1277,7 @@
     */
    @Override
    public boolean existsByLegacyDispatchOrdId(Long legacyDispatchOrdId) {
        if (legacyDispatchOrdId == null) {
            return false;
        }
        SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectByLegacyDispatchOrdId(legacyDispatchOrdId);
        return emergencyInfo != null;
        return sysEmergencyTaskService.existsByLegacyDispatchOrdId(legacyDispatchOrdId);
    }
    @Autowired
@@ -1757,21 +1383,109 @@
        return sb.toString();
    }
    /**
     * 获取文件类型
     * 从TaskCreateVO设置地址和坐标信息到任务对象
     * 
     * @param fileName 文件名
     * @return 文件类型
     * @param task 任务对象
     * @param createVO 创建VO
     */
    private String getFileType(String fileName) {
        if (StringUtils.isEmpty(fileName)) {
            return "";
    private void setAddressAndCoordinatesFromVO(SysTask task, TaskCreateVO createVO) {
        // 设置通用地址和坐标信息
        if (createVO.getDepartureAddress() != null) {
            task.setDepartureAddress(createVO.getDepartureAddress());
        }
        int lastDotIndex = fileName.lastIndexOf(".");
        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) {
            return fileName.substring(lastDotIndex + 1).toLowerCase();
        if (createVO.getDestinationAddress() != null) {
            task.setDestinationAddress(createVO.getDestinationAddress());
        }
        return "";
        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());
        }
    }
    /**
     * 设置任务类型特定信息(急救转运/福祉车)
     *
     * @param task 任务对象
     * @param createVO 创建VO
     */
    private void setTaskTypeSpecificInfo(SysTask task, TaskCreateVO createVO) {
        // 设置急救转运特定信息
        if (createVO.getTransferTime() != null) {
            task.setPlannedStartTime(createVO.getTransferTime());
        }
        if (createVO.getTransferDistance() != null) {
            task.setEstimatedDistance(createVO.getTransferDistance());
        }
        // 设置福祉车特定信息
        if (createVO.getServiceTime() != null) {
            task.setPlannedStartTime(createVO.getServiceTime());
        }
        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坐标
     *
     * @param task 任务对象
     */
    private void autoFillMissingGpsCoordinates(SysTask task) {
        // 自动获取出发地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")));
                }
            } 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")));
                }
            } catch (Exception e) {
                log.error("自动获取目的地GPS坐标失败", e);
            }
        }
    }
    /**
@@ -1805,473 +1519,6 @@
    }
    /**
     * 保存任务执行人员信息(包含角色类型)
     *
     * @param taskId 任务ID
     * @param 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 = userName;
        for (int i = 0; i < assignees.size(); i++) {
            TaskCreateVO.AssigneeInfo assigneeInfo = assignees.get(i);
            SysTaskAssignee taskAssignee = new SysTaskAssignee();
            taskAssignee.setTaskId(taskId);
            taskAssignee.setUserId(assigneeInfo.getUserId());
            taskAssignee.setUserName(assigneeInfo.getUserName());
            taskAssignee.setUserType(assigneeInfo.getUserType());
            // 第一个执行人员为主要执行人
            taskAssignee.setIsPrimary(i == 0 ? "1" : "0");
            taskAssignee.setSortOrder(i);
            taskAssignee.setCreateTime(now);
            taskAssignee.setCreateBy(currentUser);
            taskAssignee.setUpdateTime(now);
            taskAssignee.setUpdateBy(currentUser);
            taskAssignees.add(taskAssignee);
        }
        // 批量保存
        if (!taskAssignees.isEmpty()) {
            sysTaskAssigneeMapper.batchInsertSysTaskAssignee(taskAssignees);
        }
    }
    /**
     * 保存急救转运任务扩展信息
     *
     * @param taskId 任务ID
     * @param createVO 任务创建对象
     */
    private void saveEmergencyInfo(Long taskId,String createUserName, TaskCreateVO createVO,String serviceOrderId,String dispatchOrderId, String serviceOrdNo) {
        SysTaskEmergency emergencyInfo = new SysTaskEmergency();
        emergencyInfo.setTaskId(taskId);
        // 设置患者信息
        if (createVO.getPatient() != null) {
            emergencyInfo.setPatientContact(createVO.getPatient().getContact());
            emergencyInfo.setPatientPhone(createVO.getPatient().getPhone());
            emergencyInfo.setPatientName(createVO.getPatient().getName());
            emergencyInfo.setPatientGender(createVO.getPatient().getGender());
            emergencyInfo.setPatientIdCard(createVO.getPatient().getIdCard());
            emergencyInfo.setPatientCondition(createVO.getPatient().getCondition());
        }
        // 设置转出医院信息
        if (createVO.getHospitalOut() != null) {
            emergencyInfo.setHospitalOutId(createVO.getHospitalOut().getId());
            emergencyInfo.setHospitalOutName(createVO.getHospitalOut().getName());
            emergencyInfo.setHospitalOutDepartment(createVO.getHospitalOut().getDepartment());
            emergencyInfo.setHospitalOutDepartmentId(createVO.getHospitalOut().getDepartmentId());
            emergencyInfo.setHospitalOutBedNumber(createVO.getHospitalOut().getBedNumber());
            emergencyInfo.setHospitalOutAddress(createVO.getHospitalOut().getAddress());
            // 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);
                }
            }
        }
        // 设置转入医院信息
        if (createVO.getHospitalIn() != null) {
            emergencyInfo.setHospitalInId(createVO.getHospitalIn().getId());
            emergencyInfo.setHospitalInName(createVO.getHospitalIn().getName());
            emergencyInfo.setHospitalInDepartment(createVO.getHospitalIn().getDepartment());
            emergencyInfo.setHospitalInDepartmentId(createVO.getHospitalIn().getDepartmentId());
            emergencyInfo.setHospitalInBedNumber(createVO.getHospitalIn().getBedNumber());
            emergencyInfo.setHospitalInAddress(createVO.getHospitalIn().getAddress());
            // 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);
                    }
                }
        }
        // 设置费用信息
        emergencyInfo.setTransferDistance(createVO.getTransferDistance());
        emergencyInfo.setTransferPrice(createVO.getPrice());
        // 设置单据类型ID
        emergencyInfo.setDocumentTypeId(createVO.getDocumentTypeId());
        // 设置任务类型ID
        emergencyInfo.setTaskTypeId(createVO.getTaskTypeId());
        // 设置病情ID列表(将List<Long>转换为逗号分隔的字符串)
        if (createVO.getDiseaseIds() != null && !createVO.getDiseaseIds().isEmpty()) {
            String diseaseIdsStr = createVO.getDiseaseIds().stream()
                .map(String::valueOf)
                .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(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);
    }
    /**
     * 保存福祉车任务扩展信息
     *
     * @param taskId 任务ID
     * @param createVO 任务创建对象
     */
    private void saveWelfareInfo(Long taskId,String userName, TaskCreateVO createVO) {
        SysTaskWelfare welfareInfo = new SysTaskWelfare();
        welfareInfo.setTaskId(taskId);
        // 设置乘客信息
        if (createVO.getPassenger() != null) {
            welfareInfo.setPassengerContact(createVO.getPassenger().getContact());
            welfareInfo.setPassengerPhone(createVO.getPassenger().getPhone());
        }
        // 设置地址信息
        welfareInfo.setPickupAddress(createVO.getStartAddress());
        welfareInfo.setDestinationAddress(createVO.getEndAddress());
        // 设置GPS坐标
        welfareInfo.setPickupLongitude(createVO.getDepartureLongitude());
        welfareInfo.setPickupLatitude(createVO.getDepartureLatitude());
        welfareInfo.setDestinationLongitude(createVO.getDestinationLongitude());
        welfareInfo.setDestinationLatitude(createVO.getDestinationLatitude());
        // 设置距离和费用
        // 优先使用福祉车专用的distance字段,如果没有则使用通用的estimatedDistance
        BigDecimal serviceDistance = createVO.getDistance() != null ? createVO.getDistance() : createVO.getEstimatedDistance();
        welfareInfo.setServiceDistance(serviceDistance);
        welfareInfo.setServicePrice(createVO.getPrice());
        // 系统字段
        welfareInfo.setCreateTime(DateUtils.getNowDate());
        welfareInfo.setUpdateTime(DateUtils.getNowDate());
        welfareInfo.setCreateBy(userName);
        welfareInfo.setUpdateBy(userName);
        sysTaskWelfareMapper.insertSysTaskWelfare(welfareInfo);
    }
    /**
     * 获取附件分类描述
     *
     * @param category 附件分类代码
     * @return 分类描述
     */
    private String getCategoryDesc(String category) {
        if (category == null || category.isEmpty()) {
            return "未分类";
        }
        switch (category) {
            case "1": return "知情同意书";
            case "2": return "病人资料";
            case "3": return "操作记录";
            case "4": return "出车前";
            case "5": return "出车后";
            case "6": return "系安全带";
            default: return "其他";
        }
    }
    /**
     * 构建附件的完整URL
     *
     * @param attachment 附件对象
     */
    private void buildAttachmentUrl(SysTaskAttachment attachment) {
        if (attachment != null && StringUtils.isNotEmpty(attachment.getFilePath())) {
            String imageUrl = imageUrlConfig.getImageUrl();
            if (StringUtils.isNotEmpty(imageUrl)) {
                // 拼接完整URL:域名 + 相对路径
                attachment.setFileUrl(imageUrl + attachment.getFilePath());
            } else {
                // 如果未配置域名,直接使用相对路径
                attachment.setFileUrl(attachment.getFilePath());
            }
        }
    }
    /**
     * 检查任务是否可以出发
     * 检查:
     * 1. 车辆是否有未完成的任务
@@ -2281,11 +1528,11 @@
     * @return AjaxResult 校验结果
     */
    @Override
    public com.ruoyi.common.core.domain.AjaxResult checkTaskCanDepart(Long taskId) {
    public AjaxResult checkTaskCanDepart(Long taskId) {
        // 获取任务详情
        SysTask task = this.getTaskDetail(taskId);
        if (task == null) {
            return com.ruoyi.common.core.domain.AjaxResult.error("任务不存在");
            return AjaxResult.error("任务不存在");
        }
        
        List<Map<String, Object>> conflicts = new ArrayList<>();
@@ -2369,7 +1616,7 @@
        result.put("valid", conflicts.isEmpty());
        result.put("conflicts", conflicts);
        
        return com.ruoyi.common.core.domain.AjaxResult.success(result);
        return AjaxResult.success(result);
    }
    /**
@@ -2381,35 +1628,8 @@
     */
    @Override
    @Transactional
    public com.ruoyi.common.core.domain.AjaxResult setAssigneeReady(Long taskId, Long userId) {
        // 1. 查询执行人关联信息
        List<SysTaskAssignee> assignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
        SysTaskAssignee targetAssignee = assignees.stream()
            .filter(a -> a.getUserId().equals(userId))
            .findFirst()
            .orElse(null);
        if (targetAssignee == null) {
            return com.ruoyi.common.core.domain.AjaxResult.error("您不是该任务的执行人");
        }
        // 2. 更新就绪状态
        targetAssignee.setIsReady("1");
        targetAssignee.setReadyTime(new Date());
        targetAssignee.setUpdateBy(SecurityUtils.getUsername());
        targetAssignee.setUpdateTime(new Date());
        sysTaskAssigneeMapper.updateSysTaskAssignee(targetAssignee);
        // 3. 检查是否所有执行人都已就绪
        boolean allReady = assignees.stream()
            .allMatch(a -> a.getUserId().equals(userId) || "1".equals(a.getIsReady()));
        Map<String, Object> result = new HashMap<>();
        result.put("allReady", allReady);
        result.put("message", "就绪成功");
        return com.ruoyi.common.core.domain.AjaxResult.success(result);
    public AjaxResult setAssigneeReady(Long taskId, Long userId) {
        return sysTaskAssigneeService.setAssigneeReady(taskId, userId);
    }
    /**
@@ -2421,27 +1641,8 @@
     */
    @Override
    @Transactional
    public com.ruoyi.common.core.domain.AjaxResult cancelAssigneeReady(Long taskId, Long userId) {
        // 查询执行人关联信息
        List<SysTaskAssignee> assignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
        SysTaskAssignee targetAssignee = assignees.stream()
            .filter(a -> a.getUserId().equals(userId))
            .findFirst()
            .orElse(null);
        if (targetAssignee == null) {
            return com.ruoyi.common.core.domain.AjaxResult.error("您不是该任务的执行人");
        }
        // 更新就绪状态
        targetAssignee.setIsReady("0");
        targetAssignee.setReadyTime(null);
        targetAssignee.setUpdateBy(SecurityUtils.getUsername());
        targetAssignee.setUpdateTime(new Date());
        sysTaskAssigneeMapper.updateSysTaskAssignee(targetAssignee);
        return com.ruoyi.common.core.domain.AjaxResult.success("已取消就绪");
    public AjaxResult cancelAssigneeReady(Long taskId, Long userId) {
        return sysTaskAssigneeService.cancelAssigneeReady(taskId, userId);
    }
   
}