mall + pay:

1、调整微信支付,修复 v2 传递的时间不正确
2、调整 mp js ticket 接口到 system 模块
This commit is contained in:
YunaiV 2023-07-06 00:19:05 +08:00
parent 20eb0a2a88
commit 67d60e32f8
23 changed files with 129 additions and 131 deletions

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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");
} }
} }

View File

@ -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;

View File

@ -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 接口
; ;
/** /**

View File

@ -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;

View File

@ -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 相关 -->

View File

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

View File

@ -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());

View File

@ -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);

View File

@ -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())

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

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

View File

@ -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 文档")

View File

@ -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)

View File

@ -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();

View File

@ -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("删除成功");