CaseFrontSheetMainService.java 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. package thyyxxk.webserver.service.casefrontsheet;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.alibaba.fastjson.serializer.SerializerFeature;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.scheduling.annotation.Scheduled;
  9. import org.springframework.stereotype.Service;
  10. import org.springframework.transaction.annotation.Transactional;
  11. import org.springframework.web.client.RestTemplate;
  12. import thyyxxk.webserver.config.exception.ExceptionEnum;
  13. import thyyxxk.webserver.constants.sidicts.Insutype;
  14. import thyyxxk.webserver.constants.sidicts.MedType;
  15. import thyyxxk.webserver.dao.his.LoginDao;
  16. import thyyxxk.webserver.dao.his.casefrontsheet.BasSelectOverviewDao;
  17. import thyyxxk.webserver.dao.his.casefrontsheet.CaseFrontSheetDao;
  18. import thyyxxk.webserver.dao.his.casefrontsheet.SheetCreatedDao;
  19. import thyyxxk.webserver.entity.ResultVo;
  20. import thyyxxk.webserver.entity.api.forpowersi.drgdip.frontsheetqualitycheck.QualityCheckParams;
  21. import thyyxxk.webserver.entity.casefrontsheet.*;
  22. import thyyxxk.webserver.entity.covid.Region;
  23. import thyyxxk.webserver.entity.dictionary.CodeName;
  24. import thyyxxk.webserver.entity.dictionary.HisWjwMatchEntity;
  25. import thyyxxk.webserver.service.externalhttp.PowersiSrvc;
  26. import thyyxxk.webserver.service.zhuyuanyisheng.EmrServer;
  27. import thyyxxk.webserver.utils.*;
  28. import java.lang.reflect.Field;
  29. import java.util.*;
  30. import java.util.concurrent.ConcurrentHashMap;
  31. @Slf4j
  32. @Service
  33. public class CaseFrontSheetMainService {
  34. private static ConcurrentHashMap<String, List<CodeName>> allDictionary;
  35. private final CaseFrontSheetDao dao;
  36. private final SheetCreatedDao createdDao;
  37. private final BasSelectOverviewDao basDao;
  38. private final LoginDao userDao;
  39. private final PowersiSrvc srvc;
  40. private final EmrServer emrService;
  41. public CaseFrontSheetMainService(SheetCreatedDao createdDao, CaseFrontSheetDao dao, BasSelectOverviewDao basDao,
  42. LoginDao userDao, PowersiSrvc srvc, EmrServer emrService) {
  43. this.dao = dao;
  44. this.createdDao = createdDao;
  45. this.basDao = basDao;
  46. this.userDao = userDao;
  47. this.srvc = srvc;
  48. this.emrService = emrService;
  49. if (allDictionary == null) {
  50. allDictionary = new ConcurrentHashMap<>();
  51. }
  52. }
  53. public ResultVo<Map<String, List<CodeName>>> getAllDictionary() {
  54. if (allDictionary.isEmpty()) {
  55. allDictionary.put("getMarriageCode", createdDao.getMarriageCode());
  56. allDictionary.put("getSexCode", createdDao.getSexCode());
  57. allDictionary.put("getAdmissWay", createdDao.getAdmissWay());
  58. allDictionary.put("getBloodType", createdDao.getBloodType());
  59. allDictionary.put("getAnaesthesia", createdDao.getAnaesthesia());
  60. allDictionary.put("getOperateScale", createdDao.getOperateScale());
  61. allDictionary.put("getAdmissStatus", createdDao.getAdmissStatus());
  62. allDictionary.put("getDisAdmissStatus", createdDao.getDisAdmissStatus());
  63. allDictionary.put("getCutHealGrade", createdDao.getCutHealGrade());
  64. allDictionary.put("getDisdiagStatus", createdDao.getDisdiagStatus());
  65. allDictionary.put("getHbsag", createdDao.getHbsag());
  66. allDictionary.put("getDiagConform", createdDao.getDiagConform());
  67. allDictionary.put("getDisdiagType", createdDao.getDisdiagType());
  68. allDictionary.put("getPatientStatus", createdDao.getPatientStatus());
  69. allDictionary.put("getQualityLevel", createdDao.getQualityLevel());
  70. allDictionary.put("getZyDismissWay", createdDao.getZyDismissWay());
  71. allDictionary.put("getTumorLevelT", createdDao.getTumorLevelT());
  72. allDictionary.put("getTumorLevelN", createdDao.getTumorLevelN());
  73. allDictionary.put("getTumorLevelM", createdDao.getTumorLevelM());
  74. allDictionary.put("getTumorLevel", createdDao.getTumorLevel());
  75. allDictionary.put("getRelations", createdDao.getRelations());
  76. List<CodeName> temp = new ArrayList<>();
  77. temp.add(new CodeName());
  78. temp.addAll(createdDao.getStatutoryEpidemic());
  79. allDictionary.put("getStatutoryEpidemic", temp);
  80. allDictionary.put("getClinicalPathwayManagement", createdDao.getClinicalPathwayManagement());
  81. allDictionary.put("getDrgsManagement", createdDao.getDrgsManagement());
  82. allDictionary.put("getCaseClassification", createdDao.getCaseClassification());
  83. allDictionary.put("getOccupation", createdDao.getOccupation());
  84. allDictionary.put("getCountry", createdDao.getCountry());
  85. allDictionary.put("getNation", createdDao.getNation());
  86. allDictionary.put("getPayMethod", createdDao.getPayMethod());
  87. }
  88. return ResultVoUtil.success(allDictionary);
  89. }
  90. public ResultVo<String> resetDictionary() {
  91. allDictionary.clear();
  92. return ResultVoUtil.success();
  93. }
  94. @Scheduled(cron = "0 0 3 * * ?")
  95. public void refreshDictionary() {
  96. resetDictionary();
  97. }
  98. public ResultVo<List<CodeName>> getUserWards() {
  99. String code = TokenUtil.getTokenUserId();
  100. List<Integer> roles = createdDao.selectUserRoles(code);
  101. List<CodeName> list;
  102. if (roles.contains(7) || roles.contains(1)) {
  103. list = createdDao.getAllWards();
  104. } else {
  105. list = createdDao.getUserWards(code);
  106. }
  107. list.removeIf(Objects::isNull);
  108. return ResultVoUtil.success(list);
  109. }
  110. public ResultVo<List<CodeName>> getAllWards() {
  111. return ResultVoUtil.success(createdDao.getAllWards());
  112. }
  113. public ResultVo<List<SheetOverview>> getPatientOverview(String ward) {
  114. return ResultVoUtil.success(dao.getPatientOverview(ward));
  115. }
  116. public ResultVo<List<SheetOverview>> getOutPatient(GetOutSheet param) {
  117. param.setEnd(param.getEnd() + " 23:59:59");
  118. if (StringUtil.isBlank(param.getWard())) {
  119. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择科室!");
  120. }
  121. return ResultVoUtil.success(dao.getOutPatients(param));
  122. }
  123. /**
  124. * 查询病案首页汇总
  125. *
  126. * @param param 查询的条件
  127. * @return 返回数据
  128. */
  129. public ResultVo<GetBasOverviewRet> getOutPatientForBas(GetOutSheet param) {
  130. GetBasOverviewRet ret = new GetBasOverviewRet();
  131. if (StringUtil.notBlank(param.getWard())) {
  132. int cd = dao.getCDBlfxCount(param.getWard());
  133. int all = dao.getAllDisPatientCount(param.getWard());
  134. if (cd == 0 || all == 0) {
  135. ret.setCdPercentage("0.00%");
  136. } else {
  137. ret.setCdPercentage(DecimalUtil.getPercent(cd, all));
  138. }
  139. }
  140. if (StringUtil.notBlank(param.getStart())) {
  141. param.setStart(param.getStart() + " 00:00:00");
  142. }
  143. if (StringUtil.notBlank(param.getEnd())) {
  144. param.setEnd(param.getEnd() + " 23:59:59");
  145. }
  146. List<SheetOverview> list;
  147. if (StringUtil.notBlank(param.getBah())) {
  148. if (param.getFileStatus() == 0) {
  149. list = basDao.selectPatientsForBasByBah(param);
  150. if (list.isEmpty()) {
  151. if (basDao.selectInHospCount(param.getBah()) > 0) {
  152. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "此患者没有出院结算,请联系病房处理。");
  153. }
  154. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有找到此患者的未归档病案。");
  155. }
  156. } else {
  157. list = basDao.selectPatientsFromSignedBase(param);
  158. if (list.isEmpty()) {
  159. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有找到此患者的已归档病案。");
  160. }
  161. }
  162. if (param.getLateFlag() != 3) {
  163. list.removeIf(item -> !item.getLateFlag().equals(param.getLateFlag()));
  164. }
  165. ret.setList(list);
  166. return ResultVoUtil.success(ret);
  167. }
  168. if (StringUtil.notBlank(param.getWard())) {
  169. if (param.getFileStatus() == 0) {
  170. list = basDao.selectPatientsForBasByWard(param);
  171. } else {
  172. list = basDao.selectPatientsForBasByWard2(param);
  173. }
  174. if (param.getLateFlag() != 3) {
  175. list.removeIf(item -> !item.getLateFlag().equals(param.getLateFlag()));
  176. }
  177. ret.setList(list);
  178. return ResultVoUtil.success(ret);
  179. }
  180. if (param.getFileStatus() == 0) {
  181. list = basDao.selectPatientsForBasByFileStatus(param);
  182. } else {
  183. list = basDao.selectPatientsForBasByFileStatus2(param);
  184. }
  185. if (param.getLateFlag() != 3) {
  186. list.removeIf(item -> !item.getLateFlag().equals(param.getLateFlag()));
  187. }
  188. ret.setList(list);
  189. return ResultVoUtil.success(ret);
  190. }
  191. public ResultVo<CaseFrontsheetMain> getPatientInfo(SheetOverview overview) {
  192. String bah = overview.getBah();
  193. Integer times = overview.getTimes();
  194. StandardAddressMember standardAddressMember = getStandardAddressMember(bah);
  195. CaseFrontsheetMain sheet = dao.selectSignedSheetMain(bah, times);
  196. if (null != sheet) {
  197. sheet.setDisdiagList(getSheetDisDiags(bah, times, 1));
  198. sheet.setSurgeryList(getSheetSurgeries(bah, times, 1));
  199. if (null != standardAddressMember) {
  200. sheet.setStandardAddress(standardAddressMember.makeStandardAddress());
  201. }
  202. if (sheet.getAge() == 0 && null == sheet.getAgeDays()) {
  203. sheet.setAgeDays(DateUtil.calculateNewBornAge(sheet.getBirthDate(), sheet.getAdmissDate()));
  204. dao.updateNewBornAge(bah, times, sheet.getAgeDays());
  205. }
  206. if (StringUtil.isBlank(sheet.getMedType())) {
  207. String psnmedtype = dao.selectMedType(sheet.getBah(), sheet.getAdmissTimes());
  208. MedType medType = MedType.get(psnmedtype);
  209. if (null != medType) {
  210. sheet.setMedType(psnmedtype);
  211. sheet.setMedTypeName(medType.getName());
  212. }
  213. }
  214. return ResultVoUtil.success(sheet);
  215. }
  216. int flag = overview.getInOutFlag();
  217. if (flag == 2) {
  218. flag = dao.selectActCount(bah, times) > 0 ? 1 : 2;
  219. }
  220. sheet = dao.getAPatientMi(bah);
  221. CaseFrontsheetMain sheet1 = dao.getZyLedgerFile(bah, times);
  222. CaseFrontsheetMain sheet2 = flag == 1 ? dao.getZyActPatient("zy_actpatient", "yz_act_order", bah, times) :
  223. dao.getZyActPatient("zy_inactpatient", "yz_inact_order", bah, times);
  224. if (null == sheet2) {
  225. sheet2 = flag == 1 ? dao.getZyActPatient("zy_inactpatient", "yz_inact_order", bah, times) :
  226. dao.getZyActPatient("zy_actpatient", "yz_act_order", bah, times);
  227. }
  228. sheet.setAge(DateUtil.calculateAge(sheet.getBirthDate(), sheet2.getAdmissDate()));
  229. if (null != sheet.getAge() && sheet.getAge() == 0) {
  230. sheet.setAgeDays(DateUtil.calculateNewBornAge(sheet.getBirthDate(), sheet2.getAdmissDate()));
  231. }
  232. if (StringUtil.isBlank(sheet2.getMedType())) {
  233. String injurySerialNo = dao.selectInjurySerialNo(bah, times);
  234. if (StringUtil.notBlank(injurySerialNo)) {
  235. sheet2.setMedType("42");
  236. }
  237. }
  238. sheet2.setMedTypeName(MedType.getName(sheet2.getMedType()));
  239. sheet2.setInsutype(Insutype.getName(sheet2.getInsutype()));
  240. final int hasInfant = dao.getInfant(bah, times);
  241. sheet2.setHasInfant(String.valueOf(hasInfant));
  242. if (null == sheet2.getDismissDate()) {
  243. final Date dismissDate = flag == 1 ?
  244. dao.getDismissDateFromYzActOrder("yz_inact_order", bah, times)
  245. : dao.getDismissDateFromYzActOrder("yz_act_order", bah, times);
  246. sheet2.setDismissDate(dismissDate);
  247. }
  248. CaseFrontsheetMain sheet3 = dao.getBatjBa1(bah, times);
  249. if (sheet3 == null && dao.isBatjBa1Exist(bah, times) == 0) {
  250. dao.createBatjBa1(bah, times, sheet.getName(), sheet2.getAdmissDate(),
  251. sheet2.getAdmissDept(), sheet2.getAdmissWard());
  252. log.info("insert batjBa1>>> " + bah + ", " + times);
  253. }
  254. CaseFrontsheetMain sheet4 = flag == 1 ? dao.getBatjBa2ForInPatient(bah, times) :
  255. dao.getBatjBa2ForOutPatient(bah, times);
  256. if (sheet4 == null && dao.isBatjBa2Exist(bah, times) == 0) {
  257. dao.createBatjBa2(bah, times);
  258. log.info("insert batjBa2>>> " + bah + ", " + times);
  259. }
  260. mergeObject(sheet1, sheet);
  261. mergeObject(sheet2, sheet);
  262. mergeObject(sheet3, sheet);
  263. mergeObject(sheet4, sheet);
  264. if (dao.getDismissOrder(bah, times) > 0) {
  265. sheet.setZyDismissWay("0");
  266. }
  267. if (dao.getDeathOrder(bah, times) > 0) {
  268. sheet.setZyDismissWay("4");
  269. }
  270. Integer days = DateUtil.daysBetween(sheet.getDismissDate(), sheet.getAdmissDate());
  271. sheet.setAdmissDays(0 == days ? "1" : String.valueOf(days));
  272. if (null == sheet.getQualityControlDate()) {
  273. sheet.setQualityControlDate(new Date());
  274. }
  275. sheet.setDisdiagList(getSheetDisDiags(bah, times, 0));
  276. sheet.setSurgeryList(getSheetSurgeries(bah, times, 0));
  277. if (null == standardAddressMember) {
  278. sheet.setLivePlaceCombo(sheet.getLivePlace());
  279. } else {
  280. sheet.setStandardAddress(standardAddressMember.makeStandardAddress());
  281. sheet.setLivePlaceCombo(standardAddressMember.makeAddressCombo() + sheet.getLivePlace());
  282. }
  283. return ResultVoUtil.success(sheet);
  284. }
  285. private StandardAddressMember getStandardAddressMember(String bah) {
  286. StandardAddressMember member = dao.selectStandardAddressMember(bah);
  287. if (null != member) {
  288. return member;
  289. }
  290. String socialNo = dao.selectSocialNo(bah);
  291. if (null == socialNo || socialNo.trim().length() < 15) {
  292. return null;
  293. }
  294. Integer district;
  295. try {
  296. district = Integer.parseInt(socialNo.substring(0, 6));
  297. } catch (Exception e) {
  298. return null;
  299. }
  300. Region city = dao.selectParentRegion(district);
  301. if (null == city) {
  302. return null;
  303. }
  304. Region province = dao.selectParentRegion(city.getCode());
  305. if (null == province) {
  306. return null;
  307. }
  308. member = new StandardAddressMember();
  309. member.setCityCode(city.getCode());
  310. member.setCityName(city.getName());
  311. member.setDistrictCode(district);
  312. member.setDistrictName(dao.selectRegionName(district));
  313. member.setProvinceCode(province.getCode());
  314. member.setProvinceName(province.getName());
  315. return member;
  316. }
  317. private List<CaseFrontsheetDisdiag> getSheetDisDiags(String bah, int times, int status) {
  318. List<CaseFrontsheetDisdiag> disdiags = status == 1 ?
  319. dao.selectSignedSheetDiags(bah, times) : dao.getDisdiags(bah, times);
  320. if (disdiags.isEmpty()) {
  321. JSONObject emrPatientData = emrService.getEmrPatientData(bah, times);
  322. JSONArray diagList = emrPatientData.getJSONArray("出院诊断");
  323. if (null != diagList) {
  324. for (int i = 0; i < diagList.size(); i++) {
  325. JSONObject diagItem = diagList.getJSONObject(i);
  326. CaseFrontsheetDisdiag diag = dao.selectDiagInfoByCode(diagItem.getString("code"));
  327. if (null != diag) {
  328. diag.setNo(disdiags.size() + 1);
  329. disdiags.add(diag);
  330. }
  331. }
  332. }
  333. }
  334. while (disdiags.size() < 27) {
  335. disdiags.add(new CaseFrontsheetDisdiag());
  336. }
  337. return disdiags;
  338. }
  339. private List<CaseFrontsheetSurgery> getSheetSurgeries(String bah, int times, int status) {
  340. List<CaseFrontsheetSurgery> surgeries = status == 1 ?
  341. dao.selectSignedSheetSurgeries(bah, times) : dao.getSurgeries(bah, times);
  342. if (surgeries.isEmpty()) {
  343. JSONArray oprtList = emrService.getPatientSurgery(bah, times);
  344. for (int i = 0; i < oprtList.size(); i++) {
  345. JSONObject oprtItem = oprtList.getJSONObject(i);
  346. JSONObject oprtName = oprtItem.getJSONObject("手术名称");
  347. if (null == oprtName) {
  348. continue;
  349. }
  350. JSONArray oprtNameVals = oprtName.getJSONArray("value");
  351. if (null == oprtNameVals) {
  352. continue;
  353. }
  354. String opdate = oprtItem.getJSONObject("手术日期").getString("value");
  355. JSONArray oprtorArr = oprtItem.getJSONObject("术者").getJSONArray("value");
  356. JSONObject oprtor = null == oprtorArr ? new JSONObject() : oprtorArr.getJSONObject(0);
  357. JSONArray assis1Arr = oprtItem.getJSONObject("第一助手").getJSONArray("value");
  358. JSONObject assis1 = null == assis1Arr ? new JSONObject() : assis1Arr.getJSONObject(0);
  359. JSONArray assis2Arr = oprtItem.getJSONObject("第二助手").getJSONArray("value");
  360. JSONObject assis2 = null == assis2Arr ? new JSONObject() : assis2Arr.getJSONObject(0);
  361. JSONArray anstorArr = oprtItem.getJSONObject("麻醉医生").getJSONArray("value");
  362. JSONObject anstor = null == anstorArr ? new JSONObject() : anstorArr.getJSONObject(0);
  363. for (int j = 0; j < oprtNameVals.size(); j++) {
  364. JSONObject oprtCodeName = oprtNameVals.getJSONObject(j);
  365. CaseFrontsheetSurgery surgery = dao.selectSurgeryByCode(oprtCodeName.getString("code"));
  366. if (null != surgery) {
  367. surgery.setNo(surgeries.size() + 1);
  368. surgery.setDate(DateUtil.parse(opdate));
  369. surgery.setOperator(oprtor.getString("code"));
  370. surgery.setOperatorName(oprtor.getString("name"));
  371. surgery.setAssistantOne(assis1.getString("code"));
  372. surgery.setAssistantOneName(assis1.getString("name"));
  373. surgery.setAssistantTwo(assis2.getString("code"));
  374. surgery.setAssistantTwoName(assis2.getString("name"));
  375. surgery.setAnaesthesiaor(anstor.getString("code"));
  376. surgery.setAnaesthesiaorName(anstor.getString("name"));
  377. surgeries.add(surgery);
  378. }
  379. }
  380. }
  381. }
  382. while (surgeries.size() < 5) {
  383. surgeries.add(new CaseFrontsheetSurgery());
  384. }
  385. return surgeries;
  386. }
  387. private void mergeObject(CaseFrontsheetMain origin, CaseFrontsheetMain destination) {
  388. if (origin == null || destination == null) {
  389. return;
  390. }
  391. Field[] fields = destination.getClass().getDeclaredFields();
  392. for (Field field : fields) {
  393. try {
  394. field.setAccessible(true);
  395. Object valueD = field.get(origin);
  396. Object valueO = field.get(destination);
  397. if (null == valueO) {
  398. field.set(destination, valueD);
  399. }
  400. field.setAccessible(false);
  401. } catch (Exception e) {
  402. log.error("合并实体类出错", e);
  403. }
  404. }
  405. }
  406. private ResultVo<List<CodeName>> saveSheet(CaseFrontsheetMain sheet) {
  407. String bah = sheet.getBah();
  408. int times = sheet.getAdmissTimes();
  409. dao.updateAPatientMi(sheet);
  410. Integer[] addrs = sheet.getStandardAddress();
  411. if (null != addrs && addrs.length > 0) {
  412. Integer province = addrs[0];
  413. Integer city = addrs.length > 1 ? addrs[1] : null;
  414. Integer district = addrs.length > 2 ? addrs[2] : null;
  415. dao.updateAddressCascader(bah, province, city, district);
  416. }
  417. dao.updateZyActPatient(bah, times, sheet.getAutopsy(), sheet.getDiagConform1(),
  418. sheet.getDiagConform2(), sheet.getDiagConform3(), sheet.getDiagConform4(),
  419. sheet.getDiagConform5(), sheet.getHasSurgery(), sheet.getPathologicDiagStr(),
  420. sheet.getPathologicDiagCode(), sheet.getClinicDiagCode(), sheet.getClinicDiagStr());
  421. dao.updateZyInActPatient(bah, times, sheet.getAutopsy(), sheet.getDiagConform1(), sheet.getDiagConform2(),
  422. sheet.getDiagConform3(), sheet.getDiagConform4(), sheet.getDiagConform5(), sheet.getHasSurgery(),
  423. sheet.getPathologicDiagStr(), sheet.getPathologicDiagCode(), sheet.getClinicDiagCode(), sheet.getClinicDiagStr());
  424. dao.updateBatjBa1(sheet);
  425. dao.updateBatjBa2(sheet);
  426. dao.deleteOldDisdiag(bah, times);
  427. if (!sheet.getDisdiagList().isEmpty()) {
  428. List<CaseFrontsheetDisdiag> diags = sheet.getDisdiagList();
  429. for (int i = 0; i < diags.size(); i++) {
  430. CaseFrontsheetDisdiag item = diags.get(i);
  431. if (StringUtil.isBlank(item.getCode())) {
  432. break;
  433. }
  434. item.setNo(i + 1);
  435. item.setBah(bah);
  436. item.setTimes(times);
  437. dao.writeNewDisdiag(item);
  438. }
  439. }
  440. dao.deleteOldSurgeryRecord(bah, times);
  441. if (!sheet.getSurgeryList().isEmpty()) {
  442. List<CaseFrontsheetSurgery> surgeries = sheet.getSurgeryList();
  443. for (int i = 0; i < surgeries.size(); i++) {
  444. CaseFrontsheetSurgery item = surgeries.get(i);
  445. if (StringUtil.isBlank(item.getCode())) {
  446. break;
  447. }
  448. if (null == item.getDate()) {
  449. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "手术日期不能为空!");
  450. }
  451. item.setNo(i + 1);
  452. item.setBah(bah);
  453. item.setTimes(times);
  454. dao.writeNewZySurgeryRecord(item);
  455. }
  456. }
  457. return ResultVoUtil.success();
  458. }
  459. private ResultVo<List<CodeName>> archiveSheet(CaseFrontsheetMain sheet) {
  460. String staff = TokenUtil.getTokenUserId();
  461. List<Integer> roles = userDao.getUserRoles(staff);
  462. if (roles.contains(7) || roles.contains(1)) {
  463. String bah = sheet.getBah();
  464. int times = sheet.getAdmissTimes();
  465. sheet.setLateFlag(isLateSubmit(sheet.getDismissDate()) ? 1 : 0);
  466. //插入数据 SignDate 签收日期 在点击签收后 向数据库中插入
  467. sheet.setSignDate(new Date());
  468. sheet.setFileStatus(1);
  469. //判断是否已经插入过了
  470. Integer fileStatus = dao.selectFileStatus(sheet.getBah(), sheet.getAdmissTimes());
  471. if (null == fileStatus) {
  472. insertSheetData(sheet);
  473. basDao.updateActFileStatus(bah, times, 1);
  474. return ResultVoUtil.success();
  475. }
  476. if (fileStatus == 1) {
  477. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请勿重复签收 ( ˉ ⌓ ˉ ๑)");
  478. }
  479. dao.updateSignStatus(bah, times);
  480. basDao.updateActFileStatus(bah, times, 1);
  481. return ResultVoUtil.success();
  482. }
  483. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有签收首页的权限。");
  484. }
  485. private void insertSheetData(CaseFrontsheetMain sheet) {
  486. //在t_case_frontsheet_main表中插入 主体的内容
  487. dao.insert(sheet);
  488. //循环插主要的诊断
  489. QueryWrapper<CaseFrontsheetDisdiag> diagWrapper = new QueryWrapper<>();
  490. diagWrapper.eq("bah", sheet.getBah());
  491. diagWrapper.eq("times", sheet.getAdmissTimes());
  492. createdDao.delete(diagWrapper);
  493. for (CaseFrontsheetDisdiag caseFrontsheetDisdiag : sheet.getDisdiagList()) {
  494. caseFrontsheetDisdiag.setBah(sheet.getBah());
  495. caseFrontsheetDisdiag.setTimes(sheet.getAdmissTimes());
  496. if (caseFrontsheetDisdiag.getNo() != null) {
  497. createdDao.insert(caseFrontsheetDisdiag);
  498. }
  499. }
  500. //循环插入做过的手术
  501. QueryWrapper<CaseFrontsheetSurgery> surgeryWrapper = new QueryWrapper<>();
  502. surgeryWrapper.eq("bah", sheet.getBah());
  503. surgeryWrapper.eq("times", sheet.getAdmissTimes());
  504. basDao.delete(surgeryWrapper);
  505. for (CaseFrontsheetSurgery caseFrontsheetSurgery : sheet.getSurgeryList()) {
  506. caseFrontsheetSurgery.setBah(sheet.getBah());
  507. caseFrontsheetSurgery.setTimes(sheet.getAdmissTimes());
  508. if (caseFrontsheetSurgery.getNo() != null) {
  509. basDao.insert(caseFrontsheetSurgery);
  510. }
  511. }
  512. }
  513. @Transactional(rollbackFor = Exception.class)
  514. public synchronized ResultVo<String> unArchiveSheet(OpCaseFrontsheet param) {
  515. CaseFrontsheetMain sheet = param.getSheet();
  516. if (sheet.getFileStatus() == 0) {
  517. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未签收的病案首页无需解除签收!");
  518. }
  519. Map<String, Object> map = new HashMap<>();
  520. map.put("bah", sheet.getBah());
  521. map.put("admiss_times", sheet.getAdmissTimes());
  522. dao.deleteByMap(map);
  523. map.put("times", map.remove("admiss_times"));
  524. createdDao.deleteByMap(map);
  525. basDao.deleteByMap(map);
  526. log.info("解除签收状态, 操作员:{} >>> 住院号:{}, 住院次数:{}",
  527. param.getStaffId(), sheet.getBah(), sheet.getAdmissTimes());
  528. basDao.updateActFileStatus(sheet.getBah(), sheet.getAdmissTimes(), 0);
  529. dao.writeBaOpLog(param.getOpType(), param.getStaffId(), sheet.getBah(), sheet.getAdmissTimes());
  530. log.info("写入病案操作日志, 操作员:{} >>> 住院号:{}, 住院次数:{}, 操作编码:{}",
  531. param.getStaffId(), sheet.getBah(), sheet.getAdmissTimes(), param.getOpType());
  532. return ResultVoUtil.success("已成功解除签收。");
  533. }
  534. private JSONObject powersiQualityCheck(CaseFrontsheetMain sheet) {
  535. JSONObject obj = new JSONObject();
  536. obj.put("functionId", "100138");
  537. JSONObject baseinfo = new JSONObject();
  538. baseinfo.put("name", sheet.getName());
  539. baseinfo.put("age", sheet.getAge());
  540. baseinfo.put("sex_id", sheet.getSex());
  541. Integer agedays = sheet.getAgeDays();
  542. baseinfo.put("nwb_age", agedays);
  543. baseinfo.put("out_hosp_id", FilterUtil.filterDismissWay(sheet.getZyDismissWay()));
  544. baseinfo.put("is_autopsy_id", sheet.getAutopsy());
  545. JSONObject inputParam = new JSONObject();
  546. inputParam.put("baseInfo", baseinfo);
  547. JSONArray hsptzdDagnsInfo = new JSONArray();
  548. for (CaseFrontsheetDisdiag diag : sheet.getDisdiagList()) {
  549. if (null == diag.getNo()) {
  550. break;
  551. }
  552. JSONObject itm = new JSONObject();
  553. itm.put("icd_code", diag.getCode());
  554. itm.put("dagns_type", diag.getNo() == 1 ? 1 : 2);
  555. itm.put("disease_name", diag.getName());
  556. itm.put("order", diag.getNo());
  557. hsptzdDagnsInfo.add(itm);
  558. }
  559. inputParam.put("hsptzdDagnsInfo", hsptzdDagnsInfo);
  560. JSONArray hsptzdOprtInfo = new JSONArray();
  561. for (CaseFrontsheetSurgery surgery : sheet.getSurgeryList()) {
  562. if (null == surgery.getNo()) {
  563. break;
  564. }
  565. JSONObject itm = new JSONObject();
  566. itm.put("oprt_code", surgery.getCode());
  567. itm.put("oprt_name", surgery.getName());
  568. itm.put("oprt_type", surgery.getNo() == 1 ? 1 : 2);
  569. itm.put("order", surgery.getNo());
  570. hsptzdOprtInfo.add(itm);
  571. }
  572. inputParam.put("hsptzdOprtInfo", hsptzdOprtInfo);
  573. obj.put("inputParam", inputParam);
  574. try {
  575. JSONObject result = srvc.setlQualityControl(obj);
  576. log.info("\n病案质控接口:\n参数:{}\n结果:{}", obj, result);
  577. return result;
  578. } catch (Exception e) {
  579. log.error("创智诊断校验访问失败:http://172.16.32.183:8917/mmg-transceiver/interfaceFactory/call");
  580. return null;
  581. }
  582. }
  583. public ResultVo<Map<String, List<CodeName>>> printVerification(OpCaseFrontsheet param) {
  584. CaseFrontsheetMain sheet = param.getSheet();
  585. Integer status = dao.selectFileStatus(sheet.getBah(), sheet.getAdmissTimes());
  586. if (null != status && status == 1) {
  587. String userDept = dao.selectUserDept(TokenUtil.getTokenUserId());
  588. if (!userDept.equals("2100000")) {
  589. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "已最终归档病案首页无法打印!");
  590. }
  591. }
  592. dao.deleteSheetInfo(sheet.getBah(), sheet.getAdmissTimes());
  593. ResultVo<List<CodeName>> save = saveSheet(param.getSheet());
  594. if (save.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  595. Map<String, List<CodeName>> map = new HashMap<>();
  596. map.put("force", save.getData());
  597. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "校验未通过。", map);
  598. }
  599. sheet.setIsDoctorPrint(true);
  600. sheet.setAddressMember(getStandardAddress(sheet.getStandardAddress()));
  601. Map<String, List<CodeName>> warnings = beginAnalyzeSheet(sheet, param.getOpType());
  602. if (warnings.get("force").isEmpty()) {
  603. saveSheet(sheet);
  604. if (param.getPage() == 2) {
  605. sheet.setFileStatus(0);
  606. insertSheetData(sheet);
  607. }
  608. if (warnings.get("advice").isEmpty()) {
  609. return ResultVoUtil.success();
  610. }
  611. }
  612. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "校验未通过。", warnings);
  613. }
  614. public ResultVo<List<CodeName>> saveVerify(OpCaseFrontsheet info) {
  615. CaseFrontsheetMain sheet = info.getSheet();
  616. if (sheet.getFileStatus() == 1 && !userDao.getUserRoles(TokenUtil.getTokenUserId()).contains(7)) {
  617. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "已签收的病案首页无法保存,如需保存,请联系病案室对此病案解除签收。");
  618. }
  619. int optype = info.getOpType();
  620. sheet.setAddressMember(getStandardAddress(sheet.getStandardAddress()));
  621. List<CodeName> message = optype == 1 ? VerifyCaseFrontSheet.getInstance().saveVerify(sheet) :
  622. VerifyCaseFrontSheet.getInstance().printVerify(sheet, optype);
  623. if (message.isEmpty()) {
  624. final String bah = sheet.getBah();
  625. final int times = sheet.getAdmissTimes();
  626. dao.writeBaOpLog(optype, info.getStaffId(), bah, times);
  627. return optype == 1 ? saveSheet(sheet) : archiveSheet(sheet);
  628. }
  629. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "校验未通过。", message);
  630. }
  631. private Map<String, List<CodeName>> beginAnalyzeSheet(CaseFrontsheetMain sheet, int optype) {
  632. List<CodeName> force = VerifyCaseFrontSheet.getInstance().printVerify(sheet, optype);
  633. CaseFrontsheetDisdiag disdiag = sheet.getDisdiagList().get(0);
  634. List<CodeName> advice = VerifyCaseFrontSheet.getInstance().adviseVerification(sheet.getSocialNo(), disdiag.getCode());
  635. setlQualityControlPass(sheet, advice);
  636. surgeryChargesVerify(sheet, advice);
  637. JSONObject powersi = powersiQualityCheck(sheet);
  638. if (null != powersi) {
  639. JSONObject responseEntity = powersi.getJSONObject("responseEntity");
  640. if (null != responseEntity) {
  641. JSONArray retarr = responseEntity.getJSONArray("newSettleMemInfo");
  642. if (null != retarr && retarr.size() > 0) {
  643. for (int i = 0; i < retarr.size(); i++) {
  644. advice.add(new CodeName("", retarr.getJSONObject(i).getString("result_msg")));
  645. }
  646. }
  647. }
  648. }
  649. Map<String, List<CodeName>> map = new HashMap<>();
  650. map.put("force", force);
  651. map.put("advice", advice);
  652. return map;
  653. }
  654. public ResultVo<Map<String, List<CodeName>>> sheetVerification(SheetOverview view) {
  655. if (StringUtil.isBlank(view.getBah()) || null == view.getTimes() || null == view.getInOutFlag()) {
  656. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "住院号、住院次数、在院状态不能为空。");
  657. }
  658. CaseFrontsheetMain sheet = getPatientInfo(view).getData();
  659. if (null == sheet) {
  660. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到病案数据。");
  661. }
  662. Map<String, List<CodeName>> warnings = beginAnalyzeSheet(sheet, 4);
  663. List<CodeName> forces = warnings.get("force");
  664. if (view.getInOutFlag() == 1) {
  665. forces.removeIf(item -> Objects.equals(item.getCode(), "dismissDate"));
  666. forces.removeIf(item -> Objects.equals(item.getCode(), "pathologicDiagCode"));
  667. }
  668. if (forces.isEmpty()) {
  669. Integer status = dao.selectFileStatus(sheet.getBah(), sheet.getAdmissTimes());
  670. status = null == status ? -1 : status;
  671. if (status == 0) {
  672. dao.deleteSheetInfo(view.getBah(), view.getTimes());
  673. }
  674. if (status < 1) {
  675. sheet.setFileStatus(0);
  676. insertSheetData(sheet);
  677. }
  678. }
  679. return ResultVoUtil.success(warnings);
  680. }
  681. public ResultVo<List<YiBaoDisdiag>> getYbDiags(String bah, int times) {
  682. List<YiBaoDisdiag> diags = dao.getYbDiags(bah, times);
  683. return ResultVoUtil.success(diags);
  684. }
  685. @Transactional
  686. public ResultVo<String> saveYbDiags(SaveYbDiagParam param) {
  687. dao.deleteOldYbDiag(param.getBah(), param.getTimes());
  688. List<String> diagCodes = new ArrayList<>();
  689. for (int i = 0; i < param.getYbDiags().size(); i++) {
  690. YiBaoDisdiag diag = param.getYbDiags().get(i);
  691. if (StringUtil.isBlank(diag.getCode())) {
  692. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】诊断编码不能为空!");
  693. }
  694. if (StringUtil.isBlank(diag.getName())) {
  695. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】诊断名称不能为空!");
  696. }
  697. if (StringUtil.isBlank(diag.getCyzg())) {
  698. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】出院转归不能为空!");
  699. }
  700. if (null == diag.getSiDiagType()) {
  701. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】诊断类别不能为空!");
  702. }
  703. if (diagCodes.contains(diag.getCode())) {
  704. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断编码:" + diag.getCode() + "】请勿填入重复的诊断!");
  705. }
  706. diagCodes.add(diag.getCode());
  707. diag.setNo(i + 1);
  708. diag.setBah(param.getBah());
  709. diag.setTimes(param.getTimes());
  710. dao.insertNewYbDiag(diag);
  711. }
  712. return ResultVoUtil.success();
  713. }
  714. public ResultVo<List<SheetOverview>> advanceSearch(AdvanceSearchParam param) {
  715. return ResultVoUtil.success(dao.advanceSearch(param));
  716. }
  717. public ResultVo<String> fetchSsfz(String code, String bah, Integer times) {
  718. DisefamilyGrade disefamilyGrade = dao.selectDisefamilyGrade(code);
  719. if (null == disefamilyGrade) {
  720. return ResultVoUtil.success("无对照的病种。");
  721. }
  722. boolean hasModified = dao.selectModified(bah, times) > 0;
  723. List<String> surgeries = hasModified ? dao.selectPatientSurgeryCodes(bah, times, "batj_ba4_modify")
  724. : dao.selectPatientSurgeryCodes(bah, times, "batj_ba4");
  725. if (ListUtil.isBlank(surgeries)) {
  726. return ResultVoUtil.success("有对照的非手术分值:" + disefamilyGrade.getNoneOprnGrade());
  727. }
  728. List<OprnDisefamilyGrade> oprnGrades = dao.selectOperationDisefamilies(disefamilyGrade.getDisefamilyCode());
  729. int ssfz = 0;
  730. for (OprnDisefamilyGrade oprn : oprnGrades) {
  731. if (surgeries.contains(oprn.getOprnCode())) {
  732. if (oprn.getOprnGrade() > ssfz) {
  733. ssfz = oprn.getOprnGrade();
  734. }
  735. }
  736. }
  737. if (ssfz != 0) {
  738. return ResultVoUtil.success("有对照的手术分值:" + ssfz);
  739. }
  740. return ResultVoUtil.success("有对照的非手术分值:" + disefamilyGrade.getNoneOprnGrade());
  741. }
  742. private boolean isLateSubmit(Date dismissDate) {
  743. long days = (System.currentTimeMillis() - dismissDate.getTime()) / 1000 / (3600 * 24);
  744. return (int) days > 7;
  745. }
  746. public void increaseDiagWeight(String code) {
  747. dao.increaseDiagWeight(code);
  748. }
  749. public ResultVo<CodeName> selectSiDiagByBaDiag(String code) {
  750. CodeName result = dao.selectSiDiagByBaDiag(code);
  751. if (null == result) {
  752. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到此诊断的医保对照诊断。");
  753. }
  754. return ResultVoUtil.success(result);
  755. }
  756. private StandardAddressMember getStandardAddress(Integer[] addrs) {
  757. if (null == addrs || addrs.length < 3) {
  758. return null;
  759. }
  760. return dao.selectStandardAddressMember2(addrs[0], addrs[1], addrs[2]);
  761. }
  762. private void setlQualityControlPass(CaseFrontsheetMain sheet, List<CodeName> messages) {
  763. String patNo = sheet.getBah();
  764. int times = sheet.getAdmissTimes();
  765. String admdvs = dao.selectSetlInsuplcAdmdvs(patNo, times);
  766. if (StringUtil.notBlank(admdvs) && admdvs.startsWith("43")) {
  767. Integer qualityPassed = dao.qualityPass(patNo, times);
  768. if (null == qualityPassed || qualityPassed != 1) {
  769. messages.add(new CodeName("", "此患者医保结算清单质控未通过!"));
  770. }
  771. }
  772. }
  773. private void surgeryChargesVerify(CaseFrontsheetMain sheet, List<CodeName> messages) {
  774. List<CaseFrontsheetSurgery> surgeries = sheet.getSurgeryList();
  775. if (null != surgeries && !surgeries.isEmpty()) {
  776. List<HisWjwMatchEntity> surgeryChargeCode = dao.selectSurgeryChargeCode(surgeries);
  777. for (HisWjwMatchEntity entity : surgeryChargeCode) {
  778. if (StringUtil.notBlank(entity.getWjwCode())) {
  779. entity.setChargeCode(entity.getWjwCode().split("\\^"));
  780. entity.setChargeName(entity.getWjwName().split("\\^"));
  781. Integer chargeSumamt = dao.selectChargeSumamt(sheet.getBah(), sheet.getAdmissTimes(), entity.getChargeCode());
  782. if (null == chargeSumamt || chargeSumamt < 1) {
  783. String charges = entity.getWjwName().replaceAll("\\^", ",");
  784. messages.add(new CodeName("surgeryTable", "患者有手术【" + entity.getName() +
  785. "】,但没有找到对应的收费项目【" + charges + "】。"));
  786. }
  787. }
  788. }
  789. }
  790. }
  791. public ResultVo<String> frontsheetQualityCheck(CaseFrontsheetMain sheet) {
  792. List<CodeName> anstWays = dao.selectZdAnstWays();
  793. Map<String, CodeName> anstWaysMap = new HashMap<>();
  794. for (CodeName item : anstWays) {
  795. anstWaysMap.put(item.getCode(), item);
  796. }
  797. List<CodeName> countries = dao.selectZdCountries();
  798. Map<String, CodeName> countriesMap = new HashMap<>();
  799. for (CodeName item : countries) {
  800. countriesMap.put(item.getCode(), item);
  801. }
  802. List<CodeName> nations = dao.selectZdNations();
  803. Map<String, CodeName> nationsMap = new HashMap<>();
  804. for (CodeName item : nations) {
  805. nationsMap.put(item.getCode(), item);
  806. }
  807. QualityCheckParams params = new QualityCheckParams();
  808. params.setBaseInfo(FrontSheetUtil.fillBaseInfoFromSheet(sheet, countriesMap, nationsMap));
  809. params.setDiseInfoList(FrontSheetUtil.fillDiseInfoFromSheet(sheet.getDisdiagList()));
  810. params.setOprtInfoList(FrontSheetUtil.fillOprtInfoFromSheet(sheet.getSurgeryList(), anstWaysMap));
  811. JSONObject jsonParams = JSONObject.parseObject(JSON.toJSONString(params, SerializerFeature.WriteNullStringAsEmpty));
  812. String url = "http://172.16.32.126:8080/drg_web/drgGroupThird/V2/groupAndQuality.action";
  813. RestTemplate template = new RestTemplate();
  814. String result = template.postForObject(url, jsonParams, String.class);
  815. result = "http://172.16.32.126:8080" + result;
  816. String url2 = "http://172.16.32.126:8080/drg_web/drgGroupThird/V2/drgGroupAndQuality.action";
  817. String result2 = template.postForObject(url2, jsonParams, String.class);
  818. log.info("病案质控:\n参数:{}\n结果:{}", jsonParams, result2);
  819. return ResultVoUtil.success(result);
  820. }
  821. public ResultVo<String> isMedinsSetl(String patNo, Integer times) {
  822. String admdvs = dao.selectSetlInsuplcAdmdvs(patNo, times);
  823. if (StringUtil.isBlank(admdvs)) {
  824. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "自费及工伤患者无需进行医保结算单质控。");
  825. }
  826. if (!admdvs.startsWith("43")) {
  827. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "跨省异地患者无需进行医保结算单质控。");
  828. }
  829. return ResultVoUtil.success();
  830. }
  831. }