package thyyxxk.wxservice_server.controller.api; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import thyyxxk.wxservice_server.config.auth.PassToken; import thyyxxk.wxservice_server.config.exception.ExceptionEnum; import thyyxxk.wxservice_server.config.properties.ApiAddr; import thyyxxk.wxservice_server.dao.api.PowersiPluginDao; import thyyxxk.wxservice_server.entity.ResultVo; import thyyxxk.wxservice_server.entity.assessment.PushQuestionnaireVisit; import thyyxxk.wxservice_server.entity.medinsmobilepay.InsuinfoRequest; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.OrdState; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.request.CommonRequest; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.request.PowersiMipSetlinfo; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.request.RevokeSettleRequest; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.response.BillInfo; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.response.CommonResponse; import thyyxxk.wxservice_server.entity.medinsmobilepay.frompowersiplugin.response.Upload6201; import thyyxxk.wxservice_server.factory.thmz.ThmzService; import thyyxxk.wxservice_server.factory.thmz.model.QueryReceiptRequest; import thyyxxk.wxservice_server.factory.thmz.model.SaveMzPayRequest; import thyyxxk.wxservice_server.service.IdCardAnalyzeService; import thyyxxk.wxservice_server.service.PushWxMessageService; import thyyxxk.wxservice_server.utils.*; import thyyxxk.wxservice_server.utils.mip.DataHandler; import java.io.IOException; import java.math.BigDecimal; import java.util.*; @Slf4j @RestController @RequestMapping("/api/mobilePayPlugin") public class PowersiMiPayPlugin { private final PowersiPluginDao dao; private final IdCardAnalyzeService idCardAnalyzeService; private final ThmzService thmzService; private final PushWxMessageService messageService; private final String hisMipApi; private final DataHandler dataHandler = DataHandler.newInstance(); @Autowired public PowersiMiPayPlugin(PowersiPluginDao dao, IdCardAnalyzeService idCardAnalyzeService, ThmzService thmzService, PushWxMessageService messageService, ApiAddr apiAddr) throws IOException { this.dao = dao; this.idCardAnalyzeService = idCardAnalyzeService; this.thmzService = thmzService; this.messageService = messageService; this.hisMipApi = apiAddr.getHisMipApi(); } @PostMapping("/lockOrder") public ResultVo lockOrder(@RequestBody InsuinfoRequest request) { String openid = TokenUtil.getInstance().getUserOpenid(); dao.lockOrder(request.getHisOrdNum(), openid,1); return ResultVoUtil.success(openid); } @PostMapping("/unlockOrder") public ResultVo unlockOrder(@RequestBody InsuinfoRequest request) { dao.lockOrder(request.getHisOrdNum(), null, 0); return ResultVoUtil.success("操作成功。"); } private JSONObject decryptRequest(JSONObject body) throws Exception { body.put("code", 0); JSONObject decrypt = dataHandler.processRspData(body.toJSONString()); return decrypt.getJSONObject("data"); } @PassToken @PostMapping("/patientInquiry") public CommonResponse patientInquiry(@RequestBody JSONObject body) throws Exception { JSONObject request = decryptRequest(body); List patNos = dao.selectPatientCount(request.getString("idNo")); if (patNos.isEmpty()) { return new CommonResponse("未查询到建档信息。"); } return new CommonResponse(); } @PassToken @PostMapping("/patientCreate") public CommonResponse patientCreate(@RequestBody JSONObject body) throws Exception { JSONObject request = decryptRequest(body); return idCardAnalyzeService.createCardFromPowersiPlugin(request); } @PassToken @PostMapping("/billListInquiry") public JSONObject billListInquiry(@RequestBody JSONObject body) throws Exception { JSONObject request = decryptRequest(body); List patNos = dao.selectPatientCount(request.getString("idNo")); if (patNos.isEmpty()) { JSONObject res = new JSONObject(); res.put("code", -1); res.put("success", false); res.put("message", "没有患者的建档信息。"); return res; } List list = new ArrayList<>(); for (String patNo : patNos) { QueryReceiptRequest receiptRequest = new QueryReceiptRequest.Builder() .patCardNo(patNo).build(); ResultVo>> vo = thmzService.getMzChargeDetailForUnPaid(receiptRequest); if (vo.getCode() != ExceptionEnum.SUCCESS.getCode()) { continue; } List> feeList = vo.getData(); for (Map map : feeList) { BillInfo billInfo = new BillInfo(map); if (billInfo.getVipFlag() != 0) { continue; } String url = hisMipApi + "/writeMtReceipt?hisOrdNum=" + billInfo.getBizId(); String writeMtReceipt = new RestTemplate().getForObject(url, String.class); if (Objects.equals(writeMtReceipt, "SUCCESS")) { billInfo.setIdNo(request.getString("idNo")); billInfo.setIdType(request.getString("idType")); billInfo.setDeptId(dao.selectDeptId(billInfo.getDeptName())); list.add(billInfo); } } } if (list.isEmpty()) { JSONObject res = new JSONObject(); res.put("code", -1); res.put("success", false); res.put("message", "没有患者的待缴费信息。"); return res; } String listRef = JSONArray.toJSONString(list); JSONObject temp = new JSONObject(); temp.put("billInfo", JSONArray.parseArray(listRef)); String raw = dataHandler.buildReqData(temp); JSONObject response = JSONObject.parseObject(raw); response.put("code", 0); response.put("success", true); response.put("message", "OK"); return response; } @PassToken @PostMapping("/billDetailInquiry") public JSONObject billDetailInquiry(@RequestBody JSONObject body) throws Exception { JSONObject request = decryptRequest(body); String bizId = request.getString("bizId"); bizId = null == bizId ? "" : bizId; String[] arr = bizId.split("_"); if (arr.length != 3) { JSONObject res = new JSONObject(); res.put("code", -1); res.put("success", false); res.put("message", "bizId[" + bizId + "]不正确!"); return res; } request.put("patNo", arr[0]); request.put("times", Integer.parseInt(arr[1])); Upload6201 upload6201 = new RestTemplate().postForObject(hisMipApi + "/getUpload6201", request, Upload6201.class); if (null == upload6201) { JSONObject res = new JSONObject(); res.put("code", -1); res.put("success", false); res.put("message", "网络异常,请稍后再试。"); return res; } upload6201.setIdNo(request.getString("idNo")); upload6201.setIdType(request.getString("idType")); upload6201.setUserName(request.getString("userName")); String raw = dataHandler.buildReqData(JSONObject.toJSONString(upload6201)); JSONObject response = JSONObject.parseObject(raw); response.put("code", 0); response.put("success", true); response.put("message", "OK"); return response; } @PassToken @PostMapping("/settleNotify") public CommonResponse settleNotify(@RequestBody JSONObject body) throws Exception { JSONObject request = decryptRequest(body); PowersiMipSetlinfo setlinfo = dao.selectById(request.getString("platformOrderId")); if (null == setlinfo) { setlinfo = JSONObject.parseObject(request.toJSONString(), PowersiMipSetlinfo.class); JSONObject hiExtData = request.getJSONObject("hiExtData"); if (null != hiExtData) { JSONObject clrObj = hiExtData.getJSONObject("setlinfo"); if (null != clrObj) { String clrOptins = clrObj.getString("clrOptins"); String clrType = clrObj.getString("clrType"); setlinfo.setClrOptins(clrOptins); setlinfo.setClrType(clrType); } } int insert = dao.insert(setlinfo); if (insert == 1) { saveMzOrder(setlinfo); return new CommonResponse(); } return new CommonResponse("HIS业务处理失败。"); } if (setlinfo.getMzSaved() == 0) { saveMzOrder(setlinfo); return new CommonResponse(); } return new CommonResponse(); } private void saveMzOrder(PowersiMipSetlinfo setlinfo) { SaveMzPayRequest saveMzPayRequest = new SaveMzPayRequest.Builder() .payTime(DateUtil.formatDatetime(setlinfo.getTraceTime())) .patCardNo(setlinfo.getMedOrgOrd().split("_")[0]) .agtOrdNum(setlinfo.getThirdOrderId()) .payAmt(setlinfo.getFeeSumamt()) .fundpayAmt(setlinfo.getFundPay()) .acctpayAmt(setlinfo.getPsnAcctPay()) .couponAmt(BigDecimal.ZERO) .cashpayAmt(setlinfo.getOwnpayAmt()) .hisOrdNum(setlinfo.getMedOrgOrd()) .psOrdNum(setlinfo.getPlatformOrderId()) .isNormalClinic(true).build(); ResultVo res = thmzService.saveMzPay(saveMzPayRequest); if (res.getCode() == ExceptionEnum.SUCCESS.getCode()) { dao.updateMzSaved(setlinfo.getPlatformOrderId()); } pushMessage(setlinfo.getMedOrgOrd(), setlinfo.getUserName()); } private void pushMessage(String hisOrdNum, String userName) { String[] arr = hisOrdNum.split("_"); int times = Integer.parseInt(arr[1]); PushQuestionnaireVisit visit = dao.getVisit(arr[0], times, hisOrdNum); String visitId = hisOrdNum.replaceAll("_", "AND") + "AND" + visit.getDoctorCode() + "AND" + visit.getDeptCode(); String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxbde6b16acad84204&redirect_uri=" + "https://staticweb.hnthyy.cn/wxserver/redirect/page2?to=doctorGradeByPush_" + visitId + "&response_type=code&scope=snsapi_base&state=1#wechat_redirect"; String msgContent = "{\"touser\":\"" + visit.getOpenid() + "\",\"data\":" + "{\"keyword1\":{\"color\":\"#173177\",\"value\":\"" + userName + "\"}," + "\"keyword2\":{\"color\":\"#173177\",\"value\":\"长沙泰和医院\"}," + "\"keyword3\":{\"color\":\"#173177\",\"value\":\"" + visit.getDeptName() + "\"}," + "\"keyword4\":{\"color\":\"#173177\",\"value\":\"" + visit.getDoctorName() + "\"}," + "\"keyword5\":{\"color\":\"#173177\",\"value\":\"" + visit.getVisitDate() + "\"}," + "\"remark\":{\"color\":\"#FF0000\",\"value\":\"特邀请您对医生服务作出评价。\"}," + "\"first\":{\"color\":\"#FF0000\",\"value\":\"您曾在我院进行诊疗。\"}}," + "\"template_id\":\"G4YAN56RmDjEPpNyP5fpCdr5TghyqspDeWlWaD5Eg2o\"," + "\"url\":\"" + url + "\"}"; JSONObject message = JSONObject.parseObject(msgContent); messageService.pushMessage2(message); } @PassToken @GetMapping("/isMipOrder") public ResultVo isMipOrder(@RequestParam("hisOrdNum") String hisOrdNum) throws Exception { PowersiMipSetlinfo setlinfo = getSetlinfo(hisOrdNum, null); if (null == setlinfo) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST); } return ResultVoUtil.success(setlinfo.getPlatformOrderId()); } @PassToken @PostMapping("/revokeMipSettle") public ResultVo revokeMipSettle(@RequestBody CommonRequest request) throws Exception { PowersiMipSetlinfo setlinfo = getRefundableSetl(request.getHisOrdNum()); if (null == setlinfo) { setlinfo = getSetlinfo(request.getHisOrdNum(), OrdState.REFUND_SUCCEED); if (null != setlinfo) { return ResultVoUtil.success("医保移动支付退款成功"); } return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有可以退款的结算交易。"); } Date now = new Date(); RevokeSettleRequest refd = new RevokeSettleRequest(); if (StringUtil.notBlank(request.getRefdType())) { refd.setRefdType(request.getRefdType()); } refd.setMedOrgOrd(request.getHisOrdNum()); refd.setMedRefdId(SnowFlakeId.instance().nextId()); refd.setRefdTime(DateUtil.formatDatetime(now)); refd.setTotlRefdAmt(setlinfo.getFeeSumamt()); refd.setPsnAcctRefdAmt(setlinfo.getPsnAcctPay()); refd.setFundRefdAmt(setlinfo.getFundPay()); refd.setCashRefdAmt(setlinfo.getOwnpayAmt()); refd.setRefdReason(request.getRefundReason()); refd.setEcToken(request.getEcToken()); refd.setPlatformOrderId(setlinfo.getPlatformOrderId()); JSONObject raw = JSONObject.parseObject(JSONObject.toJSONString(refd)); String body = dataHandler.buildReqData(raw); String url = "http://webhis.thyy.cn:8077/powersiMipRefund"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity<>(body, headers); RestTemplate restTemplate = new RestTemplate(); String encRes = restTemplate.postForObject(url, entity, String.class); JSONObject decRes = dataHandler.processRspData(encRes); Integer code = decRes.getInteger("code"); if (null != code && code == 0) { JSONObject data = decRes.getJSONObject("data"); OrdState state = OrdState.get(data.getString("refStatus")); if (null == state) { return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR); } String refId = data.getString("platformRefdId"); dao.updateRevokeInfo(request.getStaffId(), now, refId, setlinfo.getMedOrgOrd(), state); if (state == OrdState.REFUND_SUCCEED) { return ResultVoUtil.success("医保移动支付退款成功"); } if (state == OrdState.REFUND_PROCEEDING) { return ResultVoUtil.success("医保移动支付退款进行中,请稍后查询退款结果。"); } if (state == OrdState.REFUND_ABNORMAL) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保移动支付退款异常,请稍后查询退款结果。"); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, data.getString("failMsg")); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, decRes.getString("message")); } private PowersiMipSetlinfo getRefundableSetl(String id) { PowersiMipSetlinfo setlinfo = getSetlinfo(id, OrdState.SETTLED); if (null == setlinfo) { setlinfo = getSetlinfo(id, OrdState.REFUND_FAILED); if (null == setlinfo) { setlinfo = getSetlinfo(id, OrdState.REFUND_ABNORMAL); } } return setlinfo; } private PowersiMipSetlinfo getSetlinfo(String id, OrdState state) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("med_org_ord", id); if (null == state) { List list = dao.selectList(wrapper); if (list == null || list.isEmpty()) { return null; } return list.get(0); } wrapper.eq("ord_state", state); return dao.selectOne(wrapper); } @PassToken @GetMapping("/queryRefundState") public ResultVo queryRefundState(@RequestParam("hisOrdNum") String hisOrdNum) throws Exception { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("med_org_ord", hisOrdNum); wrapper.ne("ord_state", OrdState.SETTLED); wrapper.isNotNull("platform_refd_id"); PowersiMipSetlinfo setlinfo = dao.selectOne(wrapper); if (null == setlinfo) { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST); } JSONObject params = new JSONObject(); params.put("platformRefdId", setlinfo.getPlatformRefdId()); params.put("orgCodg", "H43010500370"); JSONObject raw = JSONObject.parseObject(JSONObject.toJSONString(params)); String body = dataHandler.buildReqData(raw); String url = "http://webhis.thyy.cn:8077/powersiMipRefundQuery"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity<>(body, headers); RestTemplate restTemplate = new RestTemplate(); String encRes = restTemplate.postForObject(url, entity, String.class); JSONObject decRes = dataHandler.processRspData(encRes); Integer code = decRes.getInteger("code"); if (null != code && code == 0) { JSONObject data = decRes.getJSONObject("data"); data.remove("hiExtData"); OrdState state = OrdState.get(data.getString("refdStatus")); if (null == state) { return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR); } String refId = data.getString("platformRefdId"); dao.updateRefundState(refId, state); return ResultVoUtil.success(state.toString()); } return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, decRes.getString("message")); } }