|  |  | 
 |  |  | import com.alibaba.fastjson2.JSONObject; | 
 |  |  | import com.fasterxml.jackson.databind.JsonNode; | 
 |  |  | import com.fasterxml.jackson.databind.ObjectMapper; | 
 |  |  | import com.google.common.reflect.TypeToken; | 
 |  |  | import com.google.gson.Gson; | 
 |  |  | import com.google.gson.JsonArray; | 
 |  |  | import com.google.gson.JsonObject; | 
 |  |  | import com.ruoyi.common.core.redis.RedisCache; | 
 |  |  | import com.ruoyi.common.enums.MsgLSEnum; | 
 |  |  | import com.ruoyi.common.enums.ServiceFromEnum; | 
 |  |  | import com.ruoyi.common.enums.VisitSendStateEnum; | 
 |  |  | import com.ruoyi.common.enums.WxGZHEnum; | 
 |  |  | import com.ruoyi.common.exception.base.BaseException; | 
 |  |  | import com.ruoyi.common.utils.HttpUtil; | 
 |  |  | import com.ruoyi.common.utils.OkHttpExample; | 
 |  |  | import com.ruoyi.common.utils.RSAPublicKeyExample; | 
 |  |  | import com.ruoyi.common.utils.StringUtils; | 
 |  |  | import com.ruoyi.common.utils.http.HttpUtils; | 
 |  |  | import com.ruoyi.quartz.service.ICollectHISService; | 
 |  |  | import com.smartor.common.LSHospTokenUtil; | 
 |  |  | import com.smartor.domain.*; | 
 |  |  | import com.smartor.mapper.HeLibraryMapper; | 
 |  |  | import com.smartor.mapper.ServiceSubtaskMapper; | 
 |  |  | import com.smartor.mapper.ServiceTaskMapper; | 
 |  |  | import com.smartor.mapper.SysUserImportMapper; | 
 |  |  | 
 |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
 |  |  | import org.springframework.beans.factory.annotation.Value; | 
 |  |  | import org.springframework.stereotype.Component; | 
 |  |  | import org.springframework.transaction.PlatformTransactionManager; | 
 |  |  | import org.springframework.transaction.annotation.Transactional; | 
 |  |  |  | 
 |  |  | import java.io.File; | 
 |  |  | import java.io.FileWriter; | 
 |  |  | import java.io.IOException; | 
 |  |  | import java.lang.reflect.Type; | 
 |  |  | import java.net.URLEncoder; | 
 |  |  | import java.nio.charset.StandardCharsets; | 
 |  |  | import java.nio.file.Files; | 
 |  |  | import java.nio.file.Paths; | 
 |  |  | import java.security.MessageDigest; | 
 |  |  | import java.text.ParseException; | 
 |  |  | import java.text.SimpleDateFormat; | 
 |  |  | import java.time.LocalDate; | 
 |  |  | import java.time.LocalDateTime; | 
 |  |  | import java.time.LocalTime; | 
 |  |  | 
 |  |  |     private IServicePatientTempService iServicePatientTempService; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private PlatformTransactionManager transactionManager; | 
 |  |  |     private IHNGatherPatArchiveService ihnGatherPatArchiveService; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private SysUserImportMapper sysUserImportMapper; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private HeLibraryMapper heLibraryMapper; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     private ICollectHISService ichService; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     @Value("${localIP}") | 
 |  |  |     private String localIP; | 
 |  |  | 
 |  |  |     @Autowired | 
 |  |  |     IPatArchiveService patArchiveService; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     IPatMedInhospService patMedInhospService; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     IPatMedOuthospService patMedOuthospService; | 
 |  |  | 
 |  |  |     @Autowired | 
 |  |  |     IIvrTaskTemplateService iIvrTaskTemplateService; | 
 |  |  |  | 
 |  |  |     @Value("${hosp_info_url}") | 
 |  |  |     private String hospInfoUrl; | 
 |  |  |     @Autowired | 
 |  |  |     IXHGatherPatArchiveService ixhGatherPatArchiveService; | 
 |  |  |  | 
 |  |  |     @Autowired | 
 |  |  |     ICollectHISService icollectHis; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     @Value("${appid}") | 
 |  |  |     private String appid; | 
 |  |  |  | 
 |  |  |     @Value("${server.port}") | 
 |  |  |     private String port; | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     @Value("${spring.profiles.active}") | 
 |  |  |     private String active; | 
 |  |  |  | 
 |  |  |     public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) { | 
 |  |  |         System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); | 
 |  |  | 
 |  |  |      */ | 
 |  |  |     public void dealHisData() { | 
 |  |  |         log.info("【dealHisData】开始执行HIS数据采集任务"); | 
 |  |  |         long startTime = System.currentTimeMillis(); | 
 |  |  |         // 获取昨天0点到今天0点的时间范围 | 
 |  |  |         LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN); | 
 |  |  |         LocalDateTime yesterdayZero = todayZero.minusDays(1); | 
 |  |  |         log.info("【dealHisData】采集时间范围:{} ~ {}", yesterdayZero, todayZero); | 
 |  |  |  | 
 |  |  |         try { | 
 |  |  |             // 获取昨天0点到今天0点的时间范围 | 
 |  |  |             LocalDateTime todayZero = LocalDateTime.now().with(LocalTime.MIN); | 
 |  |  |             LocalDateTime yesterdayZero = todayZero.minusDays(1); | 
 |  |  |         if (active.trim().equals("xh")) { | 
 |  |  |             try { | 
 |  |  |                 // 采集入院数据 | 
 |  |  |                 log.info("【dealHisData】新华开始采集入院数据"); | 
 |  |  |                 ixhGatherPatArchiveService.getInHospDataGather("0", yesterdayZero, todayZero); | 
 |  |  |                 log.info("【dealHisData】新华入院数据采集完成"); | 
 |  |  |  | 
 |  |  |             log.info("【dealHisData】采集时间范围:{} ~ {}", yesterdayZero, todayZero); | 
 |  |  |                 // 采集出院数据 | 
 |  |  |                 log.info("【dealHisData】新华开始采集出院数据"); | 
 |  |  |                 ixhGatherPatArchiveService.getInHospDataGather("1", yesterdayZero, todayZero); | 
 |  |  |                 log.info("【dealHisData】新华出院数据采集完成"); | 
 |  |  |  | 
 |  |  |             // 采集入院数据 | 
 |  |  |             log.info("【dealHisData】开始采集入院数据"); | 
 |  |  |             getInHospInfo("0", yesterdayZero, todayZero); | 
 |  |  |             log.info("【dealHisData】入院数据采集完成"); | 
 |  |  |  | 
 |  |  |             // 采集出院数据 | 
 |  |  |             log.info("【dealHisData】开始采集出院数据"); | 
 |  |  |             getInHospInfo("1", yesterdayZero, todayZero); | 
 |  |  |             log.info("【dealHisData】出院数据采集完成"); | 
 |  |  |  | 
 |  |  |             long endTime = System.currentTimeMillis(); | 
 |  |  |             log.info("【dealHisData】HIS数据采集任务完成,总耗时:{}ms", endTime - startTime); | 
 |  |  |  | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("【dealHisData】HIS数据采集异常", e); | 
 |  |  |             // 这里可以添加告警通知逻辑,比如发送邮件或短信 | 
 |  |  |             } catch (Exception e) { | 
 |  |  |                 log.error("【dealHisData】新华数据采集异常", e); | 
 |  |  |             } | 
 |  |  |         } else if (active.trim().equals("hn")) { | 
 |  |  |             try { | 
 |  |  |                 // 河南数据采集 | 
 |  |  |                 HnDataGatherVO hnDataGatherVO = new HnDataGatherVO(); | 
 |  |  |                 log.info("【dealHisData】河南开始采集数据"); | 
 |  |  |                 ihnGatherPatArchiveService.hnDataGather(hnDataGatherVO); | 
 |  |  |                 log.info("【dealHisData】河南结束采集数据"); | 
 |  |  |             } catch (Exception e) { | 
 |  |  |                 log.error("【dealHisData】河南数据采集异常", e); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 这个只是新华临时使用,平时用不到 | 
 |  |  |      */ | 
 |  |  |     public void dealHisData2() { | 
 |  |  |         //将患者信息、出入院数据全部采集 | 
 |  |  |         // 指定的开始日期 | 
 |  |  | 
 |  |  |         // 从开始日期到当前日期逐天打印 | 
 |  |  |         for (LocalDate date = endDate; !date.isAfter(currentDate); date = date.plusDays(1)) { | 
 |  |  |             System.out.println(date.format(formatter)); | 
 |  |  |             getInHospInfo("0", date.minusDays(1).atStartOfDay(), date.atStartOfDay()); | 
 |  |  |             getInHospInfo("1", date.minusDays(1).atStartOfDay(), date.atStartOfDay()); | 
 |  |  |             ixhGatherPatArchiveService.getInHospDataGather("0", date.minusDays(1).atStartOfDay(), date.atStartOfDay()); | 
 |  |  |             ixhGatherPatArchiveService.getInHospDataGather("1", date.minusDays(1).atStartOfDay(), date.atStartOfDay()); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |     } | 
 |  |  | 
 |  |  |                 //丽水有的医院还没法做长期任务随访 | 
 |  |  |                 List<ServiceSubtask> subtaskList2 = new ArrayList<>(); | 
 |  |  |                 if (visitHosp == 2) { | 
 |  |  |                     for (ServiceSubtask serviceSubtask : subtaskList) { | 
 |  |  |                         Boolean b = VisitSendStateEnum.getDescByCode(serviceSubtask.getOrgid()); | 
 |  |  |                         if (b) subtaskList2.add(serviceSubtask); | 
 |  |  |                     try { | 
 |  |  |                         for (ServiceSubtask serviceSubtask : subtaskList) { | 
 |  |  |                             Boolean b = VisitSendStateEnum.getDescByCode(serviceSubtask.getOrgid()); | 
 |  |  |  | 
 |  |  |                             if (b) subtaskList2.add(serviceSubtask); | 
 |  |  |                         } | 
 |  |  |                     } catch (Exception e) { | 
 |  |  |                         log.error("-------长期任务异常为:", e); | 
 |  |  |                         continue; | 
 |  |  |                     } | 
 |  |  | //                    for (ServiceSubtask serviceSubtask : subtaskList) { | 
 |  |  | //                        Boolean b = VisitSendStateEnum.getDescByCode(serviceSubtask.getOrgid()); | 
 |  |  | // | 
 |  |  | //                        if (b) subtaskList2.add(serviceSubtask); | 
 |  |  | //                    } | 
 |  |  |                     subtaskList = subtaskList2; | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  | 
 |  |  |                                     serviceSubtask.setResult("error"); | 
 |  |  |                                     serviceSubtask.setRemark(patArchive.getNotrequiredreason()); | 
 |  |  |                                     serviceSubtask.setSendstate(4L); | 
 |  |  | //                                    serviceSubtask.setFinishtime(new Date()); | 
 |  |  |                                     iServiceSubtaskService.insertServiceSubtask(serviceSubtask); | 
 |  |  |                                     continue; | 
 |  |  |                                 } | 
 |  |  | 
 |  |  |                                 serviceOutPath.setRadix(format); | 
 |  |  |                                 serviceOutPath.setUpdateTime(new Date()); | 
 |  |  |                                 iServiceOutPathService.updateServiceOutPath(serviceOutPath); | 
 |  |  |                                 sendMagParam.setPhone(serviceSubtask.getPhone()); | 
 |  |  |                                 sendMagParam.setUrl(ip + ":" + req_path + "/wt?p=" + format); | 
 |  |  |                                 sendMagParam.setContent("【新华医院】您好,邀请您填写出院调查表,请点击" + sendMagParam.getUrl() + "填写。感谢您配合!"); | 
 |  |  |                                 //先判断一下发的是不是宣教 | 
 |  |  |                                 if (!"3".equals(serviceSubtask.getType())) { | 
 |  |  |                                     sendMagParam.setPhone(serviceSubtask.getPhone()); | 
 |  |  |                                     sendMagParam.setUrl(ip + ":" + req_path + "/wt?p=" + format); | 
 |  |  |                                     sendMagParam.setContent("【新华医院】您好,邀请您填写出院调查表,请点击" + sendMagParam.getUrl() + "填写。感谢您配合!"); | 
 |  |  |                                 } else { | 
 |  |  |                                     HeLibrary heLibrary = heLibraryMapper.selectHeLibraryById(serviceSubtask.getLibtemplateid()); | 
 |  |  |                                     if ("2".equals(heLibrary.getHetype())) { | 
 |  |  |                                         sendMagParam.setPhone(serviceSubtask.getPhone()); | 
 |  |  |                                         sendMagParam.setContent(heLibrary.getPreachcontent()); | 
 |  |  |                                     } | 
 |  |  |                                 } | 
 |  |  |                                 String isSuccess = null; | 
 |  |  |                                 if (visitHosp == 1) { | 
 |  |  |                                     Map<String, String> req = new HashMap<>(); | 
 |  |  | 
 |  |  |                                 serviceSubtask.setResult("error"); | 
 |  |  |                                 serviceSubtask.setRemark("系统错误"); | 
 |  |  |                                 serviceSubtask.setSendstate(5L); | 
 |  |  | //                                serviceSubtask.setFinishtime(new Date()); | 
 |  |  |                                 serviceSubtask.setGuid(guid); | 
 |  |  |                                 iServiceSubtaskService.updateServiceSubtask(serviceSubtask); | 
 |  |  |                             } | 
 |  |  | 
 |  |  |                                     serviceSubtask.setResult("error"); | 
 |  |  |                                     serviceSubtask.setRemark(patArchive.getNotrequiredreason()); | 
 |  |  |                                     serviceSubtask.setSendstate(4L); | 
 |  |  | //                                    serviceSubtask.setFinishtime(new Date()); | 
 |  |  |                                     iServiceSubtaskService.insertServiceSubtask(serviceSubtask); | 
 |  |  |                                     continue; | 
 |  |  |                                 } | 
 |  |  |                                 String patid = rsaPublicKeyExample.encryptedData(serviceSubtask.getPatid().toString(), pub_key); | 
 |  |  |                                 String url = null; | 
 |  |  |                                 url = ip + ":" + req_path + "/outsideChainwt?param1=" + taskId + "¶m2=" + patid + "¶m3=" + URLEncoder.encode(ivrTask1.getTaskName(), StandardCharsets.UTF_8.toString()) + "¶m5=false"; | 
 |  |  | //                                String wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskDesc(), "无"); | 
 |  |  |  | 
 |  |  |                                 //获取微信公众号请求信息根据机构ID | 
 |  |  |                                 List<String> wxqqxx = WxGZHEnum.getDescByCode(patArchive.getOrgid()); | 
 |  |  | 
 |  |  |                                     ss.setRemark("该机构的公众号配置信息不全,无法通过公众号发送"); | 
 |  |  |                                     ss.setSendstate(5L); | 
 |  |  |                                     ss.setId(serviceSubtask.getId()); | 
 |  |  | //                                    ss.setFinishtime(new Date()); | 
 |  |  |                                     serviceSubtaskMapper.updateServiceSubtask(ss); | 
 |  |  |                                     continue; | 
 |  |  |                                 } | 
 |  |  | 
 |  |  |                                     ss.setRemark("公众号发送失败,his系统的患者id为空"); | 
 |  |  |                                     ss.setSendstate(5L); | 
 |  |  |                                     ss.setId(serviceSubtask.getId()); | 
 |  |  | //                                    ss.setFinishtime(new Date()); | 
 |  |  |                                     serviceSubtaskMapper.updateServiceSubtask(ss); | 
 |  |  |                                     continue; | 
 |  |  |                                 } | 
 |  |  | 
 |  |  |                                 serviceSubtask.setResult("error"); | 
 |  |  |                                 serviceSubtask.setRemark("系统错误"); | 
 |  |  |                                 serviceSubtask.setSendstate(5L); | 
 |  |  | //                                serviceSubtask.setFinishtime(new Date()); | 
 |  |  |                                 serviceSubtask.setGuid(guid); | 
 |  |  |                                 iServiceSubtaskService.updateServiceSubtask(serviceSubtask); | 
 |  |  |                             } | 
 |  |  | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 获取患者出入院信息 | 
 |  |  |      * | 
 |  |  |      * @param cry       出入院类型:0-入院,1-出院 | 
 |  |  |      * @param startTime 开始时间 | 
 |  |  |      * @param endTime   结束时间 | 
 |  |  |      */ | 
 |  |  |     @Transactional | 
 |  |  |     public void getInHospInfo(String cry, LocalDateTime startTime, LocalDateTime endTime) { | 
 |  |  |         String typeName = "0".equals(cry) ? "入院" : "出院"; | 
 |  |  |         log.info("【getInHospInfo】开始获取{}患者信息,时间范围:{} ~ {}", typeName, startTime, endTime); | 
 |  |  |         long startTimeMillis = System.currentTimeMillis(); | 
 |  |  |  | 
 |  |  |         try { | 
 |  |  |             // 第一步:构建请求参数并调用HIS接口 | 
 |  |  |             List<ThiedInhospInfo> thiedInhospInfoList = fetchHisData(cry, startTime, endTime); | 
 |  |  |  | 
 |  |  |             if (CollectionUtils.isEmpty(thiedInhospInfoList)) { | 
 |  |  |                 log.info("【getInHospInfo】{}患者信息为空,跳过处理", typeName); | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             log.info("【getInHospInfo】获取到{}条{}患者信息", thiedInhospInfoList.size(), typeName); | 
 |  |  |  | 
 |  |  |             // 第二步:保存原始数据到文件(用于备份) | 
 |  |  |             saveRawDataToFile(cry, thiedInhospInfoList); | 
 |  |  |  | 
 |  |  |             // 第三步:处理患者数据 | 
 |  |  |             processPatientData(thiedInhospInfoList, cry); | 
 |  |  |  | 
 |  |  |             long endTimeMillis = System.currentTimeMillis(); | 
 |  |  |             log.info("【getInHospInfo】{}患者信息处理完成,耗时:{}ms", typeName, endTimeMillis - startTimeMillis); | 
 |  |  |  | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("【getInHospInfo】获取{}患者信息异常", typeName, e); | 
 |  |  |             throw new RuntimeException("获取" + typeName + "患者信息失败", e); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 第一步:调用HIS接口获取数据 | 
 |  |  |      */ | 
 |  |  |     private List<ThiedInhospInfo> fetchHisData(String cry, LocalDateTime startTime, LocalDateTime endTime) { | 
 |  |  |         try { | 
 |  |  |             // 构建请求参数 | 
 |  |  |             Map<String, String> requestParams = buildRequestParams(cry, startTime, endTime); | 
 |  |  |  | 
 |  |  |             // 构建请求头 | 
 |  |  |             Map<String, String> headers = buildRequestHeaders(startTime); | 
 |  |  |  | 
 |  |  |             // 发送HTTP请求 | 
 |  |  |             String result = HttpUtils.sendPostByHeader(hospInfoUrl, new Gson().toJson(requestParams), headers); | 
 |  |  |  | 
 |  |  |             // 解析响应数据 | 
 |  |  |             return parseResponseData(result); | 
 |  |  |  | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("【fetchHisData】调用HIS接口异常", e); | 
 |  |  |             throw e; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 构建请求参数 | 
 |  |  |      */ | 
 |  |  |     private Map<String, String> buildRequestParams(String cry, LocalDateTime startTime, LocalDateTime endTime) { | 
 |  |  |         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"); | 
 |  |  |         Map<String, String> req = new HashMap<>(); | 
 |  |  |  | 
 |  |  |         if ("1".equals(cry)) { | 
 |  |  |             // 出院参数 | 
 |  |  |             req.put("cashStartDate", startTime.format(formatter)); | 
 |  |  |             req.put("cashEndDate", endTime.format(formatter)); | 
 |  |  |             req.put("currStatus", "4"); | 
 |  |  |         } else { | 
 |  |  |             // 入院参数 | 
 |  |  |             req.put("admissStartDate", startTime.format(formatter)); | 
 |  |  |             req.put("admissEndDate", endTime.format(formatter)); | 
 |  |  |             req.put("currStatus", "2"); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         return req; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 构建请求头 | 
 |  |  |      */ | 
 |  |  |     private Map<String, String> buildRequestHeaders(LocalDateTime startTime) { | 
 |  |  |         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"); | 
 |  |  |         Map<String, String> header = new HashMap<>(); | 
 |  |  |         header.put("x-hcsb-serviceno", "IS002347"); | 
 |  |  |         header.put("x-hcsb-version", "2.0"); | 
 |  |  |         header.put("x-hcsb-sourcesyscode", "14"); | 
 |  |  |         header.put("x-hcsb-token", "ArGE2JnHtxG/Zx5nrnGY4eOfMUJGGJokAJHigG1BrCY="); | 
 |  |  |         header.put("x-hcsb-msgdate", startTime.format(formatter)); | 
 |  |  |         return header; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 解析响应数据 | 
 |  |  |      */ | 
 |  |  |     private List<ThiedInhospInfo> parseResponseData(String result) { | 
 |  |  |         try { | 
 |  |  |             Gson gson = new Gson(); | 
 |  |  |             JsonObject jsonObject = gson.fromJson(result, JsonObject.class); | 
 |  |  |             JsonArray resultArray = jsonObject.getAsJsonObject("data").getAsJsonArray("result"); | 
 |  |  |             Type resultType = new TypeToken<List<ThiedInhospInfo>>() { | 
 |  |  |             }.getType(); | 
 |  |  |             return gson.fromJson(resultArray, resultType); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("【parseResponseData】解析响应数据异常,原始数据:{}", result, e); | 
 |  |  |             throw e; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 第二步:保存原始数据到文件 | 
 |  |  |      */ | 
 |  |  |     private void saveRawDataToFile(String cry, List<ThiedInhospInfo> dataList) { | 
 |  |  |         try { | 
 |  |  |             String typeName = "0".equals(cry) ? "入院信息" : "出院信息"; | 
 |  |  |             String filename = typeName + "_" + System.currentTimeMillis() + ".json"; | 
 |  |  |             String filePath = "D:\\public\\HIS数据采集\\" + filename; | 
 |  |  |  | 
 |  |  |             File file = new File(filePath); | 
 |  |  |             File parentDir = file.getParentFile(); | 
 |  |  |             if (!parentDir.exists()) { | 
 |  |  |                 parentDir.mkdirs(); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             if (!file.exists()) { | 
 |  |  |                 file.createNewFile(); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             // 将数据写入文件 | 
 |  |  |             try (FileWriter writer = new FileWriter(file)) { | 
 |  |  |                 writer.write(new Gson().toJson(dataList)); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             log.info("【saveRawDataToFile】原始数据已保存到文件:{}", filePath); | 
 |  |  |  | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("【saveRawDataToFile】保存原始数据到文件异常", e); | 
 |  |  |             // 文件保存失败不影响主流程,只记录日志 | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 第三步:处理患者数据 | 
 |  |  |      */ | 
 |  |  |     private void processPatientData(List<ThiedInhospInfo> thiedInhospInfoList, String cry) { | 
 |  |  |         int successCount = 0; | 
 |  |  |         int skipCount = 0; | 
 |  |  |         int errorCount = 0; | 
 |  |  |  | 
 |  |  |         for (ThiedInhospInfo thiedInhospInfo : thiedInhospInfoList) { | 
 |  |  |             try { | 
 |  |  |                 if (processSinglePatient(thiedInhospInfo, cry)) { | 
 |  |  |                     successCount++; | 
 |  |  |                 } else { | 
 |  |  |                     skipCount++; | 
 |  |  |                 } | 
 |  |  |             } catch (Exception e) { | 
 |  |  |                 errorCount++; | 
 |  |  |                 log.error("【processPatientData】处理患者数据异常,患者ID:{}", thiedInhospInfo.getPatiMediaNo(), e); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         log.info("【processPatientData】患者数据处理完成,成功:{},跳过:{},失败:{}", successCount, skipCount, errorCount); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 处理单个患者数据 | 
 |  |  |      */ | 
 |  |  |     private boolean processSinglePatient(ThiedInhospInfo thiedInhospInfo, String cry) { | 
 |  |  |         // 验证身份证号 | 
 |  |  |         if (StringUtils.isEmpty(thiedInhospInfo.getPatiIdCardNo())) { | 
 |  |  |             log.warn("【processSinglePatient】患者身份证号为空,跳过处理,患者编号:{}", thiedInhospInfo.getPatiMediaNo()); | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 处理患者档案信息 | 
 |  |  |         PatArchive patArchive = processPatientArchive(thiedInhospInfo, cry); | 
 |  |  |  | 
 |  |  |         // 处理患者住院信息 | 
 |  |  |         processPatientInhospInfo(thiedInhospInfo, patArchive, cry); | 
 |  |  |  | 
 |  |  |         return true; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 处理患者档案信息 | 
 |  |  |      */ | 
 |  |  |     private PatArchive processPatientArchive(ThiedInhospInfo thiedInhospInfo, String cry) { | 
 |  |  |         // 查询患者是否已存在 | 
 |  |  |         PatArchive queryArchive = new PatArchive(); | 
 |  |  |         queryArchive.setIdcardno(thiedInhospInfo.getPatiIdCardNo().trim()); | 
 |  |  |         List<PatArchive> existingArchives = patArchiveService.selectPatArchiveList(queryArchive); | 
 |  |  |  | 
 |  |  |         // 构建患者档案信息 | 
 |  |  |         PatArchive patArchive = buildPatientArchive(thiedInhospInfo, cry); | 
 |  |  |  | 
 |  |  |         // 保存或更新患者档案 | 
 |  |  |         if (CollectionUtils.isEmpty(existingArchives)) { | 
 |  |  |             patArchiveService.insertPatArchive(patArchive); | 
 |  |  |             log.debug("【processPatientArchive】新增患者档案,患者编号:{}", patArchive.getPatientno()); | 
 |  |  |         } else { | 
 |  |  |             patArchive.setId(existingArchives.get(0).getId()); | 
 |  |  |             patArchiveService.updateArchive(patArchive); | 
 |  |  |             log.debug("【processPatientArchive】更新患者档案,患者编号:{}", patArchive.getPatientno()); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         return patArchive; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 构建患者档案信息 | 
 |  |  |      */ | 
 |  |  |     private PatArchive buildPatientArchive(ThiedInhospInfo thiedInhospInfo, String cry) { | 
 |  |  |         PatArchive patArchive = new PatArchive(); | 
 |  |  |  | 
 |  |  |         // 基本信息 | 
 |  |  |         patArchive.setPatientno(thiedInhospInfo.getPatiMediaNo()); | 
 |  |  |         patArchive.setIdcardno(thiedInhospInfo.getPatiIdCardNo().trim()); | 
 |  |  |         patArchive.setName(thiedInhospInfo.getPatiRecordName()); | 
 |  |  |         patArchive.setSourcefrom(2); | 
 |  |  |         patArchive.setPattype("2"); | 
 |  |  |  | 
 |  |  |         // 性别 | 
 |  |  |         patArchive.setSex("男".equals(thiedInhospInfo.getPatiRecordGender()) ? 1L : 2L); | 
 |  |  |  | 
 |  |  |         // 民族和籍贯 | 
 |  |  |         patArchive.setNation(thiedInhospInfo.getPatiNation()); | 
 |  |  |         patArchive.setNativePlace(thiedInhospInfo.getPatiNationality()); | 
 |  |  |  | 
 |  |  |         // 居住地址 | 
 |  |  |         String homeAddr = thiedInhospInfo.getPatiHomeAddr(); | 
 |  |  |         patArchive.setPlaceOfResidence(StringUtils.isNotEmpty(homeAddr) ? homeAddr.replace("null", "") : ""); | 
 |  |  |  | 
 |  |  |         // 出生日期 | 
 |  |  |         if (StringUtils.isNotEmpty(thiedInhospInfo.getPatiBirthday())) { | 
 |  |  |             try { | 
 |  |  |                 patArchive.setBirthdate(new SimpleDateFormat("yyyy-MM-dd").parse(thiedInhospInfo.getPatiBirthday())); | 
 |  |  |             } catch (ParseException e) { | 
 |  |  |                 log.warn("【buildPatientArchive】解析出生日期失败:{}", thiedInhospInfo.getPatiBirthday(), e); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 年龄 | 
 |  |  |         if (thiedInhospInfo.getTreateAge() != null) { | 
 |  |  |             patArchive.setAge(Long.valueOf(thiedInhospInfo.getTreateAge())); | 
 |  |  |         } | 
 |  |  |         patArchive.setAgeUnit(thiedInhospInfo.getTreatAgeunit()); | 
 |  |  |  | 
 |  |  |         // 联系方式 | 
 |  |  |         patArchive.setTelcode(thiedInhospInfo.getCompanyTelNum()); | 
 |  |  |         patArchive.setRelativetelcode(thiedInhospInfo.getContactPersonPhone()); | 
 |  |  |  | 
 |  |  |         // 出院方式处理(死亡等特殊情况) | 
 |  |  |         if (StringUtils.isNotEmpty(thiedInhospInfo.getOutWayId()) && "4".equals(thiedInhospInfo.getOutWayId())) { | 
 |  |  |             patArchive.setNotrequiredFlag("1"); | 
 |  |  |             patArchive.setNotrequiredreason(thiedInhospInfo.getOutWayName()); | 
 |  |  |         } | 
 |  |  |         if ("1".equals(cry) && StringUtils.isEmpty(thiedInhospInfo.getOutWayId())) { | 
 |  |  |             patArchive.setNotrequiredFlag("1"); | 
 |  |  |             patArchive.setNotrequiredreason("出院方式为空"); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 系统字段 | 
 |  |  |         patArchive.setDelFlag("0"); | 
 |  |  |         patArchive.setCreateTime(new Date()); | 
 |  |  |         patArchive.setUpdateTime(new Date()); | 
 |  |  |  | 
 |  |  |         return patArchive; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 处理患者住院信息 | 
 |  |  |      */ | 
 |  |  |     private void processPatientInhospInfo(ThiedInhospInfo thiedInhospInfo, PatArchive patArchive, String cry) { | 
 |  |  |         // 构建住院信息 | 
 |  |  |         PatMedInhosp patMedInhosp = buildPatientInhospInfo(thiedInhospInfo, patArchive, cry); | 
 |  |  |  | 
 |  |  |         // 查询是否已存在住院记录 | 
 |  |  |         PatMedInhosp queryInhosp = new PatMedInhosp(); | 
 |  |  |         queryInhosp.setPatno(patArchive.getPatientno()); | 
 |  |  |         queryInhosp.setSerialnum(patMedInhosp.getSerialnum()); | 
 |  |  |         List<PatMedInhosp> existingInhosps = patMedInhospService.selectPatMedInhospList(queryInhosp); | 
 |  |  |  | 
 |  |  |         // 保存或更新住院信息 | 
 |  |  |         if (CollectionUtils.isNotEmpty(existingInhosps)) { | 
 |  |  |             patMedInhosp.setInhospid(existingInhosps.get(0).getInhospid()); | 
 |  |  |             patMedInhospService.updatePatMedInhosp(patMedInhosp); | 
 |  |  |             log.debug("【processPatientInhospInfo】更新住院信息,患者编号:{},流水号:{}", patArchive.getPatientno(), patMedInhosp.getSerialnum()); | 
 |  |  |         } else { | 
 |  |  |             patMedInhospService.insertPatMedInhosp(patMedInhosp); | 
 |  |  |             log.debug("【processPatientInhospInfo】新增住院信息,患者编号:{},流水号:{}", patArchive.getPatientno(), patMedInhosp.getSerialnum()); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     /** | 
 |  |  |      * 构建患者住院信息 | 
 |  |  |      */ | 
 |  |  |     private PatMedInhosp buildPatientInhospInfo(ThiedInhospInfo thiedInhospInfo, PatArchive patArchive, String cry) { | 
 |  |  |         PatMedInhosp patMedInhosp = new PatMedInhosp(); | 
 |  |  |  | 
 |  |  |         // 患者基本信息 | 
 |  |  |         patMedInhosp.setPatid(patArchive.getId()); | 
 |  |  |         patMedInhosp.setPatno(patArchive.getPatientno()); | 
 |  |  |         patMedInhosp.setPatname(patArchive.getName()); | 
 |  |  |  | 
 |  |  |         // 护理信息 | 
 |  |  |         patMedInhosp.setNurseId(thiedInhospInfo.getNurseId()); | 
 |  |  |         patMedInhosp.setNurseName(thiedInhospInfo.getNurseName()); | 
 |  |  |  | 
 |  |  |         // 住院信息 | 
 |  |  |         patMedInhosp.setSerialnum(thiedInhospInfo.getInpatientId()); | 
 |  |  |         patMedInhosp.setFuflag("1"); | 
 |  |  |         patMedInhosp.setInhospstate("0".equals(cry) ? "0" : "1"); | 
 |  |  |  | 
 |  |  |         // 医院和床位信息 | 
 |  |  |         patMedInhosp.setHospitalcode(thiedInhospInfo.getAreaId()); | 
 |  |  |         patMedInhosp.setBedNo(thiedInhospInfo.getAdmissBedNo()); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         // 时间信息 | 
 |  |  |         if (StringUtils.isNotEmpty(thiedInhospInfo.getAdmissDate())) { | 
 |  |  |             try { | 
 |  |  |                 patMedInhosp.setStarttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(thiedInhospInfo.getAdmissDate())); | 
 |  |  |             } catch (ParseException e) { | 
 |  |  |                 log.warn("【buildPatientInhospInfo】解析入院时间失败:{}", thiedInhospInfo.getAdmissDate(), e); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (StringUtils.isNotEmpty(thiedInhospInfo.getOutDate())) { | 
 |  |  |             try { | 
 |  |  |                 patMedInhosp.setEndtime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(thiedInhospInfo.getOutDate())); | 
 |  |  |             } catch (ParseException e) { | 
 |  |  |                 log.warn("【buildPatientInhospInfo】解析出院时间失败:{}", thiedInhospInfo.getOutDate(), e); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 出院信息 | 
 |  |  |         if (cry.equals("1")) { | 
 |  |  |             patMedInhosp.setLeaveldeptcode(thiedInhospInfo.getCurrDeptId()); | 
 |  |  |             patMedInhosp.setLeaveldeptname(thiedInhospInfo.getCurrDeptName()); | 
 |  |  |             patMedInhosp.setLeavediagname(thiedInhospInfo.getDiagName()); | 
 |  |  |             patMedInhosp.setLeaveicd10code(thiedInhospInfo.getDiagIcd10()); | 
 |  |  |             patMedInhosp.setOutWayId(thiedInhospInfo.getOutWayId()); | 
 |  |  |             patMedInhosp.setOutWayName(thiedInhospInfo.getOutWayName()); | 
 |  |  |             // 病区信息 | 
 |  |  |             patMedInhosp.setLeavehospitaldistrictid(thiedInhospInfo.getCurrWardCode()); | 
 |  |  |             patMedInhosp.setLeavehospitaldistrictcode(thiedInhospInfo.getCurrWardId()); | 
 |  |  |             patMedInhosp.setLeavehospitaldistrictname(thiedInhospInfo.getCurrWardName()); | 
 |  |  |             patMedInhosp.setLeaveldeptid(thiedInhospInfo.getCurrDeptCode()); | 
 |  |  |         } else { | 
 |  |  |             //入院 | 
 |  |  |             patMedInhosp.setDeptcode(thiedInhospInfo.getCurrDeptId()); | 
 |  |  |             patMedInhosp.setDeptname(thiedInhospInfo.getCurrDeptName()); | 
 |  |  |             patMedInhosp.setDiagname(thiedInhospInfo.getDiagName()); | 
 |  |  |             patMedInhosp.setIcd10code(thiedInhospInfo.getDiagIcd10()); | 
 |  |  |             patMedInhosp.setHospitaldistrictid(thiedInhospInfo.getAdmissWardCode()); | 
 |  |  |             patMedInhosp.setHospitaldistrictcode(thiedInhospInfo.getAdmissWardId()); | 
 |  |  |             patMedInhosp.setHospitaldistrictname(thiedInhospInfo.getAdmissWardName()); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         // 医生信息 | 
 |  |  |         patMedInhosp.setDrname(thiedInhospInfo.getDoctName()); | 
 |  |  |         patMedInhosp.setDrcode(thiedInhospInfo.getDoctId()); | 
 |  |  |  | 
 |  |  |  | 
 |  |  |         // 状态信息 | 
 |  |  |         patMedInhosp.setSchemestatus("0".equals(cry) ? 1L : 2L); | 
 |  |  |  | 
 |  |  |         // 系统字段 | 
 |  |  |         patMedInhosp.setDelFlag("0"); | 
 |  |  |         patMedInhosp.setOrgid("1"); | 
 |  |  |  | 
 |  |  |         return patMedInhosp; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     private String getKey() { | 
 |  |  |         Map<String, String> map = new HashMap<>(); | 
 |  |  | 
 |  |  |         } | 
 |  |  |         return toHex(md5.digest()); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     public void collectHIS() { | 
 |  |  |         try { | 
 |  |  |             // HIS数据采集 | 
 |  |  |             HnDataGatherVO hnDataGatherVO = new HnDataGatherVO(); | 
 |  |  |             log.info("【dealHisData】HIS开始采集数据"); | 
 |  |  |             ichService.hnDataGather(hnDataGatherVO); | 
 |  |  |             log.info("【dealHisData】HIS结束采集数据"); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             log.error("【dealHisData】HIS数据采集异常", e); | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  | } |