瀏覽代碼

feature: 同步 wapapi 项目 origin/publish 分支代码(latest commit: a4aa932d)

Walker 1 年之前
父節點
當前提交
3fb68a770b

+ 66 - 13
ywt-platform-outpatient-web/src/main/java/com/ywt/outpatient/controllers/taihe/DHOutpatientController.java

@@ -122,6 +122,9 @@ public class DHOutpatientController {
     // payAuthNo 缓存 key,后缀 hisOrderNo-userId
     public static final String REDIS_KEY_PAY_AUTH_NO_PATTERN = "wapapi:payAuthNo:%s-%s";
 
+    // 腾讯医保订单交易状态
+    public static final String MED_TRADE_STATE_SUCCESS = "SUCCESS"; // 支付成功
+    public static final String MED_TRADE_STATE_PAYING = "PAYING"; // 支付中
 
     /**
      * 获取门诊缴费列表
@@ -741,6 +744,15 @@ public class DHOutpatientController {
             CheckUtil.ensureNotEmpty(clinicCode, "就诊流水号不能为空");
             CheckUtil.ensureNotEmpty(hisOrdNum, "HIS 订单号不能为空");
             CheckUtil.ensureLargerThanZero(orderSum, "订单金额需大于 0");
+            // 是否医保支付
+            boolean isIns = OutpatientOrderPayInsTypeEnum.valueOf(payInsType) == OutpatientOrderPayInsTypeEnum.MED_INSURANCE;
+            String orderNo = "";
+            try {
+                orderNo = getPrevOrderInfo(hisOrdNum, isIns);
+            } catch (AppMessageException e) {
+                logger.error("DHOutpatientController#prePayConfirm(hisOrdNum={}):获取前一笔订单号:{}", hisOrdNum, e.getMessage());
+                throw e;
+            }
             int userId = userSrv.getCurrentUserIdWrapped();
             PrePayConfirmRequest req = PrePayConfirmRequest.newBuilder()
                     .setCardNo(cardNo)
@@ -756,7 +768,7 @@ public class DHOutpatientController {
             if (response.getCode() == ResultCode.SUCCEED_VALUE) {
                 if (!Checker.isNone(response.getListList())) {
                     // 预结算成功,自动取消之前生成的未支付订单,让前端可以重新创建订单
-                    autoCancelPrevOrder(hisOrdNum);
+                    autoCancelPrevOrder(orderNo);
                     PrePayConfirm p = response.getListList().get(0);
                     PrePayConfirmResp resp = new PrePayConfirmResp();
                     String invoiceNo = p.getInvoiceNo();
@@ -780,7 +792,7 @@ public class DHOutpatientController {
 //                        logger.error("DHOutpatientController#prePayConfirm(reqData={} ): Fail to update invoiceNo\n {}",
 //                                reqData, updateOutpatientOrderResponse.getMsg());
 //                    }
-                    if (OutpatientOrderPayInsTypeEnum.valueOf(payInsType) == OutpatientOrderPayInsTypeEnum.MED_INSURANCE) {
+                    if (isIns) {
                         String orderInsType = Checker.getStringValue(reqData.getOrderInsType());
                         CheckUtil.ensureNotEmpty(orderInsType, "订单费用类型不能为空");
                         // 获取身份证和姓名
@@ -912,26 +924,67 @@ public class DHOutpatientController {
         }
     }
 
-    private void autoCancelPrevOrder(String hisOrderNo) {
+    /**
+     * 获取上一笔订单的信息,如果订单已支付或支付中,则抛异常;否则返回订单编号
+     *
+     * @param hisOrderNo
+     * @param isIns
+     * @return
+     * @throws AppMessageException
+     */
+    private String getPrevOrderInfo(String hisOrderNo, boolean isIns) throws AppMessageException {
+        String orderNo = "";
         GetOutpatientOrderByHisOrderNoRequest request = GetOutpatientOrderByHisOrderNoRequest.newBuilder()
                 .setHisOrderNo(hisOrderNo)
                 .setHospitalId(BizUtil.getHospitalIdByTerminalId(BizUtil.getCurrentTerminalWrapped()))
                 .build();
         GetOutpatientOrderByHisOrderNoResponse response = taiheOutpatientServiceBlockingStub.getOutpatientOrderByHisOrderNo(request);
         if (response.getCode() == ResultCode.SUCCEED_VALUE) {
-            String orderNo = response.getOrderNo();
-            if (!StringHelper.isNullOrEmpty(orderNo)) {
-                logger.info("DHOutpatientController#autoCancelPrevOrder(): 预结算自动取消之前生成的订单 orderNo = {}", orderNo);
-                MarkOpOrderDeletedResponse markOpOrderDeletedResponse = wxInsPayServiceBlockingStub.markOpOrderDeleted(
-                        MarkOpOrderDeletedRequest.newBuilder()
-                                .setOrderNo(orderNo)
-                                .build());
-                if (markOpOrderDeletedResponse.getCode() != ResultCode.SUCCEED_VALUE) {
-                    logger.error("DHOutpatientController#autoCancelPrevOrder(): markOpOrderDeleted failed: {}", markOpOrderDeletedResponse.getMsg());
+            orderNo = response.getOrderNo();
+            if (!StringHelper.isNullOrEmpty(orderNo) && isIns) {
+                // 因为实测腾讯查单接口返回支付状态不及时,所以医保支付订单暂定创建后1分钟内不允许重复预结算,一分钟后才查单判断状态
+                // 目前订单号带时间戳标识,直接解析出订单创建时间
+                if (orderNo.length() > 14) {
+                    Date orderCreateDate = DateUtil.parseDate(orderNo.substring(0, 13), "yyyyMMddHHmmss");
+                    if (orderCreateDate != null) {
+                        long diffInMin = TimeUnit.MILLISECONDS.toMinutes(new Date().getTime() - orderCreateDate.getTime());
+                        if (diffInMin <= 1) {
+                            throw new AppMessageException("该订单正在处理中,请1分钟后再试!");
+                        }
+                    }
+                }
+                // 如果是医保支付,查询是否有已支付或支付中的订单
+                QueryPayInsOrderResponse qpioResp = wxInsPayServiceBlockingStub.queryPayInsOrder(QueryPayInsOrderRequest.newBuilder()
+                        .setHospOutTradeNo(response.getOrderNo())
+                        .setTerminal(BizUtil.getCurrentTerminalWrapped())
+                        .build());
+                if (qpioResp.getCode() != ResultCode.SUCCEED_VALUE) {
+                    logger.error("DHOutpatientController#getPrevOrderInfo(hisOrderNo={} ): 调用腾讯接口查单失败:{}", hisOrderNo, qpioResp.getMsg());
+                    throw new AppMessageException(String.format("查单失败:%s", qpioResp.getMsg()));
+                } else {
+                    if (qpioResp.getMedTradeState().equals(MED_TRADE_STATE_SUCCESS)) {
+                        throw new AppMessageException("该订单已支付成功,请返回刷新");
+                    }
+                    if (qpioResp.getMedTradeState().equals(MED_TRADE_STATE_PAYING)) {
+                        throw new AppMessageException("该订单正在支付中,请稍后");
+                    }
                 }
             }
         } else {
-            logger.error("DHOutpatientController#autoCancelPrevOrder(hisOrderNo={} ):\n {}", hisOrderNo, response.getMsg());
+            logger.error("DHOutpatientController#getPrevOrderInfo(hisOrderNo={} ):\n {}", hisOrderNo, response.getMsg());
+        }
+        return orderNo;
+    }
+
+    private void autoCancelPrevOrder(String orderNo) {
+        logger.info("DHOutpatientController#autoCancelPrevOrder(): 预结算自动取消之前生成的订单 orderNo = {}", orderNo);
+        if (StringHelper.isNullOrEmpty(orderNo)) return;
+        MarkOpOrderDeletedResponse markOpOrderDeletedResponse = wxInsPayServiceBlockingStub.markOpOrderDeleted(
+                MarkOpOrderDeletedRequest.newBuilder()
+                        .setOrderNo(orderNo)
+                        .build());
+        if (markOpOrderDeletedResponse.getCode() != ResultCode.SUCCEED_VALUE) {
+            logger.error("DHOutpatientController#autoCancelPrevOrder(): markOpOrderDeleted failed: {}", markOpOrderDeletedResponse.getMsg());
         }
     }