SiMzFeeService.java 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. package thyyxxk.simzfeeoprnsystm.service;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import thyyxxk.simzfeeoprnsystm.dao.SiLogDao;
  6. import thyyxxk.simzfeeoprnsystm.dao.SiMzDao;
  7. import thyyxxk.simzfeeoprnsystm.dao.SiSetldetailDao;
  8. import thyyxxk.simzfeeoprnsystm.dao.SiSetlinfoDao;
  9. import thyyxxk.simzfeeoprnsystm.dicts.*;
  10. import thyyxxk.simzfeeoprnsystm.external.WebHisService;
  11. import thyyxxk.simzfeeoprnsystm.pojo.*;
  12. import thyyxxk.simzfeeoprnsystm.pojo.ResultVo;
  13. import thyyxxk.simzfeeoprnsystm.pojo.SiPatInfo;
  14. import thyyxxk.simzfeeoprnsystm.utils.*;
  15. import lombok.extern.slf4j.Slf4j;
  16. import org.springframework.beans.factory.annotation.Autowired;
  17. import org.springframework.stereotype.Service;
  18. import java.math.BigDecimal;
  19. import java.math.RoundingMode;
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Objects;
  24. import java.util.concurrent.TimeUnit;
  25. @Slf4j
  26. @Service
  27. public class SiMzFeeService {
  28. private final SiMzDao mzDao;
  29. private final SiSetlinfoDao setlinfoDao;
  30. private final SiSetldetailDao setldetailDao;
  31. private final ExecService exec;
  32. private final WebHisService webHisService;
  33. private final MariadbService mariadbService;
  34. private static final String RESULT_CODE = "infcode";
  35. private static final String ERROR_MESSAGE = "err_msg";
  36. private static final String OUTPUT = "output";
  37. private final SiLogDao logDao;
  38. @Value("${web-his-url}")
  39. private String webHisUrl;
  40. @Autowired
  41. public SiMzFeeService(SiMzDao mzDao, SiSetlinfoDao setlinfoDao,
  42. SiSetldetailDao setldetailDao, ExecService exec, WebHisService webHisService, MariadbService mariadbService, SiLogDao logDao) {
  43. this.mzDao = mzDao;
  44. this.setlinfoDao = setlinfoDao;
  45. this.setldetailDao = setldetailDao;
  46. this.exec = exec;
  47. this.webHisService = webHisService;
  48. this.mariadbService = mariadbService;
  49. this.logDao = logDao;
  50. }
  51. public ResultVo<String> outpatientRegistration(MzPatientInfo p) {
  52. Regstrtn regstrtn = mzDao.selectRegstrtn(p.getPatNo(), p.getTimes());
  53. if (null == regstrtn) {
  54. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "mz_visit_table患者信息为空,请联系医生重开处方。");
  55. }
  56. ReadCardBizType readCardBizType = ReadCardBizType.get(p.getReadCardBizType());
  57. if (readCardBizType != ReadCardBizType.REGISTRATION && !p.getInsuplcAdmdvs().startsWith("43")) {
  58. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "省外异地的患者请读社保卡或医保电子凭证登记!");
  59. }
  60. if (StringUtil.notBlank(p.getMedType())) {
  61. mzDao.updateMedtype(p.getMedType(), p.getPatNo(), p.getTimes());
  62. }
  63. if (readCardBizType == ReadCardBizType.REGISTRATION) {
  64. MdtrtCertType mdtrtCertType = MdtrtCertType.getByLabel(p.getMdtrtCertType());
  65. regstrtn.setMdtrtCertType(mdtrtCertType.getCode());
  66. if (mdtrtCertType.getCode().equals(MdtrtCertType.SOCIAL_SECURITY_CARD.getCode())) {
  67. String[] out = p.getReadCardResult().split("\\|");
  68. regstrtn.setMdtrtCertNo(out[2]);
  69. regstrtn.setCardSn(out[3]);
  70. } else if (mdtrtCertType.getCode().equals(MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER.getCode())) {
  71. JSONObject qrinfo = JSONObject.parseObject(p.getReadCardResult());
  72. regstrtn.setMdtrtCertNo(qrinfo.getString("ecToken"));
  73. }
  74. }
  75. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.OUTPATIENT_REGISTRATION,
  76. p.getInsuplcAdmdvs(), p.getStaffId());
  77. regstrtn.setInsutype(p.getInsutype());
  78. regstrtn.setPsnType(p.getPsnType());
  79. regstrtn.setIptOtpNo(p.getPatNo());
  80. String ref = JSONObject.toJSONStringWithDateFormat(regstrtn, "yyyy-MM-dd HH:mm:ss");
  81. input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
  82. JSONObject result = exec.executeTrade(input, SiFunction.OUTPATIENT_REGISTRATION);
  83. log.info("【操作员:{}】,门诊挂号:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  84. if (null == result) {
  85. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  86. }
  87. Integer infcode = result.getInteger(RESULT_CODE);
  88. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, regstrtn.getPsnNo()));
  89. if (null == infcode) {
  90. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  91. }
  92. if (infcode == 0) {
  93. JSONObject output = result.getJSONObject(OUTPUT).getJSONObject("data");
  94. p.setMdtrtId(output.getString("mdtrt_id"));
  95. p.setVisitDate(regstrtn.getBegntime());
  96. mzDao.afterRegistrtn(p);
  97. return ResultVoUtil.success("挂号成功。");
  98. }
  99. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  100. }
  101. public ResultVo<String> revokeOutpatientRegistration(MzPatientInfo p) {
  102. if (null == p.getTimes()) {
  103. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  104. }
  105. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(p.getPatNo(), p.getTimes());
  106. if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
  107. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保挂号信息。");
  108. }
  109. RevokeRegRequest request = new RevokeRegRequest();
  110. request.setInsuplcAdmdvs(siPatInfo.getInsuplcAdmdvs()); ;
  111. request.setStaffId(p.getStaffId());
  112. request.setPsnNo(siPatInfo.getPsnNo());
  113. request.setMdtrtId(siPatInfo.getMdtrtId());
  114. request.setPatNo(p.getPatNo());
  115. request.setTimes(p.getTimes());
  116. return executeOutpatientRegRevoke(request);
  117. }
  118. public ResultVo<String> executeOutpatientRegRevoke(RevokeRegRequest request) {
  119. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_REGISTRATION,
  120. request.getInsuplcAdmdvs(), request.getStaffId());
  121. JSONObject data = new JSONObject();
  122. data.put("psn_no", request.getPsnNo());
  123. data.put("mdtrt_id", request.getMdtrtId());
  124. data.put("ipt_otp_no", request.getPatNo());
  125. input.getJSONObject("input").put("data", data);
  126. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_REGISTRATION);
  127. log.info("【操作员:{}】,取消门诊挂号:\n参数:{},\n结果:{}", request.getStaffId(), input, result);
  128. if (null == result) {
  129. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  130. }
  131. Integer infcode = result.getInteger(RESULT_CODE);
  132. logDao.insert(new SiLog(input, result, request.getPatNo(), request.getTimes(), infcode, request.getPsnNo()));
  133. if (null == infcode) {
  134. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  135. }
  136. if (infcode == 0) {
  137. mzDao.clearMdtrtIdForMz(request.getPatNo(), request.getTimes(), null);
  138. return ResultVoUtil.success("取消门诊挂号成功。");
  139. }
  140. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  141. }
  142. private ResultVo<String> uploadOutpatientInfo(SpcChrDiseAcct spcChrDiseAcct, SiPatInfo siPatInfo) {
  143. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.UPLOAD_OUTPATIENT_INFO,
  144. siPatInfo.getInsuplcAdmdvs(), spcChrDiseAcct.getStaffId());
  145. JSONObject mdtrtinfo = new JSONObject();
  146. List<Diagnoses> diagnosesList = new ArrayList<>();
  147. String icdCodeNew = mzDao.selectIcdCodeNew(siPatInfo.getPatNo(), siPatInfo.getTimes());
  148. if (StringUtil.isBlank(icdCodeNew)) {
  149. diagnosesList = mzDao.selectMzDiags(siPatInfo.getPatNo(), siPatInfo.getTimes());
  150. if (null == diagnosesList || diagnosesList.isEmpty()) {
  151. log.info("【{}】 上传就诊信息失败,门诊诊断为空。", siPatInfo.getPatNo());
  152. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者的门诊诊断为空,请联系医生填写。");
  153. }
  154. } else {
  155. Diagnoses base = mzDao.selectDiseinfo(siPatInfo.getPatNo(), siPatInfo.getTimes());
  156. String[] icds = icdCodeNew.split(",");
  157. for (int i = 0; i < icds.length; i++) {
  158. String icd = icds[i];
  159. String icdTextNew = mzDao.selectIcdTextNew(icd);
  160. Diagnoses diag = new Diagnoses();
  161. diag.setDiagCode(icd);
  162. diag.setDiagName(icdTextNew);
  163. diag.setDiagSrtNo(i + 1);
  164. diag.setDiagType("1");
  165. diag.setValiFlag("1");
  166. diag.setDiagDept(base.getDiagDept());
  167. diag.setDiagTime(base.getDiagTime());
  168. diag.setDiseDorNo(base.getDiseDorNo());
  169. diag.setDiseDorName(base.getDiseDorName());
  170. diagnosesList.add(diag);
  171. }
  172. }
  173. if (siPatInfo.getMedType().equals("14") || siPatInfo.getMedType().equals("51")) {
  174. if (StringUtil.isBlank(spcChrDiseAcct.getOpspDiseCode())) {
  175. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "生育门诊与慢特病门诊的病种不能为空 !");
  176. }
  177. }
  178. mdtrtinfo.put("mdtrt_id", siPatInfo.getMdtrtId());
  179. mdtrtinfo.put("psn_no", siPatInfo.getPsnNo());
  180. mdtrtinfo.put("med_type", siPatInfo.getMedType());
  181. mdtrtinfo.put("begntime", DateUtil.formatDatetime(siPatInfo.getVisitDatetime()));
  182. mdtrtinfo.put("main_cond_dscr", spcChrDiseAcct.getOpspDiseName());
  183. mdtrtinfo.put("dise_codg", spcChrDiseAcct.getOpspDiseCode());
  184. mdtrtinfo.put("dise_name", spcChrDiseAcct.getOpspDiseName());
  185. mdtrtinfo.put("birctrl_type", "");
  186. mdtrtinfo.put("birctrl_matn_date", "");
  187. mdtrtinfo.put("exp_content", spcChrDiseAcct.getExpContent());
  188. String ref = JSONObject.toJSONString(diagnosesList);
  189. input.getJSONObject("input").put("mdtrtinfo", mdtrtinfo);
  190. input.getJSONObject("input").put("diseinfo", JSONArray.parse(ref));
  191. JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_OUTPATIENT_INFO);
  192. log.info("【操作员:{}】门诊就诊信息上传:\n参数:{},\n结果:{}", spcChrDiseAcct.getStaffId(), input, result);
  193. Integer infcode = result.getInteger(RESULT_CODE);
  194. logDao.insert(new SiLog(input, result, siPatInfo.getPatNo(), siPatInfo.getTimes(), infcode, siPatInfo.getPsnNo()));
  195. if (result.getIntValue(RESULT_CODE) == 0) {
  196. Diagnoses main = diagnosesList.get(0);
  197. mzDao.updatePatDiseinfo(siPatInfo.getPatNo(), siPatInfo.getTimes(), main.getDiagCode(), main.getDiagName());
  198. return ResultVoUtil.success("门诊就诊信息上传成功。");
  199. }
  200. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  201. }
  202. public ResultVo<SiPatInfo> uploadOutpatientFeeDetails(SpcChrDiseAcct p) {
  203. String patNo = p.getPatNo();
  204. if (null == p.getTimes()) {
  205. p.setTimes(mzDao.selectMaxTimes(patNo));
  206. }
  207. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(patNo, p.getTimes());
  208. if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
  209. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【门诊号:" + patNo +
  210. "】未找到此患者的医保挂号信息,请核实。");
  211. }
  212. if (!p.getFromDirectReg()) {
  213. ResultVo<String> uplRes = uploadOutpatientInfo(p, siPatInfo);
  214. if (null != uplRes && uplRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  215. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, uplRes.getMessage());
  216. }
  217. }
  218. List<FeeDetail> feeDetails = mzDao.selectOutpatientFees(patNo, p.getTimes());
  219. if (null == feeDetails || feeDetails.isEmpty()) {
  220. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有需要上传的费用。");
  221. }
  222. MzVisit mzVisit = mzDao.selectMzVisitInfo(patNo, p.getTimes());
  223. if (null == mzVisit || StringUtil.isBlank(mzVisit.getVisitDeptCode())) {
  224. log.info("【{},{}】就诊科室没有匹配医保码,无法使用门诊统筹。", patNo, p.getTimes());
  225. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "就诊科室没有匹配医保码,无法使用门诊统筹。");
  226. }
  227. String batchNo = patNo + "_" + p.getTimes();
  228. feeDetails.forEach(item -> {
  229. item.setMdtrtId(siPatInfo.getMdtrtId());
  230. item.setPsnNo(siPatInfo.getPsnNo());
  231. item.setChrgBchno(batchNo);
  232. item.setRxCircFlag(YesOrNo.NO.getCodeStr());
  233. item.setHospApprFlag(YesOrNo.YES.getCodeStr());
  234. item.setBilgDeptCodg(mzVisit.getVisitDeptCode());
  235. item.setBilgDeptName(mzVisit.getVisitDeptName());
  236. if (siPatInfo.getMedType().equals("51")) {
  237. item.setMatnFeeFlag("1");
  238. }
  239. });
  240. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.UPLOAD_OUTPATIENT_FEE_DETAILS,
  241. siPatInfo.getInsuplcAdmdvs(), p.getStaffId());
  242. String ref = JSONArray.toJSONStringWithDateFormat(feeDetails, "yyyy-MM-dd HH:mm:ss");
  243. JSONArray feedetail = JSONArray.parseArray(ref);
  244. input.getJSONObject("input").put("feedetail", feedetail);
  245. JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_OUTPATIENT_FEE_DETAILS);
  246. log.info("【操作员:{}】门诊费用明细信息上传:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  247. if (null == result) {
  248. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  249. }
  250. Integer infcode = result.getInteger(RESULT_CODE);
  251. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, siPatInfo.getPsnNo()));
  252. if (null == infcode) {
  253. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  254. }
  255. if (infcode == 0) {
  256. JSONArray feeRes = result.getJSONObject(OUTPUT).getJSONArray("result");
  257. double fulamtOwnpayAmt = 0d;
  258. double overlmtAmt = 0d;
  259. double preselfpayAmt = 0d;
  260. double inscpScpAmt = 0d;
  261. for (int i = 0; i < feeRes.size(); i++) {
  262. JSONObject fee = feeRes.getJSONObject(i);
  263. fulamtOwnpayAmt += fee.getDoubleValue("fulamt_ownpay_amt");
  264. overlmtAmt += fee.getDoubleValue("overlmt_amt");
  265. preselfpayAmt += fee.getDoubleValue("preselfpay_amt");
  266. inscpScpAmt += fee.getDoubleValue("inscp_scp_amt");
  267. String detlSn = fee.getString("feedetl_sn");
  268. String chrgLv = fee.getString("chrgitm_lv");
  269. String chrgType = fee.getString("med_chrgitm_type");
  270. String[] sns = detlSn.split("_");
  271. int times = Integer.parseInt(sns[1]);
  272. int recNo = Integer.parseInt(sns[2]);
  273. int odrNo = Integer.parseInt(sns[3]);
  274. int itmNo = Integer.parseInt(sns[4]);
  275. mzDao.afterUploadFees(patNo, times, recNo, odrNo, itmNo, chrgLv, chrgType);
  276. }
  277. siPatInfo.setFulamtOwnpayAmt(fulamtOwnpayAmt);
  278. siPatInfo.setOverlmtAmt(overlmtAmt);
  279. siPatInfo.setPreselfpayAmt(preselfpayAmt);
  280. siPatInfo.setInscpScpAmt(inscpScpAmt);
  281. mzDao.updateSortOfAmt(siPatInfo);
  282. return ResultVoUtil.success(siPatInfo);
  283. }
  284. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  285. }
  286. public ResultVo<String> revokeOutpatientFeeDetails(MzPatientInfo p) {
  287. if (null == p.getTimes()) {
  288. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  289. }
  290. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(p.getPatNo(), p.getTimes());
  291. if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
  292. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有此患者的医保挂号信息!");
  293. }
  294. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_FEE_DETAILS,
  295. siPatInfo.getInsuplcAdmdvs(), p.getStaffId());
  296. JSONObject data = new JSONObject();
  297. data.put("mdtrt_id", siPatInfo.getMdtrtId());
  298. data.put("psn_no", siPatInfo.getPsnNo());
  299. data.put("chrg_bchno", "0000");
  300. input.getJSONObject("input").put("data", data);
  301. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_FEE_DETAILS);
  302. log.info("【操作员:{}】门诊费用明细信息撤销,参数:{},结果:{}", p.getStaffId(), input, result);
  303. if (null == result) {
  304. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  305. }
  306. Integer infcode = result.getInteger(RESULT_CODE);
  307. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, siPatInfo.getPsnNo()));
  308. if (null == infcode) {
  309. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  310. }
  311. if (infcode == 0) {
  312. mzDao.afterRevokeFees(p.getPatNo(), p.getTimes());
  313. return ResultVoUtil.success("门诊费用明细信息撤销成功。");
  314. }
  315. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  316. }
  317. public ResultVo<FundDetail> outpatientPreSettlement(MzPatientInfo p) {
  318. while (MzgjUtil.inProcessing(p.getPatNo())) {
  319. try {
  320. TimeUnit.SECONDS.sleep(1);
  321. } catch (InterruptedException e) {
  322. throw new RuntimeException(e);
  323. }
  324. }
  325. if (null == p.getTimes()) {
  326. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  327. }
  328. ResultVo<FundDetail> setlfund = getFundDetailByPatientInfo(p.getPatNo(), p.getTimes());
  329. if (setlfund != null) {
  330. return setlfund;
  331. }
  332. MzPreSetlmt mzPreSetlmt = mzDao.selectPreSetlmt(p.getPatNo(), p.getTimes());
  333. if (null == mzPreSetlmt || null == mzPreSetlmt.getMedfeeSumamt()) {
  334. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者没有已上传的费用。");
  335. }
  336. ReadCardBizType readCardBizType = ReadCardBizType.get(p.getReadCardBizType());
  337. if (readCardBizType == ReadCardBizType.SETTLEMENT) {
  338. MdtrtCertType mdtrtCertType = MdtrtCertType.getByLabel(p.getMdtrtCertType());
  339. mzPreSetlmt.setMdtrtCertType(mdtrtCertType.getCode());
  340. if (mdtrtCertType.getCode().equals(MdtrtCertType.SOCIAL_SECURITY_CARD.getCode())) {
  341. String[] out = p.getReadCardResult().split("\\|");
  342. mzPreSetlmt.setMdtrtCertNo(out[2]);
  343. mzPreSetlmt.setCardSn(out[3]);
  344. } else if (mdtrtCertType.getCode().equals(MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER.getCode())) {
  345. JSONObject qrinfo = JSONObject.parseObject(p.getReadCardResult());
  346. if (!p.getSocialNo().trim().equals(qrinfo.getString("idNo").trim())) {
  347. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证身份证与HIS身份证不一致,请确认是否人证相符。");
  348. }
  349. mzPreSetlmt.setMdtrtCertNo(qrinfo.getString("ecToken"));
  350. }
  351. }
  352. mzPreSetlmt.setMedfeeSumamt(mzPreSetlmt.getMedfeeSumamt().setScale(2, RoundingMode.HALF_UP));
  353. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.OUTPATIENT_PRE_SETTLEMENT,
  354. mzPreSetlmt.getInsuplcAdmdvs(), p.getStaffId());
  355. mzPreSetlmt.setPsnSetlway(PsnSetlWay.SETTLE_BY_ITEMS.getCode());
  356. mzPreSetlmt.setAcctUsedFlag(p.getAcctUsedFlag());
  357. mzPreSetlmt.setChrgBchno(p.getPatNo() + "_" + p.getTimes());
  358. mzPreSetlmt.setExpContent(p.getExpContent());
  359. String ref = JSONObject.toJSONString(mzPreSetlmt);
  360. input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
  361. JSONObject result = exec.executeTrade(input, SiFunction.OUTPATIENT_PRE_SETTLEMENT);
  362. log.info("【操作员:{}】门诊预结算:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  363. if (null == result) {
  364. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  365. }
  366. Integer infcode = result.getInteger(RESULT_CODE);
  367. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, mzPreSetlmt.getPsnNo()));
  368. if (null == infcode) {
  369. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  370. }
  371. if (infcode == 0) {
  372. JSONObject setlinfo = result.getJSONObject(OUTPUT).getJSONObject("setlinfo");
  373. FundDetail fundDetail = new FundDetail();
  374. fundDetail.setTotalCost(setlinfo.getString("medfee_sumamt"));
  375. fundDetail.setFundPay(setlinfo.getString("fund_pay_sumamt"));
  376. fundDetail.setCashPay(setlinfo.getString("psn_cash_pay"));
  377. fundDetail.setAcctPay(setlinfo.getString("acct_pay"));
  378. fundDetail.setSelfPay(setlinfo.getString("psn_part_amt"));
  379. fundDetail.setCardType(getCardType(mzPreSetlmt.getInsuplcAdmdvs()));
  380. return ResultVoUtil.success(fundDetail);
  381. }
  382. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  383. }
  384. private ResultVo<FundDetail> getFundDetailByPatientInfo(String patientId, int times) {
  385. SiSetlinfo sisetlinfo = mzDao.selectSettledInfo(patientId, times, 0);
  386. if (null != sisetlinfo && null != sisetlinfo.getSetlId()) {
  387. return getFundDetailFromSetlinfo(sisetlinfo);
  388. }
  389. return null;
  390. }
  391. private ResultVo<FundDetail> getFundDetailFromSetlinfo(SiSetlinfo setlinfo) {
  392. FundDetail fundDetail = new FundDetail();
  393. fundDetail.setCardType(getCardType(setlinfo.getInsuplcAdmdvs()));
  394. fundDetail.setTotalCost(String.valueOf(setlinfo.getMedfeeSumamt()));
  395. fundDetail.setFundPay(String.valueOf(setlinfo.getFundPaySumamt()));
  396. fundDetail.setCashPay(String.valueOf(setlinfo.getPsnCashPay()));
  397. fundDetail.setAcctPay(String.valueOf(setlinfo.getAcctPay()));
  398. fundDetail.setSelfPay(String.valueOf(setlinfo.getPsnPartAmt()));
  399. if (setlinfo.getRevoked() == 1) {
  400. fundDetail.reverseAll();
  401. }
  402. fundDetail.setSetlinfo(setlinfo);
  403. return ResultVoUtil.success(fundDetail);
  404. }
  405. private Integer getCardType(String insplc) {
  406. if (insplc.startsWith("4301")) {
  407. return 1;
  408. } else if (insplc.equals("439900")) {
  409. return 2;
  410. }
  411. return 3;
  412. }
  413. public ResultVo<FundDetail> outpatientSettlement(MzPatientInfo p) {
  414. ResultVo<FundDetail> setlfund = getFundDetailByPatientInfo(p.getPatNo(), p.getTimes());
  415. if (setlfund != null) {
  416. return setlfund;
  417. }
  418. Setlmt setlmt = mzDao.selectSetlmt(p.getPatNo(), p.getTimes());
  419. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.OUTPATIENT_SETTLEMENT,
  420. setlmt.getInsuplcAdmdvs(), p.getStaffId());
  421. ReadCardBizType readCardBizType = ReadCardBizType.get(p.getReadCardBizType());
  422. if (readCardBizType == ReadCardBizType.SETTLEMENT) {
  423. MdtrtCertType mdtrtCertType = MdtrtCertType.getByLabel(p.getMdtrtCertType());
  424. setlmt.setMdtrtCertType(mdtrtCertType.getCode());
  425. if (mdtrtCertType.getCode().equals(MdtrtCertType.SOCIAL_SECURITY_CARD.getCode())) {
  426. String[] out = p.getReadCardResult().split("\\|");
  427. setlmt.setMdtrtCertNo(out[2]);
  428. setlmt.setCardSn(out[3]);
  429. } else if (mdtrtCertType.getCode().equals(MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER.getCode())) {
  430. JSONObject qrinfo = JSONObject.parseObject(p.getReadCardResult());
  431. if (!p.getSocialNo().trim().equals(qrinfo.getString("idNo").trim())) {
  432. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证身份证与HIS身份证不一致,请确认是否人证相符。");
  433. }
  434. setlmt.setMdtrtCertNo(qrinfo.getString("ecToken"));
  435. }
  436. }
  437. setlmt.setMedfeeSumamt(setlmt.getMedfeeSumamt().setScale(2, RoundingMode.HALF_UP));
  438. setlmt.setPsnSetlway(PsnSetlWay.SETTLE_BY_ITEMS.getCode());
  439. setlmt.setChrgBchno(p.getPatNo() + "_" + p.getTimes());
  440. setlmt.setAcctUsedFlag(p.getAcctUsedFlag());
  441. setlmt.setInvono(SnowFlakeId.getInstance().nextId());
  442. setlmt.setExpContent(p.getExpContent());
  443. String ref = JSONObject.toJSONString(setlmt);
  444. input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
  445. JSONObject result = exec.executeTrade(input, SiFunction.OUTPATIENT_SETTLEMENT);
  446. log.info("【操作员:{}】门诊结算:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  447. if (null == result) {
  448. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR, "与医保中心的连接出现网络异常!");
  449. }
  450. Integer infcode = result.getInteger(RESULT_CODE);
  451. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, setlmt.getPsnNo()));
  452. if (null == infcode) {
  453. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  454. }
  455. if (infcode == 0) {
  456. JSONObject setlinfo = result.getJSONObject(OUTPUT).getJSONObject("setlinfo");
  457. SiSetlinfo setlEntity = JSONObject.parseObject(setlinfo.toJSONString(), SiSetlinfo.class);
  458. setlEntity.setPatNo(p.getPatNo());
  459. setlEntity.setTimes(p.getTimes());
  460. setlEntity.setLedgerSn(0);
  461. setlEntity.setStaffId(p.getStaffId());
  462. setlEntity.setRevoked(YesOrNo.NO.getCode());
  463. setlEntity.setSetlType(ClrType.OUTPATIENT.getCode());
  464. setlEntity.setInsuplcAdmdvs(setlmt.getInsuplcAdmdvs());
  465. setlEntity.setBegntime(mzDao.selectBegntime(p.getPatNo(), p.getTimes()));
  466. setlEntity.setEndtime(setlEntity.getSetlTime());
  467. setlEntity.setMzSaved(p.getSaved());
  468. BigDecimal hospitalPart = BigDecimal.ZERO;
  469. JSONArray setldetail = result.getJSONObject(OUTPUT).getJSONArray("setldetail");
  470. for (int i = 0; i < setldetail.size(); i++) {
  471. SiSetldetail setldetailEntity = JSONObject.parseObject(setldetail.getJSONObject(i).toJSONString(),
  472. SiSetldetail.class);
  473. setldetailEntity.setPatNo(p.getPatNo());
  474. setldetailEntity.setTimes(p.getTimes());
  475. setldetailEntity.setLedgerSn(0);
  476. if (setldetailEntity.getFundPayType().equals("999996") || setldetailEntity.getSetlProcInfo().equals("999996")) {
  477. hospitalPart = hospitalPart.add(BigDecimal.valueOf(setldetailEntity.getFundPayamt()));
  478. }
  479. setldetailDao.insert(setldetailEntity);
  480. }
  481. setlEntity.setHospPartAmt(hospitalPart.doubleValue());
  482. setlinfoDao.insert(setlEntity);
  483. setlinfoDao.updateSiZyInfoSetlId(p.getPatNo(), p.getTimes(), 0, setlEntity.getSetlId(),
  484. setlEntity.getMedinsSetlId(), input.getString("msgid"));
  485. webHisService.saveCumInfo(webHisUrl, setlEntity);
  486. if (BigDecimal.ZERO.compareTo(BigDecimal.valueOf(setlEntity.getPsnCashPay())) == 0) {
  487. ResultVo<String> mzChargeResponse = mzChargeFee(p.getPatNo(), p.getTimes(),
  488. String.valueOf(setlEntity.getMedfeeSumamt()));
  489. if (mzChargeResponse.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  490. revokeOutpatientSettlementForTask(setlEntity);
  491. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, mzChargeResponse.getMessage());
  492. }
  493. }
  494. return getFundDetailFromSetlinfo(setlEntity);
  495. }
  496. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  497. }
  498. public ResultVo<FundDetail> revokeOutpatientSettlement(MzPatientInfo p) {
  499. if (null == p.getTimes()) {
  500. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  501. }
  502. SiSetlinfo setlinfo = mzDao.selectSettledInfo(p.getPatNo(), p.getTimes(), 0);
  503. if (null == setlinfo) {
  504. setlinfo = mzDao.selectSettledInfo(p.getPatNo(), p.getTimes(), 1);
  505. if (null == setlinfo) {
  506. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有此患者的已结算数据。");
  507. }
  508. return getFundDetailFromSetlinfo(setlinfo);
  509. }
  510. String staffDept = mzDao.selectStaffDepartment(p.getStaffId());
  511. if (!Objects.equals(staffDept, "3020100") &&
  512. !Objects.equals(staffDept, "3060000") &&
  513. !Objects.equals(staffDept, "3100000")) {
  514. if (!Objects.equals(p.getStaffId(), setlinfo.getStaffId())) {
  515. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "您没有权限撤销本条医保业务,请到收费窗口退处方,或者联系医保科处理。");
  516. }
  517. }
  518. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_SETTLEMENT,
  519. mzDao.selectAdmdvs(setlinfo.getPatNo(), setlinfo.getTimes(), setlinfo.getLedgerSn()), p.getStaffId());
  520. JSONObject data = new JSONObject();
  521. data.put("setl_id", setlinfo.getSetlId());
  522. data.put("mdtrt_id", setlinfo.getMdtrtId());
  523. data.put("psn_no", setlinfo.getPsnNo());
  524. input.getJSONObject("input").put("data", data);
  525. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_SETTLEMENT);
  526. log.info("【操作员:{}】门诊结算撤销:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  527. if (null == result) {
  528. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  529. }
  530. Integer infcode = result.getInteger(RESULT_CODE);
  531. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, setlinfo.getPsnNo()));
  532. if (null == infcode) {
  533. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  534. }
  535. if (infcode == 0) {
  536. afterRevokeSetl(p.getPatNo(), p.getTimes(), input.getString("msgid"));
  537. if (null != p.getNeedRevokeRegistration() && p.getNeedRevokeRegistration() == 1) {
  538. revokeOutpatientFeeDetails(p);
  539. revokeOutpatientRegistration(p);
  540. }
  541. return getFundDetailFromSetlinfo(setlinfo);
  542. }
  543. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  544. }
  545. public void revokeOutpatientSettlementForTask(SiSetlinfo setlinfo) {
  546. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_SETTLEMENT,
  547. mzDao.selectAdmdvs(setlinfo.getPatNo(), setlinfo.getTimes(), setlinfo.getLedgerSn()), "99999");
  548. JSONObject data = new JSONObject();
  549. data.put("setl_id", setlinfo.getSetlId());
  550. data.put("mdtrt_id", setlinfo.getMdtrtId());
  551. data.put("psn_no", setlinfo.getPsnNo());
  552. input.getJSONObject("input").put("data", data);
  553. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_SETTLEMENT);
  554. log.info("【操作员:99999】门诊结算撤销:\n参数:{},\n结果:{}", input, result);
  555. Integer infcode = result.getInteger(RESULT_CODE);
  556. logDao.insert(new SiLog(input, result, setlinfo.getPatNo(), setlinfo.getTimes(), infcode, setlinfo.getPsnNo()));
  557. if (null != infcode && infcode == 0) {
  558. afterRevokeSetl(setlinfo.getPatNo(), setlinfo.getTimes(), input.getString("msgid"));
  559. MzPatientInfo mzPatientInfo = new MzPatientInfo();
  560. mzPatientInfo.setPatNo(setlinfo.getPatNo());
  561. mzPatientInfo.setTimes(setlinfo.getTimes());
  562. mzPatientInfo.setStaffId("99999");
  563. revokeOutpatientFeeDetails(mzPatientInfo);
  564. revokeOutpatientRegistration(mzPatientInfo);
  565. }
  566. }
  567. public void afterRevokeSetl(String patNo, int times, String msgId) {
  568. try {
  569. mzDao.deleteSetlInfo(patNo, times);
  570. mzDao.deleteSetlDetail(patNo, times);
  571. mzDao.updateRvkSetlMsgid(patNo, times, msgId);
  572. } catch (Exception e) {
  573. String sql1 = String.format("update t_si_setlinfo set revoked=1,mz_saved=0 where pat_no='%s' and times=%d;\n", patNo, times);
  574. String sql2 = String.format("delete from t_si_setldetail where pat_no='%s' and times=%d;\n", patNo, times);
  575. String sql3 = String.format("update t_si_pat_info set rvk_setl_msgid='%s' where pat_no='%s' and times=%d;",
  576. msgId, patNo, times);
  577. String sql = sql1 + sql2 + sql3;
  578. mariadbService.insertNewRecord(sql);
  579. }
  580. }
  581. public ResultVo<FundDetail> directRegistration(DirectionRegParam param) {
  582. log.info("门诊共济:{}", param);
  583. if (MzgjUtil.inProcessing(param.getPatientId())) {
  584. log.info("【{}】此患者上一次的共济流程尚未结束,请稍后再试。", param.getPatientId());
  585. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者上一次的共济流程尚未结束,请稍后再试。");
  586. }
  587. ResultVo<FundDetail> setlfund = getFundDetailByPatientInfo(param.getPatientId(), param.getTimes());
  588. if (setlfund != null) {
  589. return setlfund;
  590. }
  591. MzgjUtil.addProcess(param.getPatientId());
  592. try {
  593. return executeMzgj(param);
  594. } catch (Exception e) {
  595. log.error("门诊共济出错:", e);
  596. return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, e.getMessage());
  597. } finally {
  598. MzgjUtil.finishProcessing(param.getPatientId());
  599. }
  600. }
  601. private ResultVo<FundDetail> executeMzgj(DirectionRegParam param) {
  602. if (mzDao.selectExistCount(param.getPatientId(), param.getTimes()) == 0) {
  603. int update = mzDao.updateMzTimes(param.getPatientId(), param.getTimes());
  604. if (update == 0) {
  605. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR,
  606. "不存在此患者第[" + param.getTimes() + "]次的就诊信息,请重新查询。");
  607. }
  608. }
  609. mzDao.deleteTempPatinfo(param.getPatientId(), param.getTimes());
  610. MzPatientInfo mzptnt = new MzPatientInfo();
  611. mzptnt.setStaffId(param.getStaffId());
  612. mzptnt.setPatNo(param.getPatientId());
  613. mzptnt.setTimes(param.getTimes());
  614. mzptnt.setMedType("11");
  615. mzptnt.setAcctUsedFlag(String.valueOf(param.getAcctUsedFlag()));
  616. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(mzptnt.getPatNo(), mzptnt.getTimes());
  617. mzptnt.setInsuplcAdmdvs(siPatInfo.getInsuplcAdmdvs());
  618. mzptnt.setInsutype(siPatInfo.getInsutype());
  619. mzptnt.setPsnType(siPatInfo.getPsnType());
  620. mzptnt.setName(siPatInfo.getPsnName());
  621. mzptnt.setSocialNo(siPatInfo.getCertno());
  622. if (StringUtil.notBlank(param.getReadCardResult())) {
  623. MdtrtCertType mdtrtCertType = MdtrtCertType.get(param.getReadCardType());
  624. mzptnt.setMdtrtCertType(mdtrtCertType.getLabel());
  625. mzptnt.setReadCardBizType(ReadCardBizType.REGISTRATION.getCode());
  626. mzptnt.setReadCardResult(param.getReadCardResult());
  627. }
  628. ResultVo<String> regres = outpatientRegistration(mzptnt);
  629. if (null == regres) {
  630. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  631. }
  632. if (regres.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  633. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, regres.getMessage());
  634. }
  635. // 挂号登记成功后上传就诊信息
  636. siPatInfo = mzDao.selectSiPatInfoForMz(mzptnt.getPatNo(), mzptnt.getTimes());
  637. siPatInfo.setFromDirectReg(true);
  638. SpcChrDiseAcct spcChrDiseAcct = new SpcChrDiseAcct();
  639. spcChrDiseAcct.setStaffId(param.getStaffId());
  640. spcChrDiseAcct.setExpContent(param.getExpContent());
  641. ResultVo<String> upldMdtrtRes = uploadOutpatientInfo(spcChrDiseAcct, siPatInfo);
  642. if (null == upldMdtrtRes) {
  643. revokeOutpatientRegistration(mzptnt);
  644. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  645. }
  646. if (upldMdtrtRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  647. revokeOutpatientRegistration(mzptnt);
  648. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, upldMdtrtRes.getMessage());
  649. }
  650. // 上传就诊信息成功后生成门诊医保费用
  651. ResultVo<List<Map<String, Object>>> getMzRcptRes = webHisService.getMzReceipts(webHisUrl, mzptnt);
  652. if (null == getMzRcptRes) {
  653. revokeOutpatientRegistration(mzptnt);
  654. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  655. }
  656. if (getMzRcptRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  657. revokeOutpatientRegistration(mzptnt);
  658. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, getMzRcptRes.getMessage());
  659. }
  660. List<MzReceipt> mzReceipts = new ArrayList<>();
  661. for (Map<String, Object> item : getMzRcptRes.getData()) {
  662. int times = (int) item.get("times");
  663. if (times != mzptnt.getTimes()) {
  664. continue;
  665. }
  666. mzDao.deleteAllReceipts(param.getPatientId(), times);
  667. Map<Integer, List<MzReceipt>> orderReceiptsMap = FilterUtil.cast(item.get("mzReceipts"));
  668. for (Map.Entry<Integer, List<MzReceipt>> entry : orderReceiptsMap.entrySet()) {
  669. mzReceipts.addAll(entry.getValue());
  670. }
  671. }
  672. if (mzReceipts.isEmpty()) {
  673. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有可以上传到医保的费用。");
  674. }
  675. ResultVo<String> insertSiMzFeeRes = webHisService.insertSiMzFees(webHisUrl, mzReceipts);
  676. if (null == insertSiMzFeeRes) {
  677. revokeOutpatientRegistration(mzptnt);
  678. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  679. }
  680. if (insertSiMzFeeRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  681. revokeOutpatientRegistration(mzptnt);
  682. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, insertSiMzFeeRes.getMessage());
  683. }
  684. // 生成费用成功后上传到医保
  685. spcChrDiseAcct.setStaffId(param.getStaffId());
  686. spcChrDiseAcct.setPatNo(mzptnt.getPatNo());
  687. spcChrDiseAcct.setTimes(mzptnt.getTimes());
  688. spcChrDiseAcct.setFromDirectReg(true);
  689. ResultVo<SiPatInfo> upldFeeRes = uploadOutpatientFeeDetails(spcChrDiseAcct);
  690. if (null == upldFeeRes) {
  691. revokeOutpatientRegistration(mzptnt);
  692. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  693. }
  694. if (upldFeeRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  695. revokeOutpatientRegistration(mzptnt);
  696. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, upldFeeRes.getMessage());
  697. }
  698. // 上传完成之后结算并返回结算结果
  699. mzptnt.setReadCardBizType(ReadCardBizType.SETTLEMENT.getCode());
  700. return outpatientSettlement(mzptnt);
  701. }
  702. private ResultVo<String> mzChargeFee(String patientId, int times, String totalFee) {
  703. JSONObject params = new JSONObject();
  704. params.put("patientId", patientId);
  705. params.put("times", times);
  706. params.put("totalFee", totalFee);
  707. int tryTimes = 1;
  708. JSONObject response = webHisService.mzChargeFee(params);
  709. log.info("第{}次保存处方:\n参数:{}\n结果:{}", tryTimes, params, response);
  710. while (0 != response.getInteger("code") && tryTimes < 5
  711. && !response.getString("message").contains("已经收费")) {
  712. try {
  713. tryTimes += 1;
  714. response = webHisService.mzChargeFee(params);
  715. log.info("第{}次保存处方:\n参数:{}\n结果:{}", tryTimes, params, response);
  716. TimeUnit.SECONDS.sleep(Math.min(tryTimes, 3));
  717. } catch (Exception e) {
  718. log.error("TIMEUNIT SLEEP ERROR", e);
  719. }
  720. }
  721. if (0 != response.getInteger("code") && !response.getString("message").contains("已经收费")) {
  722. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR, "自动保存处方失败,将为您撤销门诊医保业务。");
  723. }
  724. return ResultVoUtil.success();
  725. }
  726. public ResultVo<Integer> isPatientDuringSiSettle(String patientId) {
  727. int result = MzgjUtil.inProcessing(patientId) ? 1 : 0;
  728. return ResultVoUtil.success(result);
  729. }
  730. }