liusheng
5 天以前 6659135780e718758417efde4c8c351c69e3755b
smartor/src/main/java/com/smartor/service/impl/ServiceSLTDHealthcareRecordServiceImpl.java
@@ -1,12 +1,13 @@
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.DtoConversionUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.smartor.domain.*;
@@ -14,21 +15,21 @@
import com.smartor.service.IPatArchiveService;
import com.smartor.service.IPatMedInhospService;
import com.smartor.service.IServiceSLTDHealthcareRecordService;
import com.sun.org.apache.bcel.internal.generic.NEW;
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.Array;
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
@@ -58,6 +59,9 @@
    @Autowired
    private SysUserRole2Mapper sysUserRoleMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Value("${sltd_pub_path}")
    private String sltdPubPath;
@@ -67,15 +71,15 @@
    @Override
    public List<ServiceSLTDInhospResDTO> queryHealthcareRecordList(ServiceSLTDInhospReqVO reqVO) {
        try {
            log.info("【queryHealthcareRecordList】开始调用省立同德健康记录查询接口,请求参数:{}", reqVO);
            Map<String, Object> requestParams = buildRequestParams(reqVO);
            Map<String, String> headers = buildRequestHeaders();
            String result = HttpUtils.sendPostByHeader(sltdPubPath + "osj/hbos-thirdparty-integration/standard/common/healthcareRecord/dtcQueryHealthcareRecordList", new Gson().toJson(requestParams), headers);
            log.info("【queryHealthcareRecordList】接口响应结果:{}", result);
            String cry = determineCry(reqVO);
            return parseResponseData(result, reqVO.getHealthcareRecordTypeList(), cry, reqVO.getCampusId());
            log.info("cry的值为:{}", cry);
            List<ServiceSLTDInhospResDTO> 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);
@@ -120,7 +124,7 @@
            Map<String, String> headers = buildRequestHeaders();
            String result = HttpUtils.sendPostByHeader(sltdPubPath + "/osj/hbos-thirdparty-integration/standard/common/dept/queryDeptList", new Gson().toJson(params), headers);
            log.info("【queryDeptWardAreaInfoList】接口响应结果:{}", result);
            log.info("【queryDeptWardAreaInfoList】接口响应结果:{}", StringUtils.isEmpty(result) ? "空的" : "不空");
            List<Map<String, Object>> dataList = getDataList(result);
            log.info("-----------dataList接口响应结果:{}", dataList.size());
            for (Map<String, Object> dataItem : dataList) {
@@ -172,6 +176,20 @@
        return true;
    }
    @Override
    public void aa(Map<String, Object> map) {
        List<String> 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();
        }
    }
    /**
     * 采集医院用户信息
@@ -184,7 +202,7 @@
        Map<String, Object> requestParams = buildRequestParams(reqVO);
        Map<String, String> headers = buildRequestHeaders();
        String result = HttpUtils.sendPostByHeader(sltdPubPath + "/osj/hbos-thirdparty-integration/standard/common/staff/queryStaffList", new Gson().toJson(requestParams), headers);
        log.info("【queryHealthcareRecordList】接口响应结果:{}", result);
        log.info("【queryHealthcareRecordList】接口响应结果是否有值:{}", StringUtils.isEmpty(result) ? "没值" : "有值");
        List<Map<String, Object>> dataList = getDataList(result);
        for (Map<String, Object> dataItem : dataList) {
            SysUser sysUser = new SysUser();
@@ -314,12 +332,17 @@
    }
    private String determineCry(ServiceSLTDInhospReqVO reqVO) {
        if (reqVO.getHealthcareRecordTypeList().contains("FH0108.02")) {
            if (reqVO.getStartHeadTime() != null && reqVO.getStartTailTime() != null) {
                return "0";
            } else if (StringUtils.isNotEmpty(reqVO.getPreOutHospitalHeadDate()) && StringUtils.isNotEmpty(reqVO.getPreOutHospitalTailDate())) {
                return "1";
            }
        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;
    }
@@ -353,6 +376,9 @@
        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());
@@ -361,7 +387,8 @@
        }
        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", reqVO.getStatusList() != null && !reqVO.getStatusList().isEmpty() ? reqVO.getStatusList().get(0) : null);
        params.put("status", null);
        return params;
    }
@@ -372,9 +399,8 @@
        return headers;
    }
    private List<ServiceSLTDInhospResDTO> parseResponseData(String result, List<String> types, String cry, Long orgid) {
    private List<ServiceSLTDInhospResDTO> parseResponseData(String result, List<String> types, String cry, String campusId) {
        try {
            List<Map<String, Object>> dataList = getDataList(result);
            List<ServiceSLTDInhospResDTO> resultList = new ArrayList<>();
            for (Map<String, Object> dataItem : dataList) {
@@ -382,7 +408,7 @@
            }
            log.info("【parseResponseData】成功解析{}条健康记录数据", resultList.size());
            processResultList(resultList, types, cry, orgid);
            processResultList(resultList, types, cry, campusId);
            return resultList;
        } catch (Exception e) {
            log.error("【parseResponseData】解析响应数据异常,响应内容:{}", result, e);
@@ -412,48 +438,83 @@
        Type listType = new TypeToken<List<Map<String, Object>>>() {
        }.getType();
        List<Map<String, Object>> dataList = gson.fromJson(dataJson, listType);
        // 使用 Set 去重,确保没有重复的数据
        Set<Map<String, Object>> uniqueDataSet = new HashSet<>(dataList);
        dataList = new ArrayList<>(uniqueDataSet);
        return dataList;
    }
    private void processResultList(List<ServiceSLTDInhospResDTO> resultList, List<String> types, String cry, Long orgid) {
    private void processResultList(List<ServiceSLTDInhospResDTO> resultList, List<String> types, String cry, String campusId) {
        for (String type : types)
            switch (type) {
                case "FH0108.01":
                    log.info("【parseResponseData】解析门诊数据");
                    outHospitalDate(resultList, orgid);
                    outHospitalDate(resultList);
                    break;
                case "FH0108.02":
                case "FH0109.26":
                    log.info("【parseResponseData】解析住院数据");
                    inHospitalDate(resultList, cry, orgid);
                    inHospitalDate(resultList, cry);
                    break;
                case "FH0108.03":
                    log.info("【parseResponseData】解析急诊数据");
                    outHospitalDate(resultList, orgid);
                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<ServiceSLTDInhospResDTO> resultList, Long orgid) {
    private Boolean outHospitalDate(List<ServiceSLTDInhospResDTO> resultList) {
        List<PatMedOuthosp> batchList = new ArrayList<>();
        for (ServiceSLTDInhospResDTO dto : resultList) {
            if (Objects.isNull(dto)) continue;
            PatArchive patArchive = processPatientArchive(dto, orgid);
            PatMedOuthosp patMedOuthosp = buildPatMedOuthosp(dto, patArchive, orgid);
//            //查询当前新增的门急诊数据,是否在过渡表中是否存在,如果存在,就不往门急诊表里新增了(这个先不写了,抽空了再写)
//            PatMedOuthospProvisional pmop = DtoConversionUtils.sourceToTarget(patMedOuthosp, PatMedOuthospProvisional.class);
            //先查询一下,是不是已经存在该流水号了,如果存在,就不新增了
            PatMedOuthosp pmo2 = new PatMedOuthosp();
            pmo2.setSerialnum(patMedOuthosp.getSerialnum());
            List<PatMedOuthosp> patMedOuthosps = patMedOuthospMapper.selectPatMedOuthospList(pmo2);
            if (CollectionUtils.isEmpty(patMedOuthosps)) patMedOuthospMapper.insertPatMedOuthosp(patMedOuthosp);
            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, Long orgid) {
    private PatMedOuthosp buildPatMedOuthosp(ServiceSLTDInhospResDTO dto, PatArchive patArchive) {
        PatMedOuthosp patMedOuthosp = new PatMedOuthosp();
        patMedOuthosp.setOuthospno(dto.getHealthcareRecordNo());
        patMedOuthosp.setSerialnum(dto.getHealthcareRecordNo());
@@ -488,46 +549,134 @@
        }
    }
    private Boolean inHospitalDate(List<ServiceSLTDInhospResDTO> resultList, String cry, Long orgid) {
    private Boolean inHospitalDate(List<ServiceSLTDInhospResDTO> resultList, String cry) {
        for (ServiceSLTDInhospResDTO dto : resultList) {
            if (Objects.isNull(dto)) continue;
            PatArchive patArchive = processPatientArchive(dto, orgid);
            processPatientInhospInfo(dto, patArchive, cry, orgid);
            PatArchive patArchive = processPatientArchive(dto);
            processPatientInhospInfo(dto, patArchive, cry);
        }
        return true;
    }
    private void processPatientInhospInfo(ServiceSLTDInhospResDTO dto, PatArchive patArchive, String cry, Long orgid) {
        PatMedInhosp patMedInhosp = buildPatientInhospInfo(dto, patArchive, cry, orgid);
    private void processPatientInhospInfo(ServiceSLTDInhospResDTO dto, PatArchive patArchive, String cry) {
        PatMedInhosp patMedInhosp = buildPatientInhospInfo(dto, patArchive, cry);
        PatMedInhosp queryInhosp = new PatMedInhosp();
        queryInhosp.setPatno(patArchive.getPatientno());
        queryInhosp.setSerialnum(patMedInhosp.getSerialnum());
        queryInhosp.setOrgid(dto.getOrgId());
        queryInhosp.setCampusid(dto.getCampusId());
        queryInhosp.setPatno(StringUtils.trim(patArchive.getPatientno()));
        queryInhosp.setSerialnum(StringUtils.trim(patMedInhosp.getSerialnum()));
        queryInhosp.setOrgid(StringUtils.trim(dto.getOrgId()));
        queryInhosp.setInhospstate(cry);
        log.info("----------------这里的入参为:{}", queryInhosp);
        log.info("----------------这里的入参为:{},{}", queryInhosp.getPatno(), queryInhosp.getSerialnum());
        List<PatMedInhosp> existingInhosps = patMedInhospService.selectPatMedInhosp(queryInhosp);
        if (cry.equals("0") && CollectionUtils.isNotEmpty(existingInhosps)) {
            //新增过的入院数据,不再处理
            return;
        } else if (cry.equals("1") && CollectionUtils.isNotEmpty(existingInhosps)) {
            //新增过的出院数据,也不再处理
            return;
        }
        if (cry.equals("0")) {
            //入院数据处理
            if (CollectionUtils.isEmpty(existingInhosps)) {
                //如果为空,要先判断,预入院是否有值,有值的话则更新
                queryInhosp.setInhospstate("3");
                List<PatMedInhosp> patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp);
                if (CollectionUtils.isNotEmpty(patMedInhospList)) {
                    //如果预入院不为空,则进行修改
                    patMedInhospService.updatePatMedInhosp(patMedInhosp);
                } else {
                    //如果出院不为空,则不进行处理
                    queryInhosp.setInhospstate("1");
                    patMedInhospList = patMedInhospService.selectPatMedInhosp(queryInhosp);
                    if (CollectionUtils.isNotEmpty(patMedInhospList)) {
                        return;
                    }
                }
        log.info("----------------这里的返参为:{}", existingInhosps);
        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());
                //如果都为空,则进行新增
                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<PatMedInhosp> 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<PatMedInhosp> 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<PatMedInhosp> 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, Long orgid) {
    private PatMedInhosp buildPatientInhospInfo(ServiceSLTDInhospResDTO dto, PatArchive patArchive, String cry) {
        log.info("----------------buildPatientInhospInfo这里进来了吗?{}", cry);
        PatMedInhosp patMedInhosp = new PatMedInhosp();
        patMedInhosp.setPatid(patArchive.getId());
@@ -539,6 +688,7 @@
        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()));
@@ -582,12 +732,12 @@
        patMedInhosp.setHospitaldistrictname(dto.getAreaName());
    }
    private PatArchive processPatientArchive(ServiceSLTDInhospResDTO dto, Long orgid) {
    private PatArchive processPatientArchive(ServiceSLTDInhospResDTO dto) {
        PatArchive queryArchive = new PatArchive();
        queryArchive.setIdcardno(StringUtils.isEmpty(dto.getIdCardNo()) ? "" + dto.getMedicalCardId() : dto.getIdCardNo().trim());
        List<PatArchive> existingArchives = patArchiveService.selectPatArchiveList(queryArchive);
        PatArchive patArchive = buildPatientArchive(dto, orgid);
        PatArchive patArchive = buildPatientArchive(dto);
        if (CollectionUtils.isEmpty(existingArchives)) {
            patArchiveService.insertPatArchive(patArchive);
@@ -601,7 +751,7 @@
        return patArchive;
    }
    private PatArchive buildPatientArchive(ServiceSLTDInhospResDTO dto, Long orgid) {
    private PatArchive buildPatientArchive(ServiceSLTDInhospResDTO dto) {
        PatArchive patArchive = new PatArchive();
        patArchive.setPatientno("" + dto.getPatientId());
        patArchive.setIdcardno(StringUtils.isEmpty(dto.getIdCardNo()) ? "" + dto.getMedicalCardId() : dto.getIdCardNo().trim());