SiMzService.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. package thyyxxk.webserver.service.medicalinsurance;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import thyyxxk.webserver.config.exception.ExceptionEnum;
  8. import thyyxxk.webserver.constants.Capacity;
  9. import thyyxxk.webserver.constants.sidicts.MdtrtCertType;
  10. import thyyxxk.webserver.constants.sidicts.SiFunction;
  11. import thyyxxk.webserver.dao.his.medicalinsurance.SiMzDao;
  12. import thyyxxk.webserver.entity.ResultVo;
  13. import thyyxxk.webserver.entity.markmtfees.*;
  14. import thyyxxk.webserver.entity.medicalinsurance.outpatient.*;
  15. import thyyxxk.webserver.entity.medicalinsurance.query.SiPatInfo;
  16. import thyyxxk.webserver.entity.medicalinsurance.setlinfo.FundDetail;
  17. import thyyxxk.webserver.service.externalhttp.SiMzSrvc;
  18. import thyyxxk.webserver.service.externalhttp.ThmzSystem;
  19. import thyyxxk.webserver.utils.*;
  20. import java.math.BigDecimal;
  21. import java.math.RoundingMode;
  22. import java.util.*;
  23. /**
  24. * @description: 门诊医保交易
  25. * @author: DingJie
  26. * @create: 2021-05-28 16:11:19
  27. **/
  28. @Slf4j
  29. @Service
  30. public class SiMzService {
  31. private final SiMzDao dao;
  32. private final ExecService exec;
  33. private final ThmzSystem thmz;
  34. private final SiMzSrvc mzSrvc;
  35. private static final String RESULT_CODE = "infcode";
  36. private static final String ERROR_MESSAGE = "err_msg";
  37. private static final String OUTPUT = "output";
  38. @Autowired
  39. public SiMzService(SiMzDao dao, ExecService exec, ThmzSystem thmz, SiMzSrvc mzSrvc) {
  40. this.dao = dao;
  41. this.exec = exec;
  42. this.thmz = thmz;
  43. this.mzSrvc = mzSrvc;
  44. }
  45. public ResultVo<String> outpatientRegistration(MzPatientInfo p) {
  46. p.setStaffId(TokenUtil.getTokenUserId());
  47. return mzSrvc.outpatientRegistration(p);
  48. }
  49. public ResultVo<String> revokeOutpatientRegistration(MzPatientInfo p) {
  50. p.setStaffId(TokenUtil.getTokenUserId());
  51. return mzSrvc.revokeOutpatientRegistration(p);
  52. }
  53. public ResultVo<List<Map<String, Object>>> getMzReceipts(MzPatientInfo p) {
  54. String patNo = p.getPatNo();
  55. JSONObject queryMzChargeListParam = new JSONObject();
  56. queryMzChargeListParam.put("patCardType", 21);
  57. queryMzChargeListParam.put("patCardNo", patNo);
  58. queryMzChargeListParam.put("hisOrdNum", "");
  59. Map<String, Object> mzChargeListMap = thmz.getMzChargeDetailForUnPaid(queryMzChargeListParam);
  60. if (null == mzChargeListMap) {
  61. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  62. }
  63. if (0 != (int) mzChargeListMap.get("resultCode")) {
  64. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, mzChargeListMap.get("resultMessage").toString());
  65. }
  66. List<Map<String, Object>> finalResult = new ArrayList<>();
  67. List<Map<String, String>> mzChargeList = FilterUtil.cast(mzChargeListMap.get("data"));
  68. for (Map<String, String> item : mzChargeList) {
  69. String hisOrdNum = item.get("hisOrdNum");
  70. if (null != hisOrdNum) {
  71. String[] hisOrdNumParts = hisOrdNum.split("_");
  72. int tempTimes = Integer.parseInt(hisOrdNumParts[1]);
  73. MzVisit mzVisit = dao.selectMzVisit(patNo, tempTimes);
  74. if (null == mzVisit) {
  75. continue;
  76. }
  77. Map<String, Object> childResult = new HashMap<>(Capacity.FIVE);
  78. childResult.put("times", tempTimes);
  79. childResult.put("mzVisit", mzVisit);
  80. JSONObject queryMzChargeDetailParam = new JSONObject();
  81. queryMzChargeDetailParam.put("patientId", patNo);
  82. queryMzChargeDetailParam.put("times", tempTimes);
  83. queryMzChargeDetailParam.put("receiptNo", hisOrdNumParts[2]);
  84. mzVisit.setReceiptNo(Integer.parseInt(hisOrdNumParts[2]));
  85. Map<String, Object> mzChargeDetailMap = thmz.unPaidToFullChargeDetail(queryMzChargeDetailParam);
  86. if (null != mzChargeDetailMap && 0 == (int) mzChargeDetailMap.get("resultCode")) {
  87. List<Map<String, Object>> mzChargeDetailList = FilterUtil.cast(mzChargeDetailMap.get("data"));
  88. mzChargeDetailList.removeIf(detail -> "TC".equals(detail.get("billItemCode")) ||
  89. !"5".equals(detail.get("payMark")) || "BILL99".equals(detail.get("chargeItemCode")) ||
  90. "四舍五入".equals(detail.get("tcName")));
  91. if (mzChargeDetailList.isEmpty()) {
  92. continue;
  93. }
  94. Map<Integer, List<MzReceipt>> orderReceiptsMap = new HashMap<>(Capacity.DEFAULT);
  95. String doctorName = dao.selectDoctorName(mzChargeDetailList.get(0).get("doctorCode").toString());
  96. mzChargeDetailList.forEach(detail -> {
  97. MzReceipt receipt = fillMzReceipt(detail);
  98. receipt.setPatientId(patNo);
  99. receipt.setTimes(tempTimes);
  100. receipt.setDoctorName(doctorName);
  101. if (!orderReceiptsMap.containsKey(receipt.getOrderNo())) {
  102. List<MzReceipt> list = new ArrayList<>();
  103. list.add(receipt);
  104. orderReceiptsMap.put(receipt.getOrderNo(), list);
  105. } else {
  106. orderReceiptsMap.get(receipt.getOrderNo()).add(receipt);
  107. }
  108. });
  109. List<OrderNo> orderNos = getOrderNos(patNo, tempTimes, mzVisit.getReceiptNo(), orderReceiptsMap);
  110. childResult.put("orderNos", orderNos);
  111. childResult.put("mzReceipts", orderReceiptsMap);
  112. finalResult.add(childResult);
  113. }
  114. }
  115. }
  116. return ResultVoUtil.success(finalResult);
  117. }
  118. public ResultVo<List<MzDepositFile>> getHistoryMzReceipts(String patNo, String start, String end) {
  119. List<MzDepositFile> mzChargeList = dao.selectMzDepositFiles(patNo, start, end);
  120. if (null == mzChargeList || mzChargeList.isEmpty()) {
  121. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有找到历史处方!");
  122. }
  123. return ResultVoUtil.success(mzChargeList);
  124. }
  125. public ResultVo<List<MzReceipt>> getHistoryReceiptDetail(MzDepositFile mzDepositFile) {
  126. List<MzReceipt> mzReceipts = dao.selectMzCharge(mzDepositFile.getPatNo(),
  127. mzDepositFile.getTimes(), mzDepositFile.getReceiptNo());
  128. mzReceipts.forEach(itm -> itm.setChecked(StringUtil.notBlank(itm.getNationalCode())));
  129. return ResultVoUtil.success(mzReceipts);
  130. }
  131. private MzReceipt fillMzReceipt(Map<String, Object> detail) {
  132. MzReceipt receipt = new MzReceipt();
  133. receipt.setReceiptNo((int) detail.get("receiptNo"));
  134. receipt.setOrderNo((int) detail.get("orderNo"));
  135. receipt.setItemNo((int) detail.get("itemNo"));
  136. receipt.setDrugName(detail.get("tcName").toString());
  137. receipt.setChargeItemCode(detail.get("chargeItemCode").toString());
  138. receipt.setPriceTime(DateUtil.formatPriceTime(detail.get("priceTime").toString()));
  139. receipt.setUnitPrice(new BigDecimal(detail.get("unitPrice").toString()).setScale(4, RoundingMode.HALF_UP));
  140. receipt.setQuantity(Double.valueOf(detail.get("quantity").toString()));
  141. receipt.setDrugWin((int) detail.get("drugWin"));
  142. receipt.setDoctorCode(detail.get("doctorCode").toString());
  143. receipt.setSerialNo(detail.get("serialNo").toString());
  144. receipt.setGroupNo(detail.get("groupNo").toString());
  145. receipt.setBillItemCode(detail.get("billItemCode").toString());
  146. receipt.setChargeBillCode(detail.get("chargeBillCode").toString());
  147. String table = receipt.getGroupNo().trim().equals("00") ? "zd_charge_item" : "yp_zd_dict";
  148. receipt.setNationalCode(dao.selectNationalCode(receipt.getChargeItemCode(), table));
  149. receipt.setChecked(StringUtil.notBlank(receipt.getNationalCode()));
  150. if (null != detail.get("instructionText")) {
  151. receipt.setInstructionText(detail.get("instructionText").toString());
  152. }
  153. if (null != detail.get("specification")) {
  154. receipt.setSpecification(detail.get("specification").toString());
  155. }
  156. if (null != detail.get("frequency")) {
  157. receipt.setFrequency(detail.get("frequency").toString());
  158. }
  159. if (null != detail.get("drugQuan")) {
  160. receipt.setDrugQuan(Double.valueOf(detail.get("drugQuan").toString()));
  161. }
  162. if (null != detail.get("orderDays")) {
  163. receipt.setOrderDays((Integer) detail.get("orderDays"));
  164. }
  165. // groupNo:00-项目;其他-药品
  166. if ("00".equals(receipt.getGroupNo())) {
  167. receipt.setDrugUnit(dao.selectXmChargeUnit(receipt.getChargeItemCode()));
  168. } else {
  169. if (null != detail.get("serial")) {
  170. receipt.setSerial(detail.get("serial").toString());
  171. receipt.setSpecification(dao.selectSpecification(receipt.getChargeItemCode(), receipt.getSerial()));
  172. }
  173. if (null != detail.get("supplyCode")) {
  174. receipt.setSupplyCode(dao.selectSupplyName(detail.get("supplyCode").toString()));
  175. }
  176. if (null != detail.get("drugUnit")) {
  177. receipt.setDrugUnit(dao.selectDrugUnit(detail.get("drugUnit").toString()));
  178. }
  179. }
  180. return receipt;
  181. }
  182. private List<OrderNo> getOrderNos(String patientId, int times, int receiptNo, Map<Integer, List<MzReceipt>> orderReceiptsMap) {
  183. List<OrderNo> orderNos = new ArrayList<>();
  184. for (Map.Entry<Integer, List<MzReceipt>> entry : orderReceiptsMap.entrySet()) {
  185. OrderNo orderNo = new OrderNo();
  186. orderNo.setPatientId(patientId);
  187. orderNo.setTimes(times);
  188. orderNo.setReceiptNo(entry.getValue().get(0).getReceiptNo());
  189. orderNo.setOrderNo(entry.getKey());
  190. BigDecimal total = new BigDecimal("0.00");
  191. for (MzReceipt receipt : entry.getValue()) {
  192. total = total.add(receipt.getChargeFee());
  193. }
  194. orderNo.setTotalFee(total);
  195. int count = dao.selectFeeCount(patientId, times, receiptNo, entry.getKey());
  196. orderNo.setStatus(count > 0);
  197. orderNos.add(orderNo);
  198. }
  199. return orderNos;
  200. }
  201. public ResultVo<String> insertSiMzFees(List<MzReceipt> receipts) {
  202. receipts.removeIf(itm -> !itm.getChecked());
  203. if (receipts.size() == 0) {
  204. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "请选择至少一条处方明细!");
  205. }
  206. MzReceipt receipt = receipts.get(0);
  207. int count = dao.selectFeeCount(receipt.getPatientId(), receipt.getTimes(),
  208. receipt.getReceiptNo(), receipt.getOrderNo());
  209. if (count > 0) {
  210. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该处方已生成过门特费用,请勿重复操作。");
  211. }
  212. receipts.forEach(item -> {
  213. if (item.getChecked()) {
  214. dao.insertBatchedMtFeeInfo(item);
  215. }
  216. });
  217. return ResultVoUtil.success();
  218. }
  219. public ResultVo<String> deleteMzReceipt(OrderNo param) {
  220. dao.deleteMzReceipt(param);
  221. return ResultVoUtil.success();
  222. }
  223. public ResultVo<String> deleteAllMzReceipts(MzPatientInfo p) {
  224. if (null == p.getTimes()) {
  225. p.setTimes(dao.selectMaxTimes(p.getPatNo()));
  226. }
  227. log.info("【操作员:{}】删除所有门特处方:门诊号:{},门诊次数:{}", TokenUtil.getTokenUserId(), p.getPatNo(), p.getTimes());
  228. dao.deleteAllReceipts(p.getPatNo(), p.getTimes());
  229. return ResultVoUtil.success("删除成功。");
  230. }
  231. public ResultVo<SiPatInfo> uploadOutpatientFeeDetails(SpcChrDiseAcct p) {
  232. p.setStaffId(TokenUtil.getTokenUserId());
  233. return mzSrvc.uploadOutpatientFeeDetails(p);
  234. }
  235. public ResultVo<String> revokeOutpatientFeeDetails(MzPatientInfo p) {
  236. p.setStaffId(TokenUtil.getTokenUserId());
  237. return mzSrvc.revokeOutpatientFeeDetails(p);
  238. }
  239. public ResultVo<FundDetail> outpatientPreSettlement(MzPatientInfo p) {
  240. if (null == p.getStaffId()) {
  241. p.setStaffId(TokenUtil.getTokenUserId());
  242. }
  243. return mzSrvc.outpatientPreSettlement(p);
  244. }
  245. public ResultVo<FundDetail> outpatientSettlement(MzPatientInfo p) {
  246. if (null == p.getStaffId()) {
  247. p.setStaffId(TokenUtil.getTokenUserId());
  248. }
  249. return mzSrvc.outpatientSettlement(p);
  250. }
  251. public ResultVo<FundDetail> revokeOutpatientSettlement(MzPatientInfo p) {
  252. if (null == p.getStaffId()) {
  253. p.setStaffId(TokenUtil.getTokenUserId());
  254. }
  255. return mzSrvc.revokeOutpatientSettlement(p);
  256. }
  257. public ResultVo<String> saveSiMzDiags(List<SiMzDiag> diags) {
  258. if (ListUtil.isBlank(diags)) {
  259. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有要保存的诊断!");
  260. }
  261. SiMzDiag diag = diags.get(0);
  262. dao.deleteMzDiags(diag.getPatNo(), diag.getTimes());
  263. String staffId = TokenUtil.getTokenUserId();
  264. for (SiMzDiag itm : diags) {
  265. itm.setRealOpter(staffId);
  266. dao.insertNewMzDiag(itm);
  267. }
  268. return ResultVoUtil.success("门诊诊断保存成功。");
  269. }
  270. public void updateMzSaved(String patientId, int times, int val) {
  271. dao.updateMzSaved(patientId, times, val);
  272. }
  273. public ResultVo<List<SpcChrDiseAcct>> fetchSpcSlwinfo(String socialNo) {
  274. if (StringUtil.isBlank(socialNo)) {
  275. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者身份证号不能为空,请补充!");
  276. }
  277. JSONObject input = exec.makeTradeHeader(SiFunction.OBTAIN_BASIC_PERSON_INFO);
  278. JSONObject data = new JSONObject();
  279. data.put("mdtrt_cert_type", MdtrtCertType.RESIDENT_IDENTITY_CARD.getCode());
  280. data.put("psn_cert_type", "01");
  281. data.put("mdtrt_cert_no", socialNo);
  282. data.put("certno", socialNo);
  283. input.getJSONObject("input").put("data", data);
  284. JSONObject result = exec.executeTrade(input, SiFunction.OBTAIN_BASIC_PERSON_INFO);
  285. if (null == result) {
  286. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  287. }
  288. if (null == result.getInteger(RESULT_CODE)) {
  289. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的慢特病备案,或慢特病备案已过期!");
  290. }
  291. if (result.getIntValue(RESULT_CODE) == 0) {
  292. JSONObject output = result.getJSONObject(OUTPUT);
  293. JSONObject baseinfo = output.getJSONObject("baseinfo");
  294. String psnNo = baseinfo.getString("psn_no");
  295. JSONArray insuinfo = output.getJSONArray("insuinfo");
  296. Date now = new Date();
  297. List<SpcChrDiseAcct> list = new ArrayList<>();
  298. for (int i = 0; i < insuinfo.size(); i++) {
  299. JSONObject item = insuinfo.getJSONObject(i);
  300. String admdvs = item.getString("insuplc_admdvs");
  301. input = exec.makeTradeHeaderWithInsureArea(SiFunction.QUERY_SPECIAL_CHRONIC_DISEASES_ACCREDITATION, admdvs);
  302. data = new JSONObject();
  303. data.put("psn_no", psnNo);
  304. input.getJSONObject("input").put("data", data);
  305. result = exec.executeTrade(input, SiFunction.QUERY_SPECIAL_CHRONIC_DISEASES_ACCREDITATION);
  306. if (null == result) {
  307. continue;
  308. }
  309. if (null == result.getInteger(RESULT_CODE)) {
  310. continue;
  311. }
  312. if (result.getIntValue(RESULT_CODE) == 0) {
  313. output = result.getJSONObject(OUTPUT);
  314. JSONArray details = output.getJSONArray("feedetail");
  315. if (null == details || details.size() == 0) {
  316. continue;
  317. }
  318. for (int j = 0; j < details.size(); j++) {
  319. JSONObject detail = details.getJSONObject(j);
  320. SpcChrDiseAcct spcChrDiseAcct = JSONObject.parseObject(detail.toJSONString(), SpcChrDiseAcct.class);
  321. if (now.before(spcChrDiseAcct.getEnddate())) {
  322. list.add(spcChrDiseAcct);
  323. }
  324. }
  325. if (list.size() > 0) {
  326. return ResultVoUtil.success(list);
  327. }
  328. }
  329. }
  330. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的慢特病备案,或慢特病备案已过期!");
  331. }
  332. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的慢特病备案,或慢特病备案已过期!");
  333. }
  334. }