| | |
| | | private SysTaskMapper sysTaskMapper; |
| | | |
| | | @Autowired |
| | | private SysTaskEmergencyMapper sysTaskEmergencyMapper; |
| | | |
| | | @Autowired |
| | | private SysUserMapper sysUserMapper; |
| | | |
| | | @Autowired |
| | |
| | | |
| | | @Autowired |
| | | private ITaskAttachmentService taskAttachmentService; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 同步急救转运任务到旧系统 |
| | |
| | | /** |
| | | * 重新同步失败的任务 |
| | | */ |
| | | @Override |
| | | @Transactional |
| | | @Override |
| | | public boolean retrySyncTask(Long taskId) { |
| | | try { |
| | | // 重置同步状态 |
| | |
| | | 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); |
| | |
| | | // 构建请求参数 |
| | | Map<String, String> params = buildDispatchOrderParams(task, emergency); |
| | | |
| | | |
| | | // 发送HTTP请求 |
| | | String response = sendHttpPost(legacyConfig.getDispatchCreateUrl(), params); |
| | | |
| | |
| | | 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("DispatchOrd_Check", "0"); // 3=直接强制完成 |
| | | |
| | | // 绩效和费用 |
| | | params.put("DispatchOrdPerfomance", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); |
| | | // 绩效和费用:确保数值字段不为null |
| | | String transferPrice = "0"; |
| | | if (emergency.getTransferPrice() != null) { |
| | | try { |
| | | transferPrice = emergency.getTransferPrice().toString(); |
| | | if (transferPrice.contains(".")) { |
| | | transferPrice = new java.math.BigDecimal(transferPrice).stripTrailingZeros().toPlainString(); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("转换转运价格失败,任务ID: {}, 使用默认值0", task.getTaskId(), e); |
| | | transferPrice = "0"; |
| | | } |
| | | } |
| | | params.put("DispatchOrdPerfomance", transferPrice); |
| | | params.put("StretcherMoney", "0"); // 抬担架费 |
| | | params.put("AddMoneyType", ""); // 附加项目 |
| | | params.put("AddMoney", "0"); // 附加项目费用 |
| | |
| | | params.put("ServiceOrdPtDoctorPhone", ""); // 患者医生电话 |
| | | params.put("TransferModeID", ""); // 转运方式 |
| | | params.put("ServiceOrdVIP", "0"); // VIP客户 |
| | | params.put("ServiceOrdTraTxnPrice", emergency.getTransferPrice() != null ? emergency.getTransferPrice().toString() : "0"); // 成交价 |
| | | // 价格字段复用,确保一致性 |
| | | params.put("ServiceOrdTraTxnPrice", transferPrice); // 成交价 |
| | | params.put("ServiceOrdTraPrePayment", "0"); // 需预付款 |
| | | params.put("SettlementPrice", "0"); // 结算价 |
| | | params.put("ServiceOrdTraPriceReason", ""); // 差价原因 |
| | |
| | | params.put("ServiceOrdEstimatedOrderDate", ""); // 预计派单时间 |
| | | params.put("ServiceOrdEstimatedOrderDateOld", ""); // 原预计派单时间 |
| | | params.put("ServiceOrdViaDistance", "0"); // 中途距离 |
| | | params.put("ServiceOrdTraDistance", emergency.getTransferDistance() != null ? emergency.getTransferDistance().toString() : "0"); // 距离 |
| | | // 距离字段:确保不为空,避免旧系统接口报错 |
| | | String transferDistance = "0"; |
| | | if (emergency.getTransferDistance() != null) { |
| | | try { |
| | | transferDistance = emergency.getTransferDistance().toString(); |
| | | // 去除可能的小数点后多余的0 |
| | | if (transferDistance.contains(".")) { |
| | | transferDistance = new java.math.BigDecimal(transferDistance).stripTrailingZeros().toPlainString(); |
| | | } |
| | | } catch (Exception e) { |
| | | log.warn("转换转运距离失败,任务ID: {}, 使用默认值0", task.getTaskId(), e); |
| | | transferDistance = "0"; |
| | | } |
| | | } |
| | | params.put("ServiceOrdTraDistance", transferDistance); |
| | | params.put("OrderLevel", "0"); // 查看等级 |
| | | params.put("ServiceOrdDepartureType", "1"); // 预约类型 |
| | | params.put("ConditionLevel", "0"); // 病重级别 |
| | |
| | | */ |
| | | 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()) { |
| | |
| | | // 设置默认空值 |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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); // 护士 |
| | | // 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); |
| | |
| | | // 地址信息 |
| | | params.put("province", ""); // 出发地省份 |
| | | params.put("city", ""); // 出发地城市 |
| | | params.put("ServiceOrdTraStreet", StringUtils.nvl(task.getDepartureAddress(), StringUtils.nvl(emergency.getHospitalOutAddress(), ""))); |
| | | params.put("ServiceOrdTraStreet",task.getDepartureAddress()); //派车地址 |
| | | params.put("ServiceOrdTraStreetCoo", ""); // 出发地坐标 |
| | | params.put("ServiceOrdTraEnd", StringUtils.nvl(task.getDestinationAddress(), StringUtils.nvl(emergency.getHospitalInAddress(), ""))); |
| | | params.put("ServiceOrdTraEndCoo", ""); // 目的地坐标 |
| | |
| | | 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")) { |
| | | // 重新同步成功,清除重新同步标记 |
| | | emergency.setNeedResync(0); |
| | | emergency.setDispatchSyncTime(new Date()); |
| | | emergency.setDispatchSyncErrorMsg(null); |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 批量重新同步需要更新的调度单 |
| | | */ |
| | | @Override |
| | | public int batchResyncPendingDispatchOrders() { |
| | | if (!legacyConfig.isEnabled()) { |
| | | log.info("旧系统同步已禁用"); |
| | | return 0; |
| | | } |
| | | |
| | | try { |
| | | int totalSuccessCount = 0; |
| | | int pageSize = 100; // 每页100条 |
| | | int offset = 0; |
| | | |
| | | while (true) { |
| | | // 分页查询需要重新同步的任务 |
| | | List<SysTaskEmergency> needResyncTasks = sysTaskEmergencyMapper.selectNeedResyncTasks(offset, pageSize); |
| | | |
| | | log.info("查询到需要重新同步的任务数量: {}", needResyncTasks.size()); |
| | | if (needResyncTasks == null || needResyncTasks.isEmpty()) { |
| | | log.info("没有更多需要重新同步的任务,offset: {}", offset); |
| | | break; // 没有更多数据,退出循环 |
| | | } |
| | | |
| | | 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++; |
| | | } |
| | | |
| | | // 避免过于频繁的请求 |
| | | 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; // 下一页 |
| | | } |
| | | |
| | | log.info("批量重新同步调度单完成,总成功数: {}", totalSuccessCount); |
| | | return totalSuccessCount; |
| | | |
| | | } catch (Exception e) { |
| | | log.error("批量重新同步调度单异常", e); |
| | | return 0; |
| | | } |
| | | } |
| | | } |