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.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.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 ISysDeptService deptService;
|
|
@Autowired
|
private ISysUserService userService;
|
|
@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= 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);
|
}
|
/**
|
* 查询任务管理
|
*
|
* @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<SysTask> selectSysTaskList(TaskQueryVO 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());
|
|
}
|
|
/**
|
* 新增任务管理
|
*
|
* @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");
|
|
task.setIsHeadPush(isTaskHeaderPush(userId,task.getDeptId())?"1":"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");
|
|
Boolean isHeadPush=this.isTaskHeaderPush(userId, deptId);
|
if(isHeadPush){
|
task.setIsHeadPush("1");
|
}else{
|
task.setIsHeadPush("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<Long> assigneeIds = createVO.getAssignees().stream()
|
.map(assignee -> assignee.getUserId())
|
.collect(Collectors.toList());
|
List<String> assigneeNames = createVO.getAssignees().stream()
|
.map(assignee -> assignee.getUserName())
|
.collect(Collectors.toList());
|
|
eventPublisher.publishEvent(new TaskAssignedEvent(
|
this,
|
task.getTaskId(),
|
task.getTaskCode(),
|
assigneeIds,
|
assigneeNames,
|
userId,
|
userName
|
));
|
}
|
|
/**
|
* 修改任务管理
|
*
|
* @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());
|
}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) &&
|
mapService != null) {
|
if (!updateVO.getDepartureAddress().equals(oldTask.getDepartureAddress())) {
|
try {
|
Map<String, Double> coords = mapService.geocoding(
|
updateVO.getDepartureAddress(),
|
extractCityFromAddress(updateVO.getDepartureAddress())
|
);
|
if (coords != null) {
|
task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
|
task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
|
// log.info("出发地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
|
}
|
} catch (Exception e) {
|
log.error("自动获取出发地GPS坐标失败", e);
|
}
|
}
|
}
|
|
// 自动获取目的地GPS坐标(如果更新了地址但缺失坐标)
|
if (updateVO.getDestinationAddress() != null &&
|
(updateVO.getDestinationLongitude() == null || updateVO.getDestinationLatitude() == null) &&
|
mapService != null) {
|
if (!updateVO.getDestinationAddress().equals(oldTask.getDestinationAddress())) {
|
try {
|
Map<String, Double> coords = mapService.geocoding(
|
updateVO.getDestinationAddress(),
|
extractCityFromAddress(updateVO.getDestinationAddress())
|
);
|
if (coords != null) {
|
task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
|
task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
|
// log.info("目的地GPS坐标自动获取成功: {}, {}", coords.get("lng"), coords.get("lat"));
|
}
|
} catch (Exception e) {
|
log.error("自动获取目的地GPS坐标失败", e);
|
}
|
}
|
}
|
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;
|
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()
|
&& LongUtil.isNotEmpty(dispatchOrderId)){
|
|
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();
|
SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId);
|
updateVO.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());
|
}
|
if(deptId!=null){
|
task.setDeptId(deptId);
|
}
|
|
|
// task.setAssigneeId(updateVO.getAssigneeId());
|
task.setUpdateBy(userName);
|
task.setUpdateTime(DateUtils.getNowDate());
|
task.setRemark(updateVO.getRemark());
|
|
|
// 设置地址和坐标信息
|
|
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());
|
}
|
|
|
|
|
// task.setDepartureLongitude(updateVO.getDepartureLongitude());
|
// task.setDepartureLatitude(updateVO.getDepartureLatitude());
|
// task.setDestinationLongitude(updateVO.getDestinationLongitude());
|
// task.setDestinationLatitude(updateVO.getDestinationLatitude());
|
Boolean modifyOutLongLat = false;
|
// 自动获取出发地GPS坐标(如果地址变更且缺失坐标)
|
if (task != null && updateVO.getDepartureAddress() != null
|
&& !updateVO.getDepartureAddress().equals(task.getDepartureAddress())
|
&& (updateVO.getDepartureLongitude() == null || updateVO.getDepartureLatitude() == null)
|
&& mapService != null) {
|
try {
|
Map<String, Double> coords = mapService.geocoding(
|
updateVO.getDepartureAddress(),
|
extractCityFromAddress(updateVO.getDepartureAddress())
|
);
|
if (coords != null) {
|
task.setDepartureLongitude(BigDecimal.valueOf(coords.get("lng")));
|
task.setDepartureLatitude(BigDecimal.valueOf(coords.get("lat")));
|
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 (task != null && updateVO.getDestinationAddress() != null
|
&& !updateVO.getDestinationAddress().equals(task.getDestinationAddress())
|
&& (updateVO.getDestinationLongitude() == null || updateVO.getDestinationLatitude() == null)
|
&& mapService != null) {
|
try {
|
Map<String, Double> coords = mapService.geocoding(
|
updateVO.getDestinationAddress(),
|
extractCityFromAddress(updateVO.getDestinationAddress())
|
);
|
if (coords != null) {
|
task.setDestinationLongitude(BigDecimal.valueOf(coords.get("lng")));
|
task.setDestinationLatitude(BigDecimal.valueOf(coords.get("lat")));
|
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()) {
|
// 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()
|
&& 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));
|
|
}
|
}
|
}
|
}
|
/**
|
* 批量删除任务管理
|
*
|
* @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<Long> 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<SysTaskAssignee> assignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
|
List<Long> 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<SysTaskAttachment> 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<Long> 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<SysTaskVehicle> getTaskVehicles(Long taskId) {
|
return sysTaskVehicleService.getTaskVehicles(taskId);
|
}
|
|
/**
|
* 查询可用车辆
|
*
|
* @param deptId 部门ID
|
* @param taskType 任务类型
|
* @return 可用车辆列表
|
*/
|
@Override
|
public List<SysTaskVehicle> getAvailableVehicles(Long deptId, String taskType) {
|
return sysTaskVehicleService.getAvailableVehicles(deptId, taskType);
|
}
|
|
/**
|
* 查询任务统计信息
|
*
|
* @return 任务统计信息
|
*/
|
@Override
|
public TaskStatisticsVO getTaskStatistics() {
|
return sysTaskMapper.selectTaskStatistics();
|
}
|
|
/**
|
* 查询超时任务列表
|
*
|
* @return 超时任务列表
|
*/
|
@Override
|
public List<SysTask> selectOverdueTasks() {
|
return sysTaskMapper.selectOverdueTasks();
|
}
|
|
/**
|
* 查询我的任务列表
|
*
|
* @param userId 用户ID
|
* @return 我的任务列表
|
*/
|
@Override
|
public List<SysTask> selectMyTasks(Long 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;
|
}
|
|
/**
|
* 获取任务详情(包含关联数据)
|
*
|
* @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<SysTask> 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<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);
|
}
|
}
|
}
|
|
/**
|
* 计算预计公里数
|
*
|
* @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<Map<String, Object>> conflicts = new ArrayList<>();
|
|
// 1. 检查车辆是否有未完成的任务
|
List<SysTaskVehicle> taskVehicles = task.getAssignedVehicles();
|
if (taskVehicles != null && !taskVehicles.isEmpty()) {
|
for (SysTaskVehicle taskVehicle : taskVehicles) {
|
Long vehicleId = taskVehicle.getVehicleId();
|
List<SysTask> vehicleActiveTasks = this.checkVehicleActiveTasks(vehicleId);
|
|
// 过滤掉当前任务本身
|
vehicleActiveTasks = vehicleActiveTasks.stream()
|
.filter(t -> !t.getTaskId().equals(taskId))
|
.collect(Collectors.toList());
|
|
if (!vehicleActiveTasks.isEmpty()) {
|
for (SysTask activeTask : vehicleActiveTasks) {
|
Map<String, Object> conflict = new HashMap<>();
|
conflict.put("type", "vehicle");
|
conflict.put("vehicleNo", taskVehicle.getVehicleNo());
|
conflict.put("taskId", activeTask.getTaskId());
|
conflict.put("taskCode", activeTask.getTaskCode());
|
conflict.put("taskStatus", activeTask.getTaskStatus());
|
conflict.put("message", String.format("车辆 %s 尚有未完成的任务 %s,请先完成",
|
taskVehicle.getVehicleNo(), activeTask.getTaskCode()));
|
conflicts.add(conflict);
|
}
|
}
|
}
|
}
|
|
// 2. 检查执行人员是否有未完成的任务
|
List<SysTaskAssignee> assignees = task.getAssignees();
|
if (assignees != null && !assignees.isEmpty()) {
|
for (SysTaskAssignee assignee : assignees) {
|
Long userId = assignee.getUserId();
|
|
// 查询该执行人的所有正在进行中的任务(排除PENDING、COMPLETED、CANCELLED)
|
List<SysTask> userActiveTasks = this.selectMyTasks(userId).stream()
|
.filter(t -> !TaskStatus.PENDING.getCode().equals(t.getTaskStatus())
|
&& !TaskStatus.COMPLETED.getCode().equals(t.getTaskStatus())
|
&& !TaskStatus.CANCELLED.getCode().equals(t.getTaskStatus())
|
&& !t.getTaskId().equals(taskId)) // 过滤掉当前任务
|
.collect(Collectors.toList());
|
|
if (!userActiveTasks.isEmpty()) {
|
for (SysTask activeTask : userActiveTasks) {
|
Map<String, Object> conflict = new HashMap<>();
|
conflict.put("type", "assignee");
|
conflict.put("userName", assignee.getUserName());
|
conflict.put("taskId", activeTask.getTaskId());
|
conflict.put("taskCode", activeTask.getTaskCode());
|
conflict.put("taskStatus", activeTask.getTaskStatus());
|
conflict.put("message", String.format("执行人 %s 尚有正在进行中的任务 %s,请先完成",
|
assignee.getUserName(), activeTask.getTaskCode()));
|
conflicts.add(conflict);
|
}
|
}
|
}
|
}
|
|
// 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<String, Object> conflict = new HashMap<>();
|
conflict.put("type", "assigneeReady");
|
conflict.put("message", "存在未就绪的执行人,请等待所有执行人点击就绪后再出车");
|
conflicts.add(conflict);
|
}
|
}
|
}
|
|
// 返回结果
|
Map<String, Object> 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);
|
}
|
|
}
|