Browse Source

优化缴费和保存付费信息的流程。

lighter 4 years ago
parent
commit
1c69ddc68e

+ 0 - 5
src/main/java/thyyxxk/wxservice_server/controller/AppointmentController.java

@@ -72,11 +72,6 @@ public class AppointmentController {
         return service.getDoctorQrCode(doctorCode);
     }
 
-    @PostMapping("/saveAppointment")
-    public ResultVo<String> saveAppointment(@RequestBody SaveAppointmentParam param) throws Exception {
-        return service.saveAppointment(param).get();
-    }
-
     @GetMapping("/getPaidMzGhList")
     public ResultVo<List<Map<String, String>>> getPaidMzGhList(@RequestParam("patientId") String patientId) throws ExecutionException, InterruptedException {
         return service.getPaidMzGhList(patientId).get();

+ 0 - 6
src/main/java/thyyxxk/wxservice_server/controller/InpatientController.java

@@ -5,7 +5,6 @@ import org.springframework.web.bind.annotation.*;
 import thyyxxk.wxservice_server.pojo.ResultVo;
 import thyyxxk.wxservice_server.pojo.inpatient.GetZyFeeParam;
 import thyyxxk.wxservice_server.pojo.inpatient.InpatientInfo;
-import thyyxxk.wxservice_server.pojo.wxapi.WxPayOrderPojo;
 import thyyxxk.wxservice_server.service.InpatientService;
 
 import java.util.Map;
@@ -35,9 +34,4 @@ public class InpatientController {
     public ResultVo<Map<String, Object>> getPrepaidHistory(String patientId) {
         return service.getPrepaidHistory(patientId);
     }
-
-    @PostMapping("/payYjjSuccessful")
-    public ResultVo<String> payYjjSuccessful(@RequestBody WxPayOrderPojo param) throws Exception {
-        return service.payYjjSuccessful(param).get();
-    }
 }

+ 0 - 5
src/main/java/thyyxxk/wxservice_server/controller/PayMzFeeController.java

@@ -33,11 +33,6 @@ public class PayMzFeeController {
         return service.getUnPaidDetail(patientId, hisOrdNum);
     }
 
-    @GetMapping("/saveMzChargeInfo")
-    public ResultVo<String> saveMzChargeInfo(@RequestParam("tradeNo") String tradeNo) throws Exception {
-        return service.saveMzChargeInfo(tradeNo).get();
-    }
-
     @GetMapping("/getMzPaidList")
     public ResultVo<List<Map<String, String>>> getMzPaidList(@RequestParam("patientId") String patientId) throws ExecutionException, InterruptedException {
         return service.getMzPaidList(patientId).get();

+ 1 - 0
src/main/java/thyyxxk/wxservice_server/controller/WxApiController.java

@@ -51,6 +51,7 @@ public class WxApiController {
 
     @GetMapping("/queryOrderState")
     public ResultVo<String> queryOrderState(@RequestParam("tradeNo") String tradeNo) throws Exception {
+        log.info("前端回调查询订单状态:{}", tradeNo);
         return service.queryOrderState(tradeNo).get();
     }
 

+ 4 - 43
src/main/java/thyyxxk/wxservice_server/scheduled/QueryOrderStateTask.java

@@ -9,12 +9,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import thyyxxk.wxservice_server.dao.WxApiDao;
 import thyyxxk.wxservice_server.pojo.ResultVo;
-import thyyxxk.wxservice_server.pojo.appointment.MzyReqrecPojo;
-import thyyxxk.wxservice_server.pojo.appointment.SaveAppointmentParam;
 import thyyxxk.wxservice_server.pojo.wxapi.WxPayOrderPojo;
-import thyyxxk.wxservice_server.service.AppointmentService;
-import thyyxxk.wxservice_server.service.InpatientService;
-import thyyxxk.wxservice_server.service.PayMzFeeService;
 import thyyxxk.wxservice_server.service.WxApiService;
 import thyyxxk.wxservice_server.utils.PropertiesUtil;
 import thyyxxk.wxservice_server.utils.ResultVoUtil;
@@ -27,20 +22,12 @@ import java.util.List;
 public class QueryOrderStateTask {
     private final WxApiDao dao;
     private final WxApiService service;
-    private final AppointmentService appointmentService;
-    private final PayMzFeeService payMzFeeService;
-    private final InpatientService inpatientService;
     private static volatile boolean canScheduleRun = false;
 
     @Autowired
-    public QueryOrderStateTask(WxApiDao dao, WxApiService service,
-                               AppointmentService appointmentService,
-                               PayMzFeeService payMzFeeService, InpatientService inpatientService) {
+    public QueryOrderStateTask(WxApiDao dao, WxApiService service) {
         this.dao = dao;
         this.service = service;
-        this.appointmentService = appointmentService;
-        this.payMzFeeService = payMzFeeService;
-        this.inpatientService = inpatientService;
     }
 
     @GetMapping("/start")
@@ -64,35 +51,9 @@ public class QueryOrderStateTask {
             return;
         }
         for (WxPayOrderPojo order : list) {
-            if (service.tradeNoBetweenQuery(order.getTradeNo())) {
-                continue;
-            }
-            dao.incrementQueryTimesById(order.getId());
-            ResultVo<String> stateResult = service.queryOrderState(order.getTradeNo()).get();
-            String orderState = stateResult.getData();
-            if (orderState.equals("SUCCESS")) {
-                if (order.getOrderType() == 1) {
-                    if (!appointmentService.isTradeNoBetweenQuery(order.getTradeNo())) {
-                        SaveAppointmentParam param = new SaveAppointmentParam();
-                        param.setMzyRequestId(order.getMzyRequestId());
-                        param.setTotalFee(order.getTotalFee().doubleValue());
-                        MzyReqrecPojo mzyReqrec = new MzyReqrecPojo();
-                        mzyReqrec.setPatientId(order.getPatientId());
-                        mzyReqrec.setPaymode("WX");
-                        mzyReqrec.setPsordnum(order.getTradeNo());
-                        mzyReqrec.setAgtordnum(order.getSerialNo());
-                        param.setMzyReqrec(mzyReqrec);
-                        appointmentService.saveAppointment(param);
-                    }
-                } else if (order.getOrderType() == 2) {
-                    if (!payMzFeeService.isTradeNoBetweenQuery(order.getTradeNo())) {
-                        payMzFeeService.saveMzChargeInfo(order.getTradeNo());
-                    }
-                } else if (order.getOrderType() == 3) {
-                    if (!inpatientService.isTradeNoBetweenQuery(order.getTradeNo())) {
-                        inpatientService.payYjjSuccessful(order);
-                    }
-                }
+            if (!service.tradeNoBetweenQuery(order.getTradeNo())) {
+                log.info("定时任务查询订单状态:{}", order.getTradeNo());
+                service.queryOrderState(order.getTradeNo());
             }
         }
     }

+ 14 - 71
src/main/java/thyyxxk/wxservice_server/service/AppointmentService.java

@@ -9,33 +9,36 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 import thyyxxk.wxservice_server.config.exception.ExceptionEnum;
 import thyyxxk.wxservice_server.dao.AppointmentDao;
-import thyyxxk.wxservice_server.dao.WxApiDao;
 import thyyxxk.wxservice_server.pojo.HrgResponse;
 import thyyxxk.wxservice_server.pojo.ResultVo;
 import thyyxxk.wxservice_server.pojo.appointment.*;
 import thyyxxk.wxservice_server.pojo.assessment.CovidPojo;
-import thyyxxk.wxservice_server.pojo.wxapi.WxPayOrderPojo;
-import thyyxxk.wxservice_server.utils.*;
+import thyyxxk.wxservice_server.utils.CastUtil;
+import thyyxxk.wxservice_server.utils.PropertiesUtil;
+import thyyxxk.wxservice_server.utils.ResultVoUtil;
+import thyyxxk.wxservice_server.utils.ThmzUrls;
 
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
 
 @Slf4j
 @Service
 public class AppointmentService {
-    private final AppointmentDao dao;
-    private final WxApiDao wxApiDao;
-    private final WxApiService wxApiService;
     private static List<MzClassPojo> mzClasses;
-    private static final Vector<String> tradeNosBetweenQuery = new Vector<>();
+    private final AppointmentDao dao;
 
     @Autowired
-    public AppointmentService(AppointmentDao dao, WxApiDao wxApiDao, WxApiService wxApiService) {
+    public AppointmentService(AppointmentDao dao) {
         this.dao = dao;
-        this.wxApiDao = wxApiDao;
-        this.wxApiService = wxApiService;
+    }
+
+    public static String getFutureDate(int past) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
+        Date today = calendar.getTime();
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        return format.format(today);
     }
 
     public ResultVo<List<MzClassPojo>> getAllDepartments() {
@@ -108,14 +111,6 @@ public class AppointmentService {
         return ResultVoUtil.success(retArr);
     }
 
-    public static String getFutureDate(int past) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);
-        Date today = calendar.getTime();
-        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
-        return format.format(today);
-    }
-
     public ResultVo<Object> getDoctorSources(GetDoctorSourcesParam param) {
         String url = String.format(ThmzUrls.GET_DOCTOR_BY_DATE_AND_DEPT +
                 "requestDay=%s&unitCode=%s", param.getDate(), param.getDeptCode());
@@ -196,58 +191,6 @@ public class AppointmentService {
         }
     }
 
-    public boolean isTradeNoBetweenQuery(String tradeNo) {
-        return tradeNosBetweenQuery.contains(tradeNo);
-    }
-
-    private Integer queryRegistrationState(String tradeNo) {
-        tradeNosBetweenQuery.add(tradeNo);
-        WxPayOrderPojo order = wxApiDao.selectOrderByTradeNo(tradeNo);
-        RestTemplate template = new RestTemplate();
-        JSONObject obj = new JSONObject();
-        obj.put("psOrdNum", order.getTradeNo());
-        obj.put("payMode", "WX");
-        obj.put("payAmt", order.getTotalFee().toPlainString());
-        obj.put("agtOrdNum", order.getSerialNo());
-        obj.put("payTime", DateUtil.formatDatetime(order.getPayDatetime(), "yyyy-MM-dd HH:mm:ss"));
-        HrgResponse response = template.postForObject(ThmzUrls.GET_PAY_STATUS_FOR_REGISTRATION, obj, HrgResponse.class);
-        log.info("门诊挂号订单支付状态查询结果:{}", response);
-        int result = 0;
-        if (null != response && response.getResultCode() == 0) {
-            result = response.getPayStatus();
-        }
-        return result;
-    }
-
-    @Async("asyncTask")
-    public CompletableFuture<ResultVo<String>> saveAppointment(SaveAppointmentParam param) throws Exception {
-        String tradeNo = param.getMzyReqrec().getPsordnum();
-        while (isTradeNoBetweenQuery(tradeNo)) {
-            TimeUnit.SECONDS.sleep(1);
-        }
-        Integer hasSaved = queryRegistrationState(tradeNo);
-        if (hasSaved == 1) {
-            log.info("订单号:{} 的挂号信息已保存,无需再次保存。", tradeNo);
-            tradeNosBetweenQuery.remove(tradeNo);
-            return CompletableFuture.completedFuture(ResultVoUtil.success("保存挂号信息成功。"));
-        }
-        log.info("保存挂号信息: {}", param);
-        RestTemplate template = new RestTemplate();
-        HrgResponse data = template.postForObject(ThmzUrls.PAY_REGISTRATION_FORM_HAI_CI, param, HrgResponse.class);
-        log.info("保存挂号信息结果: {}", data);
-        tradeNosBetweenQuery.remove(tradeNo);
-        if (null != data && data.getResultCode() == 0) {
-            return CompletableFuture.completedFuture(ResultVoUtil.success("保存挂号信息成功。"));
-        }
-        log.info("保存挂号信息失败,将自动退款。");
-        ResultVo<String> refund = wxApiService.autoRefund(tradeNo, "保存挂号信息失败,自动退款。");
-        if (null != refund && refund.getCode() == 200) {
-            return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存挂号信息失败,已为您自动退款,请留意到账信息。"));
-        }
-        wxApiDao.updatePayStatusOnly(tradeNo, 7);
-        return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存挂号信息失败,自动退款失败,请联系服务中心进行退款。"));
-    }
-
     public ResultVo<String> getDoctorQrCode(String doctorCode) {
         final String token = PropertiesUtil.getProperty("qywxToken");
         final String url = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=" + token +

+ 1 - 53
src/main/java/thyyxxk/wxservice_server/service/InpatientService.java

@@ -1,7 +1,5 @@
 package thyyxxk.wxservice_server.service;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
@@ -12,27 +10,20 @@ import thyyxxk.wxservice_server.pojo.ResultVo;
 import thyyxxk.wxservice_server.pojo.inpatient.GetZyFeeParam;
 import thyyxxk.wxservice_server.pojo.inpatient.InpatientInfo;
 import thyyxxk.wxservice_server.pojo.inpatient.ZyFee;
-import thyyxxk.wxservice_server.pojo.wxapi.PushMessageParam;
-import thyyxxk.wxservice_server.pojo.wxapi.WxPayOrderPojo;
-import thyyxxk.wxservice_server.utils.DateUtil;
 import thyyxxk.wxservice_server.utils.DecimalTool;
 import thyyxxk.wxservice_server.utils.ResultVoUtil;
 
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
 
 @Slf4j
 @Service
 public class InpatientService {
     private final InpatientDao dao;
-    private final WxApiService wxApiService;
-    private static final Vector<String> tradeNosBetweenQuery = new Vector<>();
 
     @Autowired
-    public InpatientService(InpatientDao dao, WxApiService wxApiService) {
+    public InpatientService(InpatientDao dao) {
         this.dao = dao;
-        this.wxApiService = wxApiService;
     }
 
     public ResultVo<InpatientInfo> getInpatientInfo(String patientId) {
@@ -78,47 +69,4 @@ public class InpatientService {
         }
     }
 
-    public boolean isTradeNoBetweenQuery(String tradeNo) {
-        return tradeNosBetweenQuery.contains(tradeNo);
-    }
-
-    @Async("asyncTask")
-    public CompletableFuture<ResultVo<String>> payYjjSuccessful(WxPayOrderPojo param) throws InterruptedException {
-        while (isTradeNoBetweenQuery(param.getTradeNo())) {
-            TimeUnit.SECONDS.sleep(1);
-        }
-        tradeNosBetweenQuery.add(param.getTradeNo());
-        int savedCount = dao.selectSavedCount(param.getTradeNo(), param.getSerialNo());
-        if (savedCount > 0) {
-            log.info("订单号:{} 的住院预交金信息已保存,无需再次保存。", param.getTradeNo());
-            tradeNosBetweenQuery.remove(param.getTradeNo());
-            return CompletableFuture.completedFuture(ResultVoUtil.success("保存住院预交金信息成功。"));
-        }
-        String datetime = DateUtil.formatDatetime(new Date(), "yyyy-MM-dd HH:mm:ss");
-        dao.payZyYjjSuccessful(param.getInpatientNo(), param.getAdmissTimes(), param.getTotalFee(),
-                datetime, param.getTradeNo(), param.getSerialNo(), "");
-        GetZyFeeParam getZyFeeParam = new GetZyFeeParam();
-        String date = DateUtil.formatDatetime(new Date(), "yyyy-MM-dd");
-        getZyFeeParam.setInpatientNo(param.getInpatientNo());
-        getZyFeeParam.setAdmissTimes(param.getAdmissTimes());
-        getZyFeeParam.setStart(date);
-        getZyFeeParam.setEnd(date);
-        dao.getZyFees(getZyFeeParam);
-        log.info("缴纳住院预交金成功:{}", JSON.toJSONStringWithDateFormat(param, "yyyy-MM-dd HH:mm:ss"));
-        String msgContent = "{\"touser\":\"\",\"data\":" +
-                "{\"keyword3\":{\"color\":\"#173177\",\"value\":\"" +param.getTotalFee() + "\"}," +
-                "\"keyword1\":{\"color\":\"#173177\",\"value\":\"" + param.getPatientName() + "\"}," +
-                "\"keyword2\":{\"color\":\"#173177\",\"value\":\"" + param.getInpatientNo() + "\"}," +
-                "\"remark\":{\"color\":\"#FF0000\",\"value\":\"感谢您的使用,祝您健康!\"}," +
-                "\"first\":{\"color\":\"#FF0000\",\"value\":\"您好,您已成功支付住院预交金,详情如下:\"}}," +
-                "\"template_id\":\"6qWVpQopIe4a_fYYnZg_yaInPoMFduDDJ4hotv3Mtxo\"," +
-                "\"url\":\"\"}";
-        PushMessageParam pojo = new PushMessageParam();
-        pojo.setCardNo(dao.selectCardNoByPatientId(param.getPatientId()));
-        pojo.setMsgContext(JSONObject.parseObject(msgContent));
-        wxApiService.pushMessage(pojo);
-        tradeNosBetweenQuery.remove(param.getTradeNo());
-        return CompletableFuture.completedFuture(ResultVoUtil.success("保存住院预交金信息成功。"));
-    }
-
 }

+ 0 - 77
src/main/java/thyyxxk/wxservice_server/service/PayMzFeeService.java

@@ -2,36 +2,21 @@ package thyyxxk.wxservice_server.service;
 
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 import thyyxxk.wxservice_server.config.exception.ExceptionEnum;
-import thyyxxk.wxservice_server.dao.WxApiDao;
 import thyyxxk.wxservice_server.pojo.HrgResponse;
 import thyyxxk.wxservice_server.pojo.ResultVo;
-import thyyxxk.wxservice_server.pojo.wxapi.WxPayOrderPojo;
 import thyyxxk.wxservice_server.utils.*;
 
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.TimeUnit;
 
 @Slf4j
 @Service
 public class PayMzFeeService {
-    private final WxApiDao dao;
-    private final WxApiService wxApiService;
-    private static final Vector<String> tradeNosBetweenQuery = new Vector<>();
-
-    @Autowired
-    public PayMzFeeService(WxApiDao dao, WxApiService wxApiService) {
-        this.dao = dao;
-        this.wxApiService = wxApiService;
-    }
 
     public ResultVo<Object> getUnPaidFee(String patientId) {
         JSONObject obj = new JSONObject();
@@ -50,68 +35,6 @@ public class PayMzFeeService {
         return getObjectResultVoFromGrg(obj, url);
     }
 
-    public boolean isTradeNoBetweenQuery(String tradeNo) {
-        return tradeNosBetweenQuery.contains(tradeNo);
-    }
-
-    private Integer queryPayStatus(WxPayOrderPojo order) {
-        tradeNosBetweenQuery.add(order.getTradeNo());
-        RestTemplate template = new RestTemplate();
-        JSONObject obj = new JSONObject();
-        obj.put("hisOrdNum", order.getHisOrdNum());
-        obj.put("psOrdNum", order.getTradeNo());
-        obj.put("payMode", "WX");
-        obj.put("payAmt", order.getTotalFee().toPlainString());
-        obj.put("agtOrdNum", order.getSerialNo());
-        obj.put("payTime", DateUtil.formatDatetime(order.getPayDatetime(), "yyyy-MM-dd HH:mm:ss"));
-        HrgResponse response = template.postForObject(ThmzUrls.GET_PAY_STATUS, obj, HrgResponse.class);
-        log.info("门诊缴费订单支付状态查询结果:{}", response);
-        if (null == response || response.getResultCode() == -1) {
-            return 0;
-        }
-        return response.getPayStatus();
-    }
-
-    @Async("asyncTask")
-    public CompletableFuture<ResultVo<String>> saveMzChargeInfo(String tradeNo) throws Exception {
-        while (isTradeNoBetweenQuery(tradeNo)) {
-            TimeUnit.SECONDS.sleep(1);
-        }
-        WxPayOrderPojo order = dao.selectOrderByTradeNo(tradeNo);
-        Integer hasSaved = queryPayStatus(order);
-        if (hasSaved == 1) {
-            log.info("订单号:{} 的门诊缴费信息已保存,无需再次保存。", tradeNo);
-            tradeNosBetweenQuery.remove(tradeNo);
-            return CompletableFuture.completedFuture(ResultVoUtil.success("保存门诊缴费信息成功。"));
-        }
-        String payTime = DateUtil.formatDatetime(new Date(), "yyyy-MM-dd HH:mm:ss");
-        JSONObject hrgParam = new JSONObject();
-        hrgParam.put("patCardType", 1);
-        hrgParam.put("patCardNo", order.getPatientId());
-        hrgParam.put("hisOrdNum", order.getHisOrdNum());
-        hrgParam.put("psOrdNum", tradeNo);
-        hrgParam.put("payMode", "WX");
-        hrgParam.put("payAmt", DecimalTool.moneyYuanToFen(order.getTotalFee()));
-        hrgParam.put("agtOrdNum", order.getSerialNo());
-        hrgParam.put("payTime", payTime);
-        log.info("保存门诊缴费信息:{}", hrgParam);
-        RestTemplate template = new RestTemplate();
-        HrgResponse response = template.postForObject(ThmzUrls.PAY_CHARGE_DETAIL_FORM_HAI_CI,
-                hrgParam, HrgResponse.class);
-        log.info("保存门诊缴费信息结果:{}", response);
-        tradeNosBetweenQuery.remove(tradeNo);
-        if (null != response && response.getResultCode() == 0) {
-            return CompletableFuture.completedFuture(ResultVoUtil.success("保存门诊缴费信息成功。"));
-        }
-        log.info("保存门诊缴费信息失败,将自动退款。");
-        ResultVo<String> refund = wxApiService.autoRefund(tradeNo, "保存门诊缴费信息失败,自动退款。");
-        if (null != refund && refund.getCode() == 200) {
-            return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存门诊缴费信息失败,已为您自动退款,请留意到账信息。"));
-        }
-        dao.updatePayStatusOnly(tradeNo, 7);
-        return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存门诊缴费信息失败,自动退款失败,请联系服务中心进行退款。"));
-    }
-
     @Async("asyncTask")
     public CompletableFuture<ResultVo<List<Map<String, String>>>> getMzPaidList(String patientId) {
         log.info("获取门诊缴费记录列表:{}", patientId);

+ 0 - 1
src/main/java/thyyxxk/wxservice_server/service/SpringRetryService.java

@@ -20,7 +20,6 @@ import java.io.IOException;
 public class SpringRetryService {
     @Retryable(value = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 1000, multiplier = 1.5))
     public JSONObject queryOrderStateFromTencent(String tradeNo) throws IOException {
-        log.info("查询订单状态:{}", tradeNo);
         String url = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" +
                 tradeNo + "?mchid=" + PropertiesUtil.getProperty("mchId");
         HttpGet httpGet = new HttpGet(url);

+ 182 - 21
src/main/java/thyyxxk/wxservice_server/service/WxApiService.java

@@ -1,5 +1,6 @@
 package thyyxxk.wxservice_server.service;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -18,10 +19,15 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 import thyyxxk.wxservice_server.config.exception.ExceptionEnum;
+import thyyxxk.wxservice_server.dao.InpatientDao;
 import thyyxxk.wxservice_server.dao.WxApiDao;
+import thyyxxk.wxservice_server.pojo.HrgResponse;
 import thyyxxk.wxservice_server.pojo.ResultVo;
-import thyyxxk.wxservice_server.pojo.wxapi.JsApiSHA1;
+import thyyxxk.wxservice_server.pojo.appointment.MzyReqrecPojo;
+import thyyxxk.wxservice_server.pojo.appointment.SaveAppointmentParam;
 import thyyxxk.wxservice_server.pojo.appointment.WeChatPayParam;
+import thyyxxk.wxservice_server.pojo.inpatient.GetZyFeeParam;
+import thyyxxk.wxservice_server.pojo.wxapi.JsApiSHA1;
 import thyyxxk.wxservice_server.pojo.wxapi.MzGuideBillParam;
 import thyyxxk.wxservice_server.pojo.wxapi.PushMessageParam;
 import thyyxxk.wxservice_server.pojo.wxapi.WxPayOrderPojo;
@@ -35,13 +41,15 @@ import java.util.concurrent.TimeUnit;
 @Slf4j
 @Service
 public class WxApiService {
+    private static final Vector<String> tradeNosBetweenQuery = new Vector<>();
     private final WxApiDao dao;
+    private final InpatientDao yjjDao;
     private final SpringRetryService retryService;
-    private static final Vector<String> tradeNosBetweenQuery = new Vector<>();
 
     @Autowired
-    public WxApiService(WxApiDao dao, SpringRetryService retryService) {
+    public WxApiService(WxApiDao dao, InpatientDao yjjDao, SpringRetryService retryService) {
         this.dao = dao;
+        this.yjjDao = yjjDao;
         this.retryService = retryService;
     }
 
@@ -57,17 +65,18 @@ public class WxApiService {
         return ResultVoUtil.success(data);
     }
 
-    public ResultVo<WxPayOrderPojo> createPayOrder(WeChatPayParam param) {
+    @Async("asyncTask")
+    public CompletableFuture<ResultVo<WxPayOrderPojo>> createPayOrder(WeChatPayParam param) {
         if (param.getOrderType() == 1) {
             int count = dao.selectSameGhCount(param.getPatientId(), param.getMzyRequestId());
             if (count > 0) {
-                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您已成功支付过一笔相同金额的订单,请勿重复支付。");
+                return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您已成功支付过一笔相同金额的订单,请勿重复支付。"));
             }
         }
         if (param.getOrderType() == 2) {
             int count = dao.selectSameMzFeeCount(param.getHisOrdNum());
             if (count > 0) {
-                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您已成功支付过一笔相同金额的订单,请勿重复支付。");
+                return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您已成功支付过一笔相同金额的订单,请勿重复支付。"));
             }
         }
         String appId = PropertiesUtil.getProperty("appId");
@@ -95,7 +104,7 @@ public class WxApiService {
                 "<device_info>WEB</device_info>" +
                 "<mch_id>" + merchantId + "</mch_id>" +
                 "<nonce_str>" + nonceStr + "</nonce_str>" +
-                "<notify_url>" + notifyUrl +"</notify_url>" +
+                "<notify_url>" + notifyUrl + "</notify_url>" +
                 "<openid>" + param.getOpenId() + "</openid>" +
                 "<out_trade_no>" + tradeNo + "</out_trade_no>" +
                 "<total_fee>" + totalFee + "</total_fee>" +
@@ -143,15 +152,15 @@ public class WxApiService {
                 order.setAdmissTimes(param.getAdmissTimes());
                 dao.insertNewOrder(order);
                 log.info("统一下单成功:{}", order);
-                return ResultVoUtil.success(order);
+                return CompletableFuture.completedFuture(ResultVoUtil.success(order));
             } else {
                 final String message = root.element("return_msg").getStringValue();
                 log.info("微信统一下单失败:{}", message);
-                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, message);
+                return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, message));
             }
         } catch (DocumentException e) {
             e.printStackTrace();
-            return ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, e.getMessage());
+            return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, e.getMessage()));
         }
     }
 
@@ -172,11 +181,161 @@ public class WxApiService {
             String successTime = obj.getString("success_time")
                     .split("\\+")[0].replace("T", " ");
             dao.updatePayStatusAndPayTime(tradeNo, 1, successTime);
-        } else {
-            updatePayStatusByTradeState(tradeState, tradeNo);
+            WxPayOrderPojo order = dao.selectOrderByTradeNo(tradeNo);
+            ResultVo<String> saveRet;
+            switch (order.getOrderType()) {
+                case 1:
+                    saveRet = saveAppointment(order);
+                    break;
+                case 2:
+                    saveRet = saveMzChargeInfo(order);
+                    break;
+                case 3:
+                    saveRet = saveZyYjjInfo(order);
+                    break;
+                default:
+                    log.info("未识别到的订单类型:{},订单号:{}", order.getOrderType(), tradeNo);
+                    saveRet = ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未识别到的订单类型,请联系服务中心。");
+                    break;
+            }
+            tradeNosBetweenQuery.remove(tradeNo);
+            return CompletableFuture.completedFuture(saveRet);
         }
+        updatePayStatusByTradeState(tradeState, tradeNo);
         tradeNosBetweenQuery.remove(tradeNo);
-        return CompletableFuture.completedFuture(ResultVoUtil.success(tradeState));
+        return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, "支付失败"));
+    }
+
+    private ResultVo<String> saveAppointment(WxPayOrderPojo order) {
+        Integer hasSaved = queryRegistrationState(order);
+        if (hasSaved == 1) {
+            log.info("订单号:{} 的挂号信息已保存,无需再次保存。", order.getTradeNo());
+            return ResultVoUtil.success("保存挂号信息成功。");
+        }
+        SaveAppointmentParam param = new SaveAppointmentParam();
+        param.setMzyRequestId(order.getMzyRequestId());
+        param.setTotalFee(order.getTotalFee().doubleValue());
+        MzyReqrecPojo mzyReqrec = new MzyReqrecPojo();
+        mzyReqrec.setPatientId(order.getPatientId());
+        mzyReqrec.setPaymode("WX");
+        mzyReqrec.setPsordnum(order.getTradeNo());
+        mzyReqrec.setAgtordnum(order.getSerialNo());
+        param.setMzyReqrec(mzyReqrec);
+        log.info("保存挂号信息: {}", param);
+        RestTemplate template = new RestTemplate();
+        HrgResponse data = template.postForObject(ThmzUrls.PAY_REGISTRATION_FORM_HAI_CI, param, HrgResponse.class);
+        log.info("保存挂号信息结果: {}", data);
+        tradeNosBetweenQuery.remove(order.getTradeNo());
+        if (null != data && data.getResultCode() == 0) {
+            return ResultVoUtil.success("保存挂号信息成功。");
+        }
+        log.info("保存挂号信息失败,将自动退款。");
+        ResultVo<String> refund = autoRefund(order.getTradeNo(), "保存挂号信息失败,自动退款。");
+        if (null != refund && refund.getCode() == 200) {
+            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存挂号信息失败,已为您自动退款,请留意到账信息。");
+        }
+        dao.updatePayStatusOnly(order.getTradeNo(), 7);
+        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存挂号信息失败,自动退款失败,请联系服务中心进行退款。");
+    }
+
+    private ResultVo<String> saveMzChargeInfo(WxPayOrderPojo order) {
+        Integer hasSaved = queryMzPayStatus(order);
+        if (hasSaved == 1) {
+            log.info("订单号:{} 的门诊缴费信息已保存,无需再次保存。", order.getTradeNo());
+            return ResultVoUtil.success("保存门诊缴费信息成功。");
+        }
+        String payTime = DateUtil.formatDatetime(new Date(), "yyyy-MM-dd HH:mm:ss");
+        JSONObject hrgParam = new JSONObject();
+        hrgParam.put("patCardType", 1);
+        hrgParam.put("patCardNo", order.getPatientId());
+        hrgParam.put("hisOrdNum", order.getHisOrdNum());
+        hrgParam.put("psOrdNum", order.getTradeNo());
+        hrgParam.put("payMode", "WX");
+        hrgParam.put("payAmt", DecimalTool.moneyYuanToFen(order.getTotalFee()));
+        hrgParam.put("agtOrdNum", order.getSerialNo());
+        hrgParam.put("payTime", payTime);
+        log.info("保存门诊缴费信息:{}", hrgParam);
+        RestTemplate template = new RestTemplate();
+        HrgResponse response = template.postForObject(ThmzUrls.PAY_CHARGE_DETAIL_FORM_HAI_CI,
+                hrgParam, HrgResponse.class);
+        log.info("保存门诊缴费信息结果:{}", response);
+        if (null != response && response.getResultCode() == 0) {
+            return ResultVoUtil.success("保存门诊缴费信息成功。");
+        }
+        log.info("保存门诊缴费信息失败,将自动退款。");
+        ResultVo<String> refund = autoRefund(order.getTradeNo(), "保存门诊缴费信息失败,自动退款。");
+        if (null != refund && refund.getCode() == 200) {
+            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存门诊缴费信息失败,已为您自动退款,请留意到账信息。");
+        }
+        dao.updatePayStatusOnly(order.getTradeNo(), 7);
+        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存门诊缴费信息失败,自动退款失败,请联系服务中心进行退款。");
+    }
+
+    public ResultVo<String> saveZyYjjInfo(WxPayOrderPojo param) {
+        int savedCount = yjjDao.selectSavedCount(param.getTradeNo(), param.getSerialNo());
+        if (savedCount > 0) {
+            log.info("订单号:{} 的住院预交金信息已保存,无需再次保存。", param.getTradeNo());
+            return ResultVoUtil.success("保存住院预交金信息成功。");
+        }
+        String datetime = DateUtil.formatDatetime(new Date(), "yyyy-MM-dd HH:mm:ss");
+        yjjDao.payZyYjjSuccessful(param.getInpatientNo(), param.getAdmissTimes(), param.getTotalFee(),
+                datetime, param.getTradeNo(), param.getSerialNo(), "");
+        GetZyFeeParam getZyFeeParam = new GetZyFeeParam();
+        String date = DateUtil.formatDatetime(new Date(), "yyyy-MM-dd");
+        getZyFeeParam.setInpatientNo(param.getInpatientNo());
+        getZyFeeParam.setAdmissTimes(param.getAdmissTimes());
+        getZyFeeParam.setStart(date);
+        getZyFeeParam.setEnd(date);
+        yjjDao.getZyFees(getZyFeeParam);
+        log.info("缴纳住院预交金成功:{}", JSON.toJSONStringWithDateFormat(param, "yyyy-MM-dd HH:mm:ss"));
+        String msgContent = "{\"touser\":\"\",\"data\":" +
+                "{\"keyword3\":{\"color\":\"#173177\",\"value\":\"" + param.getTotalFee() + "\"}," +
+                "\"keyword1\":{\"color\":\"#173177\",\"value\":\"" + param.getPatientName() + "\"}," +
+                "\"keyword2\":{\"color\":\"#173177\",\"value\":\"" + param.getInpatientNo() + "\"}," +
+                "\"remark\":{\"color\":\"#FF0000\",\"value\":\"感谢您的使用,祝您健康!\"}," +
+                "\"first\":{\"color\":\"#FF0000\",\"value\":\"您好,您已成功支付住院预交金,详情如下:\"}}," +
+                "\"template_id\":\"6qWVpQopIe4a_fYYnZg_yaInPoMFduDDJ4hotv3Mtxo\"," +
+                "\"url\":\"\"}";
+        PushMessageParam pojo = new PushMessageParam();
+        pojo.setCardNo(yjjDao.selectCardNoByPatientId(param.getPatientId()));
+        pojo.setMsgContext(JSONObject.parseObject(msgContent));
+        pushMessage(pojo);
+        return ResultVoUtil.success("保存住院预交金信息成功。");
+    }
+
+    private Integer queryRegistrationState(WxPayOrderPojo order) {
+        RestTemplate template = new RestTemplate();
+        JSONObject obj = new JSONObject();
+        obj.put("psOrdNum", order.getTradeNo());
+        obj.put("payMode", "WX");
+        obj.put("payAmt", order.getTotalFee().toPlainString());
+        obj.put("agtOrdNum", order.getSerialNo());
+        obj.put("payTime", DateUtil.formatDatetime(order.getPayDatetime(), "yyyy-MM-dd HH:mm:ss"));
+        HrgResponse response = template.postForObject(ThmzUrls.GET_PAY_STATUS_FOR_REGISTRATION, obj, HrgResponse.class);
+        log.info("门诊挂号订单支付状态查询结果:{}", response);
+        int result = 0;
+        if (null != response && response.getResultCode() == 0) {
+            result = response.getPayStatus();
+        }
+        return result;
+    }
+
+    private Integer queryMzPayStatus(WxPayOrderPojo order) {
+        tradeNosBetweenQuery.add(order.getTradeNo());
+        RestTemplate template = new RestTemplate();
+        JSONObject obj = new JSONObject();
+        obj.put("hisOrdNum", order.getHisOrdNum());
+        obj.put("psOrdNum", order.getTradeNo());
+        obj.put("payMode", "WX");
+        obj.put("payAmt", order.getTotalFee().toPlainString());
+        obj.put("agtOrdNum", order.getSerialNo());
+        obj.put("payTime", DateUtil.formatDatetime(order.getPayDatetime(), "yyyy-MM-dd HH:mm:ss"));
+        HrgResponse response = template.postForObject(ThmzUrls.GET_PAY_STATUS, obj, HrgResponse.class);
+        log.info("门诊缴费订单支付状态查询结果:{}", response);
+        if (null == response || response.getResultCode() == -1) {
+            return 0;
+        }
+        return response.getPayStatus();
     }
 
     public void updatePayStatusByTradeState(String tradeState, String tradeNo) {
@@ -224,7 +383,8 @@ public class WxApiService {
         return template.postForObject(url, param, ResultVo.class);
     }
 
-    public ResultVo<String> createOrderForMzGuideBill(MzGuideBillParam param) throws Exception {
+    @Async("asyncTask")
+    public CompletableFuture<ResultVo<String>> createOrderForMzGuideBill(MzGuideBillParam param) throws Exception {
         String outTradeNo = SnowFlakeId.instance().nextId();
         JSONObject body = new JSONObject();
         body.put("appid", PropertiesUtil.getProperty("appId"));
@@ -271,20 +431,21 @@ public class WxApiService {
             order.setHisOrdNum(param.getHisOrdNum());
             dao.insertNewOrder(order);
             JSONObject retObj = JSONObject.parseObject(ret);
-            return ResultVoUtil.success(retObj.getString("code_url"));
+            return CompletableFuture.completedFuture(ResultVoUtil.success(retObj.getString("code_url")));
         }
         log.error("请求门诊指引单二维码失败:{}", ret);
-        return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请求微信支付二维码失败,请联系管理员。");
+        return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请求微信支付二维码失败,请联系管理员。"));
     }
 
-    public ResultVo<List<Map<String, Object>>> pushMessage(PushMessageParam param) {
+    @Async("asyncTask")
+    public CompletableFuture<ResultVo<List<Map<String, Object>>>> pushMessage(PushMessageParam param) {
         JSONObject content = param.getMsgContext();
         String wxUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" +
                 PropertiesUtil.getProperty("access_token");
         List<String> openIds = dao.selectOpenIdByIcCardNo(param.getCardNo());
         if (null == openIds || openIds.isEmpty()) {
-            return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "未找到卡号【" +
-                    param.getCardNo() + "】的openId。");
+            return CompletableFuture.completedFuture(ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "未找到卡号【" +
+                    param.getCardNo() + "】的openId。"));
         }
         List<Map<String, Object>> resMapArr = new ArrayList<>();
         RestTemplate template = new RestTemplate();
@@ -301,14 +462,14 @@ public class WxApiService {
             map.put("cardNo", param.getCardNo());
             resMapArr.add(map);
         }
-        return ResultVoUtil.success(resMapArr);
+        return CompletableFuture.completedFuture(ResultVoUtil.success(resMapArr));
     }
 
     private RestTemplate getRestTemplate() {
         RestTemplate restTemplate = new RestTemplate();
         List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
         for (HttpMessageConverter<?> httpMessageConverter : list) {
-            if(httpMessageConverter instanceof StringHttpMessageConverter) {
+            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                 ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(StandardCharsets.UTF_8);
                 break;
             }

+ 3 - 18
src/main/java/thyyxxk/wxservice_server/service/WxPayNotifyService.java

@@ -16,13 +16,11 @@ import java.security.GeneralSecurityException;
 @Service
 public class WxPayNotifyService {
     private final WxApiDao dao;
-    private final PayMzFeeService payMzFeeService;
     private final WxApiService wxApiService;
 
     @Autowired
-    public WxPayNotifyService(WxApiDao dao, PayMzFeeService payMzFeeService, WxApiService wxApiService) {
+    public WxPayNotifyService(WxApiDao dao, WxApiService wxApiService) {
         this.dao = dao;
-        this.payMzFeeService = payMzFeeService;
         this.wxApiService = wxApiService;
     }
 
@@ -40,21 +38,8 @@ public class WxPayNotifyService {
         String tradeNo = cipherObj.getString("out_trade_no");
         String openId = payer.getString("openid");
         dao.updatePayOpenId(tradeNo, openId);
-        String tradeState = cipherObj.getString("trade_state");
-        if (null == tradeState) {
-            wxApiService.queryOrderState(tradeNo);
-        } else {
-            if (tradeState.equals("SUCCESS")) {
-                String successTime = cipherObj.getString("success_time");
-                successTime = successTime.split("\\+")[0].replace("T", " ");
-                dao.updatePayStatusAndPayTime(tradeNo, 1, successTime);
-                if (!payMzFeeService.isTradeNoBetweenQuery(tradeNo)) {
-                    payMzFeeService.saveMzChargeInfo(tradeNo);
-                }
-            } else {
-                wxApiService.updatePayStatusByTradeState(tradeState, tradeNo);
-            }
-        }
+        log.info("二维码支付查询订单状态:{}", tradeNo);
+        wxApiService.queryOrderState(tradeNo);
     }
 
     @Async("asyncTask")