SiMzService.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. package thyyxxk.webserver.service.medicalinsurance;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.alibaba.fastjson.JSONObject;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.stereotype.Service;
  8. import thyyxxk.webserver.config.exception.BizException;
  9. import thyyxxk.webserver.config.exception.ExceptionEnum;
  10. import thyyxxk.webserver.constants.Capacity;
  11. import thyyxxk.webserver.constants.sidicts.*;
  12. import thyyxxk.webserver.dao.his.medicalinsurance.DigitalReceiptDao;
  13. import thyyxxk.webserver.dao.his.medicalinsurance.SiMzDao;
  14. import thyyxxk.webserver.entity.ResultVo;
  15. import thyyxxk.webserver.entity.markmtfees.*;
  16. import thyyxxk.webserver.entity.medicalinsurance.digitalreceipt.*;
  17. import thyyxxk.webserver.entity.medicalinsurance.digitalreceipt.request.*;
  18. import thyyxxk.webserver.entity.medicalinsurance.manage.clinicinfo.RevokeRegRequest;
  19. import thyyxxk.webserver.entity.medicalinsurance.outpatient.*;
  20. import thyyxxk.webserver.entity.medicalinsurance.query.InsuInfo;
  21. import thyyxxk.webserver.entity.medicalinsurance.query.PsnBaseInfo;
  22. import thyyxxk.webserver.entity.medicalinsurance.query.QryPsnBsInfo;
  23. import thyyxxk.webserver.entity.medicalinsurance.query.SiPatInfo;
  24. import thyyxxk.webserver.entity.medicalinsurance.setlinfo.FundDetail;
  25. import thyyxxk.webserver.entity.outpatient.medicalinfo.MzBlRecord;
  26. import thyyxxk.webserver.service.externalhttp.SiMzSrvc;
  27. import thyyxxk.webserver.service.externalhttp.ThmzSystem;
  28. import thyyxxk.webserver.utils.*;
  29. import java.math.BigDecimal;
  30. import java.math.RoundingMode;
  31. import java.nio.charset.StandardCharsets;
  32. import java.util.*;
  33. /**
  34. * @description: 门诊医保交易
  35. * @author: DingJie
  36. * @create: 2021-05-28 16:11:19
  37. **/
  38. @Slf4j
  39. @Service
  40. public class SiMzService {
  41. private final SiMzDao dao;
  42. private final DigitalReceiptDao rxDao;
  43. private final ThmzSystem thmz;
  44. private final SiMzSrvc mzSrvc;
  45. private final SiQueryService qryService;
  46. @Value("${si-mz-fee-url}")
  47. private String siMzFeeUrl;
  48. @Value("${thmz-api-url}")
  49. private String thmzApiUrl;
  50. @Autowired
  51. public SiMzService(SiMzDao dao, DigitalReceiptDao rxDao, ThmzSystem thmz, SiMzSrvc mzSrvc,
  52. SiQueryService qryService) {
  53. this.dao = dao;
  54. this.rxDao = rxDao;
  55. this.thmz = thmz;
  56. this.mzSrvc = mzSrvc;
  57. this.qryService = qryService;
  58. }
  59. public ResultVo<String> outpatientRegistration(MzPatientInfo p) {
  60. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  61. String hisOrdNum = p.getPatNo() + "_" + p.getTimes() + "_" + 1;
  62. int mipCount = dao.selectMipayCount(hisOrdNum);
  63. if (mipCount > 0) {
  64. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者已进行移动医保支付,请勿重复登记。");
  65. }
  66. return mzSrvc.outpatientRegistration(siMzFeeUrl, p);
  67. }
  68. public ResultVo<String> revokeOutpatientRegistration(MzPatientInfo p) {
  69. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  70. return mzSrvc.revokeOutpatientRegistration(siMzFeeUrl, p);
  71. }
  72. public ResultVo<String> executeOutpatientRegRevoke(RevokeRegRequest request) {
  73. request.setStaffId(TokenUtil.getInstance().getTokenUserId());
  74. return mzSrvc.executeOutpatientRegRevoke(siMzFeeUrl, request);
  75. }
  76. public ResultVo<List<Map<String, Object>>> getMzReceipts(MzPatientInfo p) {
  77. String patNo = p.getPatNo();
  78. JSONObject queryMzChargeListParam = new JSONObject();
  79. queryMzChargeListParam.put("patCardType", 21);
  80. queryMzChargeListParam.put("patCardNo", patNo);
  81. queryMzChargeListParam.put("hisOrdNum", "");
  82. queryMzChargeListParam.put("ybRequest", 1);
  83. Map<String, Object> mzChargeListMap = thmz.getMzChargeDetailForUnPaid(thmzApiUrl, queryMzChargeListParam);
  84. if (null == mzChargeListMap) {
  85. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  86. }
  87. if (0 != (int) mzChargeListMap.get("resultCode")) {
  88. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, mzChargeListMap.get("resultMessage").toString());
  89. }
  90. List<Map<String, Object>> finalResult = new ArrayList<>();
  91. List<Map<String, String>> mzChargeList = FilterUtil.cast(mzChargeListMap.get("data"));
  92. for (Map<String, String> item : mzChargeList) {
  93. String hisOrdNum = item.get("hisOrdNum");
  94. if (null != hisOrdNum) {
  95. String[] hisOrdNumParts = hisOrdNum.split("_");
  96. int tempTimes = Integer.parseInt(hisOrdNumParts[1]);
  97. MzVisit mzVisit = dao.selectMzVisit(patNo, tempTimes);
  98. if (null == mzVisit) {
  99. continue;
  100. }
  101. if (IdCardUtil.isValidatedIdCard(mzVisit.getSocialNo())) {
  102. mzVisit.setAge(IdCardUtil.getAgeByIdCard(mzVisit.getSocialNo()));
  103. }
  104. String vipFlag = String.valueOf(item.get("vipFlag"));
  105. mzVisit.setReceiptNo(Integer.parseInt(hisOrdNumParts[2]));
  106. mzVisit.setTableClinicReceiptNo(0);
  107. mzVisit.setSettledFlag(calSettleFlag(mzVisit));
  108. mzVisit.setVipFlag(vipFlag);
  109. Map<String, Object> childResult = new HashMap<>(Capacity.FIVE);
  110. childResult.put("times", tempTimes);
  111. childResult.put("mzVisit", mzVisit);
  112. JSONObject queryMzChargeDetailParam = new JSONObject();
  113. queryMzChargeDetailParam.put("patientId", patNo);
  114. queryMzChargeDetailParam.put("times", tempTimes);
  115. queryMzChargeDetailParam.put("receiptNo", hisOrdNumParts[2]);
  116. Map<String, Object> mzChargeDetailMap = thmz.unPaidToFullChargeDetail(thmzApiUrl, queryMzChargeDetailParam);
  117. if (null != mzChargeDetailMap && 0 == (int) mzChargeDetailMap.get("resultCode")) {
  118. List<Map<String, Object>> mzChargeDetailList = FilterUtil.cast(mzChargeDetailMap.get("data"));
  119. mzChargeDetailList.removeIf(detail -> "TC".equals(detail.get("billItemCode")) ||
  120. !"5".equals(detail.get("payMark")) || "BILL99".equals(detail.get("chargeItemCode")) ||
  121. "四舍五入".equals(detail.get("tcName")));
  122. if (mzChargeDetailList.isEmpty()) {
  123. continue;
  124. }
  125. Map<Integer, List<MzReceipt>> orderReceiptsMap = new HashMap<>(Capacity.DEFAULT);
  126. String doctorName = dao.selectDoctorName(mzChargeDetailList.get(0).get("doctorCode").toString());
  127. mzChargeDetailList.forEach(detail -> {
  128. MzReceipt receipt = fillMzReceipt(detail);
  129. receipt.setPatientId(patNo);
  130. receipt.setTimes(tempTimes);
  131. receipt.setDoctorName(doctorName);
  132. if (!orderReceiptsMap.containsKey(receipt.getOrderNo())) {
  133. List<MzReceipt> list = new ArrayList<>();
  134. list.add(receipt);
  135. orderReceiptsMap.put(receipt.getOrderNo(), list);
  136. } else {
  137. orderReceiptsMap.get(receipt.getOrderNo()).add(receipt);
  138. }
  139. });
  140. List<OrderNo> orderNos = getOrderNos(patNo, tempTimes, mzVisit.getReceiptNo(), orderReceiptsMap);
  141. childResult.put("orderNos", orderNos);
  142. childResult.put("mzReceipts", orderReceiptsMap);
  143. childResult.put("zgmztczf", mzSrvc.getZgmztczf(mzVisit).getData());
  144. finalResult.add(childResult);
  145. }
  146. }
  147. }
  148. return ResultVoUtil.success(finalResult);
  149. }
  150. public ResultVo<List<MzDepositFile>> getHistoryMzReceipts(String patNo, String start, String end) {
  151. List<MzDepositFile> mzChargeList = dao.selectMzDepositFiles(patNo, start, end);
  152. if (null == mzChargeList || mzChargeList.isEmpty()) {
  153. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到历史处方!");
  154. }
  155. for (MzDepositFile depositFile : mzChargeList) {
  156. MzVisit mzVisit = new MzVisit();
  157. mzVisit.setPatientId(patNo);
  158. mzVisit.setTimes(depositFile.getTimes());
  159. mzVisit.setReceiptNo(depositFile.getReceiptNo());
  160. depositFile.setZgmztczf(mzSrvc.getZgmztczf(mzVisit).getData());
  161. }
  162. return ResultVoUtil.success(mzChargeList);
  163. }
  164. public Map<String, Object> getHistoryReceiptDetail(MzDepositFile mzDepositFile) {
  165. MzVisit mzVisit = dao.selectMzVisit(mzDepositFile.getPatNo(), mzDepositFile.getTimes());
  166. if (null == mzVisit) {
  167. throw new BizException(ExceptionEnum.NULL_POINTER, "没有找到患者的就诊信息。");
  168. }
  169. if (IdCardUtil.isValidatedIdCard(mzVisit.getSocialNo())) {
  170. mzVisit.setAge(IdCardUtil.getAgeByIdCard(mzVisit.getSocialNo()));
  171. }
  172. mzVisit.setSettledFlag(calSettleFlag(mzVisit));
  173. List<MzReceipt> mzReceipts = dao.selectMzCharge(mzDepositFile.getPatNo(),
  174. mzDepositFile.getTimes(), mzDepositFile.getReceiptNo());
  175. mzReceipts.forEach(itm -> itm.setChecked(StringUtil.notBlank(itm.getNationalCode())));
  176. Map<String, Object> map = new HashMap<>();
  177. map.put("mzVisit", mzVisit);
  178. map.put("mzReceipts", mzReceipts);
  179. return map;
  180. }
  181. public MzDepositFile mergeReceipts(List<MzDepositFile> list) {
  182. MzDepositFile minTimesVisit = list.get(0);
  183. List<MzReceipt> mergedReceipts = new ArrayList<>();
  184. for (MzDepositFile mzDepositFile : list) {
  185. if (mzDepositFile.getTimes() < minTimesVisit.getTimes()) {
  186. minTimesVisit = mzDepositFile;
  187. }
  188. List<MzReceipt> mzReceipts = dao.selectMzCharge(mzDepositFile.getPatNo(),
  189. mzDepositFile.getTimes(), mzDepositFile.getReceiptNo());
  190. mzReceipts.removeIf(item -> StringUtil.isBlank(item.getNationalCode()));
  191. mergedReceipts.addAll(mzReceipts);
  192. }
  193. String hasCovidExamFees = covidExamFeesDetect(mergedReceipts);
  194. if (StringUtil.notBlank(hasCovidExamFees)) {
  195. throw new BizException(ExceptionEnum.LOGICAL_ERROR, hasCovidExamFees);
  196. }
  197. for (int i = 0; i < mergedReceipts.size(); i++) {
  198. MzReceipt receipt = mergedReceipts.get(i);
  199. receipt.setTimes(minTimesVisit.getTimes());
  200. receipt.setItemNo(i + 1);
  201. }
  202. dao.deleteAllReceipts(list.get(0).getPatNo(), minTimesVisit.getTimes());
  203. insertBatchedMtReceipts(mergedReceipts);
  204. String message = "合并处方成功,请使用【第 " + minTimesVisit.getTimes() + " 次就诊】办理医保业务。";
  205. minTimesVisit.setMessage(message);
  206. return minTimesVisit;
  207. }
  208. private void insertBatchedMtReceipts(List<MzReceipt> receipts) {
  209. List<MzReceipt> tempList = new ArrayList<>();
  210. for (MzReceipt item : receipts) {
  211. tempList.add(item);
  212. if (tempList.size() == 50) {
  213. dao.insertMtReceipts(tempList);
  214. tempList.clear();
  215. }
  216. }
  217. if (!tempList.isEmpty()) {
  218. dao.insertMtReceipts(tempList);
  219. }
  220. }
  221. private int calSettleFlag(MzVisit f) {
  222. int siCount = dao.selectSiCount(f.getPatientId(), f.getTimes());
  223. if (siCount > 0) {
  224. return 1;
  225. }
  226. String hisOrdNum = f.getPatientId() + "_" + f.getTimes() + "_" + f.getReceiptNo();
  227. int mipay = dao.selectMipayCount(hisOrdNum);
  228. if (mipay > 0) {
  229. return 2;
  230. }
  231. int injury = dao.selectInjuryCount(f.getPatientId(), f.getTimes());
  232. return injury == 0 ? 0 : 3;
  233. }
  234. private MzReceipt fillMzReceipt(Map<String, Object> detail) {
  235. MzReceipt receipt = new MzReceipt();
  236. receipt.setReceiptNo((int) detail.get("receiptNo"));
  237. receipt.setOrderNo((int) detail.get("orderNo"));
  238. receipt.setItemNo((int) detail.get("itemNo"));
  239. receipt.setDrugName(detail.get("tcName").toString());
  240. receipt.setChargeItemCode(detail.get("chargeItemCode").toString());
  241. receipt.setPriceTime(DateUtil.formatPriceTime(detail.get("priceTime").toString()));
  242. receipt.setUnitPrice(new BigDecimal(detail.get("unitPrice").toString()).setScale(4, RoundingMode.HALF_UP));
  243. receipt.setQuantity(Double.valueOf(detail.get("quantity").toString()));
  244. receipt.setDrugWin((int) detail.get("drugWin"));
  245. receipt.setDoctorCode(detail.get("doctorCode").toString());
  246. receipt.setGroupNo(detail.get("groupNo").toString());
  247. receipt.setChargeDate(detail.get("priceTime").toString().split("\\+")[0].replace("T", " "));
  248. receipt.setBillItemCode(detail.get("billItemCode").toString());
  249. receipt.setChargeBillCode(detail.get("chargeBillCode").toString());
  250. String table = receipt.getGroupNo().trim().equals("00") ? "zd_charge_item" : "yp_zd_dict";
  251. receipt.setNationalCode(dao.selectNationalCode(receipt.getChargeItemCode(), table));
  252. receipt.setChecked(StringUtil.notBlank(receipt.getNationalCode()));
  253. if (null != detail.get("hospApprFlag")) {
  254. receipt.setHospApprFlag(detail.get("hospApprFlag").toString());
  255. }
  256. if (null != detail.get("serialNo")) {
  257. receipt.setSerialNo(detail.get("serialNo").toString());
  258. }
  259. if (null != detail.get("instructionText")) {
  260. receipt.setInstructionText(detail.get("instructionText").toString());
  261. }
  262. if (null != detail.get("specification")) {
  263. receipt.setSpecification(detail.get("specification").toString());
  264. }
  265. if (null != detail.get("frequency")) {
  266. receipt.setFrequency(detail.get("frequency").toString());
  267. }
  268. if (null != detail.get("drugQuan")) {
  269. receipt.setDrugQuan(Double.valueOf(detail.get("drugQuan").toString()));
  270. }
  271. if (null != detail.get("orderDays")) {
  272. receipt.setOrderDays((Integer) detail.get("orderDays"));
  273. }
  274. // groupNo:00-项目;其他-药品
  275. if ("00".equals(receipt.getGroupNo())) {
  276. receipt.setDrugUnit(dao.selectXmChargeUnit(receipt.getChargeItemCode()));
  277. } else {
  278. receipt.setYbComment(dao.selectYbComment(receipt.getChargeItemCode()));
  279. if (null != detail.get("serial")) {
  280. receipt.setSerial(detail.get("serial").toString());
  281. receipt.setSpecification(dao.selectSpecification(receipt.getChargeItemCode(), receipt.getSerial()));
  282. }
  283. if (null != detail.get("supplyCode")) {
  284. receipt.setSupplyCode(dao.selectSupplyName(detail.get("supplyCode").toString()));
  285. }
  286. if (null != detail.get("drugUnit")) {
  287. receipt.setDrugUnit(dao.selectDrugUnit(detail.get("drugUnit").toString()));
  288. }
  289. }
  290. return receipt;
  291. }
  292. private List<OrderNo> getOrderNos(String patientId, int times, int receiptNo, Map<Integer, List<MzReceipt>> orderReceiptsMap) {
  293. List<OrderNo> orderNos = new ArrayList<>();
  294. for (Map.Entry<Integer, List<MzReceipt>> entry : orderReceiptsMap.entrySet()) {
  295. OrderNo orderNo = new OrderNo();
  296. orderNo.setPatientId(patientId);
  297. orderNo.setTimes(times);
  298. orderNo.setReceiptNo(entry.getValue().get(0).getReceiptNo());
  299. orderNo.setOrderNo(entry.getKey());
  300. BigDecimal total = new BigDecimal("0.00");
  301. for (MzReceipt receipt : entry.getValue()) {
  302. total = total.add(receipt.getChargeFee());
  303. }
  304. orderNo.setTotalFee(total);
  305. int count = dao.selectFeeCount(patientId, times, receiptNo, entry.getKey());
  306. orderNo.setStatus(count > 0);
  307. orderNos.add(orderNo);
  308. }
  309. return orderNos;
  310. }
  311. public ResultVo<String> insertSiMzFees(List<MzReceipt> receipts) {
  312. receipts.removeIf(item -> !item.getChecked());
  313. if (receipts.isEmpty()) {
  314. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "患者没有可以报销的项目!");
  315. }
  316. String hasCovidExamFees = covidExamFeesDetect(receipts);
  317. if (StringUtil.notBlank(hasCovidExamFees)) {
  318. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, hasCovidExamFees);
  319. }
  320. dao.insertMtReceipts(receipts);
  321. return ResultVoUtil.success();
  322. }
  323. private String covidExamFeesDetect(List<MzReceipt> receipts) {
  324. StringBuilder message = new StringBuilder();
  325. for (MzReceipt receipt : receipts) {
  326. if (receipt.getChargeItemCode().trim().equals("019180")) {
  327. message.append("【019180,新型冠状病毒核酸检测】");
  328. }
  329. if (receipt.getChargeItemCode().trim().equals("019110")) {
  330. message.append("【019110,新型冠状病毒2019-ncov核酸检测试剂盒(荧光)】");
  331. }
  332. }
  333. if (message.length() > 0) {
  334. message.append("无法上传至医保中心,请单独开具处方。");
  335. return "因政策原因," + message;
  336. }
  337. return null;
  338. }
  339. public ResultVo<String> insertSiMzFeesForSupplement(List<MzReceipt> receipts) {
  340. receipts.removeIf(item -> !item.getChecked() || item.getChargeItemCode().equals("019110")
  341. || item.getChargeItemCode().equals("019180"));
  342. if (receipts.isEmpty()) {
  343. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "患者没有可以报销的项目!");
  344. }
  345. MzReceipt receipt = receipts.get(0);
  346. List<Integer> receiptNos = dao.selectGeneratedReceiptNos(receipt.getPatientId(), receipt.getTimes());
  347. for (int receiptNo : receiptNos) {
  348. if (dao.isReceiptPayed(receipt.getPatientId(), receipt.getTimes(), receiptNo) == 0) {
  349. dao.deleteCertainReceipt(receipt.getPatientId(), receipt.getTimes(), receiptNo);
  350. }
  351. }
  352. dao.insertMtReceipts(receipts);
  353. return ResultVoUtil.success();
  354. }
  355. public ResultVo<String> deleteMzReceipt(OrderNo param) {
  356. dao.deleteMzReceipt(param);
  357. return ResultVoUtil.success();
  358. }
  359. public ResultVo<String> deleteAllMzReceipts(MzPatientInfo p) {
  360. if (null == p.getTimes()) {
  361. p.setTimes(dao.selectMaxTimes(p.getPatNo()));
  362. }
  363. log.info("【操作员:{}】删除所有门特处方:门诊号:{},门诊次数:{}",
  364. TokenUtil.getInstance().getTokenUserId(), p.getPatNo(), p.getTimes());
  365. dao.deleteAllReceipts(p.getPatNo(), p.getTimes());
  366. return ResultVoUtil.success("删除成功。");
  367. }
  368. public ResultVo<SiPatInfo> uploadOutpatientFeeDetails(SpcChrDiseAcct p) {
  369. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  370. return mzSrvc.uploadOutpatientFeeDetails(siMzFeeUrl, p);
  371. }
  372. public ResultVo<String> revokeOutpatientFeeDetails(MzPatientInfo p) {
  373. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  374. return mzSrvc.revokeOutpatientFeeDetails(siMzFeeUrl, p);
  375. }
  376. public ResultVo<FundDetail> outpatientPreSettlement(MzPatientInfo p) {
  377. if (null == p.getStaffId()) {
  378. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  379. }
  380. return mzSrvc.outpatientPreSettlement(siMzFeeUrl, p);
  381. }
  382. public ResultVo<FundDetail> outpatientSettlement(MzPatientInfo p) {
  383. if (null == p.getStaffId()) {
  384. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  385. }
  386. return mzSrvc.outpatientSettlement(siMzFeeUrl, p);
  387. }
  388. public ResultVo<FundDetail> timeoutSetl(MzPatientInfo p) {
  389. if (null == p.getStaffId()) {
  390. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  391. }
  392. String logContent = dao.getLogContent(p.getMsgid());
  393. if (!logContent.contains("服务提供者后端服务响应超时")) {
  394. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR,
  395. "该笔交易不符合超时结算条件,无法进行超时结算(结算失败的原因为“服务提供者后端服务响应超时”时,方可进行超时结算)。");
  396. }
  397. return mzSrvc.timeoutSetl(siMzFeeUrl, p);
  398. }
  399. public boolean receiptAlreadyPrinted(MzPatientInfo p) {
  400. String receiptBill = dao.selectReceiptBill(p.getPatNo(), p.getTimes());
  401. return StringUtil.notBlank(receiptBill);
  402. }
  403. public ResultVo<FundDetail> revokeOutpatientSettlement(MzPatientInfo p) {
  404. if (null == p.getStaffId()) {
  405. p.setStaffId(TokenUtil.getInstance().getTokenUserId());
  406. }
  407. return mzSrvc.revokeOutpatientSettlement(siMzFeeUrl, p);
  408. }
  409. public void insertSiPatInfo(MzPatientInfo mz) {
  410. int count = dao.selectSiMzInfoCount(mz.getPatNo(), -1);
  411. if (count == 0) {
  412. PsnBaseInfo patinfo = dao.selectPsnBaseinfo(mz.getPatNo(), mz.getTimes());
  413. if (null != patinfo) {
  414. patinfo.setTimes(-1);
  415. dao.insertSiMzInfoPsnNo(patinfo);
  416. }
  417. }
  418. }
  419. public ResultVo<String> saveSiMzDiags(List<SiMzDiag> diags) {
  420. if (ListUtil.isBlank(diags)) {
  421. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有要保存的诊断!");
  422. }
  423. SiMzDiag diag = diags.get(0);
  424. dao.deleteMzDiags(diag.getPatNo(), diag.getTimes());
  425. String staffId = TokenUtil.getInstance().getTokenUserId();
  426. for (SiMzDiag itm : diags) {
  427. itm.setRealOpter(staffId);
  428. dao.insertNewMzDiag(itm);
  429. }
  430. return ResultVoUtil.success("门诊诊断保存成功。");
  431. }
  432. public Map<String, Object> queryInsuinfo(SiMzBusinessParams param) {
  433. Map<String, Object> result = new HashMap<>();
  434. QryPsnBsInfo mzptnt = new QryPsnBsInfo();
  435. mzptnt.setStaffId(param.getStaffId());
  436. mzptnt.setPatNo(param.getPatientId());
  437. mzptnt.setMedType(MedType.GENERAL_CLINIC.getCode());
  438. mzptnt.setOnlyQry(1);
  439. mzptnt.setTimes(-1);
  440. if (StringUtil.notBlank(param.getAdmdvs())) {
  441. mzptnt.setAdmdvs(param.getAdmdvs());
  442. mzptnt.setSocialNo(param.getSocialNo());
  443. }
  444. ResultVo<PsnBaseInfo> baseInfo = qryService.obtainBasicPersonInfo(mzptnt);
  445. if (null == baseInfo) {
  446. result.put("code", -2);
  447. result.put("msg", "网络异常。");
  448. return result;
  449. }
  450. if (!Objects.equals(baseInfo.getCode(), ExceptionEnum.SUCCESS.getCode())) {
  451. result.put("code", -2);
  452. result.put("msg", baseInfo.getMessage());
  453. return result;
  454. }
  455. // 如果有职工保险,就入库
  456. PsnBaseInfo psninfo = baseInfo.getData();
  457. InsuInfo insuInfo = getResidantOrEmployeeInsuInfo(psninfo.getInsuinfo());
  458. if (null == insuInfo) {
  459. result.put("code", -1);
  460. result.put("msg", "患者没有职工医保或居民医保,无法报销。");
  461. return result;
  462. }
  463. psninfo.setInsutype(insuInfo.getInsutype());
  464. int count = dao.selectSiMzInfoCount(mzptnt.getPatNo(), mzptnt.getTimes());
  465. if (count == 0) {
  466. psninfo.setMedType(MedType.GENERAL_CLINIC.getCode());
  467. psninfo.setInsuplc(insuInfo.getInsuplcAdmdvs());
  468. psninfo.setInsuplcAdmdvsName(insuInfo.getInsuplcAdmdvsName());
  469. psninfo.setLedgerSn(0);
  470. psninfo.setPsnType(insuInfo.getPsnType());
  471. psninfo.setEmpName(insuInfo.getEmpName());
  472. psninfo.setBalc(insuInfo.getBalc());
  473. dao.insertSiMzInfoPsnNo(psninfo);
  474. } else {
  475. dao.updateSiZyInfoPsnNo(mzptnt.getPatNo(), mzptnt.getTimes(), psninfo.getInsutype(),
  476. insuInfo.getBalc(), insuInfo.getInsuplcAdmdvs(), insuInfo.getInsuplcAdmdvsName());
  477. }
  478. result.put("code", 0);
  479. result.put("expContentRequired", expContentRequired(insuInfo.getInsuplcAdmdvs()));
  480. result.put("msg", "查询参保信息成功。");
  481. return result;
  482. }
  483. public ResultVo<PsnBaseInfo> queryInsuinfoDetail(SiMzBusinessParams param) {
  484. QryPsnBsInfo mzptnt = new QryPsnBsInfo();
  485. mzptnt.setStaffId(param.getStaffId());
  486. mzptnt.setPatNo(param.getPatientId());
  487. mzptnt.setMedType(MedType.GENERAL_CLINIC.getCode());
  488. mzptnt.setOnlyQry(1);
  489. mzptnt.setTimes(-1);
  490. if (StringUtil.notBlank(param.getAdmdvs())) {
  491. mzptnt.setAdmdvs(param.getAdmdvs());
  492. }
  493. ResultVo<PsnBaseInfo> baseInfo = qryService.obtainBasicPersonInfo(mzptnt);
  494. if (null == baseInfo) {
  495. throw new BizException(ExceptionEnum.NETWORK_ERROR);
  496. }
  497. if (!Objects.equals(baseInfo.getCode(), ExceptionEnum.SUCCESS.getCode())) {
  498. throw new BizException(ExceptionEnum.NETWORK_ERROR, baseInfo.getMessage());
  499. }
  500. return baseInfo;
  501. }
  502. private InsuInfo getResidantOrEmployeeInsuInfo(List<InsuInfo> list) {
  503. for (InsuInfo info : list) {
  504. Insutype insutype = Insutype.get(info.getInsutype());
  505. if (null == insutype) {
  506. continue;
  507. }
  508. if (insutype == Insutype.BASIC_MEDICAL_INSURANCE_FOR_EMPLOYEES ||
  509. insutype == Insutype.BASIC_MEDICAL_INSURANCE_FOR_RURAL_RESIDENTS) {
  510. return info;
  511. }
  512. }
  513. return null;
  514. }
  515. private int expContentRequired(String insuplc) {
  516. return (insuplc.startsWith("4301") || insuplc.equals("439900")) ? 0 : 1;
  517. }
  518. public ResultVo<FundDetail> directRegistration(SiMzBusinessParams param) {
  519. return mzSrvc.directRegistration(siMzFeeUrl, param);
  520. }
  521. public ResultVo<FundDetail> mzgjAfterModifyReceipt(SiMzBusinessParams param) {
  522. PsnBaseInfo psnBaseInfo = dao.selectLatestPsnInfo(param.getPatientId());
  523. if (null == psnBaseInfo) {
  524. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "无法办理,没有找到参保信息。");
  525. }
  526. dao.deleteAllReceipts(param.getPatientId(), param.getTimes());
  527. param.setStraitSettle(true);
  528. return mzSrvc.directRegistration(siMzFeeUrl, param);
  529. }
  530. public ResultVo<Integer> isPatientDuringSiSettle(String patientId) {
  531. return mzSrvc.isPatientDuringSiSettle(siMzFeeUrl, patientId);
  532. }
  533. public String queryModifyPermission(MzPatientInfo info) {
  534. int pre = dao.selectPresettleCount(info.getPatNo(), info.getTimes());
  535. if (pre > 0) {
  536. return "此患者的处方已上传医保,无法修改。";
  537. }
  538. String setlStaff = dao.selectSetlStaff(info.getPatNo(), info.getTimes());
  539. if (StrUtil.isEmpty(setlStaff)) {
  540. return "OK";
  541. }
  542. if (Objects.equals(info.getStaffId(), setlStaff)) {
  543. return "OK";
  544. }
  545. return "DENIED";
  546. }
  547. public Map<String, Object> modifyFundPayAmount(ModifyFundAmt amt) {
  548. amt.fixNullVal();
  549. int res = dao.modifyFundAmt(amt);
  550. Map<String, Object> resultMap = new HashMap<>();
  551. if (res > 0) {
  552. resultMap.put("code", 0);
  553. resultMap.put("msg", "更新成功,有" + res + "条数据受影响。");
  554. } else {
  555. resultMap.put("code", -1);
  556. resultMap.put("msg", "更新失败,有0条数据受影响。");
  557. }
  558. log.info("THMZ修改报销数据:\n参数:{}\n结果:{}", amt, resultMap);
  559. return resultMap;
  560. }
  561. public MzBlRecord getMzBlRecord(String patientId, Integer times) {
  562. return dao.selectMzBlRecord(patientId, times);
  563. }
  564. public ResultVo<FundDetail> ybRegForRx(SiMzBusinessParams params) {
  565. return mzSrvc.directRegistration(siMzFeeUrl, params);
  566. }
  567. public List<RxIndex> getRxIndex(IndexInquiry inquiry) {
  568. if (null == inquiry.getBegintime()) {
  569. inquiry.setBegintime(DateUtil.parse("2024-01-01", "yyyy-MM-dd"));
  570. }
  571. if (null == inquiry.getEndtime()) {
  572. inquiry.setEndtime(new Date());
  573. }
  574. List<RxIndex> list = rxDao.getRxIndex(inquiry);
  575. if (inquiry.getState() != RxState.ALL) {
  576. list.removeIf(item -> item.getState() != inquiry.getState());
  577. }
  578. return list;
  579. }
  580. public String getRxDetail(String hospRxno) {
  581. String rxFile = rxDao.getRxFile(hospRxno);
  582. if (StringUtil.notBlank(rxFile)) {
  583. return rxFile;
  584. }
  585. RxPreCheckRequest request = new RxPreCheckRequest();
  586. request.setHospRxno(hospRxno);
  587. request.setStaffId(TokenUtil.getInstance().getTokenUserId());
  588. ResultVo<String> pdfVo = mzSrvc.createRxPdf(siMzFeeUrl, makePreCheckRequest(request));
  589. if (!Objects.equals(pdfVo.getCode(), ExceptionEnum.SUCCESS.getCode())) {
  590. throw new BizException(ExceptionEnum.LOGICAL_ERROR, pdfVo.getMessage());
  591. }
  592. return pdfVo.getData();
  593. }
  594. public ResultVo<JSONObject> rxPreCheck(RxPreCheckRequest request) {
  595. makePreCheckRequest(request);
  596. if (StringUtil.isBlank(request.getRxMdtrtinfo().getMdtrtId())) {
  597. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者未做医保登记,无法进行预核验!");
  598. }
  599. return mzSrvc.rxPreCheck(siMzFeeUrl, request);
  600. }
  601. private RxPreCheckRequest makePreCheckRequest(RxPreCheckRequest request) {
  602. RxMdtrtInfo rxMdtrtInfo = rxDao.getRxMdtrtinfo(request.getHospRxno());
  603. RxPreCheck rxPreCheck = rxDao.getRxReceiptinfo(request.getHospRxno());
  604. fillMdtrtCertNo(request, rxPreCheck);
  605. rxPreCheck.setBizTypeCode("01");
  606. List<RxDrugDetail> rxDrugDetailList = rxDao.getRxDruginfo(request.getHospRxno());
  607. for (RxDrugDetail item : rxDrugDetailList) {
  608. String spec = item.getDrugSpec();
  609. String unt = String.valueOf(spec.charAt(spec.length() - 1));
  610. item.setDrugTotlcntEmp(unt);
  611. }
  612. List<RxDiseInfo> rxDiseInfoList = rxDao.getRxDiseinfo(request.getHospRxno());
  613. request.setRxPreCheck(rxPreCheck);
  614. request.setRxMdtrtinfo(rxMdtrtInfo);
  615. request.setRxDrugDetailList(rxDrugDetailList);
  616. request.setRxDiseInfoList(rxDiseInfoList);
  617. return request;
  618. }
  619. private void fillMdtrtCertNo(RxPreCheckRequest request, RxPreCheck rxPreCheck) {
  620. ReadCardType readCardType = request.getReadCardType();
  621. rxPreCheck.setMdtrtCertType(readCardType.getCode());
  622. if (readCardType == ReadCardType.SFZ) {
  623. return;
  624. }
  625. String readCardResult = request.getReadCardResult();
  626. if (StringUtil.isBlank(readCardResult)) {
  627. throw new BizException("没有获取到读卡信息,请稍后重试。");
  628. }
  629. if (readCardType == ReadCardType.DZPZ) {
  630. JSONObject qrinfo = JSONObject.parseObject(readCardResult);
  631. String ecToken = qrinfo.getString("ecToken");
  632. rxPreCheck.setMdtrtCertNo(ecToken);
  633. rxPreCheck.setEcToken(ecToken);
  634. } else if (readCardType == ReadCardType.SBK) {
  635. String[] out = readCardResult.split("\\|");
  636. rxPreCheck.setMdtrtCertNo(out[2]);
  637. rxPreCheck.setCardSn(out[3]);
  638. }
  639. }
  640. public ResultVo<JSONObject> rxSign(RxSignRequest request) {
  641. RxUpload pharInfo = rxDao.selectPharInfo(request.getStaffId());
  642. pharInfo.setHospRxno(request.getHospRxno());
  643. rxDao.updatePharInfo(pharInfo);
  644. RxUpload rxUpload = rxDao.selectRxUploadForSign(request.getHospRxno());
  645. RxSign rxSign = new RxSign();
  646. String j = JSONObject.toJSONStringWithDateFormat(rxUpload, "yyyy-MM-dd HH:mm:ss");
  647. rxSign.setOriginalValue(Base64.getEncoder().encodeToString(j.getBytes(StandardCharsets.UTF_8)));
  648. rxSign.setOriginalRxFile(rxDao.selectOriginRxFile(request.getHospRxno()));
  649. request.setRxSign(rxSign);
  650. return mzSrvc.rxSign(siMzFeeUrl, request);
  651. }
  652. public ResultVo<JSONObject> rxUpload(RxUploadRequest request) {
  653. RxUpload rxUpload = rxDao.selectFullRxUploadInfo(request.getHospRxno());
  654. request.setRxUpload(rxUpload);
  655. return mzSrvc.rxUpload(siMzFeeUrl, request);
  656. }
  657. public ResultVo<JSONObject> rxRevoke(RxRevokeRequest request) {
  658. RxRevoke rxRevoke = rxDao.selectRxRevoke(request);
  659. request.setRxRevoke(rxRevoke);
  660. return mzSrvc.rxRevoke(siMzFeeUrl, request);
  661. }
  662. public ResultVo<JSONObject> rxInfoQuery(RxInfoQueryRequest request) {
  663. RxInfoQuery rxInfoQuery = rxDao.selectRxInfoQuery(request.getHospRxno());
  664. request.setRxInfoQuery(rxInfoQuery);
  665. return mzSrvc.rxInfoQuery(siMzFeeUrl, request);
  666. }
  667. public ResultVo<JSONObject> rxAuditingQuery(RxAuditingQueryRequest request) {
  668. RxInfoQuery rxInfoQuery = rxDao.selectRxInfoQuery(request.getHospRxno());
  669. request.setRxAuditingQuery(rxInfoQuery);
  670. return mzSrvc.rxAuditingQuery(siMzFeeUrl, request);
  671. }
  672. public ResultVo<JSONObject> rxSetlQuery(RxSetlQueryRequest request) {
  673. RxInfoQuery rxInfoQuery = rxDao.selectRxInfoQuery(request.getHospRxno());
  674. request.setRxSetlQuery(rxInfoQuery);
  675. return mzSrvc.rxSetlQuery(siMzFeeUrl, request);
  676. }
  677. public ResultVo<String> regRevoke(RxRevokeRequest request) {
  678. MzPatientInfo patinfo = rxDao.getBriefPatInfo(request.getHospRxno());
  679. patinfo.setStaffId(request.getStaffId());
  680. return mzSrvc.revokeOutpatientRegistration(siMzFeeUrl, patinfo);
  681. }
  682. public ResultVo<JSONObject> medicineInquiry(MedicineInquiry inquiry) throws Exception {
  683. return mzSrvc.medicineInquiry(siMzFeeUrl, inquiry);
  684. }
  685. }