EmrServer.java 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. package thyyxxk.webserver.service.zhuyuanyisheng.emr;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.alibaba.fastjson.TypeReference;
  6. import com.alibaba.fastjson.serializer.SerializerFeature;
  7. import com.baomidou.dynamic.datasource.annotation.DS;
  8. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.apache.commons.collections4.ListUtils;
  11. import org.springframework.stereotype.Service;
  12. import org.springframework.transaction.annotation.Transactional;
  13. import org.springframework.web.client.RestTemplate;
  14. import thyyxxk.webserver.config.exception.ExceptionEnum;
  15. import thyyxxk.webserver.constants.Capacity;
  16. import thyyxxk.webserver.constants.EmrType;
  17. import thyyxxk.webserver.dao.his.LoginDao;
  18. import thyyxxk.webserver.dao.his.zhuyuanyisheng.emr.EmrPatientDao;
  19. import thyyxxk.webserver.entity.ResultVo;
  20. import thyyxxk.webserver.entity.datamodify.YzTemperature;
  21. import thyyxxk.webserver.entity.dictionary.CodeName;
  22. import thyyxxk.webserver.entity.drg.AuxiliaryFillingOfDiagnosis;
  23. import thyyxxk.webserver.entity.login.UserInfo;
  24. import thyyxxk.webserver.entity.medicalinsurance.inpatient.ZyPatientInfo;
  25. import thyyxxk.webserver.entity.zhuyuanyisheng.ZyZkList;
  26. import thyyxxk.webserver.entity.zhuyuanyisheng.emr.*;
  27. import thyyxxk.webserver.entity.zhuyuanyisheng.jianyanjiancha.YshYjReq;
  28. import thyyxxk.webserver.service.PublicServer;
  29. import thyyxxk.webserver.service.externalhttp.emr.EmrEditor;
  30. import thyyxxk.webserver.service.redislike.RedisLikeService;
  31. import thyyxxk.webserver.utils.*;
  32. import thyyxxk.webserver.websocket.WebSocketServer;
  33. import javax.websocket.Session;
  34. import java.util.*;
  35. import java.util.stream.Collectors;
  36. @Service
  37. @Slf4j
  38. @DS("his")
  39. public class EmrServer {
  40. private final EmrPatientDao dao;
  41. private final EmrEditor emr;
  42. private final PublicServer publicServer;
  43. private final LoginDao loginDao;
  44. private final RedisLikeService redisLikeService;
  45. private static final Map<String, JSONObject> TEMPLATE_DATA = new LinkedHashMap<>();
  46. private static final Map<String, String> GROUP_MAP = new HashMap<>();
  47. private final String HOSPITAL_WIDE_FOLDER = "3b1655a006ff11edbc820dada413ba28";
  48. public EmrServer(EmrPatientDao dao, EmrEditor emr, PublicServer publicServer, LoginDao loginDao, RedisLikeService redisLikeService) {
  49. this.dao = dao;
  50. this.emr = emr;
  51. this.publicServer = publicServer;
  52. this.loginDao = loginDao;
  53. this.redisLikeService = redisLikeService;
  54. }
  55. /**
  56. * 获取这个患者这个住院次数的全部电子病历
  57. *
  58. * @param patNo 住院号
  59. * @param times 住院次数
  60. * @return 数据
  61. */
  62. public ResultVo<List<JSONObject>> getPatientDataTree(String patNo, Integer times) {
  63. List<EmrPatientData> list = dao.getPatientData(patNo, times);
  64. List<JSONObject> tree = new ArrayList<>(list.size());
  65. if (ListUtil.isBlank(list)) {
  66. return ResultVoUtil.success(tree);
  67. }
  68. if (TEMPLATE_DATA.isEmpty()) {
  69. tree();
  70. }
  71. Map<String, JSONObject> temp = JSON.parseObject(JSON.toJSONString(TEMPLATE_DATA),
  72. new TypeReference<LinkedHashMap<String, JSONObject>>() {
  73. });
  74. list.forEach(item -> {
  75. JSONObject js = temp.get(item.getParent());
  76. if (js == null) {
  77. js = temp.get(HOSPITAL_WIDE_FOLDER);
  78. }
  79. if (js.getJSONArray("children") == null) {
  80. js.put("children", new ArrayList<>());
  81. }
  82. js.getJSONArray("children").add(item);
  83. });
  84. tree.addAll(temp.values());
  85. return ResultVoUtil.success(tree);
  86. }
  87. public ResultVo<Map<String, List<JSONObject>>> getEmrTree(String type) {
  88. Map<String, List<JSONObject>> map = new HashMap<>(Capacity.TWO);
  89. if ("all".equals(type)) {
  90. map.put("all", wholeHospitalTemplate());
  91. map.put("dept", getDeptTemplate());
  92. } else if ("dept".equals(type)) {
  93. map.put("dept", getDeptTemplate());
  94. } else if ("hosp".equals(type)) {
  95. map.put("all", wholeHospitalTemplate());
  96. }
  97. return ResultVoUtil.success(map);
  98. }
  99. private List<JSONObject> getDeptTemplate() {
  100. UserInfo user = redisLikeService.getUserInfoByToken();
  101. JSONArray data = new JSONArray();
  102. if (ListUtil.notBlank(user.getPartTimeDept())) {
  103. user.getPartTimeDept().forEach(item -> {
  104. data.addAll(emr.getDeptList(item));
  105. });
  106. }
  107. data.addAll(emr.getDeptList(user.getDeptCode()));
  108. return emrToTree(data);
  109. }
  110. /**
  111. * 获取 整个医院模板
  112. */
  113. private List<JSONObject> wholeHospitalTemplate() {
  114. JSONArray data = emr.getEmrTree();
  115. return emrToTree(data);
  116. }
  117. /**
  118. * 电子病历转成树状图 二次封装
  119. *
  120. * @param data 模板数据
  121. * @return 返回
  122. */
  123. public List<JSONObject> emrToTree(JSONArray data) {
  124. List<JSONObject> tree = new ArrayList<>();
  125. if (data.isEmpty()) {
  126. return tree;
  127. }
  128. emrArrToTree(data, tree);
  129. return tree;
  130. }
  131. /**
  132. * 电子病历转成树状图
  133. *
  134. * @param data 电子病历
  135. * @param tree 树
  136. */
  137. private static void emrArrToTree(JSONArray data, List<JSONObject> tree) {
  138. Map<String, JSONObject> map = new HashMap<>(data.size());
  139. for (int i = 0; i < data.size(); i++) {
  140. JSONObject item = data.getJSONObject(i);
  141. if (item.get("parent") == null) {
  142. tree.add(item);
  143. }
  144. map.put(item.getString("_id"), item);
  145. }
  146. for (int i = 0; i < data.size(); i++) {
  147. JSONObject item = data.getJSONObject(i);
  148. if (map.containsKey(item.getString("parent"))) {
  149. JSONObject parentList = map.get(item.getString("parent"));
  150. if (parentList.get("children") == null) {
  151. parentList.put("children", new JSONArray());
  152. }
  153. parentList.getJSONArray("children").add(item);
  154. }
  155. }
  156. }
  157. /**
  158. * 获取电子病历的片段
  159. *
  160. * @return 树
  161. */
  162. public ResultVo<List<JSONObject>> getSnippetTree() {
  163. JSONArray data = emr.getSnippetTree();
  164. List<JSONObject> tree = new ArrayList<>();
  165. emrArrToTree(data, tree);
  166. return ResultVoUtil.success(tree);
  167. }
  168. /**
  169. * 提取患者数据元
  170. *
  171. * @param param 结构化文档
  172. */
  173. public Map<String, Object> extractDataElement(EmrPatientData param) {
  174. EmrDataExtract emrDataExtract = dao.extractDataSource(param.getEmrCategoryCode());
  175. if (emrDataExtract == null) {
  176. return new HashMap<>();
  177. }
  178. // 获取 需要提取的数据元
  179. List<String> strings = JSON.parseArray(emrDataExtract.getDataExtract(), String.class);
  180. // 获取前端传入的数据元
  181. JSONObject elementData = param.getEmrDataElement();
  182. // 提取到的数据
  183. Map<String, Object> extractedData = new HashMap<>(strings.size());
  184. for (String el : strings) {
  185. if (elementData.containsKey(el)) {
  186. JSONObject item = elementData.getJSONObject(el);
  187. Object value = item.get("value");
  188. if (value != null) {
  189. extractedData.put(el, value);
  190. }
  191. }
  192. }
  193. EmrDataElement emrDataElement = dao.obtainPatientSOriginalData(param.getPatNo(), param.getTimes());
  194. if (emrDataElement == null) {
  195. // 创建的病历可以解锁了
  196. dao.insertDataSource(param.getPatNo(), param.getTimes(), JSON.toJSONString(extractedData));
  197. } else {
  198. JSONObject jsonObject = JSONObject.parseObject(emrDataElement.getDataElement());
  199. log.info("患者原来的数据:{}", jsonObject);
  200. jsonObject.putAll(extractedData);
  201. dao.updatePatientDataSource(param.getPatNo(), param.getTimes(), JSON.toJSONString(jsonObject));
  202. }
  203. dao.unlockMedicalRecords(param);
  204. log.info("提取到的数据:{}", JSON.toJSONString(extractedData));
  205. return extractedData;
  206. }
  207. /**
  208. * 保存患者电子病历信息
  209. *
  210. * @param param 参数
  211. * @return 提示
  212. */
  213. @Transactional(rollbackFor = Exception.class)
  214. public ResultVo<Map<String, Object>> insertEmrData(EmrPatientData param) {
  215. JSONObject saveJson = new JSONObject();
  216. saveJson.put("document", param.getDocumentData());
  217. try {
  218. emr.saveDocument(saveJson);
  219. } catch (Exception e) {
  220. e.printStackTrace();
  221. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "病历保存错误,请重试!" + e.getMessage());
  222. }
  223. param.setCreateId(TokenUtil.getTokenUserId());
  224. Integer isUpdated = dao.whetherThereIsAMedicalRecord(param.getEmrDocumentId());
  225. Map<String, Object> extractedData = extractDataElement(param);
  226. if (isUpdated != null) {
  227. dao.updateCreatedTemplate(param);
  228. insertAFragmentOfTheCourseOfTheDisease(isUpdated, param.getFragment());
  229. } else {
  230. // 新增的时候插入数据
  231. ZyPatientInfo patInfo = publicServer.getPatInfo(param.getPatNo(), param.getTimes());
  232. param.setReferPhysician(patInfo.getReferPhysician())
  233. .setConsultPhysician(patInfo.getConsultPhysician())
  234. .setDeptDirector(patInfo.getDeptDirector());
  235. if (StringUtil.isBlank(param.getParent())) {
  236. param.setParent(GROUP_MAP.get(param.getEmrCategoryCode()));
  237. }
  238. dao.emrInsertForTheFirstTime(param);
  239. insertAFragmentOfTheCourseOfTheDisease(param.getId(), param.getFragment());
  240. }
  241. return ResultVoUtil.success(extractedData);
  242. }
  243. /**
  244. * 插入病程记录的片段
  245. *
  246. * @param id 病程记录
  247. * @param fragment 片段
  248. */
  249. private void insertAFragmentOfTheCourseOfTheDisease(Integer id, List<EmrProgressNote> fragment) {
  250. if (ListUtil.isBlank(fragment)) {
  251. return;
  252. }
  253. log.info("数据:id:{},片段{}", id, JSON.toJSONString(fragment));
  254. dao.delOldFragment(id);
  255. List<List<EmrProgressNote>> lists = ListUtils.partition(fragment, 50);
  256. for (List<EmrProgressNote> list : lists) {
  257. dao.insertFragment(list, id);
  258. }
  259. }
  260. /**
  261. * 根据患者的电子病历 id 来删除
  262. * 这里用的是逻辑删除
  263. *
  264. * @param documentId 电子病历id
  265. * @return 删除电子病历的同时需要删除, 提取到的数据源.
  266. */
  267. public ResultVo<List<String>> deletePatientEmrByDocumentId(String documentId) {
  268. try {
  269. emr.deleteEmr(documentId);
  270. } catch (Exception e) {
  271. e.printStackTrace();
  272. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存病历失败,请重试!" + e.getMessage());
  273. }
  274. EmrPatientData patientData = dao.getCategoryCodeByDocumentId(documentId);
  275. EmrDataExtract emrDataExtract = dao.extractDataSource(patientData.getEmrCategoryCode());
  276. List<String> strings = new ArrayList<>();
  277. if (emrDataExtract != null) {
  278. // 获取 需要提取的数据元
  279. strings = JSON.parseArray(emrDataExtract.getDataExtract(), String.class);
  280. log.info("需要提取的数据:{}", strings);
  281. // 获取到已经提取的数据
  282. EmrDataElement emrDataElement = dao.obtainPatientSOriginalData(patientData.getPatNo(), patientData.getTimes());
  283. // 转 json
  284. JSONObject jsonObject = JSONObject.parseObject(emrDataElement.getDataElement());
  285. for (String string : strings) {
  286. // 删除提取到的数据
  287. jsonObject.remove(string);
  288. }
  289. // 更新患者数据元
  290. dao.updatePatientDataSource(patientData.getPatNo(), patientData.getTimes(), JSON.toJSONString(jsonObject));
  291. }
  292. // 删除病历
  293. dao.deletePatientEmrByDocumentId(documentId, TokenUtil.getTokenUserId());
  294. return ResultVoUtil.success(strings);
  295. }
  296. /**
  297. * 查询患者是否有指定的病历了
  298. *
  299. * @param param 住院号,住院次数,病历编码
  300. * @return 返回 Boolean
  301. */
  302. public ResultVo<Boolean> queryWhetherThePatientHasASpecifiedMedicalRecord(EmrPatientData param) {
  303. return ResultVoUtil.success(dao.queryWhetherThePatientHasASpecifiedMedicalRecord(param.getPatNo(), param.getTimes(), param.getEmrCategoryCode()) == 1);
  304. }
  305. /**
  306. * 医生诊断热缩
  307. *
  308. * @param userCode 医生编码
  309. * @param code 诊断 code
  310. * @param tableName 表名
  311. */
  312. public void hotSearchSorting(String userCode, String code, String tableName) {
  313. boolean insert = dao.queryWhetherThereIsHotSearch(userCode, code, tableName) == 0;
  314. if (insert) {
  315. dao.hotSearchSorting(userCode, code, tableName);
  316. } else {
  317. dao.updateHotSearch(userCode, code, tableName);
  318. }
  319. log.info("医生编码:{},搜索关键字:{},表名:{}", userCode, code, tableName);
  320. }
  321. /**
  322. * 根据文档 id 提交病历
  323. *
  324. * @param documentId 文档id
  325. * @return 返回数据
  326. */
  327. public ResultVo<String> submitMedicalRecord(String documentId) {
  328. String userCode = TokenUtil.getTokenUserId();
  329. String createdId = dao.getDocumentIdCreatedBy(documentId);
  330. log.info("提交病历==》 操作人:{},病历id:{},创建人:{}", userCode, documentId, createdId);
  331. if (userCode.equals(createdId)) {
  332. dao.updateSubmissionFlag(documentId, userCode);
  333. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "提交成功");
  334. }
  335. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "创建人不一致无法修改。");
  336. }
  337. public ResultVo<String> audit(String documentId) {
  338. String userCode = TokenUtil.getTokenUserId();
  339. int count = dao.updateAuditByDocumentId(documentId, userCode);
  340. if (count > 0) {
  341. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "审核成功");
  342. }
  343. return ResultVoUtil.success(ExceptionEnum.NO_DATA_EXIST, "操作失败,可能原因,已经审核完成或还未保存。");
  344. }
  345. /**
  346. * 获取电子病历数据
  347. *
  348. * @param panNo 住院号
  349. * @param times 住院次数
  350. * @param etType 类型
  351. * @return 返回数据
  352. */
  353. public JSONArray getEmrData(String panNo, Integer times, EmrType etType) {
  354. // 查询这个病历的 唯一 id
  355. List<String> idList = dao.getDocumentIdByPatietn(panNo, times, etType.getName());
  356. JSONArray returnArray = new JSONArray();
  357. if (ListUtil.isBlank(idList)) {
  358. return returnArray;
  359. }
  360. Map<String, JSONObject> surgicalSequencing = new TreeMap<>();
  361. for (String s : idList) {
  362. JSONObject jsonObject = emr.getEditorJsonDataByDocumentId(s);
  363. if (etType.getCode() == EmrType.DIAGNOSIS.getCode()) {
  364. returnArray.addAll(extractDiagnosis(jsonObject));
  365. } else if (etType.getCode() == EmrType.OPERATION.getCode()) {
  366. String key = DateUtil.formatDatetime(jsonObject.getJSONObject("手术日期").getDate("value"));
  367. surgicalSequencing.put(key, jsonObject);
  368. }
  369. }
  370. if (!surgicalSequencing.isEmpty()) {
  371. for (Map.Entry<String, JSONObject> item : surgicalSequencing.entrySet()) {
  372. returnArray.add(item.getValue());
  373. }
  374. }
  375. return returnArray;
  376. }
  377. /**
  378. * 获取患者提取到的数据
  379. *
  380. * @param patNo 住院号
  381. * @param times 次数
  382. * @return 返回 json
  383. */
  384. public JSONObject getEmrPatientData(String patNo, Integer times) {
  385. String js = dao.getEmrPatientData(patNo, times);
  386. if (StringUtil.isBlank(js)) {
  387. return new JSONObject();
  388. }
  389. return JSON.parseObject(js);
  390. }
  391. /**
  392. * 获取患者的手术
  393. *
  394. * @param patNo 获取住院号
  395. * @param times 获取住院次数
  396. * @return 返回数据
  397. */
  398. public JSONArray getPatientSurgery(String patNo, Integer times) {
  399. List<String> idList = dao.getDocumentIdByPatietn(patNo, times, "a2a2866054fe11edb28ac955a5f5cad1");
  400. JSONArray returnArray = new JSONArray();
  401. if (ListUtil.isBlank(idList)) {
  402. return returnArray;
  403. }
  404. Map<String, JSONObject> surgicalSequencing = new TreeMap<>();
  405. for (String s : idList) {
  406. JSONObject jsonObject = emr.getEditorJsonDataByDocumentId(s);
  407. JSONObject surgeryDate = jsonObject.getJSONObject("手术日期");
  408. if (null == surgeryDate) {
  409. continue;
  410. }
  411. String key = DateUtil.formatDatetime(surgeryDate.getDate("value"));
  412. if (StringUtil.isBlank(key)) {
  413. continue;
  414. }
  415. surgicalSequencing.put(key, jsonObject);
  416. }
  417. if (!surgicalSequencing.isEmpty()) {
  418. for (Map.Entry<String, JSONObject> item : surgicalSequencing.entrySet()) {
  419. returnArray.add(item.getValue());
  420. }
  421. }
  422. return returnArray;
  423. }
  424. private JSONArray extractDiagnosis(JSONObject jsonObject) {
  425. JSONObject diagnosis = jsonObject.getJSONObject("入院诊断");
  426. if (diagnosis != null) {
  427. JSONArray diagnosisArr = diagnosis.getJSONArray("value");
  428. if (diagnosisArr != null) {
  429. return diagnosisArr;
  430. }
  431. }
  432. return new JSONArray();
  433. }
  434. public ResultVo<String> getDrgIntelligentGrouping(String patNo, Integer times) {
  435. // 获取诊断
  436. JSONArray diagnosis = getEmrData(patNo, times, EmrType.DIAGNOSIS);
  437. // 获取手术
  438. JSONArray operation = getEmrData(patNo, times, EmrType.OPERATION);
  439. int ledgerSn = publicServer.getLedgerSn(patNo, times);
  440. // 获取患者数据
  441. Map<String, String> mapData = dao.drgPatientInfo(patNo, times, ledgerSn);
  442. if (mapData == null) {
  443. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有查询到患者信息。");
  444. }
  445. mapData.put("visit_id", patNo + "_" + times + "_" + ledgerSn);
  446. mapData.put("bah", patNo + "_" + times);
  447. for (int i = 0; i < diagnosis.size(); i++) {
  448. JSONObject item = diagnosis.getJSONObject(i);
  449. if (i == 0) {
  450. mapData.put("jbdm", item.getString("code"));
  451. mapData.put("zyzd", item.getString("name"));
  452. } else {
  453. mapData.put("jbdm" + i, item.getString("code"));
  454. }
  455. }
  456. int operationIndex = 1;
  457. for (int i = 0; i < operation.size(); i++) {
  458. JSONObject item = operation.getJSONObject(i);
  459. JSONArray list = null;
  460. try {
  461. list = item.getJSONObject("手术名称").getJSONArray("value");
  462. } catch (Exception e) {
  463. continue;
  464. }
  465. if (list == null) {
  466. continue;
  467. }
  468. for (int a = 0; a < list.size(); a++) {
  469. JSONObject valueList = list.getJSONObject(a);
  470. mapData.put("ssjczbm" + operationIndex, valueList.getString("code"));
  471. if (operationIndex == 1) {
  472. mapData.put("ssjczmc" + operationIndex, valueList.getString("name"));
  473. }
  474. operationIndex++;
  475. }
  476. }
  477. AuxiliaryFillingOfDiagnosis data = EntityCopy.Copy(mapData, AuxiliaryFillingOfDiagnosis.class);
  478. String url = "http://172.16.32.126:8080/drg_web/localHelp/drg_dagns/list.action";
  479. RestTemplate template = new RestTemplate();
  480. String toJsonStr = JSON.toJSONString(data, SerializerFeature.WriteNullStringAsEmpty);
  481. log.info("DRG数据:{}", toJsonStr);
  482. String res = template.postForObject(url, JSON.parseObject(toJsonStr), String.class);
  483. return ResultVoUtil.success("http://172.16.32.126:8080" + res);
  484. }
  485. /**
  486. * 获取患者最大的住院次数
  487. *
  488. * @param patNo 住院号
  489. * @return 返回最大次数
  490. */
  491. public ResultVo<Integer> getDischargeTimes(String patNo) {
  492. Integer times = dao.getMaxTimes(patNo);
  493. if (times == null) {
  494. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有查询到患者信息。");
  495. }
  496. return ResultVoUtil.success(times);
  497. }
  498. public ResultVo<JSONObject> getExtractDataElement(String patNo, Integer times) {
  499. Map<String, String> map = dao.selectEmrDataElement(patNo, times);
  500. if (map == null) {
  501. return ResultVoUtil.success();
  502. } else {
  503. return ResultVoUtil.success(JSONObject.parseObject(map.get("data_element")));
  504. }
  505. }
  506. public ResultVo<List<CodeName>> getAllWards() {
  507. return ResultVoUtil.success(loginDao.getAllWards());
  508. }
  509. /**
  510. * 获取患者已经被删除的病历
  511. *
  512. * @param patNo 住院号
  513. * @return 返回
  514. */
  515. public ResultVo<List<EmrPatientData>> getDeleteMedicalRecord(String patNo) {
  516. Integer times = dao.getAdmissTimes(patNo);
  517. if (times == null) {
  518. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "出院患者无法恢复病历,如果要恢复请先召回在院。");
  519. }
  520. return ResultVoUtil.success(dao.selectEmrDeteles(patNo, times, TokenUtil.getTokenUserId()));
  521. }
  522. public ResultVo<JSONObject> getInvalidByDocumentId(String id) {
  523. return ResultVoUtil.success(emr.getInvalidByDocumentIdApi(id));
  524. }
  525. /**
  526. * 恢复电子病历
  527. *
  528. * @param documentId 电子病历文档
  529. * @return 返回提示
  530. */
  531. public ResultVo<String> resumeMedicalRecords(String documentId) {
  532. EmrPatientData data = dao.selectemPatientDataOne(documentId);
  533. if (data.getDelFlag() == 0) {
  534. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "病历已经被恢复了请勿重复点击");
  535. }
  536. Integer times = dao.getAdmissTimes(data.getPatNo());
  537. if (times == null) {
  538. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "出院患者无法恢复病历,如果要恢复请先召回在院。");
  539. }
  540. JSONObject param = new JSONObject();
  541. param.put("_id", documentId);
  542. param.put("valid", 1);
  543. JSONObject json = emr.resumeMedicalRecords(documentId, param);
  544. log.info("恢复电子病历:{}", json);
  545. if (json.getInteger("ok") == 1) {
  546. dao.updateDeleteFlag(data.getId());
  547. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "病历恢复成功。");
  548. } else {
  549. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "病历恢复失败,请重试!");
  550. }
  551. }
  552. /**
  553. * 查询出院患者的申请
  554. *
  555. * @param flag 1 只查询自己的 2 查询审核的
  556. * @return 提示
  557. */
  558. public ResultVo<List<DischargedEmrModifyApply>> getDisReqEmr(Integer flag) {
  559. QueryWrapper<?> qw = new QueryWrapper<>();
  560. if (flag == 1) {
  561. qw.eq("req_id", TokenUtil.getTokenUserId());
  562. } else if (flag == 2) {
  563. qw.eq("req_status", 0);
  564. }
  565. qw.ge("edit_date", DateUtil.formatDatetime(new Date(), DateUtil.DATE));
  566. return ResultVoUtil.success(dao.getDisReqEmr(qw));
  567. }
  568. public ResultVo<List<DischargedEmrModifyApply>> downloadTheDischargeEdit(String start, String end) {
  569. log.info("导出出院编辑数据:开始:{},结束:{}", start, end);
  570. return ResultVoUtil.success(dao.selectDisReqEmyDownload(start, end));
  571. }
  572. /**
  573. * 申请出院患者修改
  574. *
  575. * @param param 参数
  576. * @return 提示
  577. */
  578. @Transactional(rollbackFor = Exception.class)
  579. public ResultVo<String> saveDisEmrReq(DischargedEmrModifyApply param) {
  580. param.setReqId(TokenUtil.getTokenUserId());
  581. log.info("申请出院患者修改病历:{}", JSON.toJSONString(param));
  582. int num = dao.deleteRequest(param.getPatNo());
  583. dao.insertApplicationEmrDis(param);
  584. if (num > 0) {
  585. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "修改原申请成功。");
  586. } else {
  587. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "申请成功。");
  588. }
  589. }
  590. /**
  591. * 删除申请
  592. *
  593. * @param patNo 住院号
  594. * @return 提示
  595. */
  596. public ResultVo<String> deleteDisEmrDis(String patNo) {
  597. dao.deleteRequest(patNo);
  598. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "操作成功。");
  599. }
  600. /**
  601. * 通过申请
  602. *
  603. * @param patNo 住院号
  604. * @return 提示
  605. */
  606. public ResultVo<String> adoptEmrDisReq(String patNo) {
  607. int num = dao.adoptEmrDisReq(patNo, null, 1);
  608. if (num > 0) {
  609. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  610. }
  611. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "操作失败,原申请可能已经被删除了。");
  612. }
  613. /**
  614. * 拒绝出院患者申请
  615. *
  616. * @param patNo 住院号
  617. * @param reviewNotes 审核信息
  618. * @return 提示
  619. */
  620. public ResultVo<String> refuseEmrDisReq(String patNo, String reviewNotes) {
  621. int num = dao.adoptEmrDisReq(patNo, reviewNotes, 2);
  622. if (num > 0) {
  623. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  624. }
  625. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "操作失败,原申请可能已经被删除了。");
  626. }
  627. /**
  628. * 查询出院患者是否已经通过了编辑
  629. *
  630. * @param patNo 住院号
  631. * @return Boolean
  632. */
  633. public ResultVo<Boolean> isDisReqEdit(String patNo) {
  634. QueryWrapper<?> qw = new QueryWrapper<>();
  635. qw.eq("pat_no", patNo);
  636. qw.eq("req_status", 1);
  637. qw.ge("edit_date", DateUtil.formatDatetime(new Date(), DateUtil.DATE));
  638. List<DischargedEmrModifyApply> list = dao.getDisReqEmr(qw);
  639. if (ListUtil.isBlank(list)) {
  640. return ResultVoUtil.success(false);
  641. } else {
  642. return ResultVoUtil.success(true);
  643. }
  644. }
  645. public ResultVo<Object> getHistory(String documentId) {
  646. return ResultVoUtil.success(emr.getHistory(documentId));
  647. }
  648. public ResultVo<List<MedicalHistoryPrompts>> getEmrTips() {
  649. return ResultVoUtil.success(dao.selectEmrTips(TokenUtil.getTokenUserId()));
  650. }
  651. public ResultVo<String> addEmrTips(MedicalHistoryPrompts param) {
  652. log.info("数据:{}", JSON.toJSONString(param));
  653. UserInfo userInfo = redisLikeService.getUserInfoByToken();
  654. param.setDept(userInfo.getDeptCode());
  655. param.setCreatorId(userInfo.getCode());
  656. dao.insertEmrTips(param);
  657. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  658. }
  659. public ResultVo<String> updateEmrTips(MedicalHistoryPrompts param) {
  660. if (param.getId() == null) {
  661. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "id 为空无法更新。");
  662. }
  663. dao.updateEmrTips(param);
  664. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  665. }
  666. public ResultVo<String> deleteEmrTips(Integer id) {
  667. dao.delEmrTips(id);
  668. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION);
  669. }
  670. /**
  671. * 在病程记录中获取文本数据
  672. *
  673. * @param name 名称
  674. * @return 返回数据
  675. */
  676. public ResultVo<List<MedicalHistoryPrompts>> getEmrTipsData(String name, int typeCode) {
  677. QueryWrapper<?> qw = new QueryWrapper<>();
  678. UserInfo us = redisLikeService.getUserInfoByToken();
  679. if (typeCode == 1) {
  680. qw.eq("creator_id", us.getCode());
  681. } else if (typeCode == 2) {
  682. qw.eq("dept", us.getDeptCode());
  683. }
  684. qw.like("query_key", name)
  685. .eq("type_code", typeCode)
  686. .orderByDesc("count");
  687. return ResultVoUtil.success(dao.getEmrTipsData(qw));
  688. }
  689. public ResultVo<List<ZyPatientInfo>> getListOfDischargedPatients(String patNo) {
  690. List<ZyPatientInfo> list = dao.getListOfDischargedPatients(patNo);
  691. if (ListUtil.isBlank(list)) {
  692. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有" + patNo + "的出院记录。");
  693. }
  694. return ResultVoUtil.success(list);
  695. }
  696. public ResultVo<JSONObject> getYzTemperature(String patNo, Integer times) {
  697. JSONObject js = new JSONObject();
  698. List<YzTemperature> list = dao.getYzTemperature(patNo, times);
  699. if (ListUtil.isBlank(list)) {
  700. return ResultVoUtil.success(js);
  701. }
  702. Map<Date, YzTemperature> map = new LinkedHashMap<>(list.size());
  703. for (YzTemperature item : list) {
  704. Date key = item.getTempDate();
  705. if (map.containsKey(key)) {
  706. YzTemperature yz = map.get(key);
  707. yz.setOtherInfo(nullToEmpty(yz.getOtherInfo()) + nullToEmpty(item.getOtherInfo()));
  708. } else {
  709. map.put(key, item);
  710. }
  711. }
  712. js.put("list", list);
  713. js.put("map", map);
  714. return ResultVoUtil.success(js);
  715. }
  716. public ResultVo<List<YshYjReq>> getExamine(String patNo, Integer times) {
  717. return ResultVoUtil.success(dao.getExamine(patNo, times));
  718. }
  719. private String nullToEmpty(String str) {
  720. if (StringUtil.isBlank(str)) {
  721. return "";
  722. }
  723. return str;
  724. }
  725. public ResultVo<ZyZkList> whetherItExistsInTheDepartment(String patNo, Integer times) {
  726. ZyZkList zk = dao.getMaxTransferDateByPatNo(patNo, times);
  727. if (zk != null) {
  728. zk.setTimeout(DateUtil.moreThanHours(zk.getOpTime(), 48));
  729. }
  730. return ResultVoUtil.success(zk);
  731. }
  732. public ResultVo<String> emrSocketUnlock(String sid, String documentId) {
  733. List<Session> list = WebSocketServer.getEmrMap(sid);
  734. if (ListUtil.isBlank(list)) {
  735. return ResultVoUtil.success();
  736. }
  737. list.removeIf(item -> {
  738. if (EmrWebSocketServer.sessionParseUserCode(item).equals(TokenUtil.getTokenUserId())) {
  739. WebSocketServer.emrSendMessage(item, "{\"closeSoctek\":\"true\"}");
  740. return true;
  741. }
  742. return false;
  743. });
  744. if (StringUtil.notBlank(documentId)) {
  745. EmrWebSocketServiceV2.close(documentId);
  746. }
  747. return ResultVoUtil.success();
  748. }
  749. public ResultVo<String> electronicMedicalRecordSequencing(List<EmrPatientData> data) {
  750. if (ListUtil.isBlank(data)) {
  751. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择有效的分类数据。");
  752. }
  753. data.forEach(item -> {
  754. dao.updateTheNode(item.getParent(), item.getId());
  755. });
  756. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "操作成功。");
  757. }
  758. public void tree() {
  759. JSONArray data = emr.getEmrTree();
  760. for (int i = 0; i < data.size(); i++) {
  761. JSONObject item = data.getJSONObject(i);
  762. if (item.getString("_id").equals(HOSPITAL_WIDE_FOLDER)) {
  763. item.put("name", "其他病历");
  764. }
  765. if ("group-category".equals(item.getString("type"))) {
  766. TEMPLATE_DATA.put(item.getString("_id"), item);
  767. }
  768. GROUP_MAP.put(item.getString("code"), item.getString("parent"));
  769. }
  770. log.info("获取所有的父节点:{}", JSON.toJSONString(TEMPLATE_DATA));
  771. }
  772. private void 重置父级节点() {
  773. List<EmrPatientData> patData = dao.查询历史数据();
  774. patData.forEach(item -> {
  775. if (GROUP_MAP.containsKey(item.getEmrCategoryCode())) {
  776. String value = GROUP_MAP.get(item.getEmrCategoryCode());
  777. dao.updateTheNode(value, item.getId());
  778. }
  779. });
  780. }
  781. public ResultVo<Map<String, List<EmrPatientData>>> getPastHistory(String patNo, Integer times) {
  782. List<EmrPatientData> list = dao.getHisPatInfo(patNo, times);
  783. Map<String, List<EmrPatientData>> grouping = new HashMap<>();
  784. if (ListUtil.notBlank(list)) {
  785. grouping = list.stream().collect(
  786. Collectors.groupingBy(item -> item.getTimes().toString())
  787. );
  788. }
  789. return ResultVoUtil.success(grouping);
  790. }
  791. }