Pārlūkot izejas kodu

mall + pay:
1、调整微信支付,修复 v2 传递的时间不正确
2、调整 mp js ticket 接口到 system 模块

YunaiV 1 gadu atpakaļ
vecāks
revīzija
67d60e32f8
23 mainītis faili ar 129 papildinājumiem un 131 dzēšanām
  1. 4 4
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
  2. 2 2
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java
  3. 1 2
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXLitePayClient.java
  4. 1 2
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXNativePayClient.java
  5. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPayClientConfig.java
  6. 28 23
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java
  7. 1 1
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java
  8. 4 3
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayDisplayModeEnum.java
  9. 2 5
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java
  10. 2 2
      yudao-module-member/yudao-module-member-biz/pom.xml
  11. 0 2
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.http
  12. 1 0
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
  13. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java
  14. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
  15. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/test-integration/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDOTest.java
  16. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/test-integration/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapperIntegrationTest.java
  17. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java
  18. 4 0
      yudao-module-system/yudao-module-system-biz/pom.xml
  19. 4 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http
  20. 3 2
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.java
  21. 5 2
      yudao-server/src/main/resources/static/pay_wx_pub.html
  22. 51 60
      yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue
  23. 10 15
      yudao-ui-admin/src/views/mall/promotion/seckill/seckillTime/index.vue

+ 4 - 4
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java

@@ -5,10 +5,10 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClient;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXLitePayClient;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXNativePayClient;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPubPayClient;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXLitePayClient;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXNativePayClient;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPubPayClient;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
 import lombok.extern.slf4j.Slf4j;
 

+ 2 - 2
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPayClientConfig.java

@@ -9,8 +9,6 @@ import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.util.Set;
 
-// TODO 芋艿:参数校验
-
 /**
  * 支付宝的 PayClientConfig 实现类
  * 属性主要来自 {@link com.alipay.api.AlipayConfig} 的必要属性
@@ -111,7 +109,9 @@ public class AlipayPayClientConfig implements PayClientConfig {
 
     @Override
     public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
+        // TODO 芋艿:参数校验
         return validator.validate(this,
                 MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
     }
+
 }

+ 1 - 2
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXLitePayClient.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
+package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.DateUtil;
@@ -9,7 +9,6 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.util.io.FileUtils;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
-import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;

+ 1 - 2
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXNativePayClient.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
+package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.DateUtil;
@@ -8,7 +8,6 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.util.io.FileUtils;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
-import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayRefundNotifyRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPayClientConfig.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
+package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
 
 import cn.hutool.core.io.IoUtil;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;

+ 28 - 23
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/wx/WXPubPayClient.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
+package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.LocalDateTimeUtil;
@@ -7,6 +7,7 @@ import cn.hutool.core.lang.Assert;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.util.io.FileUtils;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayNotifyReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
@@ -15,6 +16,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReq
 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
+import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum;
 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
@@ -33,6 +35,8 @@ import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.Objects;
 
+import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
+
 /**
  * 微信支付(公众号)的 PayClient 实现类
  *
@@ -70,29 +74,29 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
 
     @Override
     public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
-        throw new UnsupportedOperationException();
-//
-//        WxPayMpOrderResult response;
-//        try {
-//            switch (config.getApiVersion()) {
-//                case WXPayClientConfig.API_VERSION_V2:
-//                    response = this.unifiedOrderV2(reqDTO);
-//                    break;
-//                case WXPayClientConfig.API_VERSION_V3:
-//                    WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
-//                    // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
-//                    response = new WxPayMpOrderResult();
-//                    BeanUtil.copyProperties(responseV3, response, true);
-//                    break;
-//                default:
-//                    throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
-//            }
-//        } catch (WxPayException e) {
-//            log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
+        WxPayMpOrderResult response = null;
+        try {
+            switch (config.getApiVersion()) {
+                case WXPayClientConfig.API_VERSION_V2:
+                    response = this.unifiedOrderV2(reqDTO);
+                    break;
+                case WXPayClientConfig.API_VERSION_V3:
+                    WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
+                    // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
+                    response = new WxPayMpOrderResult();
+                    BeanUtil.copyProperties(responseV3, response, true);
+                    break;
+                default:
+                    throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
+            }
+        } catch (WxPayException e) {
+            log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
 //            return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
 //                    ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping);
-//        }
-//        return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
+            System.out.println();
+        }
+        return new PayOrderUnifiedRespDTO().setDisplayMode(PayDisplayModeEnum.CUSTOM.getMode())
+                .setDisplayContent(JsonUtils.toJsonString(response));
     }
 
 
@@ -190,7 +194,8 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
     }
 
     private static String formatDate(LocalDateTime time) {
-        return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyy-MM-dd'T'HH:mm:ssXXX");
+//        return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyy-MM-dd'T'HH:mm:ssXXX");
+        return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), "yyyyMMddHHmmss");
     }
 
 }

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.pay.core.enums;
 import cn.hutool.core.util.ArrayUtil;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPayClientConfig;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 

+ 4 - 3
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayDisplayModeEnum.java

@@ -13,12 +13,13 @@ import lombok.Getter;
 public enum PayDisplayModeEnum {
 
     URL("url"), // Redirect 跳转链接的方式
-    IFRAME("iframe"), // IFrame 内嵌链接的方式
+    IFRAME("iframe"), // IFrame 内嵌链接的方式【目前暂时用不到】
     FORM("form"), // HTML 表单提交
     QR_CODE("qr_code"), // 二维码的文字内容
-    QR_CODE_URL("qr_code_url"), // 二维码的图片链接
+    QR_CODE_URL("qr_code_url"), // 二维码的图片链接【目前暂时用不到】
     BAR_CODE("bar_code"), // 条形码
-    APP("app"), // 应用
+    APP("app"), // 应用【目前暂时用不到】
+    CUSTOM("custom"), // 自定义:每种支付方式,做个性化处理;例如说,微信公众号支付时,调用 JSAPI 接口
     ;
 
     /**

+ 2 - 5
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImplIntegrationTest.java

@@ -2,17 +2,14 @@ package cn.iocoder.yudao.framework.pay.core.client.impl;
 
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.RandomUtil;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayQrPayClient;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayWapPayClient;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPubPayClient;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPubPayClient;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
-import com.alipay.api.response.AlipayTradePrecreateResponse;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 

+ 2 - 2
yudao-module-member/yudao-module-member-biz/pom.xml

@@ -41,11 +41,11 @@
         </dependency>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
+            <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
         </dependency>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
+            <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
         </dependency>
 
         <!-- Web 相关 -->

+ 0 - 2
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.http

@@ -1,2 +0,0 @@
-### 请求 /login 接口 => 成功
-GET {{userServerUrl}}/wx/mp/get-jsapi-ticket

+ 1 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java

@@ -125,6 +125,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
     @Override
     public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
         // 获得对应的手机号信息
+        // TODO @芋艿:需要弱化微信小程序的依赖,通过 system 获取手机号
         WxMaPhoneNumberInfo phoneNumberInfo;
         try {
             phoneNumberInfo = wxMaService.getUserService().getNewPhoneNoInfo(reqVO.getPhoneCode());

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java

@@ -94,7 +94,7 @@ public interface PayOrderConvert {
     @Mapping(target = "id", ignore = true)
     PayOrderExtensionDO convert(PayOrderSubmitReqVO bean, String userIp);
 
-    PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO);
+    PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO, String userIp);
 
     PayOrderSubmitRespVO convert(PayOrderUnifiedRespDTO bean);
 

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java

@@ -141,7 +141,7 @@ public class PayOrderServiceImpl implements PayOrderService {
         orderExtensionMapper.insert(orderExtension);
 
         // 3. 调用三方接口
-        PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqVO)
+        PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqVO, userIp)
                 // 商户相关的字段
                 .setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
                 .setSubject(order.getSubject()).setBody(order.getBody())

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/test-integration/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDOTest.java

@@ -1,7 +1,7 @@
 package cn.iocoder.yudao.module.pay.dal.dataobject.merchant;
 
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPayClientConfig;
 import org.junit.jupiter.api.Test;
 
 public class PayChannelDOTest {

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/test-integration/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapperIntegrationTest.java

@@ -4,7 +4,7 @@ import cn.hutool.core.io.IoUtil;
 import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
 import cn.iocoder.yudao.module.pay.test.BaseDbIntegrationTest;
 import org.junit.jupiter.api.Test;

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java

@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
-import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
+import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPayClientConfig;
 import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO;

+ 4 - 0
yudao-module-system/yudao-module-system-biz/pom.xml

@@ -58,6 +58,10 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
+        </dependency>
 
         <!-- Web 相关 -->
         <dependency>

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http

@@ -0,0 +1,4 @@
+### 请求 /login 接口 => 成功
+POST {{appApi}}/system/wx-mp/create-jsapi-signature?url=http://www.iocoder.cn
+Authorization: Bearer {{appToken}}
+tenant-id: {{appTenentId}}

+ 3 - 2
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.member.controller.app.weixin;
+package cn.iocoder.yudao.module.system.controller.app.weixin;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -19,7 +19,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 @Tag(name = "微信公众号")
 @RestController
-@RequestMapping("/member/wx-mp")
+@RequestMapping("/system/wx-mp")
 @Validated
 @Slf4j
 public class AppWxMpController {
@@ -27,6 +27,7 @@ public class AppWxMpController {
     @Resource
     private WxMpService mpService;
 
+    // TODO @芋艿:需要额外考虑个问题;多租户下,如果每个小程序一个微信公众号,则会存在多个 appid;
     @PostMapping("/create-jsapi-signature")
     @Operation(summary = "创建微信 JS SDK 初始化所需的签名",
         description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档")

+ 5 - 2
yudao-server/src/main/resources/static/pay_wx_pub.html

@@ -16,8 +16,8 @@
 <script>
     let shopOrderId = undefined;
     let payOrderId = undefined;
-    // let server = 'http://127.0.0.1:48080';
-    let server = 'http://niubi.natapp1.cc';
+    let server = 'http://127.0.0.1:48080';
+    // let server = 'http://niubi.natapp1.cc';
     // TODO openid
     let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0";
     $(function() {
@@ -26,6 +26,9 @@
         $.ajax({
             url: server + "/app-api/wx/mp/create-jsapi-signature?url=" + document.location.href,
             method: 'POST',
+						headers: {
+              'tenant-id': 1
+						},
             success: function( result ) {
                 if (result.code !== 0) {
                     alert('获取 JsapiTicket 失败,原因:' + result.msg)

+ 51 - 60
yudao-ui-admin/src/views/mall/promotion/seckill/seckillActivity/index.vue

@@ -17,7 +17,7 @@
             </el-form-item>
             <el-form-item label="参与场次" prop="timeId">
                 <el-select v-model="queryParams.timeId" placeholder="请选择参与场次" clearable size="small">
-                    <el-option v-for="item in SeckillConfigList" :key="item.id" :label="item.name" :value="item.id"/>
+                    <el-option v-for="item in seckillTimeList" :key="item.id" :label="item.name" :value="item.id" />
                 </el-select>
             </el-form-item>
             <el-form-item label="创建时间" prop="createTime">
@@ -38,9 +38,8 @@
                     v-hasPermi="['promotion:seckill-activity:create']">新增秒杀活动</el-button>
             </el-col>
             <el-col :span="1.5">
-              <el-button v-hasPermi="['promotion:seckill-activity:create']" icon="el-icon-menu" plain size="mini" type="primary"
-                         @click="openSeckillConfig">管理参与场次
-              </el-button>
+                <el-button type="primary" plain icon="el-icon-menu" size="mini" @click="openSeckillTime"
+                    v-hasPermi="['promotion:seckill-activity:create']">管理参与场次</el-button>
             </el-col>
             <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
         </el-row>
@@ -55,8 +54,8 @@
             </el-table-column>
             <el-table-column label="参与场次" prop="timeIds" width="250">
                 <template v-slot="scope">
-                    <span v-for="item in SeckillConfigList" v-if="scope.row.timeIds.includes(item.id)"
-                          :key="item.id">
+                    <span v-for="item in seckillTimeList" :key="item.id"
+                        v-if="scope.row.timeIds.includes(item.id)">
                         <el-tag style="margin:4px;" size="small">{{ item.name }}</el-tag>
                     </span>
                 </template>
@@ -111,13 +110,12 @@
                 <el-form-item label="场次选择">
                     <el-select v-model="form.timeIds" placeholder="请选择参与场次" clearable size="small" multiple filterable
                         style="width: 880px">
-                      <el-option v-for="item in SeckillConfigList" :key="item.id" :label="item.name" :value="item.id">
-                            <span style="float: left">{{ item.name + ': { ' }} {{ item.startTime }} -- {{
-                                item.endTime +
-                                ' }'
-                              }}</span>
-                        <span style="float: right; color: #8492a6; font-size: 13px"></span>
-                      </el-option>
+                        <el-option v-for="item in seckillTimeList" :key="item.id" :label="item.name" :value="item.id">
+                            <span style="float: left">{{ item.name + ': { ' }} {{ item.startTime }} -- {{ item.endTime +
+                                    ' }'
+                            }}</span>
+                            <span style="float: right; color: #8492a6; font-size: 13px"></span>
+                        </el-option>
                     </el-select>
                 </el-form-item>
                 <el-form-item label="商品选择">
@@ -188,17 +186,10 @@
 </template>
 
 <script>
-import {getSkuOptionList} from "@/api/mall/product/sku";
-import {
-  closeSeckillActivity,
-  createSeckillActivity,
-  deleteSeckillActivity,
-  getSeckillActivity,
-  getSeckillActivityPage,
-  updateSeckillActivity
-} from "@/api/mall/promotion/seckillActivity";
-import {getSeckillConfigList} from "@/api/mall/promotion/SeckillConfig";
-import {deepClone} from "@/utils";
+import { getSkuOptionList } from "@/api/mall/product/sku";
+import { createSeckillActivity, updateSeckillActivity, closeSeckillActivity, deleteSeckillActivity, getSeckillActivity, getSeckillActivityPage, exportSeckillActivityExcel } from "@/api/mall/promotion/seckillActivity";
+import { getSeckillTimeList } from "@/api/mall/promotion/seckillTime";
+import { deepClone } from "@/utils";
 
 export default {
     name: "PromotionSeckillActivity",
@@ -206,26 +197,26 @@ export default {
     },
     data() {
         return {
-          // 遮罩层
-          loading: true,
-          // 显示搜索条件
-          showSearch: true,
-          // 总条数
-          total: 0,
-          // 秒杀活动列表
-          list: [],
-          // 秒杀场次列表
-          SeckillConfigList: [],
-          // 弹出层标题
-          title: "",
-          // 是否显示弹出层
-          open: false,
-          // 查询参数
-          queryParams: {
-            pageNo: 1,
-            pageSize: 10,
-            name: null,
-            status: null,
+            // 遮罩层
+            loading: true,
+            // 显示搜索条件
+            showSearch: true,
+            // 总条数
+            total: 0,
+            // 秒杀活动列表
+            list: [],
+            // 秒杀场次列表
+            seckillTimeList: [],
+            // 弹出层标题
+            title: "",
+            // 是否显示弹出层
+            open: false,
+            // 查询参数
+            queryParams: {
+                pageNo: 1,
+                pageSize: 10,
+                name: null,
+                status: null,
                 timeId: null,
                 createTime: [],
             },
@@ -270,18 +261,18 @@ export default {
                 this.total = response.data.total;
                 this.loading = false;
             });
-          if (timeId) {
-            //查询完成后设置为空
-            this.$route.params.timeId = undefined
-          }
-          // 获得 SKU 商品列表
-          getSkuOptionList().then(response => {
-            this.productSkus = response.data;
-          });
-          // 获取参与场次列表
-          getSeckillConfigList().then(response => {
-            this.SeckillConfigList = response.data;
-          });
+            if (timeId) {
+                //查询完成后设置为空
+                this.$route.params.timeId = undefined
+            }
+            // 获得 SKU 商品列表
+            getSkuOptionList().then(response => {
+                this.productSkus = response.data;
+            });
+            // 获取参与场次列表
+            getSeckillTimeList().then(response => {
+                this.seckillTimeList = response.data;
+            });
         },
         /** 取消按钮 */
         cancel() {
@@ -315,10 +306,10 @@ export default {
             this.resetForm("queryForm");
             this.handleQuery();
         },
-      /**打开秒杀场次管理页面 */
-      openSeckillConfig() {
-        this.$tab.openPage("秒杀场次管理", "/promotion/seckill-time");
-      },
+        /**打开秒杀场次管理页面 */
+        openSeckillTime() {
+            this.$tab.openPage("秒杀场次管理", "/promotion/seckill-time");
+        },
         /** 新增按钮操作 */
         handleAdd() {
             this.reset();

+ 10 - 15
yudao-ui-admin/src/views/mall/promotion/seckill/seckillTime/index.vue

@@ -63,19 +63,14 @@
 </template>
 
 <script>
-import {
-  createSeckillConfig,
-  deleteSeckillConfig,
-  getSeckillConfig,
-  getSeckillConfigList,
-  updateSeckillConfig
-} from "@/api/mall/promotion/SeckillConfig";
+import { createSeckillTime, updateSeckillTime, deleteSeckillTime, getSeckillTime, getSeckillTimePage, exportSeckillTimeExcel, getSeckillTimeList } from "@/api/mall/promotion/seckillTime";
 import router from "@/router";
-import {deepClone} from "@/utils";
+import { deepClone } from "@/utils";
 
 export default {
-  name: "PromotionSeckillConfig",
-  components: {},
+  name: "PromotionSeckillTime",
+  components: {
+  },
   data() {
     return {
       // 遮罩层
@@ -109,7 +104,7 @@ export default {
     getList() {
       this.loading = true;
       // 执行查询
-      getSeckillConfigList().then(response => {
+      getSeckillTimeList().then(response => {
         this.list = response.data;
         this.loading = false;
       });
@@ -153,7 +148,7 @@ export default {
     handleUpdate(row) {
       this.reset();
       const id = row.id;
-      getSeckillConfig(id).then(response => {
+      getSeckillTime(id).then(response => {
         response.data.startAndEndTime = [response.data.startTime, response.data.endTime]
         this.form = response.data;
         this.open = true;
@@ -173,7 +168,7 @@ export default {
         data.endTime = this.form.startAndEndTime[1];
         // 修改的提交
         if (this.form.id != null) {
-          updateSeckillConfig(data).then(response => {
+          updateSeckillTime(data).then(response => {
             this.$modal.msgSuccess("修改成功");
             this.open = false;
             this.getList();
@@ -181,7 +176,7 @@ export default {
           return;
         }
         // 添加的提交
-        createSeckillConfig(data).then(response => {
+        createSeckillTime(data).then(response => {
           this.$modal.msgSuccess("新增成功");
           this.open = false;
           this.getList();
@@ -192,7 +187,7 @@ export default {
     handleDelete(row) {
       const id = row.id;
       this.$modal.confirm('是否确认删除秒杀时段编号为"' + id + '"的数据项?').then(function () {
-        return deleteSeckillConfig(id);
+        return deleteSeckillTime(id);
       }).then(() => {
         this.getList();
         this.$modal.msgSuccess("删除成功");