package thyyxxk.webserver.service.zhuyuanyisheng.emr; import cn.hutool.core.codec.Base64; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.http.HttpRequest; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.dtflys.forest.Forest; import com.dtflys.forest.http.ForestRequest; import com.dtflys.forest.interceptor.Interceptor; import com.dtflys.forest.reflection.ForestMethod; import com.dtflys.forest.utils.ForestDataType; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.ListUtils; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import thyyxxk.webserver.config.envionment.ApiUrl; import thyyxxk.webserver.config.envionment.ArchiveConfig; import thyyxxk.webserver.config.envionment.SystemConfig; import thyyxxk.webserver.config.exception.ExceptionEnum; import thyyxxk.webserver.constants.Capacity; import thyyxxk.webserver.constants.EmrType; import thyyxxk.webserver.dao.his.LoginDao; import thyyxxk.webserver.dao.his.zhuyuanyisheng.emr.EmrFolderDao; import thyyxxk.webserver.dao.his.zhuyuanyisheng.emr.EmrPatientDao; import thyyxxk.webserver.entity.ResultVo; import thyyxxk.webserver.entity.datamodify.YzTemperature; import thyyxxk.webserver.entity.dictionary.CodeName; import thyyxxk.webserver.entity.drg.AuxiliaryFillingOfDiagnosis; import thyyxxk.webserver.entity.fluorescenceTest.FluorescenceSpecimenResult; import thyyxxk.webserver.entity.login.UserInfo; import thyyxxk.webserver.entity.medicalinsurance.inpatient.ZyPatientInfo; import thyyxxk.webserver.entity.outpatient.thmz.MzEmrPatientData; import thyyxxk.webserver.entity.zhuyuanyisheng.ZyZkList; import thyyxxk.webserver.entity.zhuyuanyisheng.emr.*; import thyyxxk.webserver.entity.zhuyuanyisheng.jianyanjiancha.YshYjReq; import thyyxxk.webserver.entity.zhuyuanyisheng.shoushu.OpRecord; import thyyxxk.webserver.http.drg.DrgWebApi; import thyyxxk.webserver.service.PublicServer; import thyyxxk.webserver.service.hutoolcache.ExtraCache; import thyyxxk.webserver.service.externalhttp.emr.EmrEditor; import thyyxxk.webserver.service.hutoolcache.UserCache; import thyyxxk.webserver.utils.*; import javax.annotation.PostConstruct; import java.util.*; import java.util.stream.Collectors; @Service @Slf4j @RequiredArgsConstructor public class EmrServer { private final EmrPatientDao dao; private final EmrEditor emr; private final EmrFolderDao folderDao; private final PublicServer publicServer; private final LoginDao loginDao; private final ExtraCache extraCache; private final UserCache userCache; private static final ArchiveConfig archiveConfig = SpringUtil.getBean(ArchiveConfig.class); private static String emrToken = null; private static String EMR_URL; public static final String THIS_IS_DIR = "This is Dir"; private final DrgWebApi drgWebApi; private final ApiUrl apiUrl; private final SystemConfig systemConfig; @Value("${forest.variables.emrUrl}") public void setUrl(String key) { EMR_URL = key; } public static class EmrInterceptor implements Interceptor { @Override public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) { request.addHeader("emr-token", emrToken); } } @PostConstruct @Scheduled(cron = "* * */12 * * ?") public void token() { if (EMR_URL == null) { return; } try { String URL = EMR_URL.replace("/emr/runtime/api/v1", ""); String result = HttpRequest.post(URL + "/emr/runtime/api/v1/oauth/token") .header("Authorization", "Basic " + Base64.encode("user:dc71ccfec05b799ad52360c48d504019")) .form("grant_type", "client_credentials").execute().body(); JSONObject data = JSONObject.parseObject(result); emrToken = data.getString("access_token"); } catch (Exception ignored) { } } /** * 获取这个患者这个住院次数的全部电子病历 * * @param patNo 住院号 * @param times 住院次数 * @return 数据 */ public ResultVo> getPatientDataTree(String patNo, Integer times) { List list = dao.getPatientData(patNo, times); List folder = extraCache.getValue("电子病历文件夹", () -> folderDao.getFolderByName("HOSPITAL")); folder = JSONObject.parseArray(JSONObject.toJSONString(folder), EmrPatientData.class); if (ListUtil.isBlank(list)) { return ResultVoUtil.success(folder); } folder.addAll(list); Map folderMap = new HashMap<>(); List result = new ArrayList<>(); folder.add(EmrPatientData.builder() .id(null) .emrDocumentId("noFolder") .name("可拖动病历调整到合适文件夹,右键确认排序") .emrCategoryCode(THIS_IS_DIR) .sort(0) .children(new ArrayList<>()) .parent(null) .build()); for (EmrPatientData item : folder) { folderMap.put(item.getEmrDocumentId(), item); if (item.getParent() == null) { if ("group-category".equals(item.getType())) result.add(item); } } for (EmrPatientData item : folder) { String key = item.getParent(); EmrPatientData parent = folderMap.get(key); if (parent != null) { if (parent.getChildren() == null) { parent.setChildren(new ArrayList<>()); } parent.getChildren().add(item); } else { if (THIS_IS_DIR.equals(item.getEmrCategoryCode())) { continue; } EmrPatientData no = folderMap.get("noFolder"); no.getChildren().add(item); } } result.sort(Comparator.comparing((o) -> o.getSort() == null ? 0 : o.getSort())); return ResultVoUtil.success(result); } public ResultVo>> getEmrTree(String type) { Map> map = new HashMap<>(Capacity.TWO); if ("all".equals(type)) { map.put("all", wholeHospitalTemplate()); map.put("dept", getDeptTemplate()); } else if ("dept".equals(type)) { map.put("dept", getDeptTemplate()); } else if ("hosp".equals(type)) { map.put("all", wholeHospitalTemplate()); } return ResultVoUtil.success(map); } private List getDeptTemplate() { UserInfo user = userCache.getUserInfoByToken(); JSONArray data = new JSONArray(); if (ListUtil.notBlank(user.getPartTimeDept())) { user.getPartTimeDept().forEach(item -> { data.addAll(emr.getDeptList(item)); }); } data.addAll(emr.getDeptList(user.getDeptCode())); return emrToTree(data); } /** * 获取 整个医院模板 */ private List wholeHospitalTemplate() { JSONArray data; if (StrUtil.isBlank(systemConfig.getEmrZyDeptCode())) { data = emr.getEmrTree(); } else { data = emr.getDeptList(systemConfig.getEmrZyDeptCode()); } return emrToTree(data); } /** * 电子病历转成树状图 二次封装 * * @param data 模板数据 * @return 返回 */ public List emrToTree(JSONArray data) { List tree = new ArrayList<>(); if (data.isEmpty()) { return tree; } emrArrToTree(data, tree); return tree; } /** * 电子病历转成树状图 * * @param data 电子病历 * @param tree 树 */ private static void emrArrToTree(JSONArray data, List tree) { Map map = new HashMap<>(data.size()); for (int i = 0; i < data.size(); i++) { JSONObject item = data.getJSONObject(i); if (item.get("parent") == null) { tree.add(item); } map.put(item.getString("_id"), item); } for (int i = 0; i < data.size(); i++) { JSONObject item = data.getJSONObject(i); if (map.containsKey(item.getString("parent"))) { JSONObject parentList = map.get(item.getString("parent")); parentList.computeIfAbsent("children", k -> new JSONArray()); parentList.getJSONArray("children").add(item); } } } /** * 获取电子病历的片段 * * @return 树 */ public ResultVo> getSnippetTree() { JSONArray data = emr.getSnippetTree(); List tree = new ArrayList<>(); emrArrToTree(data, tree); return ResultVoUtil.success(tree); } /** * 提取患者数据元 * * @param param 结构化文档 */ public Map extractDataElement(EmrPatientData param) { EmrDataExtract emrDataExtract = dao.extractDataSource(param.getEmrCategoryCode()); if (emrDataExtract == null) { return new HashMap<>(); } // 获取 需要提取的数据元 List strings = JSON.parseArray(emrDataExtract.getDataExtract(), String.class); // 获取前端传入的数据元 Map extractedData = getStringObjectMap(param, strings); EmrDataElement emrDataElement = dao.obtainPatientSOriginalData(param.getPatNo(), param.getTimes()); if (emrDataElement == null) { // 创建的病历可以解锁了 dao.insertDataSource(param.getPatNo(), param.getTimes(), JSON.toJSONString(extractedData)); } else { JSONObject jsonObject = JSONObject.parseObject(emrDataElement.getDataElement()); jsonObject.putAll(extractedData); dao.updatePatientDataSource(param.getPatNo(), param.getTimes(), JSON.toJSONString(jsonObject)); } return extractedData; } @NotNull private static Map getStringObjectMap(EmrPatientData param, List strings) { JSONObject elementData = param.getEmrDataElement(); // 提取到的数据 Map extractedData = new HashMap<>(strings.size()); for (String el : strings) { if (elementData.containsKey(el)) { JSONObject item; try { item = elementData.getJSONObject(el); } catch (Exception ignore) { throw new RuntimeException("数据元提取失败,但病历保存成功。数据元名称:【" + el + "】,粘贴时请使用(文本粘贴)。"); } Object value = item.get("value"); if (value != null) { extractedData.put(el, value); } } } return extractedData; } /** * 保存电子病历 * * @param param 参数 * @return 提示 */ @Transactional(rollbackFor = Exception.class) public ResultVo> insertEmrData(EmrPatientData param) { EmrPatientData patientData = dao.getCategoryCodeByDocumentId(param.getEmrDocumentId()); // TM的新增病历也是用的这个方法,所以要考虑没有id的病历 if (patientData != null) { if (!SignCompleteEnum.INIT.getCode().equals(patientData.getSignComplete())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者完成电子签名无法修改。"); } if (patientData.getDelFlag() == 1) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "病历已删除。"); } } JSONObject saveJson = new JSONObject(); saveJson.put("document", param.getDocumentData()); try { emr.saveDocument(saveJson); } catch (Exception e) { return ResultVoUtil.fail(ExceptionEnum.EMR_SAVE, "病历保存错误,请重试!" + e.getMessage()); } param.setCreateId(TokenUtil.getInstance().getTokenUserId()); Integer isUpdated = dao.whetherThereIsAMedicalRecord(param.getEmrDocumentId()); if (isUpdated != null) { dao.updateCreatedTemplate(param); insertAFragmentOfTheCourseOfTheDisease(isUpdated, param.getFragment()); } else { // 新增的时候插入数据 ZyPatientInfo patInfo = publicServer.getPatInfo(param.getPatNo(), param.getTimes()); param.setReferPhysician(patInfo.getReferPhysician()); param.setConsultPhysician(patInfo.getConsultPhysician()); param.setDeptDirector(patInfo.getDeptDirector()); dao.emrInsertForTheFirstTime(param); insertAFragmentOfTheCourseOfTheDisease(param.getId(), param.getFragment()); } Map extractedData; try { extractedData = extractDataElement(param); } catch (Exception e) { return ResultVoUtil.fail(ExceptionEnum.EMR_EXTRACT_OBJECTS, e.getMessage()); } return ResultVoUtil.success(extractedData); } /** * 插入病程记录的片段 * * @param id 病程记录 * @param fragment 片段 */ private void insertAFragmentOfTheCourseOfTheDisease(Integer id, List fragment) { if (ListUtil.isBlank(fragment)) { return; } dao.delOldFragment(id); List> lists = ListUtils.partition(fragment, 50); for (List list : lists) { dao.insertFragment(list, id); } } /** * 根据患者的电子病历 id 来删除 * 这里用的是逻辑删除 * * @param documentId 电子病历id * @return 删除电子病历的同时需要删除, 提取到的数据源. */ public ResultVo> deletePatientEmrByDocumentId(String documentId) { EmrPatientData patientData = dao.getCategoryCodeByDocumentId(documentId); if (!SignCompleteEnum.INIT.getCode().equals(patientData.getSignComplete())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者完成电子签名无法删除。"); } // 医务部可以自由删除其他医生的病历 if (!publicServer.needRule(38)) { if (!patientData.getCreateId().equals(TokenUtil.getInstance().getTokenUserId())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "创建人不是你无法删除。"); } } EmrDataExtract emrDataExtract = dao.extractDataSource(patientData.getEmrCategoryCode()); List strings = new ArrayList<>(); if (emrDataExtract != null) { // 获取 需要提取的数据元 strings = JSON.parseArray(emrDataExtract.getDataExtract(), String.class); // 获取到已经提取的数据 EmrDataElement emrDataElement = dao.obtainPatientSOriginalData(patientData.getPatNo(), patientData.getTimes()); // 转 json JSONObject jsonObject = JSONObject.parseObject(emrDataElement.getDataElement()); for (String string : strings) { // 删除提取到的数据 jsonObject.remove(string); } // 更新患者数据元 dao.updatePatientDataSource(patientData.getPatNo(), patientData.getTimes(), JSON.toJSONString(jsonObject)); } // 删除病历 dao.deletePatientEmrByDocumentId(documentId, TokenUtil.getInstance().getTokenUserId()); return ResultVoUtil.success(strings); } /** * 查询患者是否有指定的病历了 * * @param param 住院号,住院次数,病历编码 * @return 返回 Boolean */ public ResultVo queryWhetherThePatientHasASpecifiedMedicalRecord(EmrPatientData param) { return ResultVoUtil.success(dao.queryWhetherThePatientHasASpecifiedMedicalRecord(param.getPatNo(), param.getTimes(), param.getEmrCategoryCode()) == 1); } /** * 医生诊断热缩 * * @param userCode 医生编码 * @param code 诊断 code * @param tableName 表名 */ public void hotSearchSorting(String userCode, String code, String tableName) { boolean insert = dao.queryWhetherThereIsHotSearch(userCode, code, tableName) == 0; if (insert) { dao.hotSearchSorting(userCode, code, tableName); } else { dao.updateHotSearch(userCode, code, tableName); } } /** * 根据文档 id 提交病历 * * @param documentId 文档id * @return 返回数据 */ public ResultVo submitMedicalRecord(String documentId) { String userCode = TokenUtil.getInstance().getTokenUserId(); String createdId = dao.getDocumentIdCreatedBy(documentId); if (userCode.equals(createdId)) { dao.updateSubmissionFlag(documentId, userCode); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "提交成功"); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "创建人不一致无法修改。"); } public ResultVo audit(String documentId) { String userCode = TokenUtil.getInstance().getTokenUserId(); int count = dao.updateAuditByDocumentId(documentId, userCode); if (count > 0) { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "审核成功"); } return ResultVoUtil.success(ExceptionEnum.NO_DATA_EXIST, "操作失败,可能原因,已经审核完成或还未保存。"); } /** * 获取电子病历数据 * * @param panNo 住院号 * @param times 住院次数 * @param etType 类型 * @return 返回数据 */ public JSONArray getEmrData(String panNo, Integer times, EmrType etType) { // 查询这个病历的 唯一 id List idList = dao.getDocumentIdByPatietn(panNo, times, etType.getName()); JSONArray returnArray = new JSONArray(); if (ListUtil.isBlank(idList)) { return returnArray; } Map surgicalSequencing = new TreeMap<>(); for (String s : idList) { JSONObject jsonObject = emr.getEditorJsonDataByDocumentId(s); if (etType.getCode() == EmrType.DIAGNOSIS.getCode()) { returnArray.addAll(extractDiagnosis(jsonObject)); } else if (etType.getCode() == EmrType.OPERATION.getCode()) { String key = DateUtil.formatDatetime(jsonObject.getJSONObject("手术日期").getDate("value")); surgicalSequencing.put(key, jsonObject); } } if (!surgicalSequencing.isEmpty()) { for (Map.Entry item : surgicalSequencing.entrySet()) { returnArray.add(item.getValue()); } } return returnArray; } /** * 获取患者提取到的数据 * * @param patNo 住院号 * @param times 次数 * @return 返回 json */ public JSONObject getEmrPatientData(String patNo, Integer times) { String js = dao.getEmrPatientData(patNo, times); if (StringUtil.isBlank(js)) { return new JSONObject(); } return JSON.parseObject(js); } /** * 获取患者的手术 * * @param patNo 获取住院号 * @param times 获取住院次数 * @return 返回数据 */ public JSONArray getPatientSurgery(String patNo, Integer times) { List idList = dao.getDocumentIdByPatietn(patNo, times, "shoushujilu"); JSONArray returnArray = new JSONArray(); if (ListUtil.isBlank(idList)) { return returnArray; } Map surgicalSequencing = new TreeMap<>(); for (String s : idList) { JSONObject jsonObject = emr.getEditorJsonDataByDocumentId(s); JSONObject surgeryDate = jsonObject.getJSONObject("手术日期"); if (null == surgeryDate) { continue; } String key = DateUtil.formatDatetime(surgeryDate.getDate("value")); if (StringUtil.isBlank(key)) { continue; } surgicalSequencing.put(key, jsonObject); } if (!surgicalSequencing.isEmpty()) { for (Map.Entry item : surgicalSequencing.entrySet()) { returnArray.add(item.getValue()); } } return returnArray; } private JSONArray extractDiagnosis(JSONObject jsonObject) { JSONObject diagnosis = jsonObject.getJSONObject("入院诊断"); if (diagnosis != null) { JSONArray diagnosisArr = diagnosis.getJSONArray("value"); if (diagnosisArr != null) { return diagnosisArr; } } return new JSONArray(); } public ResultVo getDrgIntelligentGrouping(String patNo, Integer times) { if (StrUtil.isBlank(apiUrl.getDrgWebApi())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未找到DRG服务"); } // 获取诊断 JSONArray diagnosis = getEmrData(patNo, times, EmrType.DIAGNOSIS); // 获取手术 JSONArray operation = getEmrData(patNo, times, EmrType.OPERATION); int ledgerSn = publicServer.getLedgerSn(patNo, times); // 获取患者数据 Map mapData = dao.drgPatientInfo(patNo, times, ledgerSn); if (mapData == null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有查询到患者信息。"); } mapData.put("visit_id", patNo + "_" + times + "_" + ledgerSn); mapData.put("bah", patNo + "_" + times); for (int i = 0; i < diagnosis.size(); i++) { JSONObject item = diagnosis.getJSONObject(i); if (i == 0) { mapData.put("jbdm", item.getString("code")); mapData.put("zyzd", item.getString("name")); } else { mapData.put("jbdm" + i, item.getString("code")); } } int operationIndex = 1; for (int i = 0; i < operation.size(); i++) { JSONObject item = operation.getJSONObject(i); JSONArray list; try { list = item.getJSONObject("手术名称").getJSONArray("value"); } catch (Exception e) { continue; } if (list == null) { continue; } for (int a = 0; a < list.size(); a++) { JSONObject valueList = list.getJSONObject(a); mapData.put("ssjczbm" + operationIndex, valueList.getString("code")); if (operationIndex == 1) { mapData.put("ssjczmc" + operationIndex, valueList.getString("name")); } operationIndex++; } } AuxiliaryFillingOfDiagnosis data = EntityCopy.Copy(mapData, AuxiliaryFillingOfDiagnosis.class); String toJsonStr = JSON.toJSONString(data, SerializerFeature.WriteNullStringAsEmpty); return drgWebApi.getDrgIntelligentGrouping(JSON.parseObject(toJsonStr)); } /** * 获取患者最大的住院次数 * * @param patNo 住院号 * @return 返回最大次数 */ public ResultVo getDischargeTimes(String patNo) { Integer times = dao.getMaxTimes(patNo); if (times == null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有查询到患者信息。"); } return ResultVoUtil.success(times); } public ResultVo getExtractDataElement(String patNo, Integer times) { Map map = dao.selectEmrDataElement(patNo, times); if (map == null) { return ResultVoUtil.success(); } else { return ResultVoUtil.success(JSONObject.parseObject(map.get("data_element"))); } } public ResultVo> getAllWards() { return ResultVoUtil.success(loginDao.getAllWards()); } /** * 获取患者已经被删除的病历,管理员不需要限制 * * @param patNo 住院号 * @return 返回 */ public ResultVo> getDeleteMedicalRecord(String patNo) { Integer times = dao.getAdmissTimes(patNo); if (times == null) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "出院患者无法恢复病历,如果要恢复请先召回在院。"); } String userCode = TokenUtil.getInstance().getTokenUserId(); if (publicServer.needRule()) { userCode = ""; } return ResultVoUtil.success(dao.selectEmrDeteles(patNo, times, userCode)); } public ResultVo getInvalidByDocumentId(String id) { return ResultVoUtil.success(emr.getInvalidByDocumentIdApi(id)); } /** * 恢复电子病历 * * @param documentId 电子病历文档 * @return 返回提示 */ public ResultVo resumeMedicalRecords(String documentId) { EmrPatientData data = dao.selectemPatientDataOne(documentId); if (data.getDelFlag() == 0) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "病历已经被恢复了请勿重复点击"); } Integer times = dao.getAdmissTimes(data.getPatNo()); if (times == null) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "出院患者无法恢复病历,如果要恢复请先召回在院。"); } return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "病历恢复成功。"); } /** * 查询出院患者的申请 * * @param flag 1 只查询自己的 2 查询审核的 * @return 提示 */ public ResultVo> getDisReqEmr(Integer flag) { QueryWrapper qw = new QueryWrapper<>(); if (flag == 1) { qw.eq("req_id", TokenUtil.getInstance().getTokenUserId()); } else if (flag == 2) { qw.eq("req_status", 0); } qw.ge("edit_date", DateUtil.formatDatetime(new Date(), DateUtil.DATE)); return ResultVoUtil.success(dao.getDisReqEmr(qw)); } public ResultVo> downloadTheDischargeEdit(String start, String end) { return ResultVoUtil.success(dao.selectDisReqEmyDownload(start, end)); } /** * 申请出院患者修改 * * @param param 参数 * @return 提示 */ @Transactional(rollbackFor = Exception.class) public ResultVo saveDisEmrReq(DischargedEmrModifyApply param) { param.setReqId(TokenUtil.getInstance().getTokenUserId()); int num = dao.deleteRequest(param.getPatNo()); dao.insertApplicationEmrDis(param); if (num > 0) { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "修改原申请成功。"); } else { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "申请成功。"); } } /** * 删除申请 * * @param patNo 住院号 * @return 提示 */ public ResultVo deleteDisEmrDis(String patNo) { dao.deleteRequest(patNo); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "操作成功。"); } /** * 通过申请 * * @param patNo 住院号 * @return 提示 */ public ResultVo adoptEmrDisReq(String patNo) { int num = dao.adoptEmrDisReq(patNo, null, 1); if (num > 0) { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "操作失败,原申请可能已经被删除了。"); } /** * 拒绝出院患者申请 * * @param patNo 住院号 * @param reviewNotes 审核信息 * @return 提示 */ public ResultVo refuseEmrDisReq(String patNo, String reviewNotes) { int num = dao.adoptEmrDisReq(patNo, reviewNotes, 2); if (num > 0) { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "操作失败,原申请可能已经被删除了。"); } /** * 查询出院患者是否已经通过了编辑 * * @param patNo 住院号 * @return Boolean */ public ResultVo isDisReqEdit(String patNo) { QueryWrapper qw = new QueryWrapper<>(); qw.eq("pat_no", patNo); qw.eq("req_status", 1); qw.ge("edit_date", DateUtil.formatDatetime(new Date(), DateUtil.DATE)); List list = dao.getDisReqEmr(qw); if (ListUtil.isBlank(list)) { return ResultVoUtil.success(false); } else { return ResultVoUtil.success(true); } } public ResultVo getHistory(String documentId) { return ResultVoUtil.success(emr.getHistory(documentId)); } public ResultVo> getEmrTips() { return ResultVoUtil.success(dao.selectEmrTips(TokenUtil.getInstance().getTokenUserId())); } public ResultVo addEmrTips(MedicalHistoryPrompts param) { UserInfo userInfo = userCache.getUserInfoByToken(); param.setDept(userInfo.getDeptCode()); param.setCreatorId(userInfo.getCode()); dao.insertEmrTips(param); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } public ResultVo updateEmrTips(MedicalHistoryPrompts param) { if (param.getId() == null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "id 为空无法更新。"); } dao.updateEmrTips(param); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } public ResultVo deleteEmrTips(Integer id) { dao.delEmrTips(id); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } /** * 在病程记录中获取文本数据 * * @param name 名称 * @return 返回数据 */ public ResultVo> getEmrTipsData(String name, int typeCode) { QueryWrapper qw = new QueryWrapper<>(); UserInfo us = userCache.getUserInfoByToken(); if (typeCode == 1) { qw.eq("creator_id", us.getCode()); } else if (typeCode == 2) { qw.eq("dept", us.getDeptCode()); } qw.like("query_key", name) .eq("type_code", typeCode) .orderByDesc("count"); return ResultVoUtil.success(dao.getEmrTipsData(qw)); } public ResultVo> getListOfDischargedPatients(String patNo) { List list = dao.getListOfDischargedPatients(patNo); if (ListUtil.isBlank(list)) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有" + patNo + "的出院记录。"); } return ResultVoUtil.success(list); } public ResultVo getYzTemperature(YzTemperatureParam param) { JSONObject js = new JSONObject(); QueryWrapper qw = new QueryWrapper<>(); qw.eq("inpatient_no", param.getPatNo()) .eq("admiss_times", param.getTimes()) .ge("CONVERT(varchar(10), rec_date, 23)", param.getStartTime()) .le("CONVERT(varchar(10), rec_date, 23)", param.getEndTime()); List list = dao.getYzTemperature(qw); if (ListUtil.isBlank(list)) { return ResultVoUtil.success(js); } Map map = new LinkedHashMap<>(list.size()); for (YzTemperature item : list) { Date key = item.getTempDate(); if (map.containsKey(key)) { YzTemperature yz = map.get(key); yz.setOtherInfo(nullToEmpty(yz.getOtherInfo()) + nullToEmpty(item.getOtherInfo())); } else { map.put(key, item); } } js.put("list", list); js.put("map", map); return ResultVoUtil.success(js); } public ResultVo> getExamine(String patNo, Integer times) { return ResultVoUtil.success(dao.getExamine(patNo, times)); } private String nullToEmpty(String str) { if (StringUtil.isBlank(str)) { return ""; } return str; } public ResultVo whetherItExistsInTheDepartment(String patNo, Integer times) { ZyZkList zk = dao.getMaxTransferDateByPatNo(patNo, times); if (zk != null) { zk.setTimeout(DateUtil.moreThanHours(zk.getOpTime(), 48)); } return ResultVoUtil.success(zk); } public ResultVo electronicMedicalRecordSequencing(List data) { if (ListUtil.isBlank(data)) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择有效的分类数据。"); } ListUtil.batchList(data, EmrPatientDao.class, (m, item) -> { m.updateTheNode(item.getParent(), item.getId()); }); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, "操作成功。"); } public ResultVo>> getPastHistory(String patNo, Integer times) { List list = dao.getHisPatInfo(patNo, times); if (ListUtil.isBlank(list)) { return ResultVoUtil.success(new HashMap<>()); } Map> grouping = list.stream().collect( Collectors.groupingBy(item -> item.getTimes().toString()) ); return ResultVoUtil.success(grouping); } public ResultVo>> getMzPatientDataByPatNo(String patNo) { String mzNo = dao.getMzNoByPatNo(patNo); Map> map1 = new HashMap<>(); if (StringUtil.isBlank(mzNo)) { return ResultVoUtil.success(map1); } List mzList = dao.getEmrPatientMz(mzNo); if (ListUtil.isBlank(mzList)) { return ResultVoUtil.success(map1); } Map> map = mzList.stream().collect( Collectors.groupingBy(MzEmrPatientData::getTimes) ); return ResultVoUtil.success(map); } public ResultVo> getFluorescenceSpecimenResult(String patNo, Integer times) { return ResultVoUtil.success(dao.selectFluorescenceSpecimenResult(patNo, times)); } public ResultVo> getOpRecordList(String patNo, Integer times) { return ResultVoUtil.success(dao.getOpRecordList(patNo, times)); } public String getEmrToken() { return emrToken; } private static String createEmr(JSONObject param) { if (StrUtil.isBlank(archiveConfig.getArchiveUrl())) { throw new RuntimeException("电子病历生成路径为空"); } param.put("emrToken", emrToken); String text = Forest.post(archiveConfig.getEmrArchiveUrl()) .contentTypeJson() .addBody(param) .bodyType(ForestDataType.JSON) .addHeader("emr-token", emrToken) .execute(String.class); int index = text.lastIndexOf("
buffer:,"); if (index != -1) { String[] split = text.substring(text.lastIndexOf("
buffer:,") + 13).split(","); return Base64.encode(Convert.toPrimitiveByteArray(split)); } throw new RuntimeException(text); } public static String getPdfBase(String documentId) { JSONObject param = new JSONObject(); param.put("emrToken", true); param.put("stream", true); param.put("arcive", false); param.put("patientId", false); param.put("params", new JSONObject() {{ put("documentId", documentId); }}); param.put("fileName", "病历pdf"); param.put("type", "document"); return createEmr(param); } public static String getPdfBase64ByTemplate(cn.hutool.json.JSONObject template, Object data) { JSONObject param = new JSONObject(); param.put("emrToken", true); param.put("stream", true); param.put("arcive", false); param.put("patientId", false); param.put("params", new JSONObject() {{ put("document", template); put("appContext", data); }}); param.put("fileName", "病历pdf"); param.put("type", "template"); return createEmr(param); } public static String getPdfBase64ByCategoryId(String id, String categoryCode, Object data) { JSONObject param = new JSONObject(); param.put("emrToken", true); param.put("stream", true); param.put("arcive", false); param.put("patientId", false); param.put("params", new JSONObject() {{ put("categoryId", id); put("categoryCode", categoryCode); put("appContext", new JSONObject() {{ put("data", data); }}); }}); param.put("fileName", "病历pdf"); param.put("type", "template"); return createEmr(param); } public ResultVo newDir(EmrPatientData data) { data.setEmrDocumentId(SnowFlakeId.instance().nextId()); data.setCreateDate(new Date()); data.setCreateId(TokenUtil.getInstance().getTokenUserId()); data.setEmrCategoryCode(THIS_IS_DIR); if (data.getParent() == null) { return ResultVoUtil.success(ExceptionEnum.LOGICAL_ERROR, "父节点为空请重新创建!"); } dao.insert(data); return ResultVoUtil.success(); } public ResultVo delDir(String dirId) { boolean dirHasFile = dao.dirHasFile(dirId); if (dirHasFile) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "文件夹下面还存在文件无法删除。"); } int i = dao.delDir(dirId, TokenUtil.getInstance().getTokenUserId()); if (i > 0) { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } return ResultVoUtil.success(ExceptionEnum.LOGICAL_ERROR, "无法删除,创建人不是你,或者这个是文件。"); } public ResultVo rename(String name, String documentId) { int i = dao.rename(name, documentId); if (i > 0) { return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE); } return ResultVoUtil.success(ExceptionEnum.LOGICAL_ERROR, "重命名失败。"); } }