CaseFrontSheetMainService.java 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  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.emr.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. if (null == sheet.getDismissDate()) {
  215. Date dismissDate = dao.getDismissDateFromYzActOrder("yz_act_order", bah, times);
  216. if (null == dismissDate) {
  217. dismissDate = dao.getDismissDateFromYzActOrder("yz_inact_order", bah, times);
  218. }
  219. sheet.setDismissDate(dismissDate);
  220. Integer days = DateUtil.daysBetween(dismissDate, sheet.getAdmissDate());
  221. sheet.setAdmissDays(0 == days ? "1" : String.valueOf(days));
  222. }
  223. return ResultVoUtil.success(sheet);
  224. }
  225. int flag = overview.getInOutFlag();
  226. if (flag == 2) {
  227. flag = dao.selectActCount(bah, times) > 0 ? 1 : 2;
  228. }
  229. sheet = dao.getAPatientMi(bah);
  230. CaseFrontsheetMain sheet1 = dao.getZyLedgerFile(bah, times);
  231. CaseFrontsheetMain sheet2 = flag == 1 ? dao.getZyActPatient("zy_actpatient", "yz_act_order", bah, times) :
  232. dao.getZyActPatient("zy_inactpatient", "yz_inact_order", bah, times);
  233. if (null == sheet2) {
  234. sheet2 = flag == 1 ? dao.getZyActPatient("zy_inactpatient", "yz_inact_order", bah, times) :
  235. dao.getZyActPatient("zy_actpatient", "yz_act_order", bah, times);
  236. }
  237. sheet.setAge(DateUtil.calculateAge(sheet.getBirthDate(), sheet2.getAdmissDate()));
  238. if (null != sheet.getAge() && sheet.getAge() == 0) {
  239. sheet.setAgeDays(DateUtil.calculateNewBornAge(sheet.getBirthDate(), sheet2.getAdmissDate()));
  240. }
  241. if (StringUtil.isBlank(sheet2.getMedType())) {
  242. String injurySerialNo = dao.selectInjurySerialNo(bah, times);
  243. if (StringUtil.notBlank(injurySerialNo)) {
  244. sheet2.setMedType("42");
  245. }
  246. }
  247. sheet2.setMedTypeName(MedType.getName(sheet2.getMedType()));
  248. sheet2.setInsutype(Insutype.getName(sheet2.getInsutype()));
  249. final int hasInfant = dao.getInfant(bah, times);
  250. sheet2.setHasInfant(String.valueOf(hasInfant));
  251. if (null == sheet2.getDismissDate()) {
  252. final Date dismissDate = flag == 1 ?
  253. dao.getDismissDateFromYzActOrder("yz_inact_order", bah, times)
  254. : dao.getDismissDateFromYzActOrder("yz_act_order", bah, times);
  255. sheet2.setDismissDate(dismissDate);
  256. }
  257. CaseFrontsheetMain sheet3 = dao.getBatjBa1(bah, times);
  258. if (sheet3 == null && dao.isBatjBa1Exist(bah, times) == 0) {
  259. dao.createBatjBa1(bah, times, sheet.getName(), sheet2.getAdmissDate(),
  260. sheet2.getAdmissDept(), sheet2.getAdmissWard());
  261. log.info("insert batjBa1>>> " + bah + ", " + times);
  262. }
  263. CaseFrontsheetMain sheet4 = flag == 1 ? dao.getBatjBa2ForInPatient(bah, times) :
  264. dao.getBatjBa2ForOutPatient(bah, times);
  265. if (sheet4 == null && dao.isBatjBa2Exist(bah, times) == 0) {
  266. dao.createBatjBa2(bah, times);
  267. log.info("insert batjBa2>>> " + bah + ", " + times);
  268. }
  269. mergeObject(sheet1, sheet);
  270. mergeObject(sheet2, sheet);
  271. mergeObject(sheet3, sheet);
  272. mergeObject(sheet4, sheet);
  273. if (dao.getDismissOrder(bah, times) > 0) {
  274. sheet.setZyDismissWay("0");
  275. }
  276. if (dao.getDeathOrder(bah, times) > 0) {
  277. sheet.setZyDismissWay("4");
  278. }
  279. Integer days = DateUtil.daysBetween(sheet.getDismissDate(), sheet.getAdmissDate());
  280. sheet.setAdmissDays(0 == days ? "1" : String.valueOf(days));
  281. if (null == sheet.getQualityControlDate()) {
  282. sheet.setQualityControlDate(new Date());
  283. }
  284. sheet.setDisdiagList(getSheetDisDiags(bah, times, 0));
  285. sheet.setSurgeryList(getSheetSurgeries(bah, times, 0));
  286. if (null == standardAddressMember) {
  287. sheet.setLivePlaceCombo(sheet.getLivePlace());
  288. } else {
  289. sheet.setStandardAddress(standardAddressMember.makeStandardAddress());
  290. sheet.setLivePlaceCombo(standardAddressMember.makeAddressCombo() + sheet.getLivePlace());
  291. }
  292. return ResultVoUtil.success(sheet);
  293. }
  294. private StandardAddressMember getStandardAddressMember(String bah) {
  295. StandardAddressMember member = dao.selectStandardAddressMember(bah);
  296. if (null != member) {
  297. return member;
  298. }
  299. String socialNo = dao.selectSocialNo(bah);
  300. if (null == socialNo || socialNo.trim().length() < 15) {
  301. return null;
  302. }
  303. Integer district;
  304. try {
  305. district = Integer.parseInt(socialNo.substring(0, 6));
  306. } catch (Exception e) {
  307. return null;
  308. }
  309. Region city = dao.selectParentRegion(district);
  310. if (null == city) {
  311. return null;
  312. }
  313. Region province = dao.selectParentRegion(city.getCode());
  314. if (null == province) {
  315. return null;
  316. }
  317. member = new StandardAddressMember();
  318. member.setCityCode(city.getCode());
  319. member.setCityName(city.getName());
  320. member.setDistrictCode(district);
  321. member.setDistrictName(dao.selectRegionName(district));
  322. member.setProvinceCode(province.getCode());
  323. member.setProvinceName(province.getName());
  324. return member;
  325. }
  326. private List<CaseFrontsheetDisdiag> getSheetDisDiags(String bah, int times, int status) {
  327. List<CaseFrontsheetDisdiag> disdiags = status == 1 ?
  328. dao.selectSignedSheetDiags(bah, times) : dao.getDisdiags(bah, times);
  329. if (disdiags.isEmpty()) {
  330. JSONObject emrPatientData = emrService.getEmrPatientData(bah, times);
  331. JSONArray diagList;
  332. try {
  333. diagList = emrPatientData.getJSONArray("出院诊断");
  334. } catch (Exception e) {
  335. diagList = null;
  336. }
  337. if (null != diagList) {
  338. for (int i = 0; i < diagList.size(); i++) {
  339. JSONObject diagItem = diagList.getJSONObject(i);
  340. CaseFrontsheetDisdiag diag = dao.selectDiagInfoByCode(diagItem.getString("code"));
  341. if (null != diag) {
  342. diag.setNo(disdiags.size() + 1);
  343. disdiags.add(diag);
  344. }
  345. }
  346. }
  347. }
  348. while (disdiags.size() < 27) {
  349. disdiags.add(new CaseFrontsheetDisdiag());
  350. }
  351. return disdiags;
  352. }
  353. private List<CaseFrontsheetSurgery> getSheetSurgeries(String bah, int times, int status) {
  354. List<CaseFrontsheetSurgery> surgeries = status == 1 ?
  355. dao.selectSignedSheetSurgeries(bah, times) : dao.getSurgeries(bah, times);
  356. if (surgeries.isEmpty()) {
  357. JSONArray oprtList = emrService.getPatientSurgery(bah, times);
  358. for (int i = 0; i < oprtList.size(); i++) {
  359. JSONObject oprtItem = oprtList.getJSONObject(i);
  360. JSONObject oprtName;
  361. try {
  362. oprtName = oprtItem.getJSONObject("手术名称");
  363. } catch (Exception e) {
  364. continue;
  365. }
  366. if (null == oprtName) {
  367. continue;
  368. }
  369. JSONArray oprtNameVals = oprtName.getJSONArray("value");
  370. if (null == oprtNameVals) {
  371. continue;
  372. }
  373. String opdate = oprtItem.getJSONObject("手术日期").getString("value");
  374. JSONArray oprtorArr = oprtItem.getJSONObject("术者").getJSONArray("value");
  375. JSONObject oprtor = null == oprtorArr ? new JSONObject() : oprtorArr.getJSONObject(0);
  376. JSONArray assis1Arr = oprtItem.getJSONObject("第一助手").getJSONArray("value");
  377. JSONObject assis1 = null == assis1Arr ? new JSONObject() : assis1Arr.getJSONObject(0);
  378. JSONArray assis2Arr = oprtItem.getJSONObject("第二助手").getJSONArray("value");
  379. JSONObject assis2 = null == assis2Arr ? new JSONObject() : assis2Arr.getJSONObject(0);
  380. JSONArray anstorArr = oprtItem.getJSONObject("麻醉医生").getJSONArray("value");
  381. JSONObject anstor = null == anstorArr ? new JSONObject() : anstorArr.getJSONObject(0);
  382. for (int j = 0; j < oprtNameVals.size(); j++) {
  383. JSONObject oprtCodeName = oprtNameVals.getJSONObject(j);
  384. CaseFrontsheetSurgery surgery = dao.selectSurgeryByCode(oprtCodeName.getString("code"));
  385. if (null != surgery) {
  386. surgery.setNo(surgeries.size() + 1);
  387. surgery.setDate(DateUtil.parse(opdate));
  388. surgery.setOperator(oprtor.getString("code"));
  389. surgery.setOperatorName(oprtor.getString("name"));
  390. surgery.setAssistantOne(assis1.getString("code"));
  391. surgery.setAssistantOneName(assis1.getString("name"));
  392. surgery.setAssistantTwo(assis2.getString("code"));
  393. surgery.setAssistantTwoName(assis2.getString("name"));
  394. surgery.setAnaesthesiaor(anstor.getString("code"));
  395. surgery.setAnaesthesiaorName(anstor.getString("name"));
  396. surgeries.add(surgery);
  397. }
  398. }
  399. }
  400. }
  401. while (surgeries.size() < 5) {
  402. surgeries.add(new CaseFrontsheetSurgery());
  403. }
  404. return surgeries;
  405. }
  406. private void mergeObject(CaseFrontsheetMain origin, CaseFrontsheetMain destination) {
  407. if (origin == null || destination == null) {
  408. return;
  409. }
  410. Field[] fields = destination.getClass().getDeclaredFields();
  411. for (Field field : fields) {
  412. try {
  413. field.setAccessible(true);
  414. Object valueD = field.get(origin);
  415. Object valueO = field.get(destination);
  416. if (null == valueO) {
  417. field.set(destination, valueD);
  418. }
  419. field.setAccessible(false);
  420. } catch (Exception e) {
  421. log.error("合并实体类出错", e);
  422. }
  423. }
  424. }
  425. private ResultVo<List<CodeName>> saveSheet(CaseFrontsheetMain sheet) {
  426. String bah = sheet.getBah();
  427. int times = sheet.getAdmissTimes();
  428. dao.updateAPatientMi(sheet);
  429. Integer[] addrs = sheet.getStandardAddress();
  430. if (null != addrs && addrs.length > 0) {
  431. Integer province = addrs[0];
  432. Integer city = addrs.length > 1 ? addrs[1] : null;
  433. Integer district = addrs.length > 2 ? addrs[2] : null;
  434. dao.updateAddressCascader(bah, province, city, district);
  435. }
  436. dao.updateZyActPatient(bah, times, sheet.getAutopsy(), sheet.getDiagConform1(),
  437. sheet.getDiagConform2(), sheet.getDiagConform3(), sheet.getDiagConform4(),
  438. sheet.getDiagConform5(), sheet.getHasSurgery(), sheet.getPathologicDiagStr(),
  439. sheet.getPathologicDiagCode(), sheet.getClinicDiagCode(), sheet.getClinicDiagStr());
  440. dao.updateZyInActPatient(bah, times, sheet.getAutopsy(), sheet.getDiagConform1(), sheet.getDiagConform2(),
  441. sheet.getDiagConform3(), sheet.getDiagConform4(), sheet.getDiagConform5(), sheet.getHasSurgery(),
  442. sheet.getPathologicDiagStr(), sheet.getPathologicDiagCode(), sheet.getClinicDiagCode(), sheet.getClinicDiagStr());
  443. dao.updateBatjBa1(sheet);
  444. dao.updateBatjBa2(sheet);
  445. dao.deleteOldDisdiag(bah, times);
  446. if (!sheet.getDisdiagList().isEmpty()) {
  447. List<CaseFrontsheetDisdiag> diags = sheet.getDisdiagList();
  448. for (int i = 0; i < diags.size(); i++) {
  449. CaseFrontsheetDisdiag item = diags.get(i);
  450. if (StringUtil.isBlank(item.getCode())) {
  451. break;
  452. }
  453. item.setNo(i + 1);
  454. item.setBah(bah);
  455. item.setTimes(times);
  456. dao.writeNewDisdiag(item);
  457. }
  458. }
  459. dao.deleteOldSurgeryRecord(bah, times);
  460. if (!sheet.getSurgeryList().isEmpty()) {
  461. List<CaseFrontsheetSurgery> surgeries = sheet.getSurgeryList();
  462. for (int i = 0; i < surgeries.size(); i++) {
  463. CaseFrontsheetSurgery item = surgeries.get(i);
  464. if (StringUtil.isBlank(item.getCode())) {
  465. break;
  466. }
  467. if (null == item.getDate()) {
  468. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "手术日期不能为空!");
  469. }
  470. item.setNo(i + 1);
  471. item.setBah(bah);
  472. item.setTimes(times);
  473. dao.writeNewZySurgeryRecord(item);
  474. }
  475. }
  476. return ResultVoUtil.success();
  477. }
  478. private ResultVo<List<CodeName>> archiveSheet(CaseFrontsheetMain sheet) {
  479. String staff = TokenUtil.getTokenUserId();
  480. List<Integer> roles = userDao.getUserRoles(staff);
  481. if (roles.contains(7) || roles.contains(1)) {
  482. String bah = sheet.getBah();
  483. int times = sheet.getAdmissTimes();
  484. sheet.setLateFlag(isLateSubmit(sheet.getDismissDate()) ? 1 : 0);
  485. //插入数据 SignDate 签收日期 在点击签收后 向数据库中插入
  486. sheet.setSignDate(new Date());
  487. sheet.setFileStatus(1);
  488. //判断是否已经插入过了
  489. Integer fileStatus = dao.selectFileStatus(sheet.getBah(), sheet.getAdmissTimes());
  490. if (null == fileStatus) {
  491. insertSheetData(sheet);
  492. basDao.updateActFileStatus(bah, times, 1);
  493. return ResultVoUtil.success();
  494. }
  495. if (fileStatus == 1) {
  496. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请勿重复签收 ( ˉ ⌓ ˉ ๑)");
  497. }
  498. dao.updateSignStatus(bah, times);
  499. basDao.updateActFileStatus(bah, times, 1);
  500. return ResultVoUtil.success();
  501. }
  502. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有签收首页的权限。");
  503. }
  504. private void insertSheetData(CaseFrontsheetMain sheet) {
  505. //在t_case_frontsheet_main表中插入 主体的内容
  506. dao.insert(sheet);
  507. //循环插主要的诊断
  508. QueryWrapper<CaseFrontsheetDisdiag> diagWrapper = new QueryWrapper<>();
  509. diagWrapper.eq("bah", sheet.getBah());
  510. diagWrapper.eq("times", sheet.getAdmissTimes());
  511. createdDao.delete(diagWrapper);
  512. for (CaseFrontsheetDisdiag caseFrontsheetDisdiag : sheet.getDisdiagList()) {
  513. caseFrontsheetDisdiag.setBah(sheet.getBah());
  514. caseFrontsheetDisdiag.setTimes(sheet.getAdmissTimes());
  515. if (caseFrontsheetDisdiag.getNo() != null) {
  516. createdDao.insert(caseFrontsheetDisdiag);
  517. }
  518. }
  519. //循环插入做过的手术
  520. QueryWrapper<CaseFrontsheetSurgery> surgeryWrapper = new QueryWrapper<>();
  521. surgeryWrapper.eq("bah", sheet.getBah());
  522. surgeryWrapper.eq("times", sheet.getAdmissTimes());
  523. basDao.delete(surgeryWrapper);
  524. for (CaseFrontsheetSurgery caseFrontsheetSurgery : sheet.getSurgeryList()) {
  525. caseFrontsheetSurgery.setBah(sheet.getBah());
  526. caseFrontsheetSurgery.setTimes(sheet.getAdmissTimes());
  527. if (caseFrontsheetSurgery.getNo() != null) {
  528. basDao.insert(caseFrontsheetSurgery);
  529. }
  530. }
  531. }
  532. @Transactional(rollbackFor = Exception.class)
  533. public synchronized ResultVo<String> unArchiveSheet(OpCaseFrontsheet param) {
  534. CaseFrontsheetMain sheet = param.getSheet();
  535. if (sheet.getFileStatus() == 0) {
  536. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未签收的病案首页无需解除签收!");
  537. }
  538. Map<String, Object> map = new HashMap<>();
  539. map.put("bah", sheet.getBah());
  540. map.put("admiss_times", sheet.getAdmissTimes());
  541. dao.deleteByMap(map);
  542. map.put("times", map.remove("admiss_times"));
  543. createdDao.deleteByMap(map);
  544. basDao.deleteByMap(map);
  545. log.info("解除签收状态, 操作员:{} >>> 住院号:{}, 住院次数:{}",
  546. param.getStaffId(), sheet.getBah(), sheet.getAdmissTimes());
  547. basDao.updateActFileStatus(sheet.getBah(), sheet.getAdmissTimes(), 0);
  548. dao.writeBaOpLog(param.getOpType(), param.getStaffId(), sheet.getBah(), sheet.getAdmissTimes());
  549. log.info("写入病案操作日志, 操作员:{} >>> 住院号:{}, 住院次数:{}, 操作编码:{}",
  550. param.getStaffId(), sheet.getBah(), sheet.getAdmissTimes(), param.getOpType());
  551. return ResultVoUtil.success("已成功解除签收。");
  552. }
  553. private JSONObject powersiQualityCheck(CaseFrontsheetMain sheet) {
  554. JSONObject obj = new JSONObject();
  555. obj.put("functionId", "100138");
  556. JSONObject baseinfo = new JSONObject();
  557. baseinfo.put("name", sheet.getName());
  558. baseinfo.put("age", sheet.getAge());
  559. baseinfo.put("sex_id", sheet.getSex());
  560. Integer agedays = sheet.getAgeDays();
  561. baseinfo.put("nwb_age", agedays);
  562. baseinfo.put("out_hosp_id", FilterUtil.filterDismissWay(sheet.getZyDismissWay()));
  563. baseinfo.put("is_autopsy_id", sheet.getAutopsy());
  564. JSONObject inputParam = new JSONObject();
  565. inputParam.put("baseInfo", baseinfo);
  566. JSONArray hsptzdDagnsInfo = new JSONArray();
  567. for (CaseFrontsheetDisdiag diag : sheet.getDisdiagList()) {
  568. if (null == diag.getNo()) {
  569. break;
  570. }
  571. JSONObject itm = new JSONObject();
  572. itm.put("icd_code", diag.getCode());
  573. itm.put("dagns_type", diag.getNo() == 1 ? 1 : 2);
  574. itm.put("disease_name", diag.getName());
  575. itm.put("order", diag.getNo());
  576. hsptzdDagnsInfo.add(itm);
  577. }
  578. inputParam.put("hsptzdDagnsInfo", hsptzdDagnsInfo);
  579. JSONArray hsptzdOprtInfo = new JSONArray();
  580. for (CaseFrontsheetSurgery surgery : sheet.getSurgeryList()) {
  581. if (null == surgery.getNo()) {
  582. break;
  583. }
  584. JSONObject itm = new JSONObject();
  585. itm.put("oprt_code", surgery.getCode());
  586. itm.put("oprt_name", surgery.getName());
  587. itm.put("oprt_type", surgery.getNo() == 1 ? 1 : 2);
  588. itm.put("order", surgery.getNo());
  589. hsptzdOprtInfo.add(itm);
  590. }
  591. inputParam.put("hsptzdOprtInfo", hsptzdOprtInfo);
  592. obj.put("inputParam", inputParam);
  593. try {
  594. JSONObject result = srvc.setlQualityControl(obj);
  595. log.info("\n病案质控接口:\n参数:{}\n结果:{}", obj, result);
  596. return result;
  597. } catch (Exception e) {
  598. log.error("创智诊断校验访问失败:http://172.16.32.183:8917/mmg-transceiver/interfaceFactory/call");
  599. return null;
  600. }
  601. }
  602. public ResultVo<Map<String, List<CodeName>>> printVerification(OpCaseFrontsheet param) {
  603. CaseFrontsheetMain sheet = param.getSheet();
  604. Integer status = dao.selectFileStatus(sheet.getBah(), sheet.getAdmissTimes());
  605. if (null != status && status == 1) {
  606. String userCode = TokenUtil.getTokenUserId();
  607. String userDept = dao.selectUserDept(userCode);
  608. if (!userDept.equals("2100000") && !userCode.equals("01897")) {
  609. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "已最终归档病案首页无法打印!");
  610. }
  611. }
  612. ResultVo<List<CodeName>> save = saveSheet(param.getSheet());
  613. if (save.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  614. Map<String, List<CodeName>> map = new HashMap<>();
  615. map.put("force", save.getData());
  616. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "校验未通过。", map);
  617. }
  618. sheet.setIsDoctorPrint(true);
  619. sheet.setAddressMember(getStandardAddress(sheet.getStandardAddress()));
  620. Map<String, List<CodeName>> warnings = beginAnalyzeSheet(sheet, param.getOpType());
  621. if (warnings.get("force").isEmpty()) {
  622. if (param.getPage() == 2) {
  623. saveSheet(sheet);
  624. }
  625. if (warnings.get("advice").isEmpty()) {
  626. return ResultVoUtil.success();
  627. }
  628. }
  629. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "校验未通过。", warnings);
  630. }
  631. public ResultVo<List<CodeName>> saveVerify(OpCaseFrontsheet info) {
  632. CaseFrontsheetMain sheet = info.getSheet();
  633. if (sheet.getFileStatus() == 1 && !userDao.getUserRoles(TokenUtil.getTokenUserId()).contains(7)) {
  634. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "已签收的病案首页无法保存,如需保存,请联系病案室对此病案解除签收。");
  635. }
  636. int optype = info.getOpType();
  637. sheet.setAddressMember(getStandardAddress(sheet.getStandardAddress()));
  638. List<CodeName> message = optype == 1 ? VerifyCaseFrontSheet.getInstance().saveVerify(sheet) :
  639. VerifyCaseFrontSheet.getInstance().printVerify(sheet, optype);
  640. if (message.isEmpty()) {
  641. final String bah = sheet.getBah();
  642. final int times = sheet.getAdmissTimes();
  643. dao.writeBaOpLog(optype, info.getStaffId(), bah, times);
  644. return optype == 1 ? saveSheet(sheet) : archiveSheet(sheet);
  645. }
  646. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "校验未通过。", message);
  647. }
  648. private Map<String, List<CodeName>> beginAnalyzeSheet(CaseFrontsheetMain sheet, int optype) {
  649. List<CodeName> force = VerifyCaseFrontSheet.getInstance().printVerify(sheet, optype);
  650. CaseFrontsheetDisdiag disdiag = sheet.getDisdiagList().get(0);
  651. List<CodeName> advice = VerifyCaseFrontSheet.getInstance().adviseVerification(sheet.getSocialNo(), disdiag.getCode());
  652. setlQualityControlPass(sheet, advice);
  653. surgeryChargesVerify(sheet, advice);
  654. JSONObject powersi = powersiQualityCheck(sheet);
  655. if (null != powersi) {
  656. JSONObject responseEntity = powersi.getJSONObject("responseEntity");
  657. if (null != responseEntity) {
  658. JSONArray retarr = responseEntity.getJSONArray("newSettleMemInfo");
  659. if (null != retarr && retarr.size() > 0) {
  660. for (int i = 0; i < retarr.size(); i++) {
  661. advice.add(new CodeName("", retarr.getJSONObject(i).getString("result_msg")));
  662. }
  663. }
  664. }
  665. }
  666. Map<String, List<CodeName>> map = new HashMap<>();
  667. map.put("force", force);
  668. map.put("advice", advice);
  669. return map;
  670. }
  671. public ResultVo<Map<String, List<CodeName>>> sheetVerification(SheetOverview view) {
  672. if (StringUtil.isBlank(view.getBah()) || null == view.getTimes() || null == view.getInOutFlag()) {
  673. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "住院号、住院次数、在院状态不能为空。");
  674. }
  675. CaseFrontsheetMain sheet = getPatientInfo(view).getData();
  676. if (null == sheet) {
  677. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到病案数据。");
  678. }
  679. Map<String, List<CodeName>> warnings = beginAnalyzeSheet(sheet, 4);
  680. List<CodeName> forces = warnings.get("force");
  681. if (view.getInOutFlag() == 1) {
  682. forces.removeIf(item -> Objects.equals(item.getCode(), "dismissDate"));
  683. forces.removeIf(item -> Objects.equals(item.getCode(), "pathologicDiagCode"));
  684. }
  685. return ResultVoUtil.success(warnings);
  686. }
  687. public ResultVo<List<YiBaoDisdiag>> getYbDiags(String bah, int times) {
  688. List<YiBaoDisdiag> diags = dao.getYbDiags(bah, times);
  689. return ResultVoUtil.success(diags);
  690. }
  691. @Transactional
  692. public ResultVo<String> saveYbDiags(SaveYbDiagParam param) {
  693. dao.deleteOldYbDiag(param.getBah(), param.getTimes());
  694. List<String> diagCodes = new ArrayList<>();
  695. for (int i = 0; i < param.getYbDiags().size(); i++) {
  696. YiBaoDisdiag diag = param.getYbDiags().get(i);
  697. if (StringUtil.isBlank(diag.getCode())) {
  698. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】诊断编码不能为空!");
  699. }
  700. if (StringUtil.isBlank(diag.getName())) {
  701. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】诊断名称不能为空!");
  702. }
  703. if (StringUtil.isBlank(diag.getCyzg())) {
  704. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】出院转归不能为空!");
  705. }
  706. if (null == diag.getSiDiagType()) {
  707. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断序号:" + diag.getNo() + "】诊断类别不能为空!");
  708. }
  709. if (diagCodes.contains(diag.getCode())) {
  710. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【诊断编码:" + diag.getCode() + "】请勿填入重复的诊断!");
  711. }
  712. diagCodes.add(diag.getCode());
  713. diag.setNo(i + 1);
  714. diag.setBah(param.getBah());
  715. diag.setTimes(param.getTimes());
  716. dao.insertNewYbDiag(diag);
  717. }
  718. return ResultVoUtil.success();
  719. }
  720. public ResultVo<List<SheetOverview>> advanceSearch(AdvanceSearchParam param) {
  721. return ResultVoUtil.success(dao.advanceSearch(param));
  722. }
  723. public ResultVo<String> fetchSsfz(String code, String bah, Integer times) {
  724. DisefamilyGrade disefamilyGrade = dao.selectDisefamilyGrade(code);
  725. if (null == disefamilyGrade) {
  726. return ResultVoUtil.success("无对照的病种。");
  727. }
  728. boolean hasModified = dao.selectModified(bah, times) > 0;
  729. List<String> surgeries = hasModified ? dao.selectPatientSurgeryCodes(bah, times, "batj_ba4_modify")
  730. : dao.selectPatientSurgeryCodes(bah, times, "batj_ba4");
  731. if (ListUtil.isBlank(surgeries)) {
  732. return ResultVoUtil.success("有对照的非手术分值:" + disefamilyGrade.getNoneOprnGrade());
  733. }
  734. List<OprnDisefamilyGrade> oprnGrades = dao.selectOperationDisefamilies(disefamilyGrade.getDisefamilyCode());
  735. int ssfz = 0;
  736. for (OprnDisefamilyGrade oprn : oprnGrades) {
  737. if (surgeries.contains(oprn.getOprnCode())) {
  738. if (oprn.getOprnGrade() > ssfz) {
  739. ssfz = oprn.getOprnGrade();
  740. }
  741. }
  742. }
  743. if (ssfz != 0) {
  744. return ResultVoUtil.success("有对照的手术分值:" + ssfz);
  745. }
  746. return ResultVoUtil.success("有对照的非手术分值:" + disefamilyGrade.getNoneOprnGrade());
  747. }
  748. private boolean isLateSubmit(Date dismissDate) {
  749. long days = (System.currentTimeMillis() - dismissDate.getTime()) / 1000 / (3600 * 24);
  750. return (int) days > 7;
  751. }
  752. public void increaseDiagWeight(String code) {
  753. dao.increaseDiagWeight(code);
  754. }
  755. public ResultVo<CodeName> selectSiDiagByBaDiag(String code) {
  756. CodeName result = dao.selectSiDiagByBaDiag(code);
  757. if (null == result) {
  758. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到此诊断的医保对照诊断。");
  759. }
  760. return ResultVoUtil.success(result);
  761. }
  762. private StandardAddressMember getStandardAddress(Integer[] addrs) {
  763. if (null == addrs || addrs.length < 3) {
  764. return null;
  765. }
  766. return dao.selectStandardAddressMember2(addrs[0], addrs[1], addrs[2]);
  767. }
  768. private void setlQualityControlPass(CaseFrontsheetMain sheet, List<CodeName> messages) {
  769. String patNo = sheet.getBah();
  770. int times = sheet.getAdmissTimes();
  771. String admdvs = dao.selectSetlInsuplcAdmdvs(patNo, times);
  772. if (StringUtil.notBlank(admdvs) && admdvs.startsWith("43")) {
  773. Integer qualityPassed = dao.qualityPass(patNo, times);
  774. if (null == qualityPassed || qualityPassed != 1) {
  775. messages.add(new CodeName("", "此患者医保结算清单质控未通过!"));
  776. }
  777. }
  778. }
  779. private void surgeryChargesVerify(CaseFrontsheetMain sheet, List<CodeName> messages) {
  780. List<CaseFrontsheetSurgery> surgeries = sheet.getSurgeryList();
  781. if (null != surgeries && !surgeries.isEmpty()) {
  782. List<HisWjwMatchEntity> surgeryChargeCode = dao.selectSurgeryChargeCode(surgeries);
  783. for (HisWjwMatchEntity entity : surgeryChargeCode) {
  784. if (StringUtil.notBlank(entity.getWjwCode())) {
  785. entity.setChargeCode(entity.getWjwCode().split("\\^"));
  786. entity.setChargeName(entity.getWjwName().split("\\^"));
  787. Integer chargeSumamt = dao.selectChargeSumamt(sheet.getBah(), sheet.getAdmissTimes(), entity.getChargeCode());
  788. if (null == chargeSumamt || chargeSumamt < 1) {
  789. String charges = entity.getWjwName().replaceAll("\\^", ",");
  790. messages.add(new CodeName("surgeryTable", "患者有手术【" + entity.getName() +
  791. "】,但没有找到对应的收费项目【" + charges + "】。"));
  792. }
  793. }
  794. }
  795. }
  796. }
  797. public ResultVo<String> frontsheetQualityCheck(CaseFrontsheetMain sheet) {
  798. List<CodeName> anstWays = dao.selectZdAnstWays();
  799. Map<String, CodeName> anstWaysMap = new HashMap<>();
  800. for (CodeName item : anstWays) {
  801. anstWaysMap.put(item.getCode(), item);
  802. }
  803. List<CodeName> countries = dao.selectZdCountries();
  804. Map<String, CodeName> countriesMap = new HashMap<>();
  805. for (CodeName item : countries) {
  806. countriesMap.put(item.getCode(), item);
  807. }
  808. List<CodeName> nations = dao.selectZdNations();
  809. Map<String, CodeName> nationsMap = new HashMap<>();
  810. for (CodeName item : nations) {
  811. nationsMap.put(item.getCode(), item);
  812. }
  813. QualityCheckParams params = new QualityCheckParams();
  814. params.setBaseInfo(FrontSheetUtil.fillBaseInfoFromSheet(sheet, countriesMap, nationsMap));
  815. params.setDiseInfoList(FrontSheetUtil.fillDiseInfoFromSheet(sheet.getDisdiagList()));
  816. params.setOprtInfoList(FrontSheetUtil.fillOprtInfoFromSheet(sheet.getSurgeryList(), anstWaysMap));
  817. JSONObject jsonParams = JSONObject.parseObject(JSON.toJSONString(params, SerializerFeature.WriteNullStringAsEmpty));
  818. String url = "http://172.16.32.126:8080/drg_web/drgGroupThird/V2/groupAndQuality.action";
  819. RestTemplate template = new RestTemplate();
  820. String result = template.postForObject(url, jsonParams, String.class);
  821. result = "http://172.16.32.126:8080" + result;
  822. String url2 = "http://172.16.32.126:8080/drg_web/drgGroupThird/V2/drgGroupAndQuality.action";
  823. String result2 = template.postForObject(url2, jsonParams, String.class);
  824. log.info("病案质控:\n参数:{}\n结果:{}", jsonParams, result2);
  825. return ResultVoUtil.success(result);
  826. }
  827. public ResultVo<String> isMedinsSetl(String patNo, Integer times) {
  828. String admdvs = dao.selectSetlInsuplcAdmdvs(patNo, times);
  829. if (StringUtil.isBlank(admdvs)) {
  830. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "自费及工伤患者无需进行医保结算单质控。");
  831. }
  832. if (!admdvs.startsWith("43")) {
  833. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "跨省异地患者无需进行医保结算单质控。");
  834. }
  835. return ResultVoUtil.success();
  836. }
  837. }