package com.ruoyi.system.service.impl; import java.io.*; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; import java.net.HttpURLConnection; import java.net.URL; import com.ruoyi.common.core.domain.AjaxResult; 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.file.FileUploadUtils; import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.system.domain.SysTask; import com.ruoyi.system.domain.SysTaskVehicle; import com.ruoyi.system.domain.SysTaskAttachment; import com.ruoyi.system.domain.SysTaskLog; import com.ruoyi.system.domain.SysTaskEmergency; import com.ruoyi.system.domain.SysTaskWelfare; import com.ruoyi.system.domain.SysTaskAssignee; import com.ruoyi.system.domain.enums.TaskStatus; import com.ruoyi.system.domain.VehicleInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; /** * 任务管理Service业务层处理 * * @author ruoyi * @date 2024-01-15 */ @Service public class SysTaskServiceImpl implements ISysTaskService { private static final Logger log = LoggerFactory.getLogger(SysTaskServiceImpl.class); @Autowired private SysTaskMapper sysTaskMapper; @Autowired private SysTaskAttachmentMapper sysTaskAttachmentMapper; @Autowired private SysTaskLogMapper sysTaskLogMapper; @Autowired private SysTaskEmergencyMapper sysTaskEmergencyMapper; @Autowired private SysTaskAssigneeMapper sysTaskAssigneeMapper; @Autowired(required = false) private ILegacySystemSyncService legacySystemSyncService; @Autowired private ISysEmergencyTaskService sysEmergencyTaskService; @Autowired private ApplicationEventPublisher eventPublisher; @Autowired private ImageUrlConfig imageUrlConfig; @Autowired private ISysTaskAttachmentService sysTaskAttachmentService; @Autowired private SysUserMapper sysUserMapper; @Autowired(required = false) private IMapService mapService; @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= sysUserMapper.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; } /** * 查询任务管理 * * @param taskId 任务管理主键 * @return 任务管理 */ @Override public SysTask selectSysTaskByTaskId(Long taskId) { SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); if (task != null) { // 加载急救转运扩展信息 if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) { SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId); task.setEmergencyInfo(emergencyInfo); } // 加载福祉车扩展信息 else if ("WELFARE".equals(task.getTaskType())) { SysTaskWelfare welfareInfo = sysWelfareTaskService.getWelfareInfoByTaskId(taskId); task.setWelfareInfo(welfareInfo); } } return task; } /** * 查询任务管理列表 * * @param queryVO 任务查询对象 * @return 任务管理 */ @Override public List selectSysTaskList(TaskQueryVO queryVO) { List 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 queryVO 任务查询对象 * @param taskCode 任务编号 * @return 任务管理集合 */ @Override public List 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 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()); } /** * 新增任务管理 * * @param createVO 任务创建对象 * @return 结果 */ @Override @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()); task.setTaskStatus(TaskStatus.PENDING.getCode()); task.setTaskDescription(createVO.getTaskDescription()); task.setPlannedStartTime(createVO.getPlannedStartTime()); task.setPlannedEndTime(createVO.getPlannedEndTime()); task.setAssigneeId(createVO.getAssigneeId()); task.setCreatorId(userId); // 优先使用前端传入的部门ID,如果没有则使用当前用户的部门ID task.setDeptId(createVO.getDeptId() != null ? createVO.getDeptId() : SecurityUtils.getDeptId()); task.setCreateBy(username); task.setCreateTime(DateUtils.getNowDate()); task.setUpdateBy(username); task.setUpdateTime(DateUtils.getNowDate()); task.setRemark(createVO.getRemark()); task.setDelFlag("0"); // 设置地址和坐标信息 setAddressAndCoordinatesFromVO(task, createVO); // 设置任务类型特定信息 setTaskTypeSpecificInfo(task, createVO); // 自动填充缺失的GPS坐标 autoFillMissingGpsCoordinates(task); int result = sysTaskMapper.insertSysTask(task); // 保存车辆关联信息 if (result > 0 && createVO.getVehicleIds() != null && !createVO.getVehicleIds().isEmpty()) { sysTaskVehicleService.saveTaskVehicles(task.getTaskId(), createVO.getVehicleIds(), username); } // 保存执行人员信息(包含角色类型) if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) { sysTaskAssigneeService.saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),username); } // 保存急救转运扩展信息 if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) { sysEmergencyTaskService.saveEmergencyInfo(task.getTaskId(), username, createVO, null, null, null); } // 保存福祉车扩展信息 if (result > 0 && "WELFARE".equals(createVO.getTaskType())) { sysWelfareTaskService.saveWelfareInfo(task.getTaskId(), SecurityUtils.getUsername(), createVO); } // 记录操作日志 if (result > 0) { recordTaskLog(task.getTaskId(), "CREATE", "创建任务", null, "任务类型:" + createVO.getTaskType(), SecurityUtils.getUserId(), SecurityUtils.getUsername()); } // 发布任务创建事件 if (result > 0) { eventPublisher.publishEvent(new TaskCreatedEvent( this, task.getTaskId(), task.getTaskCode(), task.getTaskType(), task.getCreatorId(), SecurityUtils.getUsername() )); } // 异步同步急救转运任务到旧系统 if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType()) && legacySystemSyncService != null) { final Long finalTaskId = task.getTaskId(); new Thread(() -> { try { Thread.sleep(2000); // 等待2秒,确保事务已提交 legacySystemSyncService.syncEmergencyTaskToLegacy(finalTaskId); } catch (Exception e) { // 同步失败不影响主流程,仅记录日志 } }).start(); } return result; } /** * 新增任务管理(允许从外部传入用户信息、部门信息和时间信息) * * @param createVO 任务创建对象 * @param userId 用户ID * @param deptId 部门ID * @param createTime 创建时间 * @param updateTime 更新时间 * @return 结果 */ @Override @Transactional public int insertTask(TaskCreateVO createVO,Long serviceOrderId,Long dispatchOrderId, String serviceOrdNo, Long userId,String userName, Long deptId, Date createTime, Date updateTime) { SysTask task = new SysTask(); if(createVO.getTaskCode()!=null){ 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"); // 设置地址和坐标信息 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()); } 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坐标 autoFillMissingGpsCoordinates(task); int result = sysTaskMapper.insertSysTask(task); // 保存车辆关联信息 if (result > 0 && createVO.getVehicleIds() != null && !createVO.getVehicleIds().isEmpty()) { sysTaskVehicleService.saveTaskVehicles(task.getTaskId(), createVO.getVehicleIds(), userName, updateTime, createTime, updateTime); } // 保存执行人员信息(包含角色类型) if (result > 0 && createVO.getAssignees() != null && !createVO.getAssignees().isEmpty()) { sysTaskAssigneeService.saveTaskAssignees(task.getTaskId(), createVO.getAssignees(),userName); } // 保存急救转运扩展信息 if (result > 0 && "EMERGENCY_TRANSFER".equals(createVO.getTaskType())) { sysEmergencyTaskService.saveEmergencyInfo(task.getTaskId(), userName, createVO, serviceOrderId, dispatchOrderId, serviceOrdNo); } // 保存福祉车扩展信息 if (result > 0 && "WELFARE".equals(createVO.getTaskType())) { sysWelfareTaskService.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) { this.sendEmeryTaskProcess(task, dispatchOrderId); } return result; } private void sendTaskAssigneeEvent(TaskCreateVO createVO,SysTask task,Long userId,String userName){ List assigneeIds = createVO.getAssignees().stream() .map(assignee -> assignee.getUserId()) .collect(Collectors.toList()); List assigneeNames = createVO.getAssignees().stream() .map(assignee -> assignee.getUserName()) .collect(Collectors.toList()); eventPublisher.publishEvent(new TaskAssignedEvent( this, task.getTaskId(), task.getTaskCode(), assigneeIds, assigneeNames, userId, userName )); } /** * 修改任务管理 * * @param updateVO 任务更新对象 * @return 结果 */ @Override @Transactional public int updateSysTask(TaskUpdateVO updateVO, Boolean updateFromLegacy) { SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(updateVO.getTaskId()); if (oldTask == null) { throw new RuntimeException("任务不存在"); } Long userId = SecurityUtils.getUserId(); 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()); // 设置预计距离 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 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 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); } } } if(updateVO.getAssignees()!=null && !updateVO.getAssignees().isEmpty()){ TaskCreateVO.AssigneeInfo assigneeInfo= updateVO.getAssignees().get(0); task.setAssigneeId(assigneeInfo.getUserId()); task.setAssigneeName(assigneeInfo.getUserName()); } // 用于跟踪是否需要重新同步(车辆、人员、地址、成交价变更) boolean needResync = false; int result = sysTaskMapper.updateSysTask(task); // 更新车辆关联 if (result > 0 && updateVO.getVehicleIds() != null && !updateVO.getVehicleIds().isEmpty()) { boolean vehiclesChanged = sysTaskVehicleService.updateTaskVehicles( updateVO.getTaskId(), updateVO.getVehicleIds(), userName); if (vehiclesChanged) { // 标记需要重新同步(车辆变更) needResync = true; } } // 更新执行人员(检测人员变更) if (result > 0 && updateVO.getAssignees() != null) { boolean assigneesChanged = sysTaskAssigneeService.updateTaskAssignees( updateVO.getTaskId(), updateVO.getAssignees(), userName); if (assigneesChanged) { // 标记需要重新同步(人员变更) needResync = true; } } Long dispatchOrderId=0L; // 更新急救转运扩展信息(检测地址和成交价变更) if (result > 0 && "EMERGENCY_TRANSFER".equals(oldTask.getTaskType())) { SysTaskEmergency oldEmergency = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(updateVO.getTaskId()); 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) { sysWelfareTaskService.updateWelfareInfo(updateVO.getTaskId(), updateVO, userName); } } // 如果是急救转运任务且有变更,标记需要重新同步 if (result > 0 && "EMERGENCY_TRANSFER".equals(oldTask.getTaskType()) && needResync && !updateFromLegacy) { sysEmergencyTaskService.markNeedResyncIfNecessary(updateVO.getTaskId(), oldTask, updateVO, updateFromLegacy); } // 记录操作日志 if (result > 0) { recordTaskLog(updateVO.getTaskId(), "UPDATE", "更新任务", buildTaskDescription(oldTask), buildTaskDescription(task), userId, userName); } if(result > 0 && oldTask.getTaskStatus().equals(TaskStatus.PENDING.getCode()) && updateVO.getAssignees() != null && !updateVO.getAssignees().isEmpty() && dispatchOrderId>0L){ this.sendTaskAssigneeEvent(updateVO,oldTask,userId,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, 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(serviceOrderId); Long taskId = taskEmergency.getTaskId(); 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()); if(updateVO.getActualStartTime() != null) { task.setActualStartTime(updateVO.getActualStartTime()); } if(updateVO.getActualEndTime() != null) { task.setActualEndTime(updateVO.getActualEndTime()); } // 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()); } // 如果更新了任务编号 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 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 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); // 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()) { // 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 && hasAssignee) { // log.info("更新执行人员 ServiceOrdID:{},dispatchOrderId:{}",serviceOrderId,dispatchOrderId); sysTaskAssigneeService.updateTaskAssignees(taskId, updateVO.getAssignees(), userName); } // 更新急救转运扩展信息 if (result > 0) { // 更新旧系统ID 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 (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() && dispatchOrderId>0L){ 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().isEmpty()){ //发送通知 eventPublisher.publishEvent(new TaskOnlyServerOrderSyncEvent(this, taskId, taskCode)); } } } } /** * 批量删除任务管理 * * @param taskIds 需要删除的任务管理主键 * @return 结果 */ @Override @Transactional public int deleteSysTaskByTaskIds(Long[] taskIds) { int result = 0; for (Long taskId : taskIds) { // 记录删除日志 recordTaskLog(taskId, "DELETE", "删除任务", null, null, SecurityUtils.getUserId(), SecurityUtils.getUsername()); result += sysTaskMapper.deleteSysTaskByTaskId(taskId); } return result; } /** * 分配任务 * * @param taskId 任务ID * @param assigneeId 执行人ID * @param remark 备注 * @return 结果 */ @Override @Transactional public int assignTask(Long taskId, Long assigneeId, String remark) { SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); if (task == null) { throw new RuntimeException("任务不存在"); } SysTask updateTask = new SysTask(); updateTask.setTaskId(taskId); updateTask.setAssigneeId(assigneeId); updateTask.setUpdateBy(SecurityUtils.getUsername()); updateTask.setUpdateTime(DateUtils.getNowDate()); int result = sysTaskMapper.assignTask(updateTask); // 记录操作日志 if (result > 0) { recordTaskLog(taskId, "ASSIGN", "分配任务", null, "分配给用户ID:" + assigneeId + ",备注:" + remark, SecurityUtils.getUserId(), SecurityUtils.getUsername()); } // 发布任务分配事件 if (result > 0) { List assigneeIds = new ArrayList<>(); assigneeIds.add(assigneeId); eventPublisher.publishEvent(new TaskAssignedEvent( this, task.getTaskId(), task.getTaskCode(), assigneeIds, null, // 姓名列表在监听器中查询 SecurityUtils.getUserId(), SecurityUtils.getUsername() )); } return result; } /** * 变更任务状态 * * @param taskId 任务ID * @param newStatus 新状态 * @param remark 备注 * @return 结果 */ @Override public int changeTaskStatus(Long taskId, TaskStatus newStatus, String remark) { return changeTaskStatusWithLocation(taskId, newStatus, remark, null); } /** * 变更任务状态(含GPS位置信息) * * @param taskId 任务ID * @param newStatus 新状态 * @param remark 备注 * @param locationLog GPS位置信息日志对象 * @return 结果 */ @Override public int changeTaskStatusWithLocation(Long taskId, TaskStatus newStatus, String remark, SysTaskLog locationLog) { SysTask oldTask = sysTaskMapper.selectSysTaskByTaskId(taskId); if (oldTask == null) { throw new RuntimeException("任务不存在"); } // 验证状态流转是否合法 TaskStatus oldTaskStatus = TaskStatus.getByCode(oldTask.getTaskStatus()); if (!oldTask.canChangeStatus(newStatus)) { throw new RuntimeException("状态流转不合法:从 " + oldTaskStatus.getInfo() + " 到 " + newStatus.getInfo()); } SysTask task = new SysTask(); task.setTaskId(taskId); task.setTaskStatus(newStatus.getCode()); task.setUpdateBy(SecurityUtils.getUsername()); task.setUpdateTime(DateUtils.getNowDate()); // 根据状态设置相应的时间 if (newStatus == TaskStatus.DEPARTING && oldTask.getActualStartTime() == null) { // 出发中:设置实际开始时间 task.setActualStartTime(DateUtils.getNowDate()); } else if (newStatus == TaskStatus.IN_PROGRESS && oldTask.getActualStartTime() == null) { // 兼容旧数据:任务中状态也设置实际开始时间 task.setActualStartTime(DateUtils.getNowDate()); } else if (newStatus == TaskStatus.COMPLETED) { // 已完成:设置实际结束时间 task.setActualEndTime(DateUtils.getNowDate()); } int result = sysTaskMapper.updateTaskStatus(task); // 记录操作日志(含GPS位置信息) if (result > 0) { recordTaskLog(taskId, "STATUS_CHANGE", "状态变更", "状态:" + oldTaskStatus.getInfo(), "状态:" + newStatus.getInfo() + ",备注:" + remark, SecurityUtils.getUserId(), SecurityUtils.getUsername(), locationLog); } // 发布任务状态变更事件 if (result > 0) { // 查询任务的所有执行人 List assignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId); List assigneeIds = null; if (assignees != null && !assignees.isEmpty()) { assigneeIds = assignees.stream() .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(), oldTask.getTaskCode(), oldTaskStatus.getCode(), newStatus.getCode(), oldTaskStatus.getInfo(), newStatus.getInfo(), assigneeIds, oldTask.getCreatorId(), userId, lng, lat, address )); } return result; } /** * 上传任务附件 * * @param taskId 任务ID * @param file 文件 * @param category 附件分类 * @return 结果 */ @Override @Transactional public Long uploadAttachment(Long taskId, MultipartFile file, String category) { return sysTaskAttachmentService.uploadAttachment(taskId, file, category); } /** * 从微信mediaId上传任务附件 * * @param taskId 任务ID * @param accessToken 微信AccessToken * @param mediaId 微信mediaId * @param category 附件分类 * @return 返回附件ID */ @Override @Transactional public Long uploadAttachmentFromWechat(Long taskId, String accessToken, String mediaId, String category) { return sysTaskAttachmentService.uploadAttachmentFromWechat(taskId, accessToken, mediaId, category); } /** * 删除任务附件 * * @param attachmentId 附件ID * @return 结果 */ @Override @Transactional public int deleteAttachment(Long attachmentId) { return sysTaskAttachmentService.deleteAttachment(attachmentId); } /** * 根据ID获取附件详情 * * @param attachmentId 附件ID * @return 附件详情 */ @Override public SysTaskAttachment getAttachmentById(Long attachmentId) { return sysTaskAttachmentService.getAttachmentById(attachmentId); } @Override public List getAttachmentsByTaskId(Long taskId) { return sysTaskAttachmentService.getAttachmentsByTaskId(taskId); } /** * 分配车辆给任务 * * @param taskId 任务ID * @param vehicleId 车辆ID * @param remark 备注 * @return 结果 */ @Override @Transactional public int assignVehicleToTask(Long taskId, Long vehicleId, String remark,Long userId,String userName) { int result = sysTaskVehicleService.assignVehicleToTask(taskId, vehicleId, remark, userId, userName); // 记录操作日志 if (result > 0) { recordTaskLog(taskId, "ASSIGN", "分配车辆", null, "分配车辆ID:" + vehicleId + ",备注:" + remark, userId, userName); } return result; } /** * 取消任务车辆分配 * * @param taskId 任务ID * @param vehicleId 车辆ID * @return 结果 */ @Override @Transactional public int unassignVehicleFromTask(Long taskId, Long vehicleId) { int result = sysTaskVehicleService.unassignVehicleFromTask(taskId, vehicleId); // 记录操作日志 if (result > 0) { recordTaskLog(taskId, "ASSIGN", "取消车辆分配", "取消车辆ID:" + vehicleId, null, SecurityUtils.getUserId(), SecurityUtils.getUsername()); } return result; } /** * 批量分配车辆给任务 * * @param taskId 任务ID * @param vehicleIds 车辆ID列表 * @param remark 备注 * @return 结果 */ @Override @Transactional public int assignMultipleVehiclesToTask(Long taskId, List vehicleIds, String remark,Long userId,String userName) { int result = sysTaskVehicleService.assignMultipleVehiclesToTask(taskId, vehicleIds, remark, userId, userName); // 记录操作日志 if (result > 0) { recordTaskLog(taskId, "ASSIGN", "批量分配车辆", null, "分配车辆数量:" + result + ",备注:" + remark, userId, userName); } return result; } /** * 查询任务关联的车辆 * * @param taskId 任务ID * @return 任务车辆关联列表 */ @Override public List getTaskVehicles(Long taskId) { return sysTaskVehicleService.getTaskVehicles(taskId); } /** * 查询可用车辆 * * @param deptId 部门ID * @param taskType 任务类型 * @return 可用车辆列表 */ @Override public List getAvailableVehicles(Long deptId, String taskType) { return sysTaskVehicleService.getAvailableVehicles(deptId, taskType); } /** * 查询任务统计信息 * * @return 任务统计信息 */ @Override public TaskStatisticsVO getTaskStatistics() { return sysTaskMapper.selectTaskStatistics(); } /** * 查询超时任务列表 * * @return 超时任务列表 */ @Override public List selectOverdueTasks() { return sysTaskMapper.selectOverdueTasks(); } /** * 查询我的任务列表 * * @param userId 用户ID * @return 我的任务列表 */ @Override public List selectMyTasks(Long userId) { List list = sysTaskMapper.selectMyTasks(userId); list.stream().forEach(task -> { if(task.getTaskType().equals("EMERGENCY_TRANSFER")){ task.setEmergencyInfo(sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(task.getTaskId())); } }); return list; } /** * 获取任务详情(包含关联数据) * * @param taskId 任务ID * @return 任务详情 */ @Override public SysTask getTaskDetail(Long taskId) { SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); if (task != null) { // 查询关联车辆 task.setAssignedVehicles(sysTaskVehicleService.getTaskVehicles(taskId)); // 查询附件(已自动拼接完整URL) task.setAttachments(sysTaskAttachmentService.getAttachmentsByTaskId(taskId)); // 查询操作日志 task.setOperationLogs(sysTaskLogMapper.selectSysTaskLogByTaskId(taskId)); // 查询执行人员列表 task.setAssignees(sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId)); // 加载急救转运扩展信息 if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) { SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId); task.setEmergencyInfo(emergencyInfo); } // 加载福祉车扩展信息 else if ("WELFARE".equals(task.getTaskType())) { SysTaskWelfare welfareInfo = sysWelfareTaskService.getWelfareInfoByTaskId(taskId); task.setWelfareInfo(welfareInfo); } } return task; } /** * 检查车辆是否有正在进行中的任务 * 正在进行中的任务是指状态不为:PENDING(待处理)、COMPLETED(已完成)、CANCELLED(已取消)的任务 * * @param vehicleId 车辆ID * @return 正在进行中的任务列表 */ @Override public List checkVehicleActiveTasks(Long vehicleId) { return sysTaskMapper.selectActiveTasksByVehicleId(vehicleId); } /** * 检查任务是否已关联旧系统服务单ID * * @param taskId 任务ID * @return true-已关联,false-未关联 */ @Override public boolean hasLegacyServiceOrdId(Long taskId) { return sysEmergencyTaskService.hasLegacyServiceOrdId(taskId); } /** * 检查任务是否已关联旧系统调度单ID * * @param taskId 任务ID * @return true-已关联,false-未关联 */ @Override public boolean hasLegacyDispatchOrdId(Long taskId) { return sysEmergencyTaskService.hasLegacyDispatchOrdId(taskId); } /** * 根据旧系统服务单ID检查是否存在任务 * * @param legacyServiceOrdId 旧系统服务单ID * @return true-存在,false-不存在 */ @Override public boolean existsByLegacyServiceOrdId(Long legacyServiceOrdId) { return sysEmergencyTaskService.existsByLegacyServiceOrdId(legacyServiceOrdId); } /** * 根据旧系统调度单ID检查是否存在任务 * * @param legacyDispatchOrdId 旧系统调度单ID * @return true-存在,false-不存在 */ @Override public boolean existsByLegacyDispatchOrdId(Long legacyDispatchOrdId) { return sysEmergencyTaskService.existsByLegacyDispatchOrdId(legacyDispatchOrdId); } @Autowired private TaskCodeGenerator taskCodeGenerator; /** * 生成任务编号 * * @return 任务编号 */ 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; } /** * 记录任务操作日志 * * @param taskId 任务ID * @param operationType 操作类型 * @param operationDesc 操作描述 * @param oldValue 操作前值 * @param newValue 操作后值 * @param operatorId 操作人ID * @param operatorName 操作人姓名 */ private void recordTaskLog(Long taskId, String operationType, String operationDesc, String oldValue, String newValue, Long operatorId, String operatorName) { recordTaskLog(taskId, operationType, operationDesc, oldValue, newValue, operatorId, operatorName, null); } /** * 记录任务操作日志(含GPS位置信息) * * @param taskId 任务ID * @param operationType 操作类型 * @param operationDesc 操作描述 * @param oldValue 操作前值 * @param newValue 操作后值 * @param operatorId 操作人ID * @param operatorName 操作人姓名 * @param log GPS位置信息日志对象(可为null) */ private void recordTaskLog(Long taskId, String operationType, String operationDesc, String oldValue, String newValue, Long operatorId, String operatorName, SysTaskLog log) { if (log == null) { log = new SysTaskLog(); } log.setTaskId(taskId); log.setOperationType(operationType); log.setOperationDesc(operationDesc); log.setOldValue(oldValue); log.setNewValue(newValue); log.setOperatorId(operatorId); log.setOperatorName(operatorName); log.setOperationTime(DateUtils.getNowDate()); // 这里可以获取IP地址 log.setIpAddress("127.0.0.1"); sysTaskLogMapper.insertSysTaskLog(log); } /** * 构建任务描述 * * @param task 任务对象 * @return 任务描述 */ private String buildTaskDescription(SysTask task) { StringBuilder sb = new StringBuilder(); sb.append("任务编号:").append(task.getTaskCode()).append(","); sb.append("任务类型:").append(task.getTaskType()).append(","); sb.append("任务状态:").append(task.getTaskStatus()).append(","); if (StringUtils.isNotEmpty(task.getTaskDescription())) { sb.append("任务描述:").append(task.getTaskDescription()).append(","); } return sb.toString(); } /** * 从TaskCreateVO设置地址和坐标信息到任务对象 * * @param task 任务对象 * @param createVO 创建VO */ private void setAddressAndCoordinatesFromVO(SysTask task, TaskCreateVO createVO) { // 设置通用地址和坐标信息 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()); } } /** * 设置任务类型特定信息(急救转运/福祉车) * * @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 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 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); } } } /** * 计算预计公里数 * * @param task 任务对象 */ private void calculateEstimatedDistance(SysTask task) { if (task.getDepartureLongitude() != null && task.getDepartureLatitude() != null && task.getDestinationLongitude() != null && task.getDestinationLatitude() != null) { // 验证GPS坐标是否有效 if (GpsDistanceUtils.isValidCoordinate(task.getDepartureLatitude(), task.getDepartureLongitude()) && GpsDistanceUtils.isValidCoordinate(task.getDestinationLatitude(), task.getDestinationLongitude())) { // 计算距离 java.math.BigDecimal distance = GpsDistanceUtils.calculateDistance( task.getDepartureLatitude(), task.getDepartureLongitude(), task.getDestinationLatitude(), task.getDestinationLongitude() ); task.setEstimatedDistance(distance); } else { // 坐标无效,设置为0 task.setEstimatedDistance(java.math.BigDecimal.ZERO); } } else { // 坐标不完整,设置为0 task.setEstimatedDistance(java.math.BigDecimal.ZERO); } } /** * 检查任务是否可以出发 * 检查: * 1. 车辆是否有未完成的任务 * 2. 执行人员是否有未完成的任务 * * @param taskId 任务ID * @return AjaxResult 校验结果 */ @Override public AjaxResult checkTaskCanDepart(Long taskId) { // 获取任务详情 SysTask task = this.getTaskDetail(taskId); if (task == null) { return AjaxResult.error("任务不存在"); } List> conflicts = new ArrayList<>(); // 1. 检查车辆是否有未完成的任务 List taskVehicles = task.getAssignedVehicles(); if (taskVehicles != null && !taskVehicles.isEmpty()) { for (SysTaskVehicle taskVehicle : taskVehicles) { Long vehicleId = taskVehicle.getVehicleId(); List vehicleActiveTasks = this.checkVehicleActiveTasks(vehicleId); // 过滤掉当前任务本身 vehicleActiveTasks = vehicleActiveTasks.stream() .filter(t -> !t.getTaskId().equals(taskId)) .collect(Collectors.toList()); if (!vehicleActiveTasks.isEmpty()) { for (SysTask activeTask : vehicleActiveTasks) { Map 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 assignees = task.getAssignees(); if (assignees != null && !assignees.isEmpty()) { for (SysTaskAssignee assignee : assignees) { Long userId = assignee.getUserId(); // 查询该执行人的所有正在进行中的任务(排除PENDING、COMPLETED、CANCELLED) List 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 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); } } } } // 3. 检查执行人是否全部就绪(受配置开关控制) String readyCheckEnabled = configService.selectConfigByKey("task.assignee.ready.check.enabled"); if ("true".equalsIgnoreCase(readyCheckEnabled)) { assignees = task.getAssignees(); if (assignees != null && !assignees.isEmpty()) { boolean allReady = assignees.stream() .allMatch(a -> "1".equals(a.getIsReady())); if (!allReady) { Map conflict = new HashMap<>(); conflict.put("type", "assigneeReady"); conflict.put("message", "存在未就绪的执行人,请等待所有执行人点击就绪后再出车"); conflicts.add(conflict); } } } // 返回结果 Map result = new HashMap<>(); result.put("valid", conflicts.isEmpty()); result.put("conflicts", conflicts); return AjaxResult.success(result); } /** * 执行人点击就绪 * * @param taskId 任务ID * @param userId 用户ID * @return 结果 */ @Override @Transactional public AjaxResult setAssigneeReady(Long taskId, Long userId) { return sysTaskAssigneeService.setAssigneeReady(taskId, userId); } /** * 取消执行人就绪 * * @param taskId 任务ID * @param userId 用户ID * @return 结果 */ @Override @Transactional public AjaxResult cancelAssigneeReady(Long taskId, Long userId) { return sysTaskAssigneeService.cancelAssigneeReady(taskId, userId); } }