Explorar el Código

退款过程中不执行保存缴费,退款结束后再继续执行。

lighter hace 2 años
padre
commit
c217d6de9b

+ 1 - 1
pom.xml

@@ -10,7 +10,7 @@
     </parent>
     <groupId>thyyxxk</groupId>
     <artifactId>wxservice-server</artifactId>
-    <version>9.7</version>
+    <version>9.8</version>
     <name>wxservice-server</name>
     <description>server for wxservice-web</description>
 

+ 6 - 6
src/main/java/thyyxxk/wxservice_server/controller/WxApiController.java

@@ -9,7 +9,7 @@ import thyyxxk.wxservice_server.entity.ResultVo;
 import thyyxxk.wxservice_server.entity.appointment.DoctorInfo;
 import thyyxxk.wxservice_server.entity.appointment.WeChatPayParam;
 import thyyxxk.wxservice_server.entity.wxapi.*;
-import thyyxxk.wxservice_server.service.AutoRefundService;
+import thyyxxk.wxservice_server.service.WxRefundService;
 import thyyxxk.wxservice_server.service.PushWxMessageService;
 import thyyxxk.wxservice_server.service.WxApiService;
 import thyyxxk.wxservice_server.utils.PropertiesUtil;
@@ -26,11 +26,11 @@ import java.util.Map;
 @RequestMapping("/wxApi")
 public class WxApiController {
     private final WxApiService service;
-    private final AutoRefundService refundService;
+    private final WxRefundService refundService;
     private final PushWxMessageService pushWxMessageService;
 
     @Autowired
-    public WxApiController(WxApiService payService, AutoRefundService refundService, PushWxMessageService pushWxMessageService) {
+    public WxApiController(WxApiService payService, WxRefundService refundService, PushWxMessageService pushWxMessageService) {
         this.service = payService;
         this.refundService = refundService;
         this.pushWxMessageService = pushWxMessageService;
@@ -43,7 +43,7 @@ public class WxApiController {
     }
 
     @GetMapping("/getJsApiSHA1")
-    public ResultVo<JsApiSHA1> getJsApiSha1Sign(@RequestParam("url") String url) {
+    public ResultVo<JsApiSHA1> getJsApiSha1Sign(@RequestParam("url") String url) throws Exception {
         JsApiSHA1 data = new JsApiSHA1();
         data.setUrl(url);
         return service.getJsapiSHA1Sign(data);
@@ -51,13 +51,13 @@ public class WxApiController {
 
     @PostMapping("/createPayOrder")
     public ResultVo<WxPayOrder> createPayOrder(HttpServletRequest request,
-                                               @RequestBody @Validated WeChatPayParam param) {
+                                               @RequestBody @Validated WeChatPayParam param) throws Exception {
         param.setClientIp(request.getRemoteAddr());
         return service.createPayOrder(param);
     }
 
     @GetMapping("/queryOrderState")
-    public ResultVo<Object> queryOrderState(@RequestParam("tradeNo") String tradeNo) throws Exception {
+    public ResultVo<Object> queryOrderState(@RequestParam("tradeNo") String tradeNo) {
         return service.queryOrderState(tradeNo, QuerySource.INTERFACE);
     }
 

+ 1 - 1
src/main/java/thyyxxk/wxservice_server/controller/WxPayNotifyController.java

@@ -31,7 +31,7 @@ public class WxPayNotifyController {
     }
 
     @PostMapping("/notify2")
-    public void paymentNotify2(@RequestBody PaymentNotify param) throws GeneralSecurityException {
+    public void paymentNotify2(@RequestBody PaymentNotify param) throws Exception {
         service.paymentNotify2(param);
     }
 }

+ 8 - 3
src/main/java/thyyxxk/wxservice_server/dao/WxApiDao.java

@@ -64,6 +64,9 @@ public interface WxApiDao {
     @Select("select count(1) from mz_deposit_file WITH(NOLOCK) where psordnum=#{tradeNo} and pay_mark=0")
     int alreadyPayed(@Param("tradeNo") String tradeNo);
 
+    @Select("select pay_status from t_wechat_pay_order where trade_no=#{tradeNo} ")
+    Integer selectPayStatus(@Param("tradeNo") String tradeNo);
+
     @Update("update t_wechat_pay_order set pay_status=4,refund_op_code='99999',refund_reason=#{rea}, " +
             "his_status=0,refund_op_datetime=getdate() where trade_no=#{tradeNo}")
     void refundOrder(@Param("tradeNo") String tradeNo, @Param("rea") String rea);
@@ -96,10 +99,12 @@ public interface WxApiDao {
     @Select("select pay_status from t_wechat_pay_order with(nolock) where trade_no=#{tradeNo}")
     Integer selectOrderStatus(@Param("tradeNo") String tradeNo);
 
-    @Select("select count(1) from mz_yj_req where patient_id=#{patId} and times=#{times} and receipt_no=#{receipt} " +
-            "and order_code='003585' and req_doctor='99999'")
-    Integer selectSelfCovidExamReceiptCount(@Param("patId") String patId, @Param("times") String times, @Param("receipt") String receipt);
+    @Update("update t_wechat_pay_order set refund_id=#{refundId}, refund_op_code=#{refundOpCode}, his_status=0, " +
+            "refund_op_datetime=#{refundOpDatetime}, refund_reason=#{refundReason}, pay_status=4 where trade_no=#{tradeNo}")
+    void updateRefundId(WxPayOrder order);
 
+    @Update("update t_wechat_pay_order set pay_status=4, refund_reason=#{msg}, his_status=0 where trade_no=#{tradeNo}")
+    void alreadyRefund(@Param("tradeNo") String tradeNo, @Param("msg") String msg);
     @Update("update t_si_setlinfo set mz_saved=1 where pat_no=#{patId} and times=#{times} and revoked=0")
     void updateMzSavedFlag(@Param("patId") String patId, @Param("times") String times);
 }

+ 2 - 2
src/main/java/thyyxxk/wxservice_server/service/BookableService.java

@@ -34,14 +34,14 @@ import java.util.concurrent.TimeUnit;
 @Service
 public class BookableService {
     private final BookableDao dao;
-    private final AutoRefundService refundService;
+    private final WxRefundService refundService;
     DelayQueue<BookedYjReq> queue = new DelayQueue<>();
 
     @Value("${hrgApiUrl}")
     private String hrgApiUrl;
 
     @Autowired
-    public BookableService(BookableDao dao, AutoRefundService refundService) {
+    public BookableService(BookableDao dao, WxRefundService refundService) {
         this.dao = dao;
         this.refundService = refundService;
     }

+ 15 - 29
src/main/java/thyyxxk/wxservice_server/service/SavePayResultService.java

@@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 import thyyxxk.wxservice_server.config.exception.ExceptionEnum;
-import thyyxxk.wxservice_server.constant.QuerySource;
+import thyyxxk.wxservice_server.constant.TradeState;
 import thyyxxk.wxservice_server.dao.InpatientDao;
 import thyyxxk.wxservice_server.dao.WxApiDao;
 import thyyxxk.wxservice_server.entity.ResultVo;
@@ -19,12 +19,10 @@ import thyyxxk.wxservice_server.entity.hrgresponse.SaveMzFeeResponse;
 import thyyxxk.wxservice_server.entity.inpatient.GetZyFeeParam;
 import thyyxxk.wxservice_server.entity.wxapi.PushMessageParam;
 import thyyxxk.wxservice_server.entity.wxapi.WxPayOrder;
-import thyyxxk.wxservice_server.utils.DateUtil;
-import thyyxxk.wxservice_server.utils.DecimalTool;
-import thyyxxk.wxservice_server.utils.ResultVoUtil;
-import thyyxxk.wxservice_server.utils.StringUtil;
+import thyyxxk.wxservice_server.utils.*;
 
 import java.util.Date;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @description: 保存付费结果
@@ -36,14 +34,14 @@ import java.util.Date;
 public class SavePayResultService {
     private final WxApiDao dao;
     private final InpatientDao yjjDao;
-    private final AutoRefundService refundService;
+    private final WxRefundService refundService;
     private final PushWxMessageService pushWxMessageService;
 
     @Value("${hrgApiUrl}")
     private String hrgApiUrl;
 
     @Autowired
-    public SavePayResultService(WxApiDao dao, InpatientDao yjjDao, AutoRefundService refundService,
+    public SavePayResultService(WxApiDao dao, InpatientDao yjjDao, WxRefundService refundService,
                                 PushWxMessageService pushWxMessageService) {
         this.dao = dao;
         this.yjjDao = yjjDao;
@@ -88,12 +86,19 @@ public class SavePayResultService {
         return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "保存挂号信息失败,自动退款失败,请联系服务中心进行退款。");
     }
 
-    public ResultVo<Object> saveMzChargeInfo(WxPayOrder order, QuerySource source, String successTime) {
+    public ResultVo<Object> saveMzChargeInfo(WxPayOrder order, String successTime) throws InterruptedException {
+        while (TradeVectorUtil.tradeNoBeingRefund(order.getTradeNo())) {
+            TimeUnit.SECONDS.sleep(3);
+        }
         if (dao.alreadyPayed(order.getTradeNo()) == 1) {
             log.info("订单号:{} 的门诊缴费信息已保存,无需再次保存。", order.getTradeNo());
             updateHisChargeStatus(order.getHisOrdNum(), order.getTradeNo());
             return ResultVoUtil.success("保存门诊缴费信息成功。");
         }
+        Integer status = dao.selectPayStatus(order.getTradeNo());
+        if (null == status || status != TradeState.SUCCESS.getCode()) {
+            return ResultVoUtil.success("因系统原因,订单已退款。请稍后重新缴费或前往一楼收费窗口缴费。");
+        }
         JSONObject hrgParam = new JSONObject();
         hrgParam.put("patCardType", 1);
         hrgParam.put("patCardNo", order.getPatientId());
@@ -110,38 +115,19 @@ public class SavePayResultService {
         if (null != saveMzFeeResponse && null != saveMzFeeResponse.getResultCode() &&
                 saveMzFeeResponse.getResultCode() == 0) {
             updateHisChargeStatus(order.getHisOrdNum(), order.getTradeNo());
-            if (source == QuerySource.INTERFACE) {
-                String hisOrdNum = order.getHisOrdNum();
-                    String[] hsrdnms = hisOrdNum.split("_");
-                    Integer isCovidExam = dao.selectSelfCovidExamReceiptCount(hsrdnms[0], hsrdnms[1], hsrdnms[2]);
-                    if (null != isCovidExam && isCovidExam > 0) {
-                        order.setBody("新冠肺炎核酸检测");
-                        order.setPayDatetime(DateUtil.parseDatetime(successTime));
-                        return ResultVoUtil.success("showBill", order);
-                    }
-            }
             return ResultVoUtil.success("保存门诊缴费信息成功。");
         }
         if (dao.alreadyPayed(order.getTradeNo()) == 1) {
             updateHisChargeStatus(order.getHisOrdNum(), order.getTradeNo());
-            if (source == QuerySource.INTERFACE) {
-                String hisOrdNum = order.getHisOrdNum();
-                String[] hsrdnms = hisOrdNum.split("_");
-                Integer isCovidExam = dao.selectSelfCovidExamReceiptCount(hsrdnms[0], hsrdnms[1], hsrdnms[2]);
-                if (null != isCovidExam && isCovidExam > 0) {
-                    order.setBody("新冠肺炎核酸检测");
-                    order.setPayDatetime(DateUtil.parseDatetime(successTime));
-                    return ResultVoUtil.success("showBill", order);
-                }
-            }
             return ResultVoUtil.success("保存门诊缴费信息成功。");
         }
         String message = "保存门诊缴费信息失败,自动退款。";
         if (null != saveMzFeeResponse && StringUtil.notBlank(saveMzFeeResponse.getResultMessage())) {
             message = saveMzFeeResponse.getResultMessage();
         }
+        log.info("【订单号:{}】发起自动退款:{}", order.getTradeNo(), message);
         ResultVo<String> refund = refundService.autoRefund(order.getTradeNo(), message);
-        log.info("【订单号:{}】保存门诊缴费信息失败,自动退款结果:{}", order.getTradeNo(), refund);
+        log.info("【订单号:{}】自动退款结果:{}", order.getTradeNo(), refund);
         if (refund.getCode() == ExceptionEnum.SUCCESS.getCode()) {
             dao.refundOrder(order.getTradeNo(), message);
             return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【" + message +  "】已为您自动退款,请留意到账信息。");

+ 12 - 24
src/main/java/thyyxxk/wxservice_server/service/WxApiService.java

@@ -51,7 +51,7 @@ public class WxApiService {
         this.savePayResultService = savePayResultService;
     }
 
-    public ResultVo<JsApiSHA1> getJsapiSHA1Sign(JsApiSHA1 data) {
+    public ResultVo<JsApiSHA1> getJsapiSHA1Sign(JsApiSHA1 data) throws Exception {
         data.setAppId(PropertiesUtil.getProperty("appId"));
         data.setTicket(PropertiesUtil.getProperty("ticket"));
         data.setNoncestr(SnowFlakeId.instance().nextId());
@@ -63,7 +63,7 @@ public class WxApiService {
         return ResultVoUtil.success(data);
     }
 
-    public ResultVo<WxPayOrder> createPayOrder(WeChatPayParam param) {
+    public ResultVo<WxPayOrder> createPayOrder(WeChatPayParam param) throws Exception {
         WxPayOrder existOrder = null;
         if (param.getOrderType() == OrderType.REGISTRATION.getCode()) {
             existOrder = dao.selectSameGhOrder(param.getPatientId(), param.getMzyRequestId());
@@ -182,13 +182,13 @@ public class WxApiService {
         }
     }
 
-    public ResultVo<Object> queryOrderState(String tradeNo, QuerySource source) throws Exception {
-        while (TradeVectorUtil.tradeNoBeingQuery(tradeNo)) {
-            log.info("订单号:{} 正在查询状态中,进入等待区。", tradeNo);
-            TimeUnit.SECONDS.sleep(3);
-        }
-        TradeVectorUtil.add(tradeNo);
+    public ResultVo<Object> queryOrderState(String tradeNo, QuerySource source) {
         try {
+            while (TradeVectorUtil.tradeNoBeingQuery(tradeNo) || TradeVectorUtil.tradeNoBeingRefund(tradeNo)) {
+                log.info("订单号:{} 正在查询状态中,进入等待区。", tradeNo);
+                TimeUnit.SECONDS.sleep(3);
+            }
+            TradeVectorUtil.addBeingQuery(tradeNo);
             WxPayOrder order = dao.selectOrderByTradeNo(tradeNo);
             OrderType orderType = OrderType.get(order.getOrderType());
             int hasSaved = 0;
@@ -202,21 +202,9 @@ public class WxApiService {
                 if (orderType == OrderType.REGISTRATION) {
                     log.info("订单号:{} 的挂号信息已保存,无需再次查询订单状态。", order.getTradeNo());
                     return ResultVoUtil.success("保存挂号信息成功。");
-                } else {
-                    log.info("订单号:{} 的门诊缴费信息已保存,无需再次查询订单状态。", order.getTradeNo());
-                    if (source == QuerySource.INTERFACE) {
-                        String hisOrdNum = order.getHisOrdNum();
-                        if (StringUtil.notBlank(hisOrdNum)) {
-                            String[] hsrdnms = hisOrdNum.split("_");
-                            Integer isCovidExam = dao.selectSelfCovidExamReceiptCount(hsrdnms[0], hsrdnms[1], hsrdnms[2]);
-                            if (null != isCovidExam && isCovidExam > 0) {
-                                order.setBody("新冠肺炎核酸检测");
-                                return ResultVoUtil.success("showBill", order);
-                            }
-                        }
-                    }
-                    return ResultVoUtil.success("保存门诊缴费信息成功。");
                 }
+                log.info("订单号:{} 的门诊缴费信息已保存,无需再次查询订单状态。", order.getTradeNo());
+                return ResultVoUtil.success("保存门诊缴费信息成功。");
             }
             JSONObject obj = retryService.queryOrderStateFromTencent(tradeNo, orderType, source);
             TradeState tradeState = TradeState.get(obj.getString("trade_state"));
@@ -228,7 +216,7 @@ public class WxApiService {
                     case REGISTRATION:
                         return savePayResultService.saveAppointment(order);
                     case OUTPATIENT:
-                        return savePayResultService.saveMzChargeInfo(order, source, successTime);
+                        return savePayResultService.saveMzChargeInfo(order, successTime);
                     case INPATIENT_PRE_PAY:
                         return savePayResultService.saveZyYjjInfo(order);
                     case SELF_HELP_MACHINE:
@@ -244,7 +232,7 @@ public class WxApiService {
             e.printStackTrace();
             return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "服务器错误,请联系管理员处理。【订单号:" + tradeNo + "】");
         } finally {
-            TradeVectorUtil.remove(tradeNo);
+            TradeVectorUtil.removeBeingQuery(tradeNo);
         }
     }
 

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

@@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import thyyxxk.wxservice_server.constant.OrderType;
-import thyyxxk.wxservice_server.constant.QuerySource;
 import thyyxxk.wxservice_server.constant.TradeState;
 import thyyxxk.wxservice_server.dao.WxApiDao;
 import thyyxxk.wxservice_server.entity.wxapi.PaymentNotify;
@@ -13,7 +12,6 @@ import thyyxxk.wxservice_server.entity.wxapi.WxPayOrder;
 import thyyxxk.wxservice_server.utils.WxPaySignUtil;
 
 import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
 
 /**
  * @author dj
@@ -43,26 +41,26 @@ public class WxPayNotifyService {
         String tradeNo = cipherObj.getString("out_trade_no");
         String openId = payer.getString("openid");
         TradeState tradeState = TradeState.get(cipherObj.getString("trade_state"));
-        if (tradeState.equals(TradeState.SUCCESS)) {
-            String successTime = cipherObj.getString("success_time")
-                    .split("\\+")[0].replace("T", " ");
-            dao.updatePayStatusAndPayTimeAndOpenId(tradeNo, tradeState.getCode(), successTime, openId);
-            WxPayOrder order = dao.selectOrderByTradeNo(tradeNo);
-            OrderType orderType = OrderType.get(order.getOrderType());
-            switch (orderType) {
-                case OUTPATIENT:
-                    savePayResultService.saveMzChargeInfo(order, QuerySource.QRCODE, successTime);
-                    break;
-                case INPATIENT_PRE_PAY:
-                    savePayResultService.saveZyYjjInfo(order);
-                    break;
-            }
-        } else {
+        if (!tradeState.equals(TradeState.SUCCESS)) {
             dao.updatePayStatusAndQueryTimesAndOpenId(tradeNo, tradeState.getCode(), openId);
+            return;
+        }
+        String successTime = cipherObj.getString("success_time")
+                .split("\\+")[0].replace("T", " ");
+        dao.updatePayStatusAndPayTimeAndOpenId(tradeNo, tradeState.getCode(), successTime, openId);
+        WxPayOrder order = dao.selectOrderByTradeNo(tradeNo);
+        OrderType orderType = OrderType.get(order.getOrderType());
+        switch (orderType) {
+            case OUTPATIENT:
+                savePayResultService.saveMzChargeInfo(order, successTime);
+                break;
+            case INPATIENT_PRE_PAY:
+                savePayResultService.saveZyYjjInfo(order);
+                break;
         }
     }
 
-    public void paymentNotify2(PaymentNotify param) throws GeneralSecurityException {
+    public void paymentNotify2(PaymentNotify param) throws Exception {
         log.info("微信支付回调2:{}", param);
         String ciphertext = WxPaySignUtil.decryptToString(param.getResource().getAssociated_data().getBytes(StandardCharsets.UTF_8),
                 param.getResource().getNonce().getBytes(StandardCharsets.UTF_8), param.getResource().getCiphertext());

+ 15 - 2
src/main/java/thyyxxk/wxservice_server/utils/TradeVectorUtil.java

@@ -4,16 +4,29 @@ import java.util.Vector;
 
 public class TradeVectorUtil {
     private final static Vector<String> tradeNosBeingQuery = new Vector<>();
+    private final static Vector<String> tradeNoBeingRefund = new Vector<>();
 
-    public static void add(String tradeNo) {
+    public static void addBeingQuery(String tradeNo) {
         tradeNosBeingQuery.add(tradeNo);
     }
 
-    public static void remove(String tradeNo) {
+    public static void removeBeingQuery(String tradeNo) {
         tradeNosBeingQuery.remove(tradeNo);
     }
 
     public static boolean tradeNoBeingQuery(String tradeNo) {
         return tradeNosBeingQuery.contains(tradeNo);
     }
+
+    public static void addBeingRefund(String tradeNo) {
+        tradeNoBeingRefund.add(tradeNo);
+    }
+
+    public static void removeBeingRefund(String tradeNo) {
+        tradeNoBeingRefund.remove(tradeNo);
+    }
+
+    public static boolean tradeNoBeingRefund(String tradeNo) {
+        return tradeNoBeingRefund.contains(tradeNo);
+    }
 }