mall + pay:
1、调整微信支付,修复 v2 传递的时间不正确 2、调整 mp js ticket 接口到 system 模块
This commit is contained in:
parent
20eb0a2a88
commit
67d60e32f8
|
@ -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.PayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
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.alipay.*;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXLitePayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXLitePayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXNativePayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXNativePayClient;
|
||||||
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.client.impl.wx.WXPubPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPubPayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
// TODO 芋艿:参数校验
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝的 PayClientConfig 实现类
|
* 支付宝的 PayClientConfig 实现类
|
||||||
* 属性主要来自 {@link com.alipay.api.AlipayConfig} 的必要属性
|
* 属性主要来自 {@link com.alipay.api.AlipayConfig} 的必要属性
|
||||||
|
@ -111,7 +109,9 @@ public class AlipayPayClientConfig implements PayClientConfig {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
|
public Set<ConstraintViolation<PayClientConfig>> verifyParam(Validator validator) {
|
||||||
|
// TODO 芋艿:参数校验
|
||||||
return validator.validate(this,
|
return validator.validate(this,
|
||||||
MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
|
MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.bean.BeanUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
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.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.PayNotifyReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
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.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
|
@ -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.bean.BeanUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
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.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.PayNotifyReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
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.PayOrderUnifiedReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
|
|
@ -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.hutool.core.io.IoUtil;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
|
@ -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.bean.BeanUtil;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
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.map.MapUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
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.PayNotifyReqDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
import cn.iocoder.yudao.framework.pay.core.client.dto.notify.PayOrderNotifyRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
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.dto.refund.PayRefundUnifiedRespDTO;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
|
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.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.WxPayOrderNotifyResult;
|
||||||
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
|
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
|
||||||
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
|
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
|
||||||
|
@ -33,6 +35,8 @@ import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微信支付(公众号)的 PayClient 实现类
|
* 微信支付(公众号)的 PayClient 实现类
|
||||||
*
|
*
|
||||||
|
@ -70,29 +74,29 @@ public class WXPubPayClient extends AbstractPayClient<WXPayClientConfig> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
public PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
|
||||||
throw new UnsupportedOperationException();
|
WxPayMpOrderResult response = null;
|
||||||
//
|
try {
|
||||||
// WxPayMpOrderResult response;
|
switch (config.getApiVersion()) {
|
||||||
// try {
|
case WXPayClientConfig.API_VERSION_V2:
|
||||||
// switch (config.getApiVersion()) {
|
response = this.unifiedOrderV2(reqDTO);
|
||||||
// case WXPayClientConfig.API_VERSION_V2:
|
break;
|
||||||
// response = this.unifiedOrderV2(reqDTO);
|
case WXPayClientConfig.API_VERSION_V3:
|
||||||
// break;
|
WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
|
||||||
// case WXPayClientConfig.API_VERSION_V3:
|
// 将 V3 的结果,统一转换成 V2。返回的字段是一致的
|
||||||
// WxPayUnifiedOrderV3Result.JsapiResult responseV3 = this.unifiedOrderV3(reqDTO);
|
response = new WxPayMpOrderResult();
|
||||||
// // 将 V3 的结果,统一转换成 V2。返回的字段是一致的
|
BeanUtil.copyProperties(responseV3, response, true);
|
||||||
// response = new WxPayMpOrderResult();
|
break;
|
||||||
// BeanUtil.copyProperties(responseV3, response, true);
|
default:
|
||||||
// break;
|
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
||||||
// default:
|
}
|
||||||
// throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
|
} catch (WxPayException e) {
|
||||||
// }
|
log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
||||||
// } catch (WxPayException e) {
|
|
||||||
// log.error("[unifiedOrder][request({}) 发起支付失败,原因({})]", toJsonString(reqDTO), e);
|
|
||||||
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
// return PayCommonResult.build(ObjectUtils.defaultIfNull(e.getErrCode(), e.getReturnCode(), "CustomErrorCode"),
|
||||||
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping);
|
// ObjectUtils.defaultIfNull(e.getErrCodeDes(), e.getCustomErrorMsg()),null, codeMapping);
|
||||||
// }
|
System.out.println();
|
||||||
// return PayCommonResult.build(CODE_SUCCESS, MESSAGE_SUCCESS, response, codeMapping);
|
}
|
||||||
|
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) {
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.pay.core.enums;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
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.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.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,13 @@ import lombok.Getter;
|
||||||
public enum PayDisplayModeEnum {
|
public enum PayDisplayModeEnum {
|
||||||
|
|
||||||
URL("url"), // Redirect 跳转链接的方式
|
URL("url"), // Redirect 跳转链接的方式
|
||||||
IFRAME("iframe"), // IFrame 内嵌链接的方式
|
IFRAME("iframe"), // IFrame 内嵌链接的方式【目前暂时用不到】
|
||||||
FORM("form"), // HTML 表单提交
|
FORM("form"), // HTML 表单提交
|
||||||
QR_CODE("qr_code"), // 二维码的文字内容
|
QR_CODE("qr_code"), // 二维码的文字内容
|
||||||
QR_CODE_URL("qr_code_url"), // 二维码的图片链接
|
QR_CODE_URL("qr_code_url"), // 二维码的图片链接【目前暂时用不到】
|
||||||
BAR_CODE("bar_code"), // 条形码
|
BAR_CODE("bar_code"), // 条形码
|
||||||
APP("app"), // 应用
|
APP("app"), // 应用【目前暂时用不到】
|
||||||
|
CUSTOM("custom"), // 自定义:每种支付方式,做个性化处理;例如说,微信公众号支付时,调用 JSAPI 接口
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,17 +2,14 @@ package cn.iocoder.yudao.framework.pay.core.client.impl;
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
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.PayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
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.AlipayPayClientConfig;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayQrPayClient;
|
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.alipay.AlipayWapPayClient;
|
||||||
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.client.impl.wx.WXPubPayClient;
|
import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WXPubPayClient;
|
||||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
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.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
### 请求 /login 接口 => 成功
|
|
||||||
GET {{userServerUrl}}/wx/mp/get-jsapi-ticket
|
|
|
@ -125,6 +125,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
|
||||||
@Override
|
@Override
|
||||||
public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
|
public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
|
||||||
// 获得对应的手机号信息
|
// 获得对应的手机号信息
|
||||||
|
// TODO @芋艿:需要弱化微信小程序的依赖,通过 system 获取手机号
|
||||||
WxMaPhoneNumberInfo phoneNumberInfo;
|
WxMaPhoneNumberInfo phoneNumberInfo;
|
||||||
try {
|
try {
|
||||||
phoneNumberInfo = wxMaService.getUserService().getNewPhoneNoInfo(reqVO.getPhoneCode());
|
phoneNumberInfo = wxMaService.getUserService().getNewPhoneNoInfo(reqVO.getPhoneCode());
|
||||||
|
|
|
@ -94,7 +94,7 @@ public interface PayOrderConvert {
|
||||||
@Mapping(target = "id", ignore = true)
|
@Mapping(target = "id", ignore = true)
|
||||||
PayOrderExtensionDO convert(PayOrderSubmitReqVO bean, String userIp);
|
PayOrderExtensionDO convert(PayOrderSubmitReqVO bean, String userIp);
|
||||||
|
|
||||||
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO);
|
PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqVO reqVO, String userIp);
|
||||||
|
|
||||||
PayOrderSubmitRespVO convert(PayOrderUnifiedRespDTO bean);
|
PayOrderSubmitRespVO convert(PayOrderUnifiedRespDTO bean);
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class PayOrderServiceImpl implements PayOrderService {
|
||||||
orderExtensionMapper.insert(orderExtension);
|
orderExtensionMapper.insert(orderExtension);
|
||||||
|
|
||||||
// 3. 调用三方接口
|
// 3. 调用三方接口
|
||||||
PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqVO)
|
PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqVO, userIp)
|
||||||
// 商户相关的字段
|
// 商户相关的字段
|
||||||
.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
|
.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性!
|
||||||
.setSubject(order.getSubject()).setBody(order.getBody())
|
.setSubject(order.getSubject()).setBody(order.getBody())
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.pay.dal.dataobject.merchant;
|
package cn.iocoder.yudao.module.pay.dal.dataobject.merchant;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
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;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class PayChannelDOTest {
|
public class PayChannelDOTest {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import cn.hutool.core.io.IoUtil;
|
||||||
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
|
import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
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.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.pay.core.enums.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.module.pay.test.BaseDbIntegrationTest;
|
import cn.iocoder.yudao.module.pay.test.BaseDbIntegrationTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
|
@ -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.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
|
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.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.pay.core.enums.PayChannelEnum;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO;
|
import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO;
|
||||||
|
|
|
@ -58,6 +58,10 @@
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
### 请求 /login 接口 => 成功
|
||||||
|
POST {{appApi}}/system/wx-mp/create-jsapi-signature?url=http://www.iocoder.cn
|
||||||
|
Authorization: Bearer {{appToken}}
|
||||||
|
tenant-id: {{appTenentId}}
|
|
@ -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 cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
@ -19,7 +19,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
@Tag(name = "微信公众号")
|
@Tag(name = "微信公众号")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/member/wx-mp")
|
@RequestMapping("/system/wx-mp")
|
||||||
@Validated
|
@Validated
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AppWxMpController {
|
public class AppWxMpController {
|
||||||
|
@ -27,6 +27,7 @@ public class AppWxMpController {
|
||||||
@Resource
|
@Resource
|
||||||
private WxMpService mpService;
|
private WxMpService mpService;
|
||||||
|
|
||||||
|
// TODO @芋艿:需要额外考虑个问题;多租户下,如果每个小程序一个微信公众号,则会存在多个 appid;
|
||||||
@PostMapping("/create-jsapi-signature")
|
@PostMapping("/create-jsapi-signature")
|
||||||
@Operation(summary = "创建微信 JS SDK 初始化所需的签名",
|
@Operation(summary = "创建微信 JS SDK 初始化所需的签名",
|
||||||
description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档")
|
description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档")
|
|
@ -16,8 +16,8 @@
|
||||||
<script>
|
<script>
|
||||||
let shopOrderId = undefined;
|
let shopOrderId = undefined;
|
||||||
let payOrderId = undefined;
|
let payOrderId = undefined;
|
||||||
// let server = 'http://127.0.0.1:48080';
|
let server = 'http://127.0.0.1:48080';
|
||||||
let server = 'http://niubi.natapp1.cc';
|
// let server = 'http://niubi.natapp1.cc';
|
||||||
// TODO openid
|
// TODO openid
|
||||||
let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0";
|
let openid = "ockUAwIZ-0OeMZl9ogcZ4ILrGba0";
|
||||||
$(function() {
|
$(function() {
|
||||||
|
@ -26,6 +26,9 @@
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: server + "/app-api/wx/mp/create-jsapi-signature?url=" + document.location.href,
|
url: server + "/app-api/wx/mp/create-jsapi-signature?url=" + document.location.href,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'tenant-id': 1
|
||||||
|
},
|
||||||
success: function( result ) {
|
success: function( result ) {
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
alert('获取 JsapiTicket 失败,原因:' + result.msg)
|
alert('获取 JsapiTicket 失败,原因:' + result.msg)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="参与场次" prop="timeId">
|
<el-form-item label="参与场次" prop="timeId">
|
||||||
<el-select v-model="queryParams.timeId" placeholder="请选择参与场次" clearable size="small">
|
<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-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建时间" prop="createTime">
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
@ -38,9 +38,8 @@
|
||||||
v-hasPermi="['promotion:seckill-activity:create']">新增秒杀活动</el-button>
|
v-hasPermi="['promotion:seckill-activity:create']">新增秒杀活动</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button v-hasPermi="['promotion:seckill-activity:create']" icon="el-icon-menu" plain size="mini" type="primary"
|
<el-button type="primary" plain icon="el-icon-menu" size="mini" @click="openSeckillTime"
|
||||||
@click="openSeckillConfig">管理参与场次
|
v-hasPermi="['promotion:seckill-activity:create']">管理参与场次</el-button>
|
||||||
</el-button>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -55,8 +54,8 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="参与场次" prop="timeIds" width="250">
|
<el-table-column label="参与场次" prop="timeIds" width="250">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<span v-for="item in SeckillConfigList" v-if="scope.row.timeIds.includes(item.id)"
|
<span v-for="item in seckillTimeList" :key="item.id"
|
||||||
:key="item.id">
|
v-if="scope.row.timeIds.includes(item.id)">
|
||||||
<el-tag style="margin:4px;" size="small">{{ item.name }}</el-tag>
|
<el-tag style="margin:4px;" size="small">{{ item.name }}</el-tag>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -111,13 +110,12 @@
|
||||||
<el-form-item label="场次选择">
|
<el-form-item label="场次选择">
|
||||||
<el-select v-model="form.timeIds" placeholder="请选择参与场次" clearable size="small" multiple filterable
|
<el-select v-model="form.timeIds" placeholder="请选择参与场次" clearable size="small" multiple filterable
|
||||||
style="width: 880px">
|
style="width: 880px">
|
||||||
<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">
|
||||||
<span style="float: left">{{ item.name + ': { ' }} {{ item.startTime }} -- {{
|
<span style="float: left">{{ item.name + ': { ' }} {{ item.startTime }} -- {{ item.endTime +
|
||||||
item.endTime +
|
' }'
|
||||||
' }'
|
}}</span>
|
||||||
}}</span>
|
<span style="float: right; color: #8492a6; font-size: 13px"></span>
|
||||||
<span style="float: right; color: #8492a6; font-size: 13px"></span>
|
</el-option>
|
||||||
</el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="商品选择">
|
<el-form-item label="商品选择">
|
||||||
|
@ -188,17 +186,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {getSkuOptionList} from "@/api/mall/product/sku";
|
import { getSkuOptionList } from "@/api/mall/product/sku";
|
||||||
import {
|
import { createSeckillActivity, updateSeckillActivity, closeSeckillActivity, deleteSeckillActivity, getSeckillActivity, getSeckillActivityPage, exportSeckillActivityExcel } from "@/api/mall/promotion/seckillActivity";
|
||||||
closeSeckillActivity,
|
import { getSeckillTimeList } from "@/api/mall/promotion/seckillTime";
|
||||||
createSeckillActivity,
|
import { deepClone } from "@/utils";
|
||||||
deleteSeckillActivity,
|
|
||||||
getSeckillActivity,
|
|
||||||
getSeckillActivityPage,
|
|
||||||
updateSeckillActivity
|
|
||||||
} from "@/api/mall/promotion/seckillActivity";
|
|
||||||
import {getSeckillConfigList} from "@/api/mall/promotion/SeckillConfig";
|
|
||||||
import {deepClone} from "@/utils";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PromotionSeckillActivity",
|
name: "PromotionSeckillActivity",
|
||||||
|
@ -206,26 +197,26 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 显示搜索条件
|
// 显示搜索条件
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
// 总条数
|
||||||
total: 0,
|
total: 0,
|
||||||
// 秒杀活动列表
|
// 秒杀活动列表
|
||||||
list: [],
|
list: [],
|
||||||
// 秒杀场次列表
|
// 秒杀场次列表
|
||||||
SeckillConfigList: [],
|
seckillTimeList: [],
|
||||||
// 弹出层标题
|
// 弹出层标题
|
||||||
title: "",
|
title: "",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
open: false,
|
open: false,
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
name: null,
|
name: null,
|
||||||
status: null,
|
status: null,
|
||||||
timeId: null,
|
timeId: null,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
},
|
},
|
||||||
|
@ -270,18 +261,18 @@ export default {
|
||||||
this.total = response.data.total;
|
this.total = response.data.total;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
if (timeId) {
|
if (timeId) {
|
||||||
//查询完成后设置为空
|
//查询完成后设置为空
|
||||||
this.$route.params.timeId = undefined
|
this.$route.params.timeId = undefined
|
||||||
}
|
}
|
||||||
// 获得 SKU 商品列表
|
// 获得 SKU 商品列表
|
||||||
getSkuOptionList().then(response => {
|
getSkuOptionList().then(response => {
|
||||||
this.productSkus = response.data;
|
this.productSkus = response.data;
|
||||||
});
|
});
|
||||||
// 获取参与场次列表
|
// 获取参与场次列表
|
||||||
getSeckillConfigList().then(response => {
|
getSeckillTimeList().then(response => {
|
||||||
this.SeckillConfigList = response.data;
|
this.seckillTimeList = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** 取消按钮 */
|
/** 取消按钮 */
|
||||||
cancel() {
|
cancel() {
|
||||||
|
@ -315,10 +306,10 @@ export default {
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm");
|
||||||
this.handleQuery();
|
this.handleQuery();
|
||||||
},
|
},
|
||||||
/**打开秒杀场次管理页面 */
|
/**打开秒杀场次管理页面 */
|
||||||
openSeckillConfig() {
|
openSeckillTime() {
|
||||||
this.$tab.openPage("秒杀场次管理", "/promotion/seckill-time");
|
this.$tab.openPage("秒杀场次管理", "/promotion/seckill-time");
|
||||||
},
|
},
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.reset();
|
this.reset();
|
||||||
|
|
|
@ -63,19 +63,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { createSeckillTime, updateSeckillTime, deleteSeckillTime, getSeckillTime, getSeckillTimePage, exportSeckillTimeExcel, getSeckillTimeList } from "@/api/mall/promotion/seckillTime";
|
||||||
createSeckillConfig,
|
|
||||||
deleteSeckillConfig,
|
|
||||||
getSeckillConfig,
|
|
||||||
getSeckillConfigList,
|
|
||||||
updateSeckillConfig
|
|
||||||
} from "@/api/mall/promotion/SeckillConfig";
|
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import {deepClone} from "@/utils";
|
import { deepClone } from "@/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PromotionSeckillConfig",
|
name: "PromotionSeckillTime",
|
||||||
components: {},
|
components: {
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
|
@ -109,7 +104,7 @@ export default {
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
// 执行查询
|
// 执行查询
|
||||||
getSeckillConfigList().then(response => {
|
getSeckillTimeList().then(response => {
|
||||||
this.list = response.data;
|
this.list = response.data;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
@ -153,7 +148,7 @@ export default {
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset();
|
this.reset();
|
||||||
const id = row.id;
|
const id = row.id;
|
||||||
getSeckillConfig(id).then(response => {
|
getSeckillTime(id).then(response => {
|
||||||
response.data.startAndEndTime = [response.data.startTime, response.data.endTime]
|
response.data.startAndEndTime = [response.data.startTime, response.data.endTime]
|
||||||
this.form = response.data;
|
this.form = response.data;
|
||||||
this.open = true;
|
this.open = true;
|
||||||
|
@ -173,7 +168,7 @@ export default {
|
||||||
data.endTime = this.form.startAndEndTime[1];
|
data.endTime = this.form.startAndEndTime[1];
|
||||||
// 修改的提交
|
// 修改的提交
|
||||||
if (this.form.id != null) {
|
if (this.form.id != null) {
|
||||||
updateSeckillConfig(data).then(response => {
|
updateSeckillTime(data).then(response => {
|
||||||
this.$modal.msgSuccess("修改成功");
|
this.$modal.msgSuccess("修改成功");
|
||||||
this.open = false;
|
this.open = false;
|
||||||
this.getList();
|
this.getList();
|
||||||
|
@ -181,7 +176,7 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 添加的提交
|
// 添加的提交
|
||||||
createSeckillConfig(data).then(response => {
|
createSeckillTime(data).then(response => {
|
||||||
this.$modal.msgSuccess("新增成功");
|
this.$modal.msgSuccess("新增成功");
|
||||||
this.open = false;
|
this.open = false;
|
||||||
this.getList();
|
this.getList();
|
||||||
|
@ -192,7 +187,7 @@ export default {
|
||||||
handleDelete(row) {
|
handleDelete(row) {
|
||||||
const id = row.id;
|
const id = row.id;
|
||||||
this.$modal.confirm('是否确认删除秒杀时段编号为"' + id + '"的数据项?').then(function () {
|
this.$modal.confirm('是否确认删除秒杀时段编号为"' + id + '"的数据项?').then(function () {
|
||||||
return deleteSeckillConfig(id);
|
return deleteSeckillTime(id);
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.$modal.msgSuccess("删除成功");
|
this.$modal.msgSuccess("删除成功");
|
||||||
|
|
Loading…
Reference in New Issue