瀏覽代碼

修改订单支付

hgw 3 年之前
父節點
當前提交
f8cd47ba1f

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TenantInfoService.java

@@ -17,6 +17,8 @@ public interface TenantInfoService extends IService<TenantInfo> {
 
     TenantInfoDto queryTenantInfo(Integer tenantId);
 
+    TenantInfoDto queryTenantInfoCheck(Integer tenantId);
+
     void opsTenantState(Integer id, Integer state);
 
     PageInfo<TenantInfoInfoPageVo> queryPage(Map<String, Object> param);

+ 2 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/TenantOrderRecordService.java

@@ -19,6 +19,8 @@ public interface TenantOrderRecordService extends IService<TenantOrderRecord> {
 
     Map<String, Object> checkTenantOrder(String orderNo);
 
+    Map<String, Object> checkTenantOrder(TenantOrderRecord orderRecord);
+
     void checkTenantOrder();
 
 }

+ 29 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/OrderPayOpsServiceImpl.java

@@ -17,6 +17,8 @@ import com.ym.mec.thirdparty.adapay.Payment;
 import com.ym.mec.util.date.DateUtil;
 import com.ym.mec.util.http.HttpUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +28,9 @@ import org.springframework.util.DigestUtils;
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -44,6 +49,8 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
     private TenantPaymentOrderService tenantPaymentOrderService;
     @Autowired
     private TenantOrderRecordService tenantOrderRecordService;
+    @Autowired
+    private RedissonClient redissonClient;
 
     @Override
     public Map<String, Object> executePayment(BigDecimal amount, String orderNo, String payChannel, String returnUrl, String orderSubject, String orderBody, String sign, String code, String platform) throws Exception {
@@ -66,6 +73,8 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
                         tenantOrderRecord::setTransNo,
                         tenantOrderRecordService::updateById
                 );
+                //主动延迟检查订单
+                delayCheckTenant();
             } else if (platform.equals("teacher")) {
                 TenantPaymentOrder tenantPaymentOrder = tenantPaymentOrderService.queryByOrderNo(payParam.getOrderNo());
                 payment = checkOrderAndGetParam(payParam,
@@ -162,7 +171,6 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
                 .ifPresent(action);
     }
 
-
     private Map<String, Object> getExpend(PaymentParam payParam) throws Exception {
         Map<String, Object> expendParams = new HashMap<>(5);
         String openId = "";
@@ -203,6 +211,26 @@ public class OrderPayOpsServiceImpl implements OrderPayOpsService {
         return paymentParams;
     }
 
+    private void delayCheckTenant() {
+        RBucket<Object> bucket = redissonClient.getBucket("delay_check_tenant");
+        if (!bucket.trySet(1, 35L, TimeUnit.SECONDS)) {
+            return;
+        }
+        //异步
+        CompletableFuture.runAsync(() -> {
+            //检查5次
+            for (int i = 0; i <= 5; i++) {
+                try {
+                    Thread.sleep(3000);//每3秒触发一次
+                    tenantOrderRecordService.checkTenantOrder();
+                } catch (InterruptedException e) {
+                    return;
+                }
+            }
+            bucket.delete();
+        });
+    }
+
     static class PaymentParam {
         private BigDecimal amount;
         private String orderNo;

+ 41 - 3
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantInfoServiceImpl.java

@@ -34,6 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -97,7 +98,11 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         tenantInfo.setState(2);
         tenantInfo.setCreatedBy(userId);
         tenantInfo.setCreatedTime(new Date());
-        baseMapper.insert(tenantInfo);
+        try {
+            baseMapper.insert(tenantInfo);
+        } catch (DuplicateKeyException e) {
+            throw new BizException("同一个手机号只能创建一个机构!");
+        }
 
         //机构id
         Integer tenantId = tenantInfo.getId();
@@ -152,7 +157,11 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         BeanUtils.copyProperties(dto, tenantInfo);
         tenantInfo.setUpdatedBy(getUserId());
         tenantInfo.setUpdatedTime(now);
-        this.updateById(tenantInfo);
+        try {
+            this.updateById(tenantInfo);
+        } catch (DuplicateKeyException e) {
+            throw new BizException("同一个手机号只能创建一个机构!");
+        }
 
         //修改机构配置
         if (Objects.nonNull(dto.getConfig())) {
@@ -197,6 +206,32 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
     }
 
     /**
+     * 订单购买信息查询
+     * 为什么要这个功能?
+     * 防重复支付,若该机构开通时已经支付还会主动查询第三方付款状态
+     *
+     * @param tenantId 机构id
+     */
+    @Override
+    public TenantInfoDto queryTenantInfoCheck(Integer tenantId) {
+        if (Objects.isNull(tenantId)) {
+            throw new BizException("请传入机构id");
+        }
+        //查询最后一条该机构开通记录
+        TenantOrderRecord oneRecord = tenantOrderRecordService.getOne(new WrapperUtil<TenantOrderRecord>().queryWrapper()
+                .eq("tenant_id_", tenantId)
+                .isNotNull("trans_no_")
+                .eq("order_type_", "TENANT_OPEN")
+                .eq("payment_channel_", "ADAPAY")
+                .orderByDesc("created_time_"));
+        //存在,就去第三方再次校验
+        if (Objects.nonNull(oneRecord)) {
+            tenantOrderRecordService.checkTenantOrder(oneRecord);
+        }
+        return queryTenantInfo(tenantId);
+    }
+
+    /**
      * 启用/停用
      * 第一个启用默认激活账号等信息
      *
@@ -323,6 +358,8 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
         try {
             log.info("createUser >>>> {}", e);
             employeeService.add(e);
+            //将创建的userId反写到机构表
+            tenantInfo.setUserId(e.getId());
         } catch (Exception ex) {
             throw new BizException("开通账号信息异常!");
         }
@@ -411,7 +448,8 @@ public class TenantInfoServiceImpl extends ServiceImpl<TenantInfoDao, TenantInfo
     }
 
     //生成订单
-    private void createOrderRecord(Integer tenantId, BigDecimal payAmount, String orderNo, TenantOrderRecordEnum tenantEnum, Integer orderState) {
+    private void createOrderRecord(Integer tenantId, BigDecimal payAmount, String orderNo, TenantOrderRecordEnum
+            tenantEnum, Integer orderState) {
         TenantOrderRecord record = new TenantOrderRecord();
         record.setTenantId(tenantId);
         record.setOrderNo(orderNo);

+ 38 - 18
mec-biz/src/main/java/com/ym/mec/biz/service/impl/TenantOrderRecordServiceImpl.java

@@ -17,12 +17,15 @@ import com.ym.mec.thirdparty.adapay.Payment;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.joda.time.LocalDateTime;
+import org.redisson.api.RBucket;
+import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 机构付款记录表(TenantOrderRecord)表服务实现类
@@ -42,6 +45,8 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
     private PlatformServeDetailService platformServeDetailService;
     @Autowired
     private TenantInfoService tenantInfoService;
+    @Autowired
+    private RedissonClient redissonClient;
 
     //订单不存在
     public static final String PAYMENT_ID_NOT_EXISTS = "payment_id_not_exists";
@@ -64,7 +69,15 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
     public Map<String, Object> checkTenantOrder(String orderNo) {
         TenantOrderRecord orderRecord = this.getOne(new WrapperUtil<TenantOrderRecord>()
                 .hasEq("order_no_", orderNo).queryWrapper());
+        return checkTenantOrder(orderRecord);
+    }
+
+    @Override
+    public Map<String, Object> checkTenantOrder(TenantOrderRecord orderRecord) {
+        return getTenantOrderState(orderRecord);
+    }
 
+    private Map<String, Object> getTenantOrderState(TenantOrderRecord orderRecord) {
         //主动去第三方查询订单状态
         checkTransOrderState(orderRecord);
 
@@ -87,8 +100,13 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
         return result;
     }
 
+
     @Override
     public void checkTenantOrder() {
+        RBucket<Object> bucket = redissonClient.getBucket("tenant_check_order");
+        if (!bucket.trySet(1, 3L, TimeUnit.SECONDS)) {
+            return;
+        }
         List<TenantOrderRecord> list = this.list(new WrapperUtil<TenantOrderRecord>().queryWrapper()
                 .isNotNull("trans_no_")
                 .eq("order_state_", 0));
@@ -115,13 +133,16 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
                     LocalDateTime now = LocalDateTime.now();
                     record.setPayDate(now.toLocalDate().toDate());
                     record.setPayTime(now.toDate());
-                    baseMapper.updateById(record);
                 }
+                baseMapper.updateById(record);
             });
         }
-
+        bucket.delete();
     }
 
+    //丢弃5分钟之前的订单 300000 = 5 * 60秒 * 1000
+    long exTime = 300000L;
+
     //主动去第三方查询订单状态
     private void checkTransOrderState(TenantOrderRecord orderRecord) {
         if (StringUtils.equals(orderRecord.getPaymentChannel(), PaymentChannelEnum.ADAPAY.getCode())) {
@@ -129,26 +150,25 @@ public class TenantOrderRecordServiceImpl extends ServiceImpl<TenantOrderRecordD
             try {
                 payment = Payment.queryPayment(orderRecord.getTransNo());
                 log.info("checkTenantOrder  payment >>>>> {}", payment);
-                boolean flag = false;
-                if (Objects.nonNull(payment.get("error_code"))) {
+                String status = (String) payment.get("status");
+                //判断状态是成功还是失败
+                if (status.equals("succeeded")) {
+                    orderRecord.setOrderState(1);
+                } else if (Objects.nonNull(payment.get("error_code"))) {
+                    //若状态是失败则判断code
                     if (!PAYMENT_ID_NOT_EXISTS.equals(payment.get("error_code"))) {
-                        //确保订单已经创建
-                        flag = true;
-                    }
-                } else {
-                    //没有异常
-                    flag = true;
-                }
-                log.info("checkTenantOrder  payment >>>>> {} flag {}", payment, flag);
-                //确保订单已经创建 再 判断状态是成功还是失败
-                if (flag && Objects.nonNull(payment.get("status"))) {
-                    String status = (String) payment.get("status");
-                    if (status.equals("succeeded")) {
-                        orderRecord.setOrderState(1);
-                    } else if (status.equals("failed")) {
+                        //不等于这个异常都是失败
                         orderRecord.setOrderState(2);
+                    } else {
+                        long orderTime = orderRecord.getCreatedTime().getTime();//订单创建时间
+                        long nowTime = new Date().getTime();
+                        //丢弃5分钟之前的订单
+                        if (nowTime - orderTime > exTime) {
+                            orderRecord.setOrderState(2);
+                        }
                     }
                 }
+                log.info("checkTenantOrder  payment >>>>> {}", payment);
                 log.info("checkTenantOrder  orderRecord >>>>> {}", JSON.toJSONString(orderRecord));
             } catch (Exception e) {
                 log.error("checkTenantOrder  payment error>>>>> {}", JSON.toJSONString(orderRecord));

+ 3 - 4
mec-web/src/main/java/com/ym/mec/web/config/ResourceServerConfig.java

@@ -1,5 +1,7 @@
 package com.ym.mec.web.config;
 
+import com.ym.mec.common.security.BaseAccessDeniedHandler;
+import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
@@ -8,9 +10,6 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.E
 import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
 import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
 
-import com.ym.mec.common.security.BaseAccessDeniedHandler;
-import com.ym.mec.common.security.BaseAuthenticationEntryPoint;
-
 @Configuration
 @EnableResourceServer
 @EnableGlobalMethodSecurity(prePostEnabled = true)
@@ -39,7 +38,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                         "/eduSubject/findSubSubjects", "/eduFinancialExpenditure/batchAdd", "/eduSendNotice/*",
                         "/oaContracts/*", "/eduStudent/organStudentOverView", "/activity/countCloudTeacherActive",
                         "/activity/organDoubleEleven2021Statis", "/activity/doubleEleven2021Statis", "/questionnaireTopic/getDetail", "/questionnaireUserResult/add",
-                        "/tenantInfo/info/*","/tenantInfo/pay/*","/tenantInfo/notify"
+                        "/tenantInfo/info/*", "/tenantInfo/checkInfo/*", "/tenantInfo/pay/*", "/tenantInfo/notify"
                 )
                 .permitAll().anyRequest().authenticated().and().httpBasic();
     }

+ 7 - 1
mec-web/src/main/java/com/ym/mec/web/controller/TenantInfoController.java

@@ -45,7 +45,7 @@ public class TenantInfoController extends BaseController {
 
     @ApiOperation("修改机构启用停用状态")
     @GetMapping(value = "/opsState/{id}")
-//    @PreAuthorize("@pcs.hasPermissions('tenantInfo/opsState')")
+    @PreAuthorize("@pcs.hasPermissions('tenantInfo/opsState')")
     public Object opsState(@ApiParam(value = "机构ID", required = true) @PathVariable("id") Integer id, Integer state) {
         tenantInfoService.opsTenantState(id, state);
         return succeed();
@@ -57,6 +57,12 @@ public class TenantInfoController extends BaseController {
         return succeed(tenantInfoService.queryTenantInfo(id));
     }
 
+    @ApiOperation("查询单个机构详情")
+    @GetMapping(value = "/checkInfo/{id}")
+    public Object queryTenantInfoCheck(@ApiParam(value = "机构ID", required = true) @PathVariable("id") Integer id) {
+        return succeed(tenantInfoService.queryTenantInfoCheck(id));
+    }
+
     @ApiImplicitParams({
             @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
             @ApiImplicitParam(name = "createdName", dataType = "String", value = "创建人"),