| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.InputStreamReader; |
| | | import java.io.OutputStream; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.net.URLEncoder; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import javax.net.ssl.HttpsURLConnection; |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.net.ssl.TrustManager; |
| | | import javax.net.ssl.X509TrustManager; |
| | | import java.security.cert.X509Certificate; |
| | | |
| | | import com.ruoyi.common.utils.LongUtil; |
| | | import com.ruoyi.system.domain.*; |
| | | import com.ruoyi.system.mapper.*; |
| | | import com.ruoyi.system.service.*; |
| | | import com.ruoyi.system.task.ITaskAttachmentService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.context.ApplicationEventPublisher; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import com.ruoyi.common.config.LegacySystemConfig; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.core.domain.entity.SysUser; |
| | | import com.ruoyi.common.core.domain.entity.SysDept; |
| | | import com.ruoyi.system.domain.vo.TaskCreateVO; |
| | | import com.ruoyi.system.mapper.SysTaskMapper; |
| | | import com.ruoyi.system.mapper.SysTaskEmergencyMapper; |
| | | import com.ruoyi.system.mapper.SysTaskVehicleMapper; |
| | | import com.ruoyi.system.mapper.SysTaskAssigneeMapper; |
| | | import com.ruoyi.system.mapper.VehicleInfoMapper; |
| | | import com.ruoyi.system.mapper.SysUserMapper; |
| | | import com.ruoyi.system.mapper.SysDeptMapper; |
| | | import com.ruoyi.system.utils.TaskStatusConverter; |
| | | |
| | | /** |
| | | * 旧系统同步Service业务层处理 |
| | |
| | | private ITaskAttachmentService taskAttachmentService; |
| | | |
| | | |
| | | @Autowired |
| | | private ApplicationEventPublisher eventPublisher; |
| | | |
| | | /** |
| | | * 同步急救转运任务到旧系统 |
| | | */ |
| | | @Autowired |
| | | private LegacyTransferSyncMapper legacyTransferSyncMapper; |
| | | |
| | | |
| | | @Autowired |
| | | private TaskEmergencySyncService taskEmergencySyncService; |
| | | |
| | | |
| | | @Autowired |
| | | private ITaskDispatchSyncService taskDispatchSyncService; |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | @Transactional |
| | | public Long syncEmergencyTaskToLegacy(Long taskId) { |
| | | if (!legacyConfig.isEnabled()) { |
| | | log.info("旧系统同步已禁用,跳过任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | try { |
| | | // 查询任务信息 |
| | | SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); |
| | | if (task == null) { |
| | | log.error("任务不存在,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 只同步急救转运任务 |
| | | if (!"EMERGENCY_TRANSFER".equals(task.getTaskType())) { |
| | | log.info("非急救转运任务,跳过同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 查询急救转运扩展信息 |
| | | SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | if (emergency == null) { |
| | | log.error("急救转运扩展信息不存在,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 如果已经同步过,不再重复同步 |
| | | if (emergency.getLegacyServiceOrdId() != null && emergency.getLegacyServiceOrdId() > 0) { |
| | | log.info("任务已同步过,任务ID: {}, ServiceOrdID: {}", taskId, emergency.getLegacyServiceOrdId()); |
| | | return emergency.getLegacyServiceOrdId(); |
| | | } |
| | | |
| | | // 更新同步状态为同步中 |
| | | emergency.setSyncStatus(1); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | // 构建请求参数 |
| | | Map<String, String> params = buildSyncParams(task, emergency); |
| | | |
| | | // 发送HTTP请求 |
| | | String response = sendHttpPost(legacyConfig.getEmergencyCreateUrl(), params); |
| | | |
| | | // 解析响应 |
| | | Long serviceOrdId = parseResponse(response); |
| | | |
| | | if (serviceOrdId != null && serviceOrdId > 0) { |
| | | // 同步成功,更新记录 |
| | | emergency.setLegacyServiceOrdId(serviceOrdId); |
| | | emergency.setSyncStatus(2); // 同步成功 |
| | | emergency.setSyncTime(new Date()); |
| | | emergency.setSyncErrorMsg(null); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | // 更新任务主表同步标记 |
| | | task.setLegacySynced(1); |
| | | sysTaskMapper.updateSysTask(task); |
| | | |
| | | log.info("任务同步成功,任务ID: {}, ServiceOrdID: {}", taskId, serviceOrdId); |
| | | return serviceOrdId; |
| | | } else { |
| | | // 同步失败 |
| | | emergency.setSyncStatus(3); // 同步失败 |
| | | emergency.setSyncTime(new Date()); |
| | | emergency.setSyncErrorMsg("旧系统返回无效的ServiceOrdID: " + response); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | log.error("任务同步失败,任务ID: {}, 响应: {}", taskId, response); |
| | | return null; |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | log.error("同步任务到旧系统异常,任务ID: {}", taskId, e); |
| | | |
| | | // 更新同步状态为失败 |
| | | try { |
| | | SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | if (emergency != null) { |
| | | emergency.setSyncStatus(3); // 同步失败 |
| | | emergency.setSyncTime(new Date()); |
| | | emergency.setSyncErrorMsg("同步异常: " + e.getMessage()); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.error("更新同步状态失败", ex); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | return taskEmergencySyncService.syncEmergency(taskId); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 批量同步未同步的急救转运任务 |
| | | * 使用分页查询,确保所有符合条件的任务都能被同步 |
| | |
| | | break; // 没有更多数据,退出循环 |
| | | } |
| | | |
| | | log.info("开始同步第 {} 页,任务数量: {}", (offset / pageSize) + 1, pendingTasks.size()); |
| | | // log.info("开始同步第 {} 页,任务数量: {}", (offset / pageSize) + 1, pendingTasks.size()); |
| | | |
| | | int pageSuccessCount = 0; |
| | | for (SysTaskEmergency emergency : pendingTasks) { |
| | | Long serviceOrdId = syncEmergencyTaskToLegacy(emergency.getTaskId()); |
| | | if (serviceOrdId != null && serviceOrdId > 0) { |
| | | if (LongUtil.isNotEmpty(serviceOrdId)) { |
| | | pageSuccessCount++; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | totalSuccessCount += pageSuccessCount; |
| | | log.info("第 {} 页同步完成,总数: {}, 成功: {}", |
| | | (offset / pageSize) + 1, pendingTasks.size(), pageSuccessCount); |
| | | // log.info("第 {} 页同步完成,总数: {}, 成功: {}", |
| | | // (offset / pageSize) + 1, pendingTasks.size(), pageSuccessCount); |
| | | |
| | | // 如果本页数据少于每页大小,说明已经是最后一页 |
| | | if (pendingTasks.size() < pageSize) { |
| | | log.info("已到达最后一页,同步结束"); |
| | | // log.info("已到达最后一页,同步结束"); |
| | | break; |
| | | } |
| | | |
| | | offset += pageSize; // 下一页 |
| | | } |
| | | |
| | | log.info("批量同步完成,总成功数: {}", totalSuccessCount); |
| | | // log.info("批量同步完成,总成功数: {}", totalSuccessCount); |
| | | return totalSuccessCount; |
| | | |
| | | } catch (Exception e) { |
| | |
| | | |
| | | // 重新同步 |
| | | Long serviceOrdId = syncEmergencyTaskToLegacy(taskId); |
| | | return serviceOrdId != null && serviceOrdId > 0; |
| | | return LongUtil.isNotEmpty(serviceOrdId); |
| | | |
| | | } catch (Exception e) { |
| | | log.error("重新同步任务失败,任务ID: {}", taskId, e); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Long syncDispatchOrderToLegacy(Long taskId) { |
| | | return taskDispatchSyncService.syncDispatch(taskId); |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | }); |
| | | } |
| | | /** |
| | | * 同步调度单到旧系统(admin_save_24.asp) |
| | | */ |
| | | |
| | | |
| | | @Override |
| | | @Transactional |
| | | public Long syncDispatchOrderToLegacy(Long taskId) { |
| | | if (!legacyConfig.isEnabled()) { |
| | | log.info("旧系统同步已禁用,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | try { |
| | | // 查询任务信息 |
| | | SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); |
| | | if (task == null) { |
| | | log.error("任务不存在,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 只同步急救转运任务 |
| | | if (!"EMERGENCY_TRANSFER".equals(task.getTaskType())) { |
| | | log.info("非急救转运任务,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 查询急救转运扩展信息 |
| | | SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | if (emergency == null) { |
| | | log.error("急救转运扩展信息不存在,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 如果已经同步过,不再重复同步 |
| | | if (emergency.getLegacyDispatchOrdId() != null && emergency.getLegacyDispatchOrdId() > 0) { |
| | | log.info("调度单已同步过,任务ID: {}, DispatchOrdID: {}", taskId, emergency.getLegacyDispatchOrdId()); |
| | | return emergency.getLegacyDispatchOrdId(); |
| | | } |
| | | |
| | | Long serviceOrdId=emergency.getLegacyServiceOrdId(); |
| | | // 必须先同步服务单 |
| | | if (serviceOrdId == null || serviceOrdId <= 0) { |
| | | log.warn("服务单未同步,无法同步调度单,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // ====== 前置校验:确保任务数据完整 ====== |
| | | |
| | | // 1. 检查是否已分配车辆 |
| | | List<SysTaskVehicle> taskVehicles = sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId); |
| | | if (taskVehicles == null || taskVehicles.isEmpty()) { |
| | | log.warn("任务未分配车辆,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 2. 检查是否已分配执行人员 |
| | | List<SysTaskAssignee> taskAssignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId); |
| | | if (taskAssignees == null || taskAssignees.isEmpty()) { |
| | | log.warn("任务未分配执行人员,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 3. 检查预约时间是否有效(必须大于1970年) |
| | | if (task.getPlannedStartTime() == null) { |
| | | log.warn("任务未设置预约时间,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 检查预约时间是否大于1970-01-01(时间戳0对应1970-01-01 00:00:00) |
| | | long timestamp1970 = 0L; |
| | | if (task.getPlannedStartTime().getTime() <= timestamp1970) { |
| | | log.warn("任务预约时间无效(小于等于1970年),跳过调度单同步,任务ID: {}, 预约时间: {}", |
| | | taskId, task.getPlannedStartTime()); |
| | | return null; |
| | | } |
| | | |
| | | // 4. 检查转出医院信息 |
| | | if (StringUtils.isEmpty(emergency.getHospitalOutName())) { |
| | | log.warn("任务未设置转出医院,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | if (StringUtils.isEmpty(emergency.getHospitalOutAddress())) { |
| | | log.warn("任务未设置转出医院地址,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 5. 检查转入医院信息 |
| | | if (StringUtils.isEmpty(emergency.getHospitalInName())) { |
| | | log.warn("任务未设置转入医院,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | if (StringUtils.isEmpty(emergency.getHospitalInAddress())) { |
| | | log.warn("任务未设置转入医院地址,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | // 6. 检查患者基本信息 |
| | | if (StringUtils.isEmpty(emergency.getPatientName())) { |
| | | log.warn("任务未设置患者姓名,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | if (StringUtils.isEmpty(emergency.getPatientPhone())) { |
| | | log.warn("任务未设置患者电话,跳过调度单同步,任务ID: {}", taskId); |
| | | return null; |
| | | } |
| | | |
| | | log.info("任务数据校验通过,开始同步调度单,任务ID: {}", taskId); |
| | | |
| | | // 更新同步状态为同步中 |
| | | emergency.setDispatchSyncStatus(1); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | SysUser u=sysUserMapper.selectUserById(task.getCreatorId()); |
| | | Integer oaUserID= u.getOaUserId(); |
| | | |
| | | // 构建请求参数 |
| | | Map<String, String> params = buildDispatchOrderParams(task, emergency); |
| | | |
| | | |
| | | // 发送HTTP请求 |
| | | String response = sendHttpPost(legacyConfig.getDispatchCreateUrl(), params); |
| | | |
| | | // 解析响应 |
| | | Long dispatchOrdId = parseResponse(response); |
| | | |
| | | if (dispatchOrdId != null && dispatchOrdId > 0) { |
| | | // 同步成功,更新记录 |
| | | emergency.setLegacyDispatchOrdId(dispatchOrdId); |
| | | emergency.setDispatchSyncStatus(2); // 同步成功 |
| | | emergency.setDispatchSyncTime(new Date()); |
| | | emergency.setDispatchSyncErrorMsg(null); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | List<SysTaskAttachment> taskAttachments= sysTaskService.getAttachmentsByTaskId(taskId); |
| | | if (taskAttachments != null && !taskAttachments.isEmpty()) { |
| | | //同步附件 |
| | | this.syncAttachmentToLegacy(taskAttachments,serviceOrdId,dispatchOrdId,oaUserID); |
| | | } |
| | | |
| | | log.info("调度单同步成功,任务ID: {}, DispatchOrdID: {}", taskId, dispatchOrdId); |
| | | return dispatchOrdId; |
| | | } else { |
| | | // 同步失败 |
| | | emergency.setDispatchSyncStatus(3); // 同步失败 |
| | | emergency.setDispatchSyncTime(new Date()); |
| | | emergency.setDispatchSyncErrorMsg("旧系统返回无效的DispatchOrdID: " + response); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | log.error("调度单同步失败,任务ID: {}, 响应: {}", taskId, response); |
| | | return null; |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | log.error("同步调度单到旧系统异常,任务ID: {}", taskId, e); |
| | | |
| | | // 更新同步状态为失败 |
| | | try { |
| | | SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | if (emergency != null) { |
| | | emergency.setDispatchSyncStatus(3); // 同步失败 |
| | | emergency.setDispatchSyncTime(new Date()); |
| | | emergency.setDispatchSyncErrorMsg("同步异常: " + e.getMessage()); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.error("更新调度单同步状态失败", ex); |
| | | } |
| | | |
| | | return null; |
| | | public void syncTaskAttachment(Long taskId, Long dispatchOrdId, Long serviceOrdId, Integer oaUserID){ |
| | | List<SysTaskAttachment> taskAttachments= sysTaskService.getAttachmentsByTaskId(taskId); |
| | | if (taskAttachments != null && !taskAttachments.isEmpty()) { |
| | | //同步附件 |
| | | this.syncAttachmentToLegacy(taskAttachments,serviceOrdId,dispatchOrdId,oaUserID); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 批量同步未同步的调度单 |
| | | * 使用分页查询,确保所有符合条件的任务都能被同步 |
| | |
| | | while (true) { |
| | | // 分页查询已同步服务单但未同步调度单的任务 |
| | | List<SysTaskEmergency> pendingTasks = sysTaskEmergencyService.selectPendingDispatchSyncTasks(offset, pageSize); |
| | | log.info("查询到未同步调度单的任务数量: {}", pendingTasks.size()); |
| | | // log.info("查询到未同步调度单的任务数量: {}", pendingTasks.size()); |
| | | if (pendingTasks == null || pendingTasks.isEmpty()) { |
| | | log.info("没有更多需要同步调度单的任务,offset: {}", offset); |
| | | break; // 没有更多数据,退出循环 |
| | | } |
| | | |
| | | log.info("开始同步调度单第 {} 页,任务数量: {}", (offset / pageSize) + 1, pendingTasks.size()); |
| | | // log.info("开始同步调度单第 {} 页,任务数量: {}", (offset / pageSize) + 1, pendingTasks.size()); |
| | | |
| | | int pageSuccessCount = 0; |
| | | for (SysTaskEmergency emergency : pendingTasks) { |
| | | log.info("开始同步调度单,任务ID: {}", emergency.getTaskId()); |
| | | // log.info("开始同步调度单,任务ID: {}", emergency.getTaskId()); |
| | | Long dispatchOrdId = syncDispatchOrderToLegacy(emergency.getTaskId()); |
| | | |
| | | if (dispatchOrdId != null && dispatchOrdId > 0) { |
| | |
| | | } |
| | | |
| | | totalSuccessCount += pageSuccessCount; |
| | | log.info("调度单第 {} 页同步完成,总数: {}, 成功: {}", |
| | | (offset / pageSize) + 1, pendingTasks.size(), pageSuccessCount); |
| | | // log.info("调度单第 {} 页同步完成,总数: {}, 成功: {}", |
| | | // (offset / pageSize) + 1, pendingTasks.size(), pageSuccessCount); |
| | | |
| | | // 如果本页数据少于每页大小,说明已经是最后一页 |
| | | if (pendingTasks.size() < pageSize) { |
| | | log.info("已到达最后一页,调度单同步结束"); |
| | | // log.info("已到达最后一页,调度单同步结束"); |
| | | break; |
| | | } |
| | | |
| | | offset += pageSize; // 下一页 |
| | | } |
| | | |
| | | log.info("批量同步调度单完成,总成功数: {}", totalSuccessCount); |
| | | // log.info("批量同步调度单完成,总成功数: {}", totalSuccessCount); |
| | | return totalSuccessCount; |
| | | |
| | | } catch (Exception e) { |
| | |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 构建调度单同步参数 |
| | | */ |
| | | private Map<String, String> buildDispatchOrderParams(SysTask task, SysTaskEmergency emergency) { |
| | | Map<String, String> params = new HashMap<>(); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | // 获取管理员ID(创建人ID对应的OA_UserID) |
| | | String adminID = this.getAdminID(task); |
| | | |
| | | // 获取调度单类型(从任务所属部门的调度单编码获取) |
| | | String dispatchOrdClass = "SA"; // 默认值 |
| | | if (task.getDeptId() != null) { |
| | | try { |
| | | SysDept dept = sysDeptMapper.selectDeptById(task.getDeptId()); |
| | | if (dept != null && StringUtils.isNotEmpty(dept.getDispatchOrderClass())) { |
| | | dispatchOrdClass = dept.getDispatchOrderClass(); |
| | | log.info("获取任务所属部门的调度单编码成功,部门ID: {}, 调度单编码: {}", task.getDeptId(), dispatchOrdClass); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("查询任务所属部门信息异常,部门ID: {}", task.getDeptId(), e); |
| | | } |
| | | } |
| | | params.put("AdminID", adminID); |
| | | |
| | | // 基本信息 |
| | | params.put("DispatchOrdClass", dispatchOrdClass); |
| | | params.put("ServiceOrdID", emergency.getLegacyServiceOrdId().toString()); |
| | | params.put("DispatchOrdState", "1"); // 调度单状态 |
| | | |
| | | // 时间信息 |
| | | if (task.getPlannedStartTime() != null) { |
| | | params.put("DispatchOrdTraSDTime", sdf.format(task.getPlannedStartTime())); // 拟出发时间 |
| | | } else { |
| | | params.put("DispatchOrdTraSDTime", ""); |
| | | } |
| | | params.put("DispatchOrd_NS_Time", task.getCreateTime() != null ? sdf.format(task.getCreateTime()) : sdf.format(new Date())); // 开单时间 |
| | | |
| | | // 车辆信息 - 从任务关联的车辆获取CarID |
| | | Long carId = getTaskVehicleCarId(task.getTaskId()); |
| | | params.put("DispatchOrdCarID", carId.toString()); |
| | | |
| | | // 联系人信息 |
| | | params.put("DispatchOrdCoName", StringUtils.nvl(emergency.getPatientContact(), "")); |
| | | params.put("DispatchOrdCoPhone", StringUtils.nvl(emergency.getPatientPhone(), "")); |
| | | params.put("ServiceOrdCoName", StringUtils.nvl(emergency.getPatientContact(), "")); |
| | | params.put("ServiceOrdCoPhone", StringUtils.nvl(emergency.getPatientPhone(), "")); |
| | | params.put("ServiceOrdPtName", StringUtils.nvl(emergency.getPatientName(), "")); |
| | | params.put("ServiceOrdTraStreet",StringUtils.nvl(task.getDepartureAddress(), StringUtils.nvl(emergency.getHospitalOutAddress(), ""))); |
| | | // 地址信息 |
| | | params.put("DispatchOrdTraStreet", StringUtils.nvl(task.getDepartureAddress(), StringUtils.nvl(emergency.getHospitalOutAddress(), ""))); |
| | | params.put("DispatchOrdTraEnd", StringUtils.nvl(task.getDestinationAddress(), StringUtils.nvl(emergency.getHospitalInAddress(), ""))); |
| | | params.put("DispatchOrdTraVia", ""); // 实际途经地 |
| | | |
| | | // 操作命令 |
| | | params.put("DispatchOrd_Check", "0"); // 3=直接强制完成 |
| | | |
| | | // 绩效和费用 |
| | | params.put("DispatchOrdPerfomance", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | params.put("StretcherMoney", "0"); // 抬担架费 |
| | | params.put("AddMoneyType", ""); // 附加项目 |
| | | params.put("AddMoney", "0"); // 附加项目费用 |
| | | params.put("AddMoneyExplain", ""); // 附加项目说明 |
| | | |
| | | // 人员信息 |
| | | params.put("EntourageName_aid1", ""); // 外援人员1 |
| | | params.put("EntourageName_aid2", ""); // 外援人员2 |
| | | params.put("DispatchOrd_NS_ID", adminID); // 调度人员ID |
| | | params.put("RecommendedCar", ""); // 指定车型 |
| | | params.put("ServiceOrdTaskRemarks", StringUtils.nvl(task.getTaskDescription(), "")); // 医护司备注 |
| | | |
| | | // 电话信息 |
| | | params.put("Phone", StringUtils.nvl(emergency.getPatientPhone(), "")); |
| | | params.put("TEL_Time", sdf.format(new Date())); |
| | | params.put("TEL_Remarks", "新系统同步创建调度单"); |
| | | |
| | | // 时长信息 |
| | | params.put("TimeLength_Program", "0"); // 大型活动保障时长 |
| | | params.put("TimeLength_ICU", "0"); // 居家ICU时长 |
| | | params.put("TimeLength_Wait", "0"); // 等待时长 |
| | | |
| | | // 里程数 |
| | | params.put("DispatchOrdTraStreetMileage", ""); // 开始里程数 |
| | | params.put("DispatchOrdTraEndMileage", ""); // 结束里程数 |
| | | |
| | | // 服务单相关信息(从admin_save_24.gds 221-255行补充) |
| | | params.put("ServiceOrdPtCondition", StringUtils.nvl(emergency.getPatientCondition(), "")); // 病情描述 |
| | | params.put("ServiceOrdPtDoctor", ""); // 患者医生 |
| | | params.put("ServiceOrdPtDoctorPhone", ""); // 患者医生电话 |
| | | params.put("TransferModeID", ""); // 转运方式 |
| | | params.put("ServiceOrdVIP", "0"); // VIP客户 |
| | | params.put("ServiceOrdTraTxnPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); // 成交价 |
| | | params.put("ServiceOrdTraPrePayment", "0"); // 需预付款 |
| | | params.put("SettlementPrice", "0"); // 结算价 |
| | | params.put("ServiceOrdTraPriceReason", ""); // 差价原因 |
| | | params.put("ServiceOrd_CC_ID", ""); // 客服人员ID |
| | | params.put("ServiceOrd_Sale_ID", ""); // 销售人员ID |
| | | params.put("ServiceOrdIntroducer", ""); // 介绍人 |
| | | params.put("ServiceOrd_work_ID", ""); // 主要企微客服ID |
| | | params.put("ServiceOrd_work_IDs", ""); // 其他企微客服ID |
| | | params.put("ServiceOrd_work_is", "0"); // 是否企微成交 |
| | | params.put("CommissionScenarioID", "0"); // 企微绩效方案 |
| | | params.put("ServiceOrdApptDate", task.getPlannedStartTime() != null ? sdf.format(task.getPlannedStartTime()) : ""); // 预约时间 |
| | | params.put("ServiceOrdPtDiagnosis", ""); // 诊断 |
| | | params.put("ServiceOrdOperationRemarks", "新系统同步创建"); // 操作备注 |
| | | params.put("ServiceOrdEstimatedOrderDate", ""); // 预计派单时间 |
| | | params.put("ServiceOrdEstimatedOrderDateOld", ""); // 原预计派单时间 |
| | | params.put("ServiceOrdViaDistance", "0"); // 中途距离 |
| | | params.put("ServiceOrdTraDistance", emergency.getTransferDistance() != null ? emergency.getTransferDistance().toString() : "0"); // 距离 |
| | | params.put("OrderLevel", "0"); // 查看等级 |
| | | params.put("ServiceOrdDepartureType", "1"); // 预约类型 |
| | | params.put("ConditionLevel", "0"); // 病重级别 |
| | | params.put("DirectionType", "0"); // 转运去向 |
| | | params.put("ServiceOrdPtOutHospID", emergency.getHospitalOutId() != null ? emergency.getHospitalOutId().toString() : "0"); // 转出医院ID |
| | | params.put("ServiceOrdPtInHospID", emergency.getHospitalInId() != null ? emergency.getHospitalInId().toString() : "0"); // 转入医院ID |
| | | params.put("ServiceOrdPtOutHosp", StringUtils.nvl(emergency.getHospitalOutName(), "")); // 转出医院 |
| | | params.put("ServiceOrdTraVia", StringUtils.nvl(task.getDepartureAddress(), StringUtils.nvl(emergency.getHospitalOutAddress(), ""))); // 转出地址 |
| | | params.put("ServiceOrdPtInHosp", StringUtils.nvl(emergency.getHospitalInName(), "")); // 转入医院 |
| | | params.put("ServiceOrdTraEnd", StringUtils.nvl(task.getDestinationAddress(), StringUtils.nvl(emergency.getHospitalInAddress(), ""))); // 转入地址 |
| | | params.put("FromHQ2_is", "0"); // 广州总部推送任务标记 |
| | | |
| | | // 病情ID列表(ICD-10疾病ID,用于诊断ICD) |
| | | // 格式:逗号分隔的ID列表,如 ",1,2,3," |
| | | String ordIcdId = ""; |
| | | if (StringUtils.isNotEmpty(emergency.getDiseaseIds())) { |
| | | // 将存储的 "1,2,3" 格式转换为旧系统要求的 ",1,2,3," 格式 |
| | | ordIcdId = "," + emergency.getDiseaseIds() + ","; |
| | | log.info("病情ID列表已设置,任务ID: {}, OrdICD_ID: {}", task.getTaskId(), ordIcdId); |
| | | } |
| | | params.put("OrdICD_ID", ordIcdId); |
| | | params.put("OrdICD_ID_old", ""); // 旧病情ID列表(用于对比是否需要更新) |
| | | |
| | | // 执行人员信息(随行人员) |
| | | syncTaskAssignees(task, params); |
| | | |
| | | return params; |
| | | } |
| | | |
| | | /** |
| | | * 同步任务执行人员信息到调度单随行人员参数 |
| | | * |
| | | * @param task 任务信息 |
| | | * @param params 调度单参数Map |
| | | */ |
| | | private void syncTaskAssignees(SysTask task, Map<String, String> params) { |
| | | try { |
| | | // 获取任务的执行人员信息列表(包含角色类型) //TODO 如果有两个司机就要 设置 Entourage_1和Entourage_2 |
| | | //两个护士就要设置 Entourage_4和Entourage_6 |
| | | //两个医生要设置 Entourage_3和Entourage_5 |
| | | List<TaskCreateVO.AssigneeInfo> assignees = getTaskAssignees(task.getTaskId()); |
| | | |
| | | if (assignees == null || assignees.isEmpty()) { |
| | | log.warn("任务无执行人员,任务ID: {}", task.getTaskId()); |
| | | // 设置默认空值 |
| | | params.put("EntourageLeadID", ""); |
| | | params.put("Entourage_1", ""); // 司机 |
| | | params.put("Entourage_2", ""); //司机 |
| | | params.put("Entourage_3", ""); // 医生 |
| | | params.put("Entourage_5", ""); //医生 |
| | | params.put("Entourage_4", ""); // 护士 |
| | | params.put("Entourage_6", ""); // 护士 |
| | | |
| | | return; |
| | | } |
| | | |
| | | String leadEntourageId = ""; // 领队的EntourageID |
| | | String driverOaId = ""; // 司机的OA_UserID |
| | | String doctorOaId = ""; // 医生的OA_UserID |
| | | String nurseOaId = ""; // 护士的OA_UserID |
| | | |
| | | // 遍历执行人员,根据角色类型分配到对应的Entourage参数 |
| | | for (int i = 0; i < assignees.size(); i++) { |
| | | TaskCreateVO.AssigneeInfo assignee = assignees.get(i); |
| | | Long userId = assignee.getUserId(); |
| | | String userType = assignee.getUserType(); // 直接使用前端传递的角色类型 |
| | | |
| | | if (userId == null) { |
| | | continue; |
| | | } |
| | | |
| | | // 查询用户的OA_UserID |
| | | SysUser user = sysUserMapper.selectUserById(userId); |
| | | if (user == null || user.getOaUserId() == null) { |
| | | log.warn("执行人员信息不存在或未配置OA_UserID,用户ID: {}", userId); |
| | | continue; |
| | | } |
| | | |
| | | String oaUserId = user.getOaUserId().toString(); |
| | | |
| | | // 根据用户类型分配到对应的Entourage参数 |
| | | if ("driver".equals(userType)) { |
| | | if (driverOaId.isEmpty()) { |
| | | driverOaId = oaUserId; |
| | | if(params.get("Entourage_1")==null) { |
| | | params.put("Entourage_1", oaUserId); |
| | | }else{ |
| | | params.put("Entourage_2", oaUserId); |
| | | } |
| | | // 如果是第一个执行人员,设置为领队 |
| | | if (i == 0 && leadEntourageId.isEmpty()) { |
| | | leadEntourageId = "1"; // 司机对应Entourage_1 |
| | | } |
| | | } |
| | | } else if ("doctor".equals(userType)) { |
| | | if (doctorOaId.isEmpty()) { |
| | | doctorOaId = oaUserId; |
| | | if(params.get("Entourage_3")==null) { |
| | | params.put("Entourage_3", oaUserId); |
| | | }else{ |
| | | params.put("Entourage_5", oaUserId); |
| | | } |
| | | // 如果是第一个执行人员,设置为领队 |
| | | if (i == 0 && leadEntourageId.isEmpty()) { |
| | | leadEntourageId = "3"; // 医生对应Entourage_3 |
| | | } |
| | | } |
| | | } else if ("nurse".equals(userType)) { |
| | | if (nurseOaId.isEmpty()) { |
| | | nurseOaId = oaUserId; |
| | | if(params.get("Entourage_4")==null) { |
| | | params.put("Entourage_4", oaUserId); |
| | | }else{ |
| | | params.put("Entourage_6", oaUserId); |
| | | } |
| | | // 如果是第一个执行人员,设置为领队 |
| | | if (i == 0 && leadEntourageId.isEmpty()) { |
| | | leadEntourageId = "4"; // 护士对应Entourage_4 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 设置参数 |
| | | params.put("EntourageLeadID", leadEntourageId); |
| | | // params.put("Entourage_1", driverOaId); // 司机 |
| | | // params.put("Entourage_3", doctorOaId); // 医生 |
| | | // params.put("Entourage_4", nurseOaId); // 护士 |
| | | |
| | | log.info("任务执行人员同步成功,任务ID: {}, 领队ID: {}, 司机: {}, 医生: {}, 护士: {}", |
| | | task.getTaskId(), leadEntourageId, driverOaId, doctorOaId, nurseOaId); |
| | | |
| | | } catch (Exception e) { |
| | | log.error("同步任务执行人员异常,任务ID: {}", task.getTaskId(), e); |
| | | // 设置默认空值 |
| | | params.put("EntourageLeadID", ""); |
| | | params.put("Entourage_1", ""); |
| | | params.put("Entourage_3", ""); |
| | | params.put("Entourage_4", ""); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取任务的执行人员信息列表(包含角色类型) |
| | | * |
| | | * @param taskId 任务ID |
| | | * @return 执行人员信息列表 |
| | | */ |
| | | private List<TaskCreateVO.AssigneeInfo> getTaskAssignees(Long taskId) { |
| | | List<TaskCreateVO.AssigneeInfo> assignees = new java.util.ArrayList<>(); |
| | | |
| | | try { |
| | | // 从数据库查询执行人员信息(按排序顺序) |
| | | List<SysTaskAssignee> taskAssignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId); |
| | | |
| | | if (taskAssignees != null && !taskAssignees.isEmpty()) { |
| | | // 将数据库中的执行人员转换为AssigneeInfo对象 |
| | | for (SysTaskAssignee taskAssignee : taskAssignees) { |
| | | TaskCreateVO.AssigneeInfo assignee = new TaskCreateVO.AssigneeInfo(); |
| | | assignee.setUserId(taskAssignee.getUserId()); |
| | | assignee.setUserName(taskAssignee.getUserName()); |
| | | assignee.setUserType(taskAssignee.getUserType()); |
| | | assignees.add(assignee); |
| | | } |
| | | |
| | | log.info("从数据库获取执行人员信息成功,任务ID: {}, 人员数量: {}", taskId, assignees.size()); |
| | | return assignees; |
| | | } |
| | | |
| | | // 如果数据库中没有执行人员信息,尝试从任务的主要执行人获取 |
| | | log.warn("数据库中未找到执行人员信息,尝试从任务主要执行人获取,任务ID: {}", taskId); |
| | | SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); |
| | | if (task != null && task.getAssigneeId() != null) { |
| | | SysUser user = sysUserMapper.selectUserById(task.getAssigneeId()); |
| | | if (user != null) { |
| | | TaskCreateVO.AssigneeInfo assignee = new TaskCreateVO.AssigneeInfo(); |
| | | assignee.setUserId(user.getUserId()); |
| | | assignee.setUserName(user.getNickName()); |
| | | assignee.setUserType(getUserType(user)); // 通过角色判断类型 |
| | | assignees.add(assignee); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("获取任务执行人员信息异常,任务ID: {}", taskId, e); |
| | | } |
| | | |
| | | return assignees; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断用户类型(司机/医生/护士/其他) |
| | | * 根据用户的角色名称来判断 |
| | | * |
| | | * @param user 用户信息 |
| | | * @return 用户类型:driver/doctor/nurse/other |
| | | */ |
| | | private String getUserType(SysUser user) { |
| | | String roleName = ""; |
| | | |
| | | // 从用户的角色列表中获取角色名称 |
| | | if (user.getRoles() != null && !user.getRoles().isEmpty()) { |
| | | roleName = user.getRoles().get(0).getRoleName(); |
| | | } |
| | | |
| | | // 判断是否为司机 |
| | | if (roleName != null && roleName.contains("司机")) { |
| | | return "driver"; |
| | | } |
| | | // 判断是否为医生 |
| | | if (roleName != null && roleName.contains("医生")) { |
| | | return "doctor"; |
| | | } |
| | | // 判断是否为护士 |
| | | if (roleName != null && roleName.contains("护士")) { |
| | | return "nurse"; |
| | | } |
| | | |
| | | // 其他类型,默认为司机(保证至少有一个人员) |
| | | log.warn("用户角色无法判断类型,默认为司机,用户ID: {}, 角色: {}", user.getUserId(), roleName); |
| | | return "driver"; |
| | | } |
| | | |
| | | /** |
| | | * 获取任务关联车辆的旧系统CarID |
| | | * |
| | | * @param taskId 任务ID |
| | | * @return CarID,如果未找到则返回0L |
| | | */ |
| | | private Long getTaskVehicleCarId(Long taskId) { |
| | | try { |
| | | // 从 sys_task_vehicle 表查询车辆ID |
| | | List<SysTaskVehicle> taskVehicles = sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId); |
| | | if (taskVehicles != null && !taskVehicles.isEmpty()) { |
| | | // 取第一个关联的车辆 |
| | | Long vehicleId = taskVehicles.get(0).getVehicleId(); |
| | | if (vehicleId != null) { |
| | | // 从 tb_vehicle_info 表获取 car_id |
| | | VehicleInfo vehicleInfo = vehicleInfoMapper.selectVehicleInfoById(vehicleId); |
| | | if (vehicleInfo != null && vehicleInfo.getCarId() != null) { |
| | | Long carId = vehicleInfo.getCarId().longValue(); |
| | | log.info("获取任务关联车辆的CarID成功,任务ID: {}, 车辆ID: {}, CarID: {}", |
| | | taskId, vehicleId, carId); |
| | | return carId; |
| | | } else { |
| | | log.warn("车辆信息中未配置CarID,任务ID: {}, 车辆ID: {}", taskId, vehicleId); |
| | | } |
| | | } else { |
| | | log.warn("任务车辆关联记录中车辆ID为空,任务ID: {}", taskId); |
| | | } |
| | | } else { |
| | | log.warn("任务未关联车辆,任务ID: {}", taskId); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("查询任务关联车辆的CarID异常,任务ID: {}", taskId, e); |
| | | } |
| | | return 0L; |
| | | } |
| | | |
| | | private String getAdminID(SysTask task) { |
| | | String adminID=""; |
| | | if (task.getCreatorId() != null) { |
| | | try { |
| | | SysUser creator = sysUserMapper.selectUserById(task.getCreatorId()); |
| | | if (creator != null && creator.getOaUserId() != null) { |
| | | adminID = creator.getOaUserId().toString(); |
| | | log.info("获取创建人OA_UserID成功,用户ID: {}, OA_UserID: {}", task.getCreatorId(), adminID); |
| | | } else { |
| | | log.warn("创建人未配置OA_UserID,用户ID: {}", task.getCreatorId()); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("查询创建人OA_UserID异常,用户ID: {}", task.getCreatorId(), e); |
| | | } |
| | | } |
| | | return adminID; |
| | | } |
| | | /** |
| | | * 构建同步参数 |
| | | */ |
| | | private Map<String, String> buildSyncParams(SysTask task, SysTaskEmergency emergency) { |
| | | Map<String, String> params = new HashMap<>(); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd"); |
| | | Long taskId=task.getTaskId(); |
| | | // 管理员ID(创建人ID对应的OA_UserID) |
| | | String adminID = this.getAdminID(task); |
| | | |
| | | params.put("adminID", adminID); |
| | | |
| | | // 服务单分类(从任务所属部门的服务单编码获取) |
| | | String serviceOrdClass = "BF"; // ServiceOrdClass默认值 |
| | | if (task.getDeptId() != null) { |
| | | try { |
| | | SysDept dept = sysDeptMapper.selectDeptById(task.getDeptId()); |
| | | if (dept != null && StringUtils.isNotEmpty(dept.getServiceOrderClass())) { |
| | | // 使用部门的服务单编码作为ServiceOrdClass |
| | | serviceOrdClass = dept.getServiceOrderClass(); |
| | | log.info("获取任务所属部门的服务单编码成功,部门ID: {}, 部门名称: {}, 服务单编码: {}", |
| | | task.getDeptId(), dept.getDeptName(), serviceOrdClass); |
| | | } else { |
| | | log.warn("任务所属部门未配置服务单编码,部门ID: {}、部门名称: {},使用默认值", |
| | | task.getDeptId(), dept != null ? dept.getDeptName() : "null"); |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("查询任务所属部门信息异常,部门ID: {}", task.getDeptId(), e); |
| | | } |
| | | } else { |
| | | log.warn("任务未关联部门,使用默认服务单编码"); |
| | | } |
| | | |
| | | // 服务单执行区域(从任务的document_type_id获取) |
| | | String serviceOrdAreaType = "1"; // 默认值 |
| | | if (StringUtils.isNotEmpty(emergency.getDocumentTypeId())) { |
| | | serviceOrdAreaType = emergency.getDocumentTypeId(); |
| | | log.info("获取单据类型ID成功,任务ID: {}, 单据类型ID: {}", task.getTaskId(), serviceOrdAreaType); |
| | | } else { |
| | | log.warn("任务未配置单据类型ID,任务ID: {},使用默认值", task.getTaskId()); |
| | | } |
| | | |
| | | // 基础信息 |
| | | params.put("ServiceOrdClass", serviceOrdClass); // 从部门的服务单编码获取 |
| | | params.put("ServiceOrdAreaType", serviceOrdAreaType); // 从任务的document_type_id获取 |
| | | |
| | | // 服务单执行类型(从任务的task_type_id获取) |
| | | String serviceOrdType = "1"; // 默认值 |
| | | if (StringUtils.isNotEmpty(emergency.getTaskTypeId())) { |
| | | serviceOrdType = emergency.getTaskTypeId(); |
| | | log.info("获取任务类型ID成功,任务ID: {}, 任务类型ID: {}", taskId, serviceOrdType); |
| | | } else { |
| | | log.warn("任务未配置任务类型ID,任务ID: {},使用默认值", taskId); |
| | | } |
| | | params.put("ServiceOrdType", serviceOrdType); // 服务单执行类型(从任务的task_type_id获取) |
| | | |
| | | params.put("ServiceOrdState", "2"); // 服务单状态(2=正式单) |
| | | params.put("ServiceOrdStartDate", task.getCreateTime() != null ? sdfDate.format(task.getCreateTime()) : sdfDate.format(new Date())); |
| | | |
| | | // 预约时间 |
| | | if (task.getPlannedStartTime() != null) { |
| | | params.put("ServiceOrdApptDate", sdf.format(task.getPlannedStartTime())); |
| | | } |
| | | |
| | | // 联系人信息 |
| | | params.put("ServiceOrdCoName", StringUtils.nvl(emergency.getPatientContact(), "")); |
| | | params.put("ServiceOrdCoPhone", StringUtils.nvl(emergency.getPatientPhone(), "")); |
| | | params.put("ServiceOrdCoTies", ""); // 联系人与患者关系 |
| | | |
| | | // 患者信息 |
| | | params.put("ServiceOrdPtName", StringUtils.nvl(emergency.getPatientName(), "")); |
| | | params.put("ServiceOrdPtAge", ""); // 年龄 |
| | | params.put("ServiceOrdPtKG", ""); // 体重 |
| | | params.put("ServiceOrdPtSex", "0".equals(emergency.getPatientGender()) ? "男" : "1".equals(emergency.getPatientGender()) ? "女" : ""); |
| | | params.put("ServiceOrdPtNat", ""); // 国籍 |
| | | params.put("ServiceOrdPtIDCard", StringUtils.nvl(emergency.getPatientIdCard(), "")); |
| | | |
| | | // 医院信息 |
| | | params.put("ServiceOrdPtOutHosp", StringUtils.nvl(emergency.getHospitalOutName(), "")); |
| | | params.put("ServiceOrdPtOutHospID", emergency.getHospitalOutId() != null ? emergency.getHospitalOutId().toString() : "0"); // 转出医院ID |
| | | params.put("ServiceOrdPtInHosp", StringUtils.nvl(emergency.getHospitalInName(), "")); |
| | | params.put("ServiceOrdPtInHospID", emergency.getHospitalInId() != null ? emergency.getHospitalInId().toString() : "0"); // 转入医院ID |
| | | |
| | | // 科室信息 |
| | | params.put("ServiceOrdPtServices", StringUtils.nvl(emergency.getHospitalOutDepartment(), "")); |
| | | params.put("ServiceOrdPtServicesID", StringUtils.nvl(emergency.getHospitalOutDepartmentId(), "0")); // 转出科室ID |
| | | params.put("ServiceOrdPtInServices", StringUtils.nvl(emergency.getHospitalInDepartment(), "")); |
| | | params.put("ServiceOrdPtInServicesID", StringUtils.nvl(emergency.getHospitalInDepartmentId(), "0")); // 转入科室ID |
| | | |
| | | // 病情信息 |
| | | params.put("ServiceOrdPtDiagnosis", ""); // 诊断 |
| | | params.put("ServiceOrdPtCondition", StringUtils.nvl(emergency.getPatientCondition(), "")); |
| | | params.put("ServiceOrdTaskRemarks", StringUtils.nvl(task.getTaskDescription(), "")); |
| | | params.put("ServiceOrdPtDoctor", ""); // 患者医生 |
| | | params.put("ServiceOrdPtDoctorPhone", ""); // 患者医生电话 |
| | | |
| | | // 地址信息 |
| | | params.put("province", ""); // 出发地省份 |
| | | params.put("city", ""); // 出发地城市 |
| | | params.put("ServiceOrdTraStreet",task.getDepartureAddress()); //派车地址 |
| | | params.put("ServiceOrdTraStreetCoo", ""); // 出发地坐标 |
| | | params.put("ServiceOrdTraEnd", StringUtils.nvl(task.getDestinationAddress(), StringUtils.nvl(emergency.getHospitalInAddress(), ""))); |
| | | params.put("ServiceOrdTraEndCoo", ""); // 目的地坐标 |
| | | params.put("ServiceOrdTraVia", ""); // 途经地 |
| | | |
| | | // 距离和价格信息 |
| | | params.put("ServiceOrdViaDistance", "0"); // 中途距离 |
| | | params.put("ServiceOrdTraDistance", emergency.getTransferDistance() != null ? emergency.getTransferDistance().toString() : "0"); |
| | | params.put("ServiceOrdTraDuration", ""); // 预计行程时间 |
| | | params.put("ServiceOrdTraUnitPrice", "0"); // 单价/公里 |
| | | params.put("ServiceOrdTraOfferPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | params.put("ServiceOrdTraTxnPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | params.put("ServiceOrdTraPrePayment", "0"); // 需预付款 |
| | | params.put("SettlementPrice", "0"); // 结算价 |
| | | params.put("ServiceOrdTraPriceReason", ""); // 差价原因 |
| | | |
| | | // 其他信息 |
| | | params.put("Phone", StringUtils.nvl(emergency.getPatientPhone(), "")); // 来电电话 |
| | | params.put("TEL_Time", sdf.format(new Date())); // 来电时间 |
| | | params.put("TEL_Remarks", "新系统同步"); // 来电备注 |
| | | params.put("TransferModeID", ""); // 转运方式 |
| | | params.put("ServiceOrdVIP", "0"); // VIP客户 |
| | | params.put("ServiceOrd_CC_ID", ""); // 客服人员ID |
| | | params.put("ServiceOrd_Sale_ID", ""); // 销售人员ID |
| | | params.put("ServiceOrdIntroducer", ""); // 介绍人 |
| | | params.put("ServiceOrd_work_ID", ""); // 主要企微客服ID |
| | | params.put("ServiceOrd_work_IDs", ""); // 其他企微客服ID |
| | | params.put("ServiceOrd_work_is", "0"); // 是否企微成交 |
| | | params.put("CommissionScenarioID", "0"); // 企微绩效方案 |
| | | params.put("ServiceOrdOperationRemarks", "新系统同步创建"); // 操作备注 |
| | | params.put("ServiceOrdEstimatedOrderDate", ""); // 预计派单时间 |
| | | params.put("ServiceOrdSource", "10"); // 订单来源(10=新系统) |
| | | params.put("OrderLevel", "0"); // 查看等级 |
| | | params.put("ServiceOrdDepartureType", "1"); // 预约类型 |
| | | params.put("ConditionLevel", "0"); // 病重级别 |
| | | params.put("DirectionType", "0"); // 转运去向 |
| | | params.put("ServiceOrd_m", "1"); // 来源入口 |
| | | params.put("FromHQ2_is", "0"); // 广州总部推送任务标记 |
| | | params.put("OrderPrice_Auto", "0"); // 订单自动报价参考值 |
| | | |
| | | return params; |
| | | } |
| | | |
| | | /** |
| | | * 发送HTTP/HTTPS POST请求 |
| | | * 支持HTTPS自签名证书 |
| | | */ |
| | | private String sendHttpPost(String urlString, Map<String, String> params) throws Exception { |
| | | URL url = new URL(urlString); |
| | | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
| | | |
| | | // 如果是HTTPS请求,配置SSL信任所有证书 |
| | | if (conn instanceof HttpsURLConnection) { |
| | | HttpsURLConnection httpsConn = (HttpsURLConnection) conn; |
| | | httpsConn.setSSLSocketFactory(createTrustAllSSLContext().getSocketFactory()); |
| | | httpsConn.setHostnameVerifier((hostname, session) -> true); // 信任所有主机名 |
| | | log.debug("配置HTTPS连接,信任所有SSL证书,URL: {}", urlString); |
| | | } |
| | | |
| | | try { |
| | | // 设置连接属性 |
| | | conn.setRequestMethod("POST"); |
| | | conn.setConnectTimeout(legacyConfig.getConnectTimeout()); |
| | | conn.setReadTimeout(legacyConfig.getReadTimeout()); |
| | | conn.setDoOutput(true); |
| | | conn.setDoInput(true); |
| | | conn.setUseCaches(false); |
| | | conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + legacyConfig.getCharset()); |
| | | conn.setRequestProperty("Accept-Charset", legacyConfig.getCharset()); |
| | | |
| | | // 构建POST数据 |
| | | StringBuilder postData = new StringBuilder(); |
| | | for (Map.Entry<String, String> entry : params.entrySet()) { |
| | | if (postData.length() > 0) { |
| | | postData.append("&"); |
| | | } |
| | | postData.append(URLEncoder.encode(entry.getKey(), legacyConfig.getCharset())); |
| | | postData.append("="); |
| | | postData.append(URLEncoder.encode(entry.getValue(), legacyConfig.getCharset())); |
| | | } |
| | | |
| | | // 发送POST数据 |
| | | try (OutputStream os = conn.getOutputStream()) { |
| | | os.write(postData.toString().getBytes(legacyConfig.getCharset())); |
| | | os.flush(); |
| | | } |
| | | |
| | | |
| | | |
| | | // 读取响应 |
| | | int responseCode = conn.getResponseCode(); |
| | | if (responseCode == HttpURLConnection.HTTP_OK) { |
| | | try (BufferedReader reader = new BufferedReader( |
| | | new InputStreamReader(conn.getInputStream(), legacyConfig.getCharset()))) { |
| | | StringBuilder response = new StringBuilder(); |
| | | String line; |
| | | while ((line = reader.readLine()) != null) { |
| | | response.append(line); |
| | | } |
| | | return response.toString().trim(); |
| | | } |
| | | } else { |
| | | log.error("请求失败,请求URL {},参数 {}",urlString,postData); |
| | | throw new Exception("HTTP/HTTPS请求失败,响应码: " + responseCode); |
| | | } |
| | | |
| | | } finally { |
| | | conn.disconnect(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 创建信任所有SSL证书的SSLContext |
| | | * 用于支持自签名证书的HTTPS请求 |
| | | * |
| | | * 注意:此方法会信任所有SSL证书,包括自签名证书 |
| | | * 仅用于与旧系统的内部通信,生产环境建议使用正规CA证书 |
| | | */ |
| | | private SSLContext createTrustAllSSLContext() throws Exception { |
| | | // 创建信任所有证书的TrustManager |
| | | TrustManager[] trustAllCerts = new TrustManager[] { |
| | | new X509TrustManager() { |
| | | @Override |
| | | public X509Certificate[] getAcceptedIssuers() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public void checkClientTrusted(X509Certificate[] certs, String authType) { |
| | | // 信任所有客户端证书 |
| | | } |
| | | |
| | | @Override |
| | | public void checkServerTrusted(X509Certificate[] certs, String authType) { |
| | | // 信任所有服务器证书 |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 安装信任所有证书的TrustManager |
| | | SSLContext sslContext = SSLContext.getInstance("TLS"); |
| | | sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); |
| | | return sslContext; |
| | | } |
| | | |
| | | /** |
| | | * 解析旧系统响应 |
| | | * 预期格式: "OK:ServiceOrdID" 或错误信息 |
| | | */ |
| | | private Long parseResponse(String response) { |
| | | if (StringUtils.isEmpty(response)) { |
| | | return null; |
| | | } |
| | | |
| | | // 去除可能的HTML标签和空白字符 |
| | | response = response.replaceAll("<[^>]*>", "").trim(); |
| | | |
| | | // 检查是否成功响应 |
| | | if (response.startsWith("OK:")) { |
| | | try { |
| | | String serviceOrdIdStr = response.substring(3).trim(); |
| | | return Long.parseLong(serviceOrdIdStr); |
| | | } catch (NumberFormatException e) { |
| | | log.error("解析ServiceOrdID失败: {}", response, e); |
| | | return null; |
| | | } |
| | | } else { |
| | | log.error("旧系统返回错误: {}", response); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 重新同步车辆和人员变更的任务到旧系统 |
| | | * 当任务的车辆信息或人员信息发生变更时,需要调用旧系统接口重新同步 |
| | | * 使用 admin_save_25.asp 接口,而不是 admin_save_24.gds |
| | | */ |
| | | @Override |
| | | @Transactional |
| | | public boolean resyncDispatchOrderToLegacy(Long taskId) { |
| | | if (!legacyConfig.isEnabled()) { |
| | | log.info("旧系统同步已禁用,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | try { |
| | | // 查询任务信息 |
| | | SysTask task = sysTaskMapper.selectSysTaskByTaskId(taskId); |
| | | if (task == null) { |
| | | log.error("任务不存在,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 只同步急救转运任务 |
| | | if (!"EMERGENCY_TRANSFER".equals(task.getTaskType())) { |
| | | log.info("非急救转运任务,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 查询急救转运扩展信息 |
| | | SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | if (emergency == null) { |
| | | log.error("急救转运扩展信息不存在,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 必须已经同步过调度单 |
| | | if (emergency.getLegacyDispatchOrdId() == null || emergency.getLegacyDispatchOrdId() <= 0) { |
| | | log.warn("调度单未同步,无法重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | Long serviceOrdId = emergency.getLegacyServiceOrdId(); |
| | | if (serviceOrdId == null || serviceOrdId <= 0) { |
| | | log.warn("服务单未同步,无法重新同步调度单,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // ====== 前置校验:确保任务数据完整 ====== |
| | | |
| | | // 1. 检查是否已分配车辆 |
| | | List<SysTaskVehicle> taskVehicles = sysTaskVehicleMapper.selectSysTaskVehicleByTaskId(taskId); |
| | | if (taskVehicles == null || taskVehicles.isEmpty()) { |
| | | log.warn("任务未分配车辆,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 2. 检查是否已分配执行人员 |
| | | List<SysTaskAssignee> taskAssignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId); |
| | | if (taskAssignees == null || taskAssignees.isEmpty()) { |
| | | log.warn("任务未分配执行人员,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 3. 检查预约时间是否有效 |
| | | if (task.getPlannedStartTime() == null || task.getPlannedStartTime().getTime() <= 0L) { |
| | | log.warn("任务预约时间无效,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 4. 检查转出医院信息 |
| | | if (StringUtils.isEmpty(emergency.getHospitalOutName()) || StringUtils.isEmpty(emergency.getHospitalOutAddress())) { |
| | | log.warn("任务转出医院信息不完整,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 5. 检查转入医院信息 |
| | | if (StringUtils.isEmpty(emergency.getHospitalInName()) || StringUtils.isEmpty(emergency.getHospitalInAddress())) { |
| | | log.warn("任务转入医院信息不完整,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | // 6. 检查患者基本信息 |
| | | if (StringUtils.isEmpty(emergency.getPatientName()) || StringUtils.isEmpty(emergency.getPatientPhone())) { |
| | | log.warn("任务患者信息不完整,跳过调度单重新同步,任务ID: {}", taskId); |
| | | return false; |
| | | } |
| | | |
| | | log.info("任务数据校验通过,开始重新同步调度单,任务ID: {}, DispatchOrdID: {}", taskId, emergency.getLegacyDispatchOrdId()); |
| | | |
| | | // 构建请求参数(使用相同的参数构建方法) |
| | | Map<String, String> params = buildDispatchOrderParams(task, emergency); |
| | | params.put("DispatchOrdID", emergency.getLegacyDispatchOrdId().toString()); |
| | | params.put("ServiceOrdID", emergency.getLegacyServiceOrdId().toString()); |
| | | params.put("DispatchOrdState", "3"); |
| | | log.info("重新同步调度单到旧系统请求参数: {}", params); |
| | | // 发送HTTP请求到旧系统(使用admin_save_25.asp接口) |
| | | String response = sendHttpPost(legacyConfig.getDispatchUpdateUrl(), params); |
| | | log.info("重新同步调度单到旧系统响应: ServiceOrdID:{},DispatchOrdId:{},Result: {}",emergency.getLegacyServiceOrdId(),emergency.getLegacyDispatchOrdId(), response); |
| | | // 解析响应 |
| | | // Long dispatchOrdId = parseResponse(response); |
| | | |
| | | if (response != null && response.equals("OK")) { |
| | | // 重新同步成功,清除重新同步标记 |
| | | SysTaskEmergency emergency=sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | Long dispatchOrderId = emergency.getLegacyDispatchOrdId(); |
| | | if(LongUtil.isEmpty(dispatchOrderId)){ |
| | | Long serviceOrderId= taskEmergencySyncService.syncEmergency(taskId); |
| | | if(LongUtil.isNotEmpty(serviceOrderId)) { |
| | | emergency.setNeedResync(0); |
| | | emergency.setDispatchSyncTime(new Date()); |
| | | emergency.setDispatchSyncErrorMsg(null); |
| | | // emergency.setSyncStatus(2); |
| | | emergency.setSyncTime(new Date()); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | log.info("调度单重新同步成功,任务ID: {}, DispatchOrdID: {}", taskId, emergency.getLegacyDispatchOrdId()); |
| | | return true; |
| | | } else { |
| | | // 重新同步失败 |
| | | emergency.setDispatchSyncErrorMsg("重新同步失败:" + response); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | log.error("调度单重新同步失败,任务ID: {}, 响应: {}", taskId, response); |
| | | return false; |
| | | } |
| | | |
| | | } catch (Exception e) { |
| | | log.error("重新同步调度单到旧系统异常,任务ID: {}", taskId, e); |
| | | |
| | | // 更新同步状态为失败 |
| | | try { |
| | | SysTaskEmergency emergency = sysTaskEmergencyService.selectSysTaskEmergencyByTaskId(taskId); |
| | | if (emergency != null) { |
| | | emergency.setDispatchSyncErrorMsg("重新同步异常: " + e.getMessage()); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | } |
| | | } catch (Exception ex) { |
| | | log.error("更新调度单同步状态失败", ex); |
| | | } |
| | | |
| | | return false; |
| | | }else { |
| | | return taskDispatchSyncService.resyncDispatchOrderToLegacy(taskId); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 批量重新同步需要更新的调度单 |
| | | */ |
| | |
| | | while (true) { |
| | | // 分页查询需要重新同步的任务 |
| | | List<SysTaskEmergency> needResyncTasks = sysTaskEmergencyMapper.selectNeedResyncTasks(offset, pageSize); |
| | | |
| | | log.info("查询到需要重新同步的任务数量: {}", needResyncTasks.size()); |
| | | |
| | | // log.info("查询到需要重新同步的任务数量: {}", needResyncTasks.size()); |
| | | if (needResyncTasks == null || needResyncTasks.isEmpty()) { |
| | | log.info("没有更多需要重新同步的任务,offset: {}", offset); |
| | | break; // 没有更多数据,退出循环 |
| | | } |
| | | |
| | | log.info("开始重新同步调度单第 {} 页,任务数量: {}", (offset / pageSize) + 1, needResyncTasks.size()); |
| | | |
| | | |
| | | // log.info("开始重新同步调度单第 {} 页,任务数量: {}", (offset / pageSize) + 1, needResyncTasks.size()); |
| | | |
| | | int pageSuccessCount = 0; |
| | | for (SysTaskEmergency emergency : needResyncTasks) { |
| | | log.info("开始重新同步调度单,任务ID: {}", emergency.getTaskId()); |
| | | boolean success = resyncDispatchOrderToLegacy(emergency.getTaskId()); |
| | | |
| | | if (success) { |
| | | pageSuccessCount++; |
| | | Long dispatchOrdId = emergency.getLegacyDispatchOrdId(); |
| | | Long taskId = emergency.getTaskId(); |
| | | if (LongUtil.isEmpty(dispatchOrdId)) { |
| | | //没有调度单,我们就调用创建调度单 |
| | | Long serviceOrderId = syncDispatchOrderToLegacy(taskId); |
| | | if (LongUtil.isNotEmpty(serviceOrderId)) { |
| | | emergency.setNeedResync(0); |
| | | emergency.setDispatchSyncTime(new Date()); |
| | | emergency.setDispatchSyncErrorMsg(null); |
| | | sysTaskEmergencyService.updateSysTaskEmergency(emergency); |
| | | |
| | | continue; |
| | | } |
| | | // log.info("开始重新同步调度单,任务ID: {}", emergency.getTaskId()); |
| | | boolean success = resyncDispatchOrderToLegacy(emergency.getTaskId()); |
| | | |
| | | if (success) { |
| | | pageSuccessCount++; |
| | | } |
| | | |
| | | // 避免过于频繁的请求 |
| | | try { |
| | | Thread.sleep(1000); // 每个请求间隔1秒 |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | log.warn("重新同步调度单被中断"); |
| | | return totalSuccessCount + pageSuccessCount; |
| | | } |
| | | } |
| | | |
| | | // 避免过于频繁的请求 |
| | | try { |
| | | Thread.sleep(1000); // 每个请求间隔1秒 |
| | | } catch (InterruptedException e) { |
| | | Thread.currentThread().interrupt(); |
| | | log.warn("重新同步调度单被中断"); |
| | | return totalSuccessCount + pageSuccessCount; |
| | | |
| | | totalSuccessCount += pageSuccessCount; |
| | | // log.info("调度单重新同步第 {} 页完成,总数: {}, 成功: {}", |
| | | // (offset / pageSize) + 1, needResyncTasks.size(), pageSuccessCount); |
| | | |
| | | // 如果本页数据少于每页大小,说明已经是最后一页 |
| | | if (needResyncTasks.size() < pageSize) { |
| | | // log.info("已到达最后一页,调度单重新同步结束"); |
| | | break; |
| | | } |
| | | |
| | | offset += pageSize; // 下一页 |
| | | } |
| | | |
| | | totalSuccessCount += pageSuccessCount; |
| | | log.info("调度单重新同步第 {} 页完成,总数: {}, 成功: {}", |
| | | (offset / pageSize) + 1, needResyncTasks.size(), pageSuccessCount); |
| | | |
| | | // 如果本页数据少于每页大小,说明已经是最后一页 |
| | | if (needResyncTasks.size() < pageSize) { |
| | | log.info("已到达最后一页,调度单重新同步结束"); |
| | | break; |
| | | } |
| | | |
| | | offset += pageSize; // 下一页 |
| | | } |
| | | |
| | | log.info("批量重新同步调度单完成,总成功数: {}", totalSuccessCount); |
| | | // log.info("批量重新同步调度单完成,总成功数: {}", totalSuccessCount); |
| | | return totalSuccessCount; |
| | | |
| | | } catch (Exception e) { |