package com.smartor.service.impl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUserDept; import com.ruoyi.common.core.domain.entity.SysUserRole; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.smartor.domain.*; import com.smartor.mapper.*; import com.smartor.service.IPatArchiveService; import com.smartor.service.IPatMedInhospService; import com.smartor.service.IServiceSLTDHealthcareRecordService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.lang.reflect.Type; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.TimeUnit; @Slf4j @Service public class ServiceSLTDHealthcareRecordServiceImpl implements IServiceSLTDHealthcareRecordService { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; public static final String APP_KEY = "ak-zUMiOWhqXiJQWPB1pCbz0pjr"; @Autowired private IPatArchiveService patArchiveService; @Autowired private IPatMedInhospService patMedInhospService; @Autowired private PatMedOuthospMapper patMedOuthospMapper; @Autowired private SysUser2Mapper sysUser2Mapper; @Autowired private SysDept2Mapper sysDeptMapper; @Autowired private SysUserDeptMapper sysUserDeptMapper; @Autowired private SysUserRole2Mapper sysUserRoleMapper; @Autowired private RedisTemplate redisTemplate; @Value("${sltd_pub_path}") private String sltdPubPath; @Value("${userPwd}") private String userPwd; @Override public List queryHealthcareRecordList(ServiceSLTDInhospReqVO reqVO) { try { Map requestParams = buildRequestParams(reqVO); Map headers = buildRequestHeaders(); String result = HttpUtils.sendPostByHeader(sltdPubPath + "osj/hbos-thirdparty-integration/standard/common/healthcareRecord/dtcQueryHealthcareRecordList", new Gson().toJson(requestParams), headers); String cry = determineCry(reqVO); log.info("cry的值为:{}", cry); List serviceSLTDInhospResDTOS = parseResponseData(result, CollectionUtils.isNotEmpty(reqVO.getStatusList()) ? reqVO.getStatusList() : reqVO.getHealthcareRecordTypeList(), cry, reqVO.getCampusId() != null ? reqVO.getCampusId().toString() : null); log.info("serviceSLTDInhospResDTOS是否返回的有值:{}", CollectionUtils.isNotEmpty(serviceSLTDInhospResDTOS) ? "有" : "没有"); return serviceSLTDInhospResDTOS; } catch (Exception e) { log.error("【queryHealthcareRecordList】调用省立同德健康记录查询接口异常,请求参数:{}", reqVO, e); throw new RuntimeException("调用省立同德健康记录查询接口失败", e); } } /** * 采集科室病区信息 * * @param serviceSLTDDeptReqVO * @return 参考 * { * "orgId": 20001001, * "campusIds": 30001002, * "unitIds": null, * "relationType": null, * "searchText": null, * "status": 1 * } */ @Override public Boolean queryDeptWardAreaInfoList(ServiceSLTDDeptReqVO serviceSLTDDeptReqVO) { log.info("【queryDeptWardAreaInfoList】开始调用省立同德科室病区查询接口,请求参数:{}", serviceSLTDDeptReqVO); try { Map params = new HashMap<>(); if (serviceSLTDDeptReqVO.getOrgId() != null) { params.put("orgId", Long.parseLong(serviceSLTDDeptReqVO.getOrgId())); } if (serviceSLTDDeptReqVO.getCampusIds() != null) { params.put("campusIds", serviceSLTDDeptReqVO.getCampusIds()); } params.put("subjectCode", serviceSLTDDeptReqVO.getSubjectCode()); params.put("orgSubjectCode", serviceSLTDDeptReqVO.getOrgSubjectCode()); params.put("deptDimensions", serviceSLTDDeptReqVO.getDeptDimensions()); params.put("serviceScopes", serviceSLTDDeptReqVO.getServiceScopes()); params.put("inpatientArea", serviceSLTDDeptReqVO.getInpatientArea()); params.put("status", serviceSLTDDeptReqVO.getStatus()); Map headers = buildRequestHeaders(); String result = HttpUtils.sendPostByHeader(sltdPubPath + "/osj/hbos-thirdparty-integration/standard/common/dept/queryDeptList", new Gson().toJson(params), headers); log.info("【queryDeptWardAreaInfoList】接口响应结果:{}", StringUtils.isEmpty(result) ? "空的" : "不空"); List> dataList = getDataList(result); log.info("-----------dataList接口响应结果:{}", dataList.size()); for (Map dataItem : dataList) { SysDept sysDept = new SysDept(); sysDept.setOrgid("" + getLongValue(dataItem, "orgId")); sysDept.setCampusid("" + getLongValue(dataItem, "campusId")); sysDept.setHisDeptId("" + getLongValue(dataItem, "deptId")); sysDept.setHisParentId(getStringValue(dataItem, "parentDeptId")); //通过his的父科室ID去找到科室ID,填充parentId if (StringUtils.isNotEmpty(getStringValue(dataItem, "parentDeptId"))) { SysDept sd = new SysDept(); sd.setHisDeptId(getStringValue(dataItem, "parentDeptId")); sd.setOrgid(getStringValue(dataItem, "orgId")); List sysDepts = sysDeptMapper.selectDeptList(sd); if (CollectionUtils.isNotEmpty(sysDepts)) { SysDept sysDept1 = sysDepts.get(0); sysDept.setParentId(sysDept1.getDeptId()); sysDept.setParentName(sysDept1.getDeptName()); } } sysDept.setDeptName(getStringValue(dataItem, "deptName")); Integer inpatientArea = getIntegerValue(dataItem, "inpatientArea"); if (inpatientArea != null && inpatientArea == 0) sysDept.setDeptType("1"); else if (inpatientArea != null && inpatientArea == 1) sysDept.setDeptType("2"); sysDept.setLeader(""); Integer status = getIntegerValue(dataItem, "status"); if (status != null & status == 0) sysDept.setStatus("1"); if (status != null & status == 1) sysDept.setStatus("0"); sysDept.setType(""); sysDept.setDeptCode("" + getLongValue(dataItem, "deptId")); sysDept.setCreateBy(null); sysDept.setCreateTime(new Date()); sysDept.setUpdateTime(new Date()); sysDept.setUpdateBy(null); SysDept sysDept1 = sysDeptMapper.selectDeptByCode(sysDept.getDeptCode(), sysDept.getOrgid()); if (Objects.isNull(sysDept1)) { int i = sysDeptMapper.insertDept(sysDept); log.info("ServiceExternalServiceImpl---addDeptInfo是否新增成功:{}", i); } else { sysDept.setDeptId(sysDept1.getDeptId()); int i = sysDeptMapper.updateDept(sysDept); log.info("ServiceExternalServiceImpl---addDeptInfo是否修改成功04:{}", i); } } } catch (Exception e) { e.printStackTrace(); } return true; } @Override public void aa(Map map) { List types = new ArrayList<>(); types.add("FH0109.27"); ObjectMapper objectMapper = new ObjectMapper(); try { String jsonString = objectMapper.writeValueAsString(map); parseResponseData(jsonString, types, "1", "20001001"); } catch (JsonProcessingException e) { e.printStackTrace(); } } /** * 采集医院用户信息 * * @param reqVO * @return */ @Override public Boolean queryHospUserInfoList(ServiceSLTDInhospReqVO reqVO) { Map requestParams = buildRequestParams(reqVO); Map headers = buildRequestHeaders(); String result = HttpUtils.sendPostByHeader(sltdPubPath + "/osj/hbos-thirdparty-integration/standard/common/staff/queryStaffList", new Gson().toJson(requestParams), headers); log.info("【queryHealthcareRecordList】接口响应结果是否有值:{}", StringUtils.isEmpty(result) ? "没值" : "有值"); List> dataList = getDataList(result); for (Map dataItem : dataList) { SysUser sysUser = new SysUser(); if (StringUtils.isEmpty(getStringValue(dataItem, "accountNo"))) { continue; } sysUser.setUserName(getStringValue(dataItem, "accountNo")); sysUser.setNickName(getStringValue(dataItem, "name")); List diagnosisObjList = (List) dataItem.get("qualifications"); if (CollectionUtils.isNotEmpty(diagnosisObjList)) { for (Object diagnosis : diagnosisObjList) { if (diagnosis instanceof Map) { Map diagnosisMap = (Map) diagnosis; String professionalTitleName = getStringValue(diagnosisMap, "professionalTitleName"); if (professionalTitleName.contains("医师")) { sysUser.setUserType("医生"); sysUser.setSearchscope("1"); } if (professionalTitleName.contains("护")) { sysUser.setUserType("护士"); sysUser.setSearchscope("2"); } sysUser.setTitle(getStringValue(diagnosisMap, "professionalTitleName")); } } } sysUser.setPhonenumber(getStringValue(dataItem, "telephone")); sysUser.setUserCode(getStringValue(dataItem, "jobNumber")); //设置性别 String genderName = getStringValue(dataItem, "genderName"); if ("男".equals(genderName)) sysUser.setSex("0"); else if ("女".equals(genderName)) sysUser.setSex("1"); else sysUser.setSex("2"); sysUser.setCreateTime(new Date()); sysUser.setUpdateTime(new Date()); sysUser.setUpdateBy("admin"); sysUser.setCreateBy("admin"); sysUser.setCreateBy("admin"); sysUser.setOrgid("" + getLongValue(dataItem, "orgId")); // sysUser.setCampusid("" + getLongValue(dataItem, "cmpusId")); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); sysUser.setPassword(passwordEncoder.encode(userPwd)); SysUser sysUser1 = sysUser2Mapper.selectUserByUserName(sysUser.getUserName()); if (ObjectUtils.isNotEmpty(sysUser1)) { sysUser.setUserId(sysUser1.getUserId()); sysUser2Mapper.updateUser(sysUser); } else { sysUser2Mapper.insertUser(sysUser); } // 处理用户与部门的关系 List businessDepts = (List) dataItem.get("businessDepts"); if (CollectionUtils.isEmpty(businessDepts)) { continue; } List> deptInfoList = new ArrayList<>(); List> hospInfoList = new ArrayList<>(); log.info("------businessDepts是否有值:{}", businessDepts.size()); for (Object businessDept : businessDepts) { if (businessDept instanceof Map) { Map businessDeptMap = (Map) businessDept; log.info("------businessDeptMap是否有值:{}", businessDeptMap); // Long hisDeptId = (Long) personnelDeptMap.get("deptId"); String hisDeptId = getStringValue(businessDeptMap, "deptId"); log.info("------hisDeptId是否有值:{}, reqVO.getOrgId()的值为:{}", hisDeptId, reqVO.getCampusId()); //在这里,hisDeptId就是deptCode SysDept sysDept = sysDeptMapper.selectDeptByCode(hisDeptId, reqVO.getOrgId()); log.info("------hisDeptId是否有值:{}, reqVO.getCampusId()的值为:{}", hisDeptId, reqVO.getCampusId()); if (Objects.isNull(sysDept)) continue; SysUserDept sysUserDept = new SysUserDept(); sysUserDept.setUserId(sysUser.getUserId()); sysUserDept.setDeptType(sysDept.getDeptType()); sysUserDept.setDeptId(sysDept.getDeptId()); sysUserDept.setDeptCode(sysDept.getDeptCode()); sysUserDept.setDeptName(sysDept.getDeptName()); sysUserDept.setOrgid(sysDept.getOrgid()); sysUserDept.setCreateTime(new Date()); sysUserDept.setDelFlag(0L); //判断一下是不是已经存在了 if (ObjectUtils.isNotEmpty(sysUser1) && ObjectUtils.isNotEmpty(sysDept)) { SysUserDept sud = new SysUserDept(); sud.setUserId(sysUser1.getUserId()); sud.setDeptId(sysDept.getDeptId()); List sysUserDepts = sysUserDeptMapper.selectSysUserDeptList(sud); if (CollectionUtils.isNotEmpty(sysUserDepts)) { sysUserDept.setId(sysUserDepts.get(0).getId()); sysUserDeptMapper.updateSysUserDept(sysUserDept); } } else { //不存在,则新增 sysUserDeptMapper.insertSysUserDept(sysUserDept); } if (StringUtils.isNotEmpty(sysDept.getDeptType()) && sysDept.getDeptType().equals("1")) { hospInfoList.add(Arrays.asList(sysDept.getDeptCode())); } else if (StringUtils.isNotEmpty(sysDept.getDeptType()) && sysDept.getDeptType().equals("2")) { deptInfoList.add(Arrays.asList(sysDept.getDeptCode())); } } } //将部门我病区放到指定字段中 Gson gson = new Gson(); sysUser.setHospInfo(gson.toJson(hospInfoList)); sysUser.setDeptInfo(gson.toJson(deptInfoList)); sysUser2Mapper.updateUser(sysUser); //设置一个默认角色(医生角色) List userRoleList = new ArrayList(); SysUserRole sur = new SysUserRole(); sur.setUserId(sysUser.getUserId()); sur.setRoleId(3L); sur.setOrgid(sysUser.getOrgid()); //先查询一下,是否存在 SysUserRole sysUserRole = sysUserRoleMapper.selectUserRoleByRoleIdAndUserId(sysUser.getUserId(), 3L); if (ObjectUtils.isNotEmpty(sysUserRole)) continue; userRoleList.add(sur); sysUserRoleMapper.batchUserRole(userRoleList); } return true; } private String determineCry(ServiceSLTDInhospReqVO reqVO) { if (CollectionUtils.isEmpty(reqVO.getStatusList())) return null; if (reqVO.getStatusList().contains("FH0109.26")) { //入院 return "0"; } else if (reqVO.getStatusList().contains("FH0109.27")) { //出院 return "1"; } else if (reqVO.getStatusList().contains("FH0109.22") || reqVO.getStatusList().contains("FH0109.23") || reqVO.getStatusList().contains("FH0109.53")) { //预入院 return "3"; } return null; } private Map buildRequestParams(ServiceSLTDInhospReqVO reqVO) { Map params = new HashMap<>(); if (reqVO.getOrgId() != null) { params.put("orgId", Long.parseLong(reqVO.getOrgId())); } if (reqVO.getCampusId() != null) { params.put("campusId", reqVO.getCampusId()); } if (reqVO.getStartHeadTime() != null) { params.put("startHeadTime", reqVO.getStartHeadTime()); } if (reqVO.getStartTailTime() != null) { params.put("startTailTime", reqVO.getStartTailTime()); } if (reqVO.getEncounterTimeStart() != null) { params.put("encounterTimeStart", reqVO.getEncounterTimeStart()); } if (reqVO.getEncounterTimeEnd() != null) { params.put("encounterTimeEnd", reqVO.getEncounterTimeEnd()); } if (reqVO.getPreOutHospitalHeadDate() != null) { params.put("preOutHospitalHeadDate", reqVO.getPreOutHospitalHeadDate()); } if (reqVO.getPreOutHospitalTailDate() != null) { params.put("preOutHospitalTailDate", reqVO.getPreOutHospitalTailDate()); } if (reqVO.getHealthcareRecordTypeList() != null && !reqVO.getHealthcareRecordTypeList().isEmpty()) { params.put("healthcareRecordTypeList", reqVO.getHealthcareRecordTypeList()); } if (reqVO.getStatusList() != null && !reqVO.getStatusList().isEmpty()) { params.put("statusList", reqVO.getStatusList()); } params.put("subjectCode", reqVO.getPatientName()); params.put("healthcareRecordNo", reqVO.getHealthcareRecordNo()); params.put("orgSubjectCode", reqVO.getIdCardNo()); if (reqVO.getDeptIdList() != null && !reqVO.getDeptIdList().isEmpty()) { params.put("deptDimensions", reqVO.getDeptIdList()); } params.put("serviceScopes", null); params.put("inpatientArea", null); // params.put("status", reqVO.getStatusList() != null && !reqVO.getStatusList().isEmpty() ? reqVO.getStatusList().get(0) : null); params.put("status", null); return params; } private Map buildRequestHeaders() { Map headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("app-key", APP_KEY); return headers; } private List parseResponseData(String result, List types, String cry, String campusId) { try { List> dataList = getDataList(result); List resultList = new ArrayList<>(); for (Map dataItem : dataList) { resultList.add(convertToDTO(dataItem)); } log.info("【parseResponseData】成功解析{}条健康记录数据", resultList.size()); processResultList(resultList, types, cry, campusId); return resultList; } catch (Exception e) { log.error("【parseResponseData】解析响应数据异常,响应内容:{}", result, e); throw new RuntimeException("解析响应数据失败", e); } } public List> getDataList(String result) { Gson gson = new Gson(); Type mapType = new TypeToken>() { }.getType(); Map responseMap = gson.fromJson(result, mapType); Number codeNum = (Number) responseMap.get("code"); String code = BigDecimal.valueOf(codeNum.longValue()).toPlainString(); if (StringUtils.isEmpty(code) || !code.equals("200")) { log.error("【parseResponseData】接口返回失败,响应码:{},响应内容:{}", code, result); throw new RuntimeException("接口调用失败,响应码:" + code); } Object dataObj = responseMap.get("data"); if (dataObj == null) { log.info("【parseResponseData】接口返回数据为空"); return new ArrayList<>(); } String dataJson = gson.toJson(dataObj); Type listType = new TypeToken>>() { }.getType(); List> dataList = gson.fromJson(dataJson, listType); // 使用 Set 去重,确保没有重复的数据 Set> uniqueDataSet = new HashSet<>(dataList); dataList = new ArrayList<>(uniqueDataSet); return dataList; } private void processResultList(List resultList, List types, String cry, String campusId) { for (String type : types) switch (type) { case "FH0108.01": log.info("【parseResponseData】解析门诊数据"); outHospitalDate(resultList); break; case "FH0109.26": log.info("【parseResponseData】解析住院数据"); inHospitalDate(resultList, cry); break; case "FH0109.22": log.info("【parseResponseData】解析预住院数据"); inHospitalDate(resultList, cry); break; case "FH0109.23": log.info("【parseResponseData】解析预住院(待安床)数据"); inHospitalDate(resultList, cry); break; case "FH0109.27": log.info("【parseResponseData】解析出院数据"); inHospitalDate(resultList, cry); break; case "FH0109.53": log.info("【parseResponseData】解析预住院(其他)数据"); inHospitalDate(resultList, cry); break; // case "FH0108.03": // log.info("【parseResponseData】解析急诊数据"); // outHospitalDate(resultList); // break; default: log.warn("【parseResponseData】未知的数据类型:{}", type); break; } } private Boolean outHospitalDate(List resultList) { List batchList = new ArrayList<>(); for (ServiceSLTDInhospResDTO dto : resultList) { if (Objects.isNull(dto)) { continue; } PatArchive patArchive = processPatientArchive(dto); PatMedOuthosp patMedOuthosp = buildPatMedOuthosp(dto, patArchive); batchList.add(patMedOuthosp); } // 批量插入,自动忽略重复 if (CollectionUtils.isNotEmpty(batchList)) { try { int insertCount = patMedOuthospMapper.batchInsertIgnore(batchList); log.info("批量插入门急诊记录,总数:{}, 实际插入:{}", batchList.size(), insertCount); } catch (Exception e) { log.error("批量插入门急诊记录失败", e); // 降级为逐条插入 for (PatMedOuthosp patMedOuthosp : batchList) { try { patMedOuthospMapper.insertPatMedOuthosp(patMedOuthosp); } catch (Exception ex) { log.warn("单条插入失败:serialnum={}", patMedOuthosp.getSerialnum()); } } } } return true; } private PatMedOuthosp buildPatMedOuthosp(ServiceSLTDInhospResDTO dto, PatArchive patArchive) { PatMedOuthosp patMedOuthosp = new PatMedOuthosp(); patMedOuthosp.setOuthospno(dto.getHealthcareRecordNo()); patMedOuthosp.setSerialnum(dto.getHealthcareRecordNo()); patMedOuthosp.setPatid(patArchive.getId()); patMedOuthosp.setPatname(patArchive.getName()); patMedOuthosp.setPatno(patArchive.getPatientno()); patMedOuthosp.setDeptcode("" + dto.getDeptId()); patMedOuthosp.setDeptname(dto.getDeptName()); patMedOuthosp.setDiagname(dto.getDiagnosisName()); patMedOuthosp.setIcd10code(dto.getDiagnosisCode()); patMedOuthosp.setDrcode("" + dto.getDoctorId()); patMedOuthosp.setDrname(dto.getDoctorName()); patMedOuthosp.setAdmitdate(parseDate(dto.getLastEncounterTime())); patMedOuthosp.setSchemestatus(1L); patMedOuthosp.setMainsuit(dto.getDiagnosisName()); patMedOuthosp.setHpi(null); patMedOuthosp.setCreateTime(new Date()); patMedOuthosp.setOrgid(dto.getOrgId()); patMedOuthosp.setCampusid(dto.getCampusId()); return patMedOuthosp; } private Date parseDate(String dateStr) { if (StringUtils.isEmpty(dateStr)) { return null; } try { return new SimpleDateFormat(DATE_FORMAT).parse(dateStr); } catch (ParseException e) { log.warn("【parseDate】解析日期失败:{}", dateStr, e); return null; } } private Boolean inHospitalDate(List resultList, String cry) { for (ServiceSLTDInhospResDTO dto : resultList) { if (Objects.isNull(dto)) continue; PatArchive patArchive = processPatientArchive(dto); processPatientInhospInfo(dto, patArchive, cry); } return true; } private void processPatientInhospInfo(ServiceSLTDInhospResDTO dto, PatArchive patArchive, String cry) { PatMedInhosp patMedInhosp = buildPatientInhospInfo(dto, patArchive, cry); PatMedInhosp queryInhosp = new PatMedInhosp(); queryInhosp.setPatno(StringUtils.trim(patArchive.getPatientno())); queryInhosp.setSerialnum(StringUtils.trim(patMedInhosp.getSerialnum())); queryInhosp.setOrgid(StringUtils.trim(dto.getOrgId())); queryInhosp.setInhospstate(cry); log.info("----------------这里的入参为:{},{}", queryInhosp.getPatno(), queryInhosp.getSerialnum()); List existingInhosps = patMedInhospService.selectPatMedInhosp(queryInhosp); if (cry.equals("0")) { //入院数据处理 if (CollectionUtils.isEmpty(existingInhosps)) { //如果为空,要先判断,预入院是否有值,有值的话则更新 queryInhosp.setInhospstate("3"); List patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp); if (CollectionUtils.isNotEmpty(patMedInhospList)) { //如果预入院不为空,则进行修改 patMedInhospService.updatePatMedInhosp(patMedInhosp); } else { //如果出院不为空,则不进行处理 queryInhosp.setInhospstate("1"); patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp); if (CollectionUtils.isNotEmpty(patMedInhospList)) { return; } } //如果都为空,则进行新增 if (CollectionUtils.isEmpty(patMedInhospList)) { try { patMedInhospService.insertPatMedInhosp(patMedInhosp); } catch (org.springframework.dao.DuplicateKeyException e) { log.warn("入院记录已存在,跳过:serialnum={}, orgid={}, state={}", patMedInhosp.getSerialnum(), patMedInhosp.getOrgid(), patMedInhosp.getInhospstate()); } } } } else if (cry.equals("1")) { // 出院数据处理 if (CollectionUtils.isEmpty(existingInhosps)) { //如果为空,要先判断,预入院是否有值,有值的话则更新 queryInhosp.setInhospstate("3"); log.info("-----patMedInhospList进来了不?入参为:{}", queryInhosp); List patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp); log.info("----patMedInhospList进来了不?返参为:{}", CollectionUtils.isEmpty(patMedInhospList) ? null : patMedInhospList.get(0).getSerialnum()); if (CollectionUtils.isNotEmpty(patMedInhospList)) { //如果预入院不为空,则进行修改 patMedInhospService.updatePatMedInhosp(patMedInhosp); } else { //如果入院不为空,则进行修改 queryInhosp.setInhospstate("0"); patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp); if (CollectionUtils.isNotEmpty(patMedInhospList)) { patMedInhospService.updatePatMedInhosp(patMedInhosp); } } //如果都为空,则进行新增 if (CollectionUtils.isEmpty(patMedInhospList)) { //如果入院不为空,则进行修改 queryInhosp.setInhospstate("0"); log.debug("出院queryInhosp入参为:{}", queryInhosp); List patMedInhosps = patMedInhospService.selectPatMedInhosp(queryInhosp); log.debug("出院patMedInhospList返参为:{}", CollectionUtils.isEmpty(patMedInhosps) ? null : patMedInhosps.size()); if (CollectionUtils.isNotEmpty(patMedInhosps)) { patMedInhospService.updatePatMedInhosp(patMedInhosp); } else { try { patMedInhospService.insertPatMedInhosp(patMedInhosp); } catch (org.springframework.dao.DuplicateKeyException e) { log.warn("出院记录已存在,跳过:serialnum={}, orgid={}, state={}", patMedInhosp.getSerialnum(), patMedInhosp.getOrgid(), patMedInhosp.getInhospstate()); } } } } } else if ("3".equals(cry)) { //预入院数据处理:任一状态存在则不新增;都不存在才新增 String serialnum = patMedInhosp.getSerialnum() == null ? "" : patMedInhosp.getSerialnum().trim(); String orgid = patMedInhosp.getOrgid() == null ? "" : patMedInhosp.getOrgid().trim(); String state = patMedInhosp.getInhospstate() == null ? "" : patMedInhosp.getInhospstate(); String lockKey = "inhosp:lock:" + serialnum + ":" + orgid + ":" + state; Boolean locked = false; try { locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS); } catch (Exception e) { log.warn("Redis锁获取失败,降级为直接插入:{}", e.getMessage()); locked = null; // 标记Redis不可用 } if (locked == null || Boolean.TRUE.equals(locked)) { try { queryInhosp.setInhospstate(null); List patMedInhospList3 = patMedInhospService.selectPatMedInhosp(queryInhosp); if (CollectionUtils.isEmpty(patMedInhospList3)) { try { patMedInhospService.insertPatMedInhosp(patMedInhosp); log.debug("成功插入预入院记录:serialnum={}", patMedInhosp.getSerialnum()); } catch (Exception e) { log.warn("预入院记录插入失败(可能已存在):serialnum={}, orgid={}, state={}, 错误:{}", patMedInhosp.getSerialnum(), patMedInhosp.getOrgid(), patMedInhosp.getInhospstate(), e.getMessage()); } } } finally { if (Boolean.TRUE.equals(locked)) { try { redisTemplate.delete(lockKey); } catch (Exception e) { log.warn("Redis锁释放失败:{}", e.getMessage()); } } } } else { log.debug("预入院记录正在被其他线程处理,跳过:serialnum={}", patMedInhosp.getSerialnum()); } } } private PatMedInhosp buildPatientInhospInfo(ServiceSLTDInhospResDTO dto, PatArchive patArchive, String cry) { log.info("----------------buildPatientInhospInfo这里进来了吗?{}", cry); PatMedInhosp patMedInhosp = new PatMedInhosp(); patMedInhosp.setPatid(patArchive.getId()); patMedInhosp.setPatno(patArchive.getPatientno()); patMedInhosp.setPatname(patArchive.getName()); patMedInhosp.setNurseId(dto.getChiefNurseId() == null ? "" : dto.getChiefNurseId().toString()); patMedInhosp.setNurseName(dto.getChiefNurseName()); patMedInhosp.setSerialnum(dto.getHealthcareRecordNo()); patMedInhosp.setFuflag("1"); if ("0".equals(cry)) patMedInhosp.setInhospstate("0"); if ("1".equals(cry)) patMedInhosp.setInhospstate("1"); if ("3".equals(cry)) patMedInhosp.setInhospstate("3"); patMedInhosp.setHospitalcode(dto.getOrgId()); patMedInhosp.setBedNo(dto.getBedNumber()); patMedInhosp.setStarttime(parseDate(dto.getStartTime())); patMedInhosp.setEndtime(parseDate(dto.getPreOutHospitalDate())); if ("1".equals(cry)) { setDischargeInfo(patMedInhosp, dto); } else { setAdmissionInfo(patMedInhosp, dto); } patMedInhosp.setDrname(dto.getDoctorName()); patMedInhosp.setDrcode("" + dto.getDoctorId()); patMedInhosp.setSchemestatus("0".equals(cry) ? 1L : 2L); patMedInhosp.setDelFlag("0"); patMedInhosp.setOrgid(dto.getOrgId()); patMedInhosp.setCampusid(dto.getCampusId()); return patMedInhosp; } private void setDischargeInfo(PatMedInhosp patMedInhosp, ServiceSLTDInhospResDTO dto) { patMedInhosp.setLeaveldeptcode("" + dto.getDeptId()); patMedInhosp.setLeaveldeptname(dto.getDeptName()); patMedInhosp.setLeavediagname(dto.getMainDischargeDiagnosis() == null ? null : dto.getMainDischargeDiagnosis().getDiagnosisDictName()); patMedInhosp.setLeaveicd10code(dto.getMainDischargeDiagnosis() == null ? null : dto.getMainDischargeDiagnosis().getDiagnosisDictCode()); patMedInhosp.setOutWayId(null); patMedInhosp.setOutWayName(null); patMedInhosp.setLeavehospitaldistrictid("" + dto.getAreaId()); patMedInhosp.setLeavehospitaldistrictcode("" + dto.getAreaId()); patMedInhosp.setLeavehospitaldistrictname(dto.getAreaName()); patMedInhosp.setLeaveldeptid("" + dto.getDeptId()); } private void setAdmissionInfo(PatMedInhosp patMedInhosp, ServiceSLTDInhospResDTO dto) { patMedInhosp.setDeptcode("" + dto.getDeptId()); patMedInhosp.setDeptname(dto.getDeptName()); patMedInhosp.setDiagname(dto.getAdmissionDiagnosisName()); patMedInhosp.setIcd10code(dto.getAdmissionDiagnosisCode()); patMedInhosp.setHospitaldistrictid("" + dto.getAreaId()); patMedInhosp.setHospitaldistrictcode("" + dto.getAreaId()); patMedInhosp.setHospitaldistrictname(dto.getAreaName()); } private PatArchive processPatientArchive(ServiceSLTDInhospResDTO dto) { PatArchive queryArchive = new PatArchive(); queryArchive.setIdcardno(StringUtils.isEmpty(dto.getIdCardNo()) ? "" + dto.getMedicalCardId() : dto.getIdCardNo().trim()); List existingArchives = patArchiveService.selectPatArchiveList(queryArchive); PatArchive patArchive = buildPatientArchive(dto); 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(ServiceSLTDInhospResDTO dto) { PatArchive patArchive = new PatArchive(); patArchive.setPatientno("" + dto.getPatientId()); patArchive.setIdcardno(StringUtils.isEmpty(dto.getIdCardNo()) ? "" + dto.getMedicalCardId() : dto.getIdCardNo().trim()); patArchive.setName(dto.getPatientName()); patArchive.setSourcefrom(2); patArchive.setPattype("2"); patArchive.setSex("男".equals(dto.getGender()) ? 1L : 2L); patArchive.setNation(dto.getNation()); patArchive.setNativePlace(dto.getNativePlace()); patArchive.setPlaceOfResidence(dto.getAddress()); patArchive.setBirthdate(parseDate(dto.getBirthday())); patArchive.setTelcode(dto.getPhone()); if (CollectionUtils.isNotEmpty(dto.getResidentContactInfos())) { patArchive.setRelativetelcode(dto.getResidentContactInfos().get(0).getTelecom()); } patArchive.setDelFlag("0"); patArchive.setCreateTime(new Date()); patArchive.setUpdateTime(new Date()); patArchive.setOrgid("" + dto.getOrgId()); patArchive.setCampusid(dto.getCampusId()); return patArchive; } private ServiceSLTDInhospResDTO convertToDTO(Map dataItem) { ServiceSLTDInhospResDTO dto = new ServiceSLTDInhospResDTO(); dto.setOrgId(getStringValue(dataItem, "orgId")); dto.setCampusId(getStringValue(dataItem, "campusId")); dto.setHealthcareRecordId(getLongValue(dataItem, "healthcareRecordId")); dto.setHealthcareRecordNo(getStringValue(dataItem, "healthcareRecordNo")); dto.setPatientId(getLongValue(dataItem, "patientId")); dto.setPatientName(getStringValue(dataItem, "patientName")); dto.setPinyin(getStringValue(dataItem, "pinyin")); dto.setNation(getStringValue(dataItem, "nation")); dto.setIdCardNo(getStringValue(dataItem, "idCardNo")); dto.setHealthcareRecordTimes(getIntegerValue(dataItem, "healthcareRecordTimes")); dto.setHospitalizationNumber(getIntegerValue(dataItem, "hospitalizationNumber")); dto.setMedicalCardId(getLongValue(dataItem, "medicalCardId")); dto.setMedicalCardType(getStringValue(dataItem, "medicalCardType")); dto.setMedicalCardTypeName(getStringValue(dataItem, "medicalCardTypeName")); dto.setMedicalCardNo(getStringValue(dataItem, "medicalCardNo")); dto.setMedicalRecordNo(getStringValue(dataItem, "medicalRecordNo")); dto.setGender(getStringValue(dataItem, "gender")); dto.setGenderCode(getStringValue(dataItem, "genderCode")); dto.setAge(getStringValue(dataItem, "age")); dto.setBirthday(getStringValue(dataItem, "birthday")); dto.setPhone(getStringValue(dataItem, "phone")); dto.setEducation(getStringValue(dataItem, "education")); dto.setEducationCode(getStringValue(dataItem, "educationCode")); dto.setNeonatal(getBooleanValue(dataItem, "neonatal")); dto.setMarriage(getStringValue(dataItem, "marriage")); dto.setMarriageCode(getStringValue(dataItem, "marriageCode")); dto.setOccupationType(getStringValue(dataItem, "occupationType")); dto.setOccupationTypeCode(getStringValue(dataItem, "occupationTypeCode")); dto.setNativePlace(getStringValue(dataItem, "nativePlace")); dto.setAreaId(getLongValue(dataItem, "areaId")); dto.setAreaName(getStringValue(dataItem, "areaName")); dto.setRoomId(getLongValue(dataItem, "roomId")); dto.setRoomNumber(getStringValue(dataItem, "roomNumber")); dto.setBedId(getLongValue(dataItem, "bedId")); dto.setBedNumber(getStringValue(dataItem, "bedNumber")); dto.setEncounterTime(getStringValue(dataItem, "encounterTime")); dto.setStartTime(getStringValue(dataItem, "startTime")); dto.setPreOutHospitalDate(getStringValue(dataItem, "preOutHospitalDate")); dto.setLastEncounterTime(getStringValue(dataItem, "lastEncounterTime")); dto.setDiagnosisCode(getStringValue(dataItem, "diagnosisCode")); dto.setDiagnosisName(getStringValue(dataItem, "diagnosisName")); dto.setHealthcareRecordStatus(getStringValue(dataItem, "healthcareRecordStatus")); dto.setHealthcareType(getStringValue(dataItem, "healthcareType")); dto.setDeptId(getLongValue(dataItem, "deptId")); dto.setDeptName(getStringValue(dataItem, "deptName")); dto.setDoctorId(getLongValue(dataItem, "doctorId")); dto.setDoctorName(getStringValue(dataItem, "doctorName")); dto.setHealthcarePeriodId(getLongValue(dataItem, "healthcarePeriodId")); dto.setChiefNurseId(getLongValue(dataItem, "chiefNurseId")); dto.setChiefNurseName(getStringValue(dataItem, "chiefNurseName")); dto.setCostCategoryName(getStringValue(dataItem, "costCategoryName")); dto.setCostCategoryCode(getStringValue(dataItem, "costCategoryCode")); dto.setCostNatureName(getStringValue(dataItem, "costNatureName")); dto.setCostNatureCode(getStringValue(dataItem, "costNatureCode")); dto.setFurtherConsultationStatus(getIntegerValue(dataItem, "furtherConsultationStatus")); Object contactsObj = dataItem.get("residentContactInfos"); if (contactsObj instanceof List) { dto.setResidentContactInfos(parseContacts((List) contactsObj)); } Object diagnosisObj = dataItem.get("diagnosisList"); if (diagnosisObj instanceof List) { dto.setDiagnosisList(parseDiagnosis((List) diagnosisObj)); } return dto; } private List parseContacts(List contactsList) { List contacts = new ArrayList<>(); for (Object contactObj : contactsList) { if (contactObj instanceof Map) { Map contactMap = (Map) contactObj; ServiceSLTDContactsResDTO contact = new ServiceSLTDContactsResDTO(); contact.setName(getStringValue(contactMap, "name")); contact.setRelationshipCode(getStringValue(contactMap, "relationshipCode")); contact.setRelationship(getStringValue(contactMap, "relationship")); contact.setTelecom(getStringValue(contactMap, "telecom")); contact.setCurrentAddress(getStringValue(contactMap, "currentAddress")); contacts.add(contact); } } return contacts; } private List parseDiagnosis(List diagnosisList) { List diagnosis = new ArrayList<>(); for (Object diagnosisObj : diagnosisList) { if (diagnosisObj instanceof Map) { Map diagnosisMap = (Map) diagnosisObj; ServiceSLTDDiagnosisResDTO diag = new ServiceSLTDDiagnosisResDTO(); diag.setDiagnosisDictCode(getStringValue(diagnosisMap, "diagnosisDictCode")); diag.setDiagnosisDictName(getStringValue(diagnosisMap, "diagnosisDictName")); diag.setDiagnosisCategory(getStringValue(diagnosisMap, "diagnosisCategory")); diag.setRecordType(getIntegerValue(diagnosisMap, "recordType")); diag.setIsMainDiagnosis(getIntegerValue(diagnosisMap, "isMainDiagnosis")); diagnosis.add(diag); } } return diagnosis; } private String getStringValue(Map map, String key) { Object value = map.get(key); if (value == null) { return null; } // 只处理数字类型,避免科学计数法 return value instanceof Number ? new BigDecimal(value.toString()).toPlainString() : value.toString(); } private Long getLongValue(Map map, String key) { Object value = map.get(key); if (value == null) return null; if (value instanceof Number) { return ((Number) value).longValue(); } try { return Long.parseLong(value.toString()); } catch (NumberFormatException e) { return null; } } private Integer getIntegerValue(Map map, String key) { Object value = map.get(key); if (value == null) return null; if (value instanceof Number) { return ((Number) value).intValue(); } try { return Integer.parseInt(value.toString()); } catch (NumberFormatException e) { return null; } } private Boolean getBooleanValue(Map map, String key) { Object value = map.get(key); if (value == null) return null; if (value instanceof Boolean) { return (Boolean) value; } return Boolean.parseBoolean(value.toString()); } }