package com.ruoyi.system.service.impl; import com.ruoyi.common.config.LegacySystemConfig; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.SysTask; import com.ruoyi.system.domain.SysTaskEmergency; import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysUserService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; 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.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; @Slf4j @Service public class TaskSyncUtilService { @Autowired private ISysUserService sysUserService; @Autowired private ISysDeptService sysDeptService; @Autowired private LegacySystemConfig legacySystemConfig; /** * 判断用户类型(司机/医生/护士/其他) * 根据用户的角色名称来判断 * * @param user 用户信息 * @return 用户类型:driver/doctor/nurse/other */ public 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"; } public String getAdminID(SysTask task) { String adminID=""; if (task.getCreatorId() != null) { try { SysUser creator = sysUserService.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; } /** * 构建同步参数 */ public Map buildSyncParams(SysTask task, SysTaskEmergency emergency) { Map 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 = sysDeptService.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.getHospitalOutBedNumber(), "")); //转出床位 params.put("ServiceOrdPtServicesID", StringUtils.nvl(emergency.getHospitalOutDepartmentId(), "0")); // 转出科室ID params.put("ServiceOrdPtInServices", StringUtils.nvl(emergency.getHospitalInBedNumber(), "")); //转入床位 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自签名证书 */ public String sendHttpPost(String urlString, Map 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(legacySystemConfig.getConnectTimeout()); conn.setReadTimeout(legacySystemConfig.getReadTimeout()); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + legacySystemConfig.getCharset()); conn.setRequestProperty("Accept-Charset", legacySystemConfig.getCharset()); // 构建POST数据 StringBuilder postData = new StringBuilder(); for (Map.Entry entry : params.entrySet()) { if (postData.length() > 0) { postData.append("&"); } postData.append(URLEncoder.encode(entry.getKey(), legacySystemConfig.getCharset())); postData.append("="); postData.append(URLEncoder.encode(entry.getValue().toString(), legacySystemConfig.getCharset())); } // 发送POST数据 try (OutputStream os = conn.getOutputStream()) { os.write(postData.toString().getBytes(legacySystemConfig.getCharset())); os.flush(); } // 读取响应 int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { try (BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream(), legacySystemConfig.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(); } } /** * 解析旧系统响应 * 预期格式: "OK:ServiceOrdID" 或错误信息 */ public 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; } } /** * 创建信任所有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; } }