陈昶聿
7 天以前 2867cf7076a584a34e63174cec0a8b89cdd03e4c
smartor/src/main/java/com/smartor/service/impl/PatSpecificArchiveGenerateServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,329 @@
package com.smartor.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ruoyi.common.core.domain.entity.PatArchive;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.outpatientvisit.domain.PatMedOuthosp;
import com.ruoyi.patarchive.domain.PatSpecificArchiveGenerateConfig;
import com.ruoyi.patarchive.mapper.PatArchiveMapper;
import com.ruoyi.patarchive.service.IPatSpecificArchiveGenerateConfigService;
import com.smartor.common.SpecificArchiveConstants;
import com.smartor.domain.PatChildArchiveDetail;
import com.smartor.domain.PatMaternityArchiveDetail;
import com.smartor.service.IPatChildArchiveService;
import com.smartor.service.IPatMaternityArchiveService;
import com.smartor.service.IPatSpecificArchiveGenerateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * ä¸“科档案生成Service业务层处理。
 *
 * <p>只处理丽水市妇幼保健院(orgid = 47226079133110211G1001)的门诊接诊完成记录,
 * æŒ‰ {@code pat_specific_archive_generate_config} é…ç½®åŒ¹é…ç§‘室和诊断后,
 * ç”Ÿæˆå¯¹åº”类型的妇科档案或儿科档案。</p>
 */
@Slf4j
@Service
public class PatSpecificArchiveGenerateServiceImpl implements IPatSpecificArchiveGenerateService {
    /** éƒ¨é—¨åˆ†ç±»ï¼šå¦‡ç§‘ */
    private static final String DEPT_CATEGORY_GYNECOLOGY = "1";
    /** éƒ¨é—¨åˆ†ç±»ï¼šå„¿ç§‘ */
    private static final String DEPT_CATEGORY_PEDIATRICS = "2";
    /** éƒ¨é—¨ç±»åž‹ï¼šç§‘室 */
    private static final String DEPT_TYPE_DEPARTMENT = "1";
    /** æ¥æºç±»åž‹ï¼šé—¨è¯Šè®°å½• */
    private static final String SOURCE_TYPE_OUTHOSP = "1";
    @Autowired
    private IPatSpecificArchiveGenerateConfigService patSpecificArchiveGenerateConfigService;
    @Autowired
    private IPatMaternityArchiveService patMaternityArchiveService;
    @Autowired
    private IPatChildArchiveService patChildArchiveService;
    @Autowired
    private PatArchiveMapper patArchiveMapper;
    @Override
    public int generateByOuthosp(PatMedOuthosp patMedOuthosp, PatArchive patArchive) {
        if (patMedOuthosp == null) {
            return 0;
        }
        // ä»…丽水市妇幼保健院生效,避免影响其他机构
        if (!SpecificArchiveConstants.LISHUI_MCH_ORG_ID.equals(patMedOuthosp.getOrgid())) {
            return 0;
        }
        if (StringUtils.isBlank(patMedOuthosp.getOuthospno())) {
            log.warn("生成专科档案跳过:门诊编号为空,serialnum={}", patMedOuthosp.getSerialnum());
            return 0;
        }
        PatArchive targetArchive = resolvePatArchive(patMedOuthosp, patArchive);
        if (targetArchive == null && patMedOuthosp.getPatid() != null) {
            targetArchive = patArchiveMapper.selectPatArchiveByPatid(patMedOuthosp.getPatid());
        }
        Long patid = targetArchive != null ? targetArchive.getId() : patMedOuthosp.getPatid();
        if (patid == null) {
            log.warn("生成专科档案跳过:未找到患者档案,outhospno={},patno={}",
                    patMedOuthosp.getOuthospno(), patMedOuthosp.getPatno());
            return 0;
        }
        String campusid = StringUtils.isNotBlank(patMedOuthosp.getCampusid())
                ? patMedOuthosp.getCampusid() : "1";
        List<PatSpecificArchiveGenerateConfig> configs =
                patSpecificArchiveGenerateConfigService.selectEffectiveConfigList(patMedOuthosp.getOrgid(), campusid);
        if (CollectionUtils.isEmpty(configs)) {
            log.debug("生成专科档案跳过:机构未配置档案生成规则,orgid={},campusid={}",
                    patMedOuthosp.getOrgid(), campusid);
            return 0;
        }
        // åŒä¸€æ¡é—¨è¯Šè®°å½•、同一部门分类、同一档案类型只生成一次
        Set<String> generatedKeys = new HashSet<>();
        int generatedCount = 0;
        for (PatSpecificArchiveGenerateConfig config : configs) {
            if (!matchConfig(config, patMedOuthosp)) {
                continue;
            }
            String archiveType = config.getArchiveType();
            String deptCategory = config.getDeptCategory();
            if (StringUtils.isBlank(archiveType) || StringUtils.isBlank(deptCategory)) {
                log.warn("生成专科档案跳过:配置不完整,configId={},deptCategory={},archiveType={}",
                        config.getId(), deptCategory, archiveType);
                continue;
            }
            String generatedKey = deptCategory + "|" + archiveType;
            if (!generatedKeys.add(generatedKey)) {
                continue;
            }
            try {
                if (DEPT_CATEGORY_GYNECOLOGY.equals(deptCategory)) {
                    PatMaternityArchiveDetail detail =
                            buildMaternityDetail(patMedOuthosp, targetArchive, config, campusid);
                    patMaternityArchiveService.insertOrUpdateMaternityArchive(detail);
                    generatedCount++;
                } else if (DEPT_CATEGORY_PEDIATRICS.equals(deptCategory)) {
                    PatChildArchiveDetail detail =
                            buildChildDetail(patMedOuthosp, targetArchive, config, campusid);
                    patChildArchiveService.insertOrUpdateChildArchive(detail);
                    generatedCount++;
                } else {
                    log.warn("生成专科档案跳过:未知部门分类,configId={},deptCategory={}",
                            config.getId(), deptCategory);
                }
            } catch (Exception e) {
                log.error("生成专科档案失败,configId={},outhospno={},deptCategory={},archiveType={}",
                        config.getId(), patMedOuthosp.getOuthospno(), deptCategory, archiveType, e);
            }
        }
        return generatedCount;
    }
    /**
     * åˆ¤æ–­é—¨è¯Šè®°å½•是否命中配置。
     *
     * <p>部门条件与诊断条件为 OR å…³ç³»ï¼šä»»ä¸€æ¡ä»¶å‘½ä¸­å³ç”Ÿæˆï¼›ä¸¤ä¸ªé›†åˆéƒ½ä¸ºç©ºæ—¶é…ç½®æ— æ•ˆã€‚</p>
     */
    private boolean matchConfig(PatSpecificArchiveGenerateConfig config, PatMedOuthosp patMedOuthosp) {
        List<String> deptCodes = parseCodes(config.getDeptCodes());
        List<String> icd10Codes = parseCodes(config.getIcd10Codes());
        if (CollectionUtils.isEmpty(deptCodes) && CollectionUtils.isEmpty(icd10Codes)) {
            return false;
        }
        boolean deptMatched = false;
        if (CollectionUtils.isNotEmpty(deptCodes)) {
            // é—¨è¯Šè®°å½•只有科室,没有病区;dept_type=2(病区)不参与门诊匹配
            if (DEPT_TYPE_DEPARTMENT.equals(config.getDeptType())) {
                deptMatched = containsIgnoreCase(deptCodes, patMedOuthosp.getDeptcode());
            }
        }
        boolean diagnosisMatched = false;
        if (CollectionUtils.isNotEmpty(icd10Codes)) {
            String icd10code = patMedOuthosp.getIcd10code();
            String diagname = patMedOuthosp.getDiagname();
            diagnosisMatched = icd10Codes.stream().anyMatch(code -> {
                if (equalsIgnoreCase(code, icd10code)) {
                    return true;
                }
                // éƒ¨åˆ† HIS æ•°æ®åªæœ‰è¯Šæ–­åç§°æ²¡æœ‰è¯Šæ–­ç ï¼Œæ­¤æ—¶å…è®¸æŒ‰è¯Šæ–­åç§°å…œåº•匹配
                return StringUtils.isBlank(icd10code) && equalsIgnoreCase(code, diagname);
            });
        }
        return deptMatched || diagnosisMatched;
    }
    private PatMaternityArchiveDetail buildMaternityDetail(PatMedOuthosp patMedOuthosp, PatArchive patArchive,
                                                           PatSpecificArchiveGenerateConfig config, String campusid) {
        PatMaternityArchiveDetail detail = new PatMaternityArchiveDetail();
        detail.setArchiveType(config.getArchiveType());
        detail.setSourceType(SOURCE_TYPE_OUTHOSP);
        fillCommonDetail(detail, patMedOuthosp, patArchive, campusid);
        if (patArchive != null) {
            detail.setAddress(patArchive.getPlaceOfResidence());
        }
        return detail;
    }
    private PatChildArchiveDetail buildChildDetail(PatMedOuthosp patMedOuthosp, PatArchive patArchive,
                                                   PatSpecificArchiveGenerateConfig config, String campusid) {
        PatChildArchiveDetail detail = new PatChildArchiveDetail();
        detail.setArchiveType(config.getArchiveType());
        detail.setSourceType(SOURCE_TYPE_OUTHOSP);
        fillCommonChildDetail(detail, patMedOuthosp, patArchive, campusid);
        detail.setParentPhone(patArchive != null
                ? firstNotBlank(patArchive.getTelcode(), patMedOuthosp.getTelcode())
                : patMedOuthosp.getTelcode());
        if (patArchive != null) {
            detail.setParentAddress(patArchive.getPlaceOfResidence());
        }
        // è¥å…»æ€§ç–¾ç—…档案同步诊断信息,方便列表直接展示
        if ("1".equals(config.getArchiveType())) {
            detail.setNutritionIcd10Code(patMedOuthosp.getIcd10code());
            detail.setNutritionDiagName(patMedOuthosp.getDiagname());
        }
        return detail;
    }
    private void fillCommonDetail(PatMaternityArchiveDetail detail, PatMedOuthosp patMedOuthosp,
                                  PatArchive patArchive, String campusid) {
        detail.setOuthospno(patMedOuthosp.getOuthospno());
        detail.setSerialnum(patMedOuthosp.getSerialnum());
        detail.setPatid(patArchive != null ? patArchive.getId() : patMedOuthosp.getPatid());
        detail.setPatname(patArchive != null
                ? firstNotBlank(patArchive.getName(), patMedOuthosp.getPatname()) : patMedOuthosp.getPatname());
        detail.setBirthdate(patArchive != null ? patArchive.getBirthdate() : null);
        detail.setIdcardno(patArchive != null
                ? firstNotBlank(patArchive.getIdcardno(), patMedOuthosp.getIdcardno()) : patMedOuthosp.getIdcardno());
        detail.setPhone(patArchive != null
                ? firstNotBlank(patArchive.getTelcode(), patMedOuthosp.getTelcode()) : patMedOuthosp.getTelcode());
        detail.setSex(patArchive != null && patArchive.getSex() != null
                ? patArchive.getSex() : patMedOuthosp.getSex());
        detail.setDiagTime(patMedOuthosp.getAdmitdate());
        detail.setArchiveTime(new Date());
        detail.setDoctorCode(patMedOuthosp.getDrcode());
        detail.setDoctorName(patMedOuthosp.getDrname());
        detail.setManagementDoctorCode(patMedOuthosp.getDrcode());
        detail.setManagementDoctorName(patMedOuthosp.getDrname());
        detail.setFirstDoctorCode(patMedOuthosp.getDrcode());
        detail.setFirstDoctorName(patMedOuthosp.getDrname());
        detail.setDeptcode(patMedOuthosp.getDeptcode());
        detail.setDeptname(patMedOuthosp.getDeptname());
        detail.setIcd10code(patMedOuthosp.getIcd10code());
        detail.setDiagname(patMedOuthosp.getDiagname());
        detail.setRegisterUser(patMedOuthosp.getDrname());
        detail.setOrgid(patMedOuthosp.getOrgid());
        detail.setCampusid(campusid);
        detail.setDelFlag("0");
    }
    private void fillCommonChildDetail(PatChildArchiveDetail detail, PatMedOuthosp patMedOuthosp,
                                       PatArchive patArchive, String campusid) {
        detail.setOuthospno(patMedOuthosp.getOuthospno());
        detail.setSerialnum(patMedOuthosp.getSerialnum());
        detail.setPatid(patArchive != null ? patArchive.getId() : patMedOuthosp.getPatid());
        detail.setPatname(patArchive != null
                ? firstNotBlank(patArchive.getName(), patMedOuthosp.getPatname()) : patMedOuthosp.getPatname());
        detail.setBirthdate(patArchive != null ? patArchive.getBirthdate() : null);
        detail.setIdcardno(patArchive != null
                ? firstNotBlank(patArchive.getIdcardno(), patMedOuthosp.getIdcardno()) : patMedOuthosp.getIdcardno());
        detail.setPhone(patArchive != null
                ? firstNotBlank(patArchive.getTelcode(), patMedOuthosp.getTelcode()) : patMedOuthosp.getTelcode());
        detail.setSex(patArchive != null && patArchive.getSex() != null
                ? patArchive.getSex() : patMedOuthosp.getSex());
        detail.setDiagTime(patMedOuthosp.getAdmitdate());
        detail.setArchiveTime(new Date());
        detail.setDoctorCode(patMedOuthosp.getDrcode());
        detail.setDoctorName(patMedOuthosp.getDrname());
        detail.setManagementDoctorCode(patMedOuthosp.getDrcode());
        detail.setManagementDoctorName(patMedOuthosp.getDrname());
        detail.setDeptcode(patMedOuthosp.getDeptcode());
        detail.setDeptname(patMedOuthosp.getDeptname());
        detail.setIcd10code(patMedOuthosp.getIcd10code());
        detail.setDiagname(patMedOuthosp.getDiagname());
        detail.setRegisterUser(patMedOuthosp.getDrname());
        detail.setOrgid(patMedOuthosp.getOrgid());
        detail.setCampusid(campusid);
        detail.setDelFlag("0");
    }
    private PatArchive resolvePatArchive(PatMedOuthosp patMedOuthosp, PatArchive patArchive) {
        if (patArchive != null && patArchive.getId() != null) {
            return patArchive;
        }
        PatArchive query = new PatArchive();
        if (StringUtils.isNotBlank(patMedOuthosp.getPatno())) {
            query.setPatientno(patMedOuthosp.getPatno());
        } else if (StringUtils.isNotBlank(patMedOuthosp.getIdcardno())) {
            query.setIdcardno(patMedOuthosp.getIdcardno());
        } else {
            return null;
        }
        query.setOrgid(patMedOuthosp.getOrgid());
        List<PatArchive> archives = patArchiveMapper.selectPatArchiveList(query);
        return CollectionUtils.isNotEmpty(archives) ? archives.get(0) : null;
    }
    private List<String> parseCodes(String raw) {
        if (StringUtils.isBlank(raw)) {
            return Collections.emptyList();
        }
        String value = raw.trim();
        try {
            JSONArray array = JSON.parseArray(value);
            if (array != null) {
                List<String> result = new ArrayList<>();
                for (Object item : array) {
                    if (item != null && StringUtils.isNotBlank(String.valueOf(item))) {
                        result.add(String.valueOf(item).trim());
                    }
                }
                return result;
            }
        } catch (Exception e) {
            log.warn("解析档案生成配置集合失败,按逗号分隔处理:{}", raw);
        }
        return Arrays.stream(value.split(","))
                .map(String::trim)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());
    }
    private String firstNotBlank(String first, String second) {
        return StringUtils.isNotBlank(first) ? first : second;
    }
    private boolean containsIgnoreCase(List<String> source, String target) {
        if (StringUtils.isBlank(target)) {
            return false;
        }
        return source.stream().anyMatch(item -> equalsIgnoreCase(item, target));
    }
    private boolean equalsIgnoreCase(String first, String second) {
        return first != null && second != null && first.trim().equalsIgnoreCase(second.trim());
    }
}