diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index c7b0e9dc7..15bf2a83a 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -70,7 +70,7 @@ 1.4.0 1.5.6 2.12.2 - 4.3.0 + 4.5.0 @@ -624,6 +624,11 @@ + + com.github.binarywang + wx-java-mp-spring-boot-starter + ${wx-java-mp.version} + diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/WxPayOneAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/WxPayOneAutoConfiguration.java new file mode 100644 index 000000000..3908fb1d7 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/WxPayOneAutoConfiguration.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.framework.pay.config; + +import cn.iocoder.yudao.framework.pay.properties.WxPayProperties; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + *
+ *  微信支付自动配置
+ *  Created by BinaryWang on 2019/4/17.
+ * 
+ * + * @author Binary Wang + */ +@Configuration +@EnableConfigurationProperties(WxPayProperties.class) +@ConditionalOnClass(WxPayService.class) +@ConditionalOnProperty(prefix = "wx.pay.one", value = "enabled", matchIfMissing = true) +public class WxPayOneAutoConfiguration { + private WxPayProperties properties; + + @Autowired + public WxPayOneAutoConfiguration(WxPayProperties properties) { + this.properties = properties; + } + + /** + * 构造微信支付服务对象. + * + * @return 微信支付service + */ + @Bean + @ConditionalOnMissingBean(WxPayService.class) + public WxPayService wxPayOneService() { + final WxPayServiceImpl wxPayService = new WxPayServiceImpl(); + WxPayConfig payConfig = new WxPayConfig(); + payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); + payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); + payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); + payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId())); + payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); + payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); + payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl())); + //以下是apiv3以及支付分相关 + payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId())); + payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl())); + payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath())); + payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath())); + payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo())); + payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key())); + wxPayService.setConfig(payConfig); + return wxPayService; + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/WxPayTwoAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/WxPayTwoAutoConfiguration.java new file mode 100644 index 000000000..b1437bec8 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/WxPayTwoAutoConfiguration.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.framework.pay.config; + +import cn.iocoder.yudao.framework.pay.properties.WxPayTwoProperties; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + *
+ *  微信支付自动配置
+ *  Created by BinaryWang on 2019/4/17.
+ * 
+ * + * @author Binary Wang + */ +@Configuration +@EnableConfigurationProperties(WxPayTwoProperties.class) +@ConditionalOnClass(WxPayService.class) +@ConditionalOnProperty(prefix = "wx.pay.two", value = "enabled", matchIfMissing = true) +public class WxPayTwoAutoConfiguration { + + private WxPayTwoProperties wxPayTwoProperties; + + @Autowired + public WxPayTwoAutoConfiguration(WxPayTwoProperties wxPayTwoProperties) { + this.wxPayTwoProperties = wxPayTwoProperties; + } + + /** + * 构造微信支付服务对象. + * + * @return 微信支付service + */ + @Bean + @ConditionalOnMissingBean(WxPayService.class) + public WxPayService wxPayTwoService() { + final WxPayServiceImpl wxPayService = new WxPayServiceImpl(); + WxPayConfig payConfig = new WxPayConfig(); + payConfig.setAppId(StringUtils.trimToNull(this.wxPayTwoProperties.getAppId())); + payConfig.setMchId(StringUtils.trimToNull(this.wxPayTwoProperties.getMchId())); + payConfig.setMchKey(StringUtils.trimToNull(this.wxPayTwoProperties.getMchKey())); + payConfig.setSubAppId(StringUtils.trimToNull(this.wxPayTwoProperties.getSubAppId())); + payConfig.setSubMchId(StringUtils.trimToNull(this.wxPayTwoProperties.getSubMchId())); + payConfig.setKeyPath(StringUtils.trimToNull(this.wxPayTwoProperties.getKeyPath())); + payConfig.setNotifyUrl(StringUtils.trimToNull(this.wxPayTwoProperties.getNotifyUrl())); + //以下是apiv3以及支付分相关 + payConfig.setServiceId(StringUtils.trimToNull(this.wxPayTwoProperties.getServiceId())); + payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.wxPayTwoProperties.getPayScoreNotifyUrl())); + payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.wxPayTwoProperties.getPrivateKeyPath())); + payConfig.setPrivateCertPath(StringUtils.trimToNull(this.wxPayTwoProperties.getPrivateCertPath())); + payConfig.setCertSerialNo(StringUtils.trimToNull(this.wxPayTwoProperties.getCertSerialNo())); + payConfig.setApiV3Key(StringUtils.trimToNull(this.wxPayTwoProperties.getApiv3Key())); + wxPayService.setConfig(payConfig); + return wxPayService; + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/properties/WxPayProperties.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/properties/WxPayProperties.java new file mode 100644 index 000000000..6559665fe --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/properties/WxPayProperties.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.framework.pay.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + *
+ *  微信支付属性配置类
+ * Created by Binary Wang on 2019/4/17.
+ * 
+ * + * @author Binary Wang + */ +@Data +@ConfigurationProperties(prefix = "wx.pay.one") +public class WxPayProperties { + /** + * 设置微信公众号或者小程序等的appid. + */ + private String appId; + + /** + * 微信支付商户号. + */ + private String mchId; + + /** + * 微信支付商户密钥. + */ + private String mchKey; + + /** + * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除. + */ + private String subAppId; + + /** + * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除. + */ + private String subMchId; + + /** + * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定. + */ + private String keyPath; + + /** + * 微信支付分serviceId + */ + private String serviceId; + /** + * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String notifyUrl; + + /** + * 微信退款异步回掉地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String refundNotifyUrl; + + /** + * 证书序列号 + */ + private String certSerialNo; + + /** + * apiV3秘钥 + */ + private String apiv3Key; + + /** + * 微信支付分回调地址 + */ + private String payScoreNotifyUrl; + + /** + * apiv3 商户apiclient_key.pem + */ + private String privateKeyPath; + + /** + * apiv3 商户apiclient_cert.pem + */ + private String privateCertPath; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/properties/WxPayTwoProperties.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/properties/WxPayTwoProperties.java new file mode 100644 index 000000000..f8c198c7c --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/properties/WxPayTwoProperties.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.framework.pay.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + *
+ *  微信支付属性配置类
+ * Created by Binary Wang on 2019/4/17.
+ * 
+ * + * @author Binary Wang + */ +@Data +@ConfigurationProperties(prefix = "wx.pay.two") +public class WxPayTwoProperties { + /** + * 设置微信公众号或者小程序等的appid. + */ + private String appId; + + /** + * 微信支付商户号. + */ + private String mchId; + + /** + * 微信支付商户密钥. + */ + private String mchKey; + + /** + * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除. + */ + private String subAppId; + + /** + * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除. + */ + private String subMchId; + + /** + * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定. + */ + private String keyPath; + + /** + * 微信支付分serviceId + */ + private String serviceId; + /** + * 微信支付异步回掉地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String notifyUrl; + + /** + * 微信退款异步回掉地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String refundNotifyUrl; + + /** + * 证书序列号 + */ + private String certSerialNo; + + /** + * apiV3秘钥 + */ + private String apiv3Key; + + /** + * 微信支付分回调地址 + */ + private String payScoreNotifyUrl; + + /** + * apiv3 商户apiclient_key.pem + */ + private String privateKeyPath; + + /** + * apiv3 商户apiclient_cert.pem + */ + private String privateCertPath; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index f2a8bf146..3a42b1c47 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,3 @@ -cn.iocoder.yudao.framework.pay.config.YudaoPayAutoConfiguration \ No newline at end of file +cn.iocoder.yudao.framework.pay.config.YudaoPayAutoConfiguration +cn.iocoder.yudao.framework.pay.config.WxPayOneAutoConfiguration +cn.iocoder.yudao.framework.pay.config.WxPayTwoAutoConfiguration \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-shop-biz/pom.xml b/yudao-module-mall/yudao-module-shop-biz/pom.xml index 932b69f99..f96408a10 100644 --- a/yudao-module-mall/yudao-module-shop-biz/pom.xml +++ b/yudao-module-mall/yudao-module-shop-biz/pom.xml @@ -79,5 +79,13 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-ip + + com.github.binarywang + wx-java-mp-spring-boot-starter + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-pay + \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/TestPayController.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/TestPayController.java new file mode 100644 index 000000000..d51431ba0 --- /dev/null +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/TestPayController.java @@ -0,0 +1,126 @@ +package cn.iocoder.yudao.module.shop.controller; + + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; +import cn.iocoder.yudao.framework.pay.properties.WxPayProperties; +import cn.iocoder.yudao.framework.pay.properties.WxPayTwoProperties; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request; +import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result; +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author perry + */ +@RequestMapping("test") +@RestController +public class TestPayController { + + @Autowired + private WxPayTwoProperties wxPayTwoProperties; + @Autowired + private WxPayProperties payProperties; + + @Autowired + private WxMpService wxMpService; + + + @GetMapping("getjsApiToken") + public CommonResult getjsApiToken() throws WxErrorException { + WxJsapiSignature wxJsapiSignature = wxMpService.createJsapiSignature("http://yuxy.perrymake.com/login"); + + return CommonResult.success(wxJsapiSignature); + } + public WxPayService wxPayService() { + final WxPayServiceImpl wxPayService = new WxPayServiceImpl(); + WxPayConfig payConfig = new WxPayConfig(); + payConfig.setAppId(StringUtils.trimToNull(payProperties.getAppId())); + payConfig.setMchId(StringUtils.trimToNull(payProperties.getMchId())); + payConfig.setMchKey(StringUtils.trimToNull(payProperties.getMchKey())); + payConfig.setSubAppId(StringUtils.trimToNull(payProperties.getSubAppId())); + payConfig.setSubMchId(StringUtils.trimToNull(payProperties.getSubMchId())); + payConfig.setKeyPath(StringUtils.trimToNull(payProperties.getKeyPath())); + payConfig.setNotifyUrl(StringUtils.trimToNull(payProperties.getNotifyUrl())); + //以下是apiv3以及支付分相关 + payConfig.setServiceId(StringUtils.trimToNull(payProperties.getServiceId())); + payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(payProperties.getPayScoreNotifyUrl())); + payConfig.setPrivateKeyPath(StringUtils.trimToNull(payProperties.getPrivateKeyPath())); + payConfig.setPrivateCertPath(StringUtils.trimToNull(payProperties.getPrivateCertPath())); + payConfig.setCertSerialNo(StringUtils.trimToNull(payProperties.getCertSerialNo())); + payConfig.setApiV3Key(StringUtils.trimToNull(payProperties.getApiv3Key())); + wxPayService.setConfig(payConfig); + return wxPayService; + } + + public WxPayService wxPay1Service() { + final WxPayServiceImpl wxPayService = new WxPayServiceImpl(); + WxPayConfig payConfig = new WxPayConfig(); + payConfig.setAppId(StringUtils.trimToNull(wxPayTwoProperties.getAppId())); + payConfig.setMchId(StringUtils.trimToNull(wxPayTwoProperties.getMchId())); + payConfig.setMchKey(StringUtils.trimToNull(wxPayTwoProperties.getMchKey())); + payConfig.setSubAppId(StringUtils.trimToNull(wxPayTwoProperties.getSubAppId())); + payConfig.setSubMchId(StringUtils.trimToNull(wxPayTwoProperties.getSubMchId())); + payConfig.setKeyPath(StringUtils.trimToNull(wxPayTwoProperties.getKeyPath())); + payConfig.setNotifyUrl(StringUtils.trimToNull(wxPayTwoProperties.getNotifyUrl())); + //以下是apiv3以及支付分相关 + payConfig.setServiceId(StringUtils.trimToNull(wxPayTwoProperties.getServiceId())); + payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(wxPayTwoProperties.getPayScoreNotifyUrl())); + payConfig.setPrivateKeyPath(StringUtils.trimToNull(wxPayTwoProperties.getPrivateKeyPath())); + payConfig.setPrivateCertPath(StringUtils.trimToNull(wxPayTwoProperties.getPrivateCertPath())); + payConfig.setCertSerialNo(StringUtils.trimToNull(wxPayTwoProperties.getCertSerialNo())); + payConfig.setApiV3Key(StringUtils.trimToNull(wxPayTwoProperties.getApiv3Key())); + wxPayService.setConfig(payConfig); + return wxPayService; + } + + @PostMapping("pay") + public CommonResult pay(@RequestBody JSONObject jsonObject , HttpServletRequest request) throws WxPayException { + WxPayUnifiedOrderV3Result.JsapiResult jsapiResult=null; + if(jsonObject.getInteger("type")==1){ + WxPayService wxPayService = wxPayService(); + WxPayUnifiedOrderV3Request wxPayUnifiedOrderV3Request = new WxPayUnifiedOrderV3Request(); + wxPayUnifiedOrderV3Request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(1)); + wxPayUnifiedOrderV3Request.setDescription("测试支付"); + wxPayUnifiedOrderV3Request.setOutTradeNo(IdWorker.getIdStr()); + wxPayUnifiedOrderV3Request.setNotifyUrl(payProperties.getNotifyUrl()); + wxPayUnifiedOrderV3Request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(jsonObject.getString("openid"))); + wxPayUnifiedOrderV3Request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(ServletUtils.getClientIP(request))); + wxPayUnifiedOrderV3Request.setAppid(payProperties.getAppId()); + wxPayUnifiedOrderV3Request.setMchid(payProperties.getMchId()); + WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPayService.unifiedOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderV3Request); + // 以下字段在return_code 和result_code都为SUCCESS的时候有返回 + jsapiResult = wxPayUnifiedOrderV3Result.getPayInfo(TradeTypeEnum.JSAPI, payProperties.getAppId(), payProperties.getMchId(), wxPayService.getConfig().getPrivateKey()); + } + + if(jsonObject.getInteger("type")==2){ + WxPayService wxPay1Service = wxPay1Service(); + WxPayUnifiedOrderV3Request wxPayUnifiedOrderV3Request = new WxPayUnifiedOrderV3Request(); + wxPayUnifiedOrderV3Request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(2)); + wxPayUnifiedOrderV3Request.setDescription("测试支付"); + wxPayUnifiedOrderV3Request.setOutTradeNo(IdWorker.getIdStr()); + wxPayUnifiedOrderV3Request.setNotifyUrl(wxPayTwoProperties.getNotifyUrl()); + wxPayUnifiedOrderV3Request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(jsonObject.getString("openid"))); + wxPayUnifiedOrderV3Request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(ServletUtils.getClientIP(request))); + WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPay1Service.unifiedOrderV3(TradeTypeEnum.JSAPI, wxPayUnifiedOrderV3Request); + // 以下字段在return_code 和result_code都为SUCCESS的时候有返回 + jsapiResult = wxPayUnifiedOrderV3Result.getPayInfo(TradeTypeEnum.JSAPI, wxPayTwoProperties.getAppId(), wxPayTwoProperties.getMchId(), wxPay1Service.getConfig().getPrivateKey()); + } + return CommonResult.success(jsapiResult); + + } + +} diff --git a/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/notify/WxPayNotifyController.java b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/notify/WxPayNotifyController.java new file mode 100644 index 000000000..710b94116 --- /dev/null +++ b/yudao-module-mall/yudao-module-shop-biz/src/main/java/cn/iocoder/yudao/module/shop/controller/admin/notify/WxPayNotifyController.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.shop.controller.admin.notify; + + +import cn.hutool.json.JSONUtil; +import com.github.binarywang.wxpay.bean.notify.OriginNotifyResponse; +import com.github.binarywang.wxpay.bean.notify.SignatureHeader; +import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result; +import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyV3Result; +import com.github.binarywang.wxpay.service.WxPayService; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * @author Javen + * @Email javen205@126.com + */ +@Slf4j +@RequestMapping("notify/wxpay") +@RestController +@Tag(name = "微信支付回调 - 订单支付") +public class WxPayNotifyController { + + + + + @Autowired + private WxPayService wxPayService; + + + + + + + + + /** + * Description: 微信支付回调接口 + * + * @author: perry + * @date: 2019/8/15 20:05 + * @param: + * @return: + */ + @PostMapping("/pay_notify") + public String wxPayNotify(@RequestBody String jsonData, HttpServletRequest request, HttpServletResponse response) { + // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 + // 支付成功结果通知 + log.info("支付原始通知=" + jsonData); + OriginNotifyResponse notifyResponse = JSONUtil.toBean(jsonData, OriginNotifyResponse.class); + log.info("支付原始通知=" + JSONUtil.toJsonPrettyStr(notifyResponse)); + WxPayOrderNotifyV3Result v3Result = null; + try { + //解密后的数据 + v3Result = wxPayService.parseOrderNotifyV3Result(jsonData, this.getRequestHeader(request)); + WxPayOrderNotifyV3Result.DecryptNotifyResult result = v3Result.getResult(); + log.info("支付通知=" + JSONUtil.toJsonPrettyStr(result)); + + } catch (Exception e) { + log.error(e.getMessage(), e); + } + // 通知应答码:HTTP应答状态码需返回5XX或4XX,同时需返回应答报文 + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return ""; + } + + /** + * 获取回调请求头:签名相关 + * + * @param request HttpServletRequest + * @return SignatureHeader + */ + public SignatureHeader getRequestHeader(HttpServletRequest request) { + // 获取通知签名 + String signature = request.getHeader("wechatpay-signature"); + String nonce = request.getHeader("wechatpay-nonce"); + String serial = request.getHeader("wechatpay-serial"); + String timestamp = request.getHeader("wechatpay-timestamp"); + + SignatureHeader signatureHeader = new SignatureHeader(); + signatureHeader.setSignature(signature); + signatureHeader.setNonce(nonce); + signatureHeader.setSerial(serial); + signatureHeader.setTimeStamp(timestamp); + return signatureHeader; + } + + + /** + * Description: 微信支付退款回调接口 + * + * @author: perry + * @date: 2019/8/15 20:05 + * @param: + * @return: + */ + @PostMapping("/refund_notify") + public String wxPayRefundNotify(@RequestBody String jsonData, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 + // 支付成功结果通知 + OriginNotifyResponse notifyResponse = JSONUtil.toBean(jsonData, OriginNotifyResponse.class); + WxPayRefundNotifyV3Result v3Result = null; + log.info("退款原始通知=" + JSONUtil.toJsonPrettyStr(jsonData)); + try { + //解密后的数据 + v3Result = wxPayService.parseRefundNotifyV3Result(JSONUtil.toJsonPrettyStr(notifyResponse), this.getRequestHeader(request)); + WxPayRefundNotifyV3Result.DecryptNotifyResult result = v3Result.getResult(); + log.info("退款通知=" + JSONUtil.toJsonPrettyStr(result)); + //退款状态 + + } catch (Exception e) { + log.error(e.getMessage(), e); + } + // 通知应答码:HTTP应答状态码需返回5XX或4XX,同时需返回应答报文 + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return ""; + + } +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/AdminUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/AdminUserController.java index 7f4957de2..37f1984ef 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/AdminUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/AdminUserController.java @@ -82,6 +82,7 @@ public class AdminUserController { @PostMapping(value = "page") @Operation(summary = "获取会员列表") @PreAuthorize("@ss.hasPermission('member:user:query')") + @TenantIgnore public CommonResult> findPageList(@RequestBody AdminUserQueryDTO queryDTO) { // 获得用户分页列表 PageResult pageResult = userService.findPageList(queryDTO); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java index 0166925dc..5543e40f3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.security.config.SecurityProperties; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; import cn.iocoder.yudao.module.member.service.auth.MemberAuthService; import io.swagger.v3.oas.annotations.tags.Tag; @@ -39,6 +40,7 @@ public class AppAuthController { @PostMapping("/login") @Operation(summary = "使用手机 + 密码登录") + @TenantIgnore public CommonResult login(@RequestBody @Valid AppAuthLoginReqVO reqVO) { return success(authService.login(reqVO)); } @@ -66,12 +68,14 @@ public class AppAuthController { @PostMapping("/sms-login") @Operation(summary = "使用手机 + 验证码登录") + @TenantIgnore public CommonResult smsLogin(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) { return success(authService.smsLogin(reqVO)); } @PostMapping("/register") @Operation(summary = "注册") + @TenantIgnore public CommonResult register(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) { return success(authService.register(reqVO)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java index 0020c9280..d98c95f51 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant; +import cn.hutool.core.date.LocalDateTimeUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; @@ -19,6 +20,9 @@ import javax.annotation.security.PermitAll; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalUnit; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -45,6 +49,9 @@ public class TenantController { @Operation(summary = "创建租户") @PreAuthorize("@ss.hasPermission('system:tenant:create')") public CommonResult createTenant(@Valid @RequestBody TenantCreateReqVO createReqVO) { + createReqVO.setAccountCount(99999); + createReqVO.setExpireTime(LocalDateTimeUtil.offset(LocalDateTime.now(),99, ChronoUnit.YEARS)); + createReqVO.setPackageId(1L); return success(tenantService.createTenant(createReqVO)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java index 4673e2990..b690c4bc0 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; +import cn.iocoder.yudao.framework.common.validation.Mobile; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; +import org.hibernate.validator.constraints.Length; import javax.validation.constraints.*; import java.time.LocalDateTime; @@ -32,15 +34,60 @@ public class TenantBaseVO { private String domain; @Schema(description = "租户套餐编号", required = true, example = "1024") - @NotNull(message = "租户套餐编号不能为空") private Long packageId; @Schema(description = "过期时间", required = true) - @NotNull(message = "过期时间不能为空") private LocalDateTime expireTime; @Schema(description = "账号数量", required = true, example = "1024") - @NotNull(message = "账号数量不能为空") private Integer accountCount; + /** + * 简介 + */ + @Schema(description = "简介", example = "https://www.iocoder.cn") + @NotEmpty(message = "简介不能为空") + @Length( max = 150, message = "简介长度为 {max}位") + private String introduction; + + /** + * 服务电话 + */ + @Schema(description = "服务电话", example = "https://www.iocoder.cn") + @NotEmpty(message = "服务电话不能为空") + @Length( max = 13, message = "服务电话长度为 {max}位") + private String serviceMobile; + + /** + * 服务时间 + */ + @Schema(description = "服务时间", example = "https://www.iocoder.cn") + @NotEmpty(message = "服务时间不能为空") + @Length( max = 20, message = "服务时间长度为 {max}位") + private String serviceTime; + + /** + * 销售负责人 + */ + @Schema(description = "销售负责人", example = "https://www.iocoder.cn") + @NotEmpty(message = "销售负责人不能为空") + @Length( max = 10, message = "销售负责人长度为 {max}位") + private String saleContactName; + + /** + * 销售负责人联系电话 + */ + @Schema(description = "销售负责人联系电话", example = "https://www.iocoder.cn") + @NotEmpty(message = "销售负责人不能为空") + @Mobile( message = "销售负责人联系电话不正确") + private String saleContactMobile; + + /** + * 微信客服地址 + */ + @Schema(description = "微信客服地址", example = "https://www.iocoder.cn") + @NotEmpty(message = "微信客服地址不能为空") + @Length( max = 300, message = "微信客服地址长度为 {max}位") + private String wxKfUrl; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java index 17b42efa3..b3cca2d31 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantDO.java @@ -79,4 +79,36 @@ public class TenantDO extends BaseDO { */ private Integer accountCount; + /** + * 简介 + */ + private String introduction; + + /** + * 服务电话 + */ + private String serviceMobile; + + /** + * 服务时间 + */ + private String serviceTime; + + /** + * 销售负责人 + */ + private String saleContactName; + + /** + * 销售负责人联系电话 + */ + private String saleContactMobile; + + /** + * 微信客服地址 + */ + private String wxKfUrl; + + + } diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index c37b3faca..c4af71582 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -54,11 +54,11 @@ - - cn.iocoder.boot - yudao-module-pay-biz - ${revision} - + + + + + @@ -68,21 +68,21 @@ - - cn.iocoder.boot - yudao-module-promotion-biz - ${revision} - - - cn.iocoder.boot - yudao-module-product-biz - ${revision} - - - cn.iocoder.boot - yudao-module-trade-biz - ${revision} - + + + + + + + + + + + + + + + cn.iocoder.boot yudao-module-shop-biz diff --git a/yudao-server/src/main/resources/1/apiclient_cert.p12 b/yudao-server/src/main/resources/1/apiclient_cert.p12 new file mode 100644 index 000000000..68aaa88cd Binary files /dev/null and b/yudao-server/src/main/resources/1/apiclient_cert.p12 differ diff --git a/yudao-server/src/main/resources/1/apiclient_cert.pem b/yudao-server/src/main/resources/1/apiclient_cert.pem new file mode 100644 index 000000000..6b9d544c0 --- /dev/null +++ b/yudao-server/src/main/resources/1/apiclient_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEQDCCAyigAwIBAgIUWP21A/krbA4ljJlAu3JsK/YCLlYwDQYJKoZIhvcNAQEL +BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT +FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg +Q0EwHhcNMjMwNDExMDgwODE3WhcNMjgwNDA5MDgwODE3WjCBmTETMBEGA1UEAwwK +MTY0MTk5MzQxNzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMUUwQwYDVQQL +DDzliJvnm4jkupHnvZHnu5zvvIjph43luobvvInmnInpmZDlhazlj7jmuJ3ljJfn +rKzkuIDliIblhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANWSWLmJaVbrJJq3uhbutKC6 +1ly6GbAxbnJgq8O9fP/MRLOljUHDSqUleVat1sVmSNwbsJuk0Hr0e1uowxGSJ3NY +iYMXMWj3S7iPxY+9ShkCJXWfvvPPjSTabk1dg3AUM8ukREQOqvlIFRyJfCUoirlj +2CGXfgMvEjtPYUouFWvB0EU9k+5LzynIyXckpVstx1rWZtlSRF/iviW5BaPf2sZk +0DDEbeMM13BsRSNOHS1NWU8DkV5zb1hNBq/T/OQ7glbs3kHqlD+TXEkcrN64Nr1r +ErohctE6Ep0d1iRUMFYjJXFvBq/1qyi62Vp1wwk1XAqoiyuIfqKGrPhl7Z6Z++cC +AwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQ +MIGNoIGKoIGHhoGEaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1 +c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQy +JnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcx +MA0GCSqGSIb3DQEBCwUAA4IBAQBChfNK0TvOcibwW7vK7ClGwolrNbGwjkAJU1MQ +IQuJUfoGnTrOLb68XKEffUqBL9SaUV9ncnkr/yJPRjltZZilbb6kFQXPqDWw6Dd1 +ffPYlxrTSofPcWmZVz6LP0Xx7snslcu/qzbPBOth/Dx/nOsexwCuAJkft72tGBww +OeKvQcfUrc5bS7Nq9GtLRgjhMbDb4LVQ+ivXLhbU4stY6v6MttMSNpN90ngpeCV0 +ZpRnKi2+fI/Gljyj5xEm8nMUYkg4vrJcsBK2PZVkRdlyNKiZXdrHn7dYwuujH3NS +1Sf46cO6gTquBGvkkAnO1NWPlz558g2EwzP5zOiPZCfKWk/7 +-----END CERTIFICATE----- diff --git a/yudao-server/src/main/resources/1/apiclient_key.pem b/yudao-server/src/main/resources/1/apiclient_key.pem new file mode 100644 index 000000000..6c80814b2 --- /dev/null +++ b/yudao-server/src/main/resources/1/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVkli5iWlW6ySa +t7oW7rSgutZcuhmwMW5yYKvDvXz/zESzpY1Bw0qlJXlWrdbFZkjcG7CbpNB69Htb +qMMRkidzWImDFzFo90u4j8WPvUoZAiV1n77zz40k2m5NXYNwFDPLpEREDqr5SBUc +iXwlKIq5Y9ghl34DLxI7T2FKLhVrwdBFPZPuS88pyMl3JKVbLcda1mbZUkRf4r4l +uQWj39rGZNAwxG3jDNdwbEUjTh0tTVlPA5Fec29YTQav0/zkO4JW7N5B6pQ/k1xJ +HKzeuDa9axK6IXLROhKdHdYkVDBWIyVxbwav9asoutladcMJNVwKqIsriH6ihqz4 +Ze2emfvnAgMBAAECggEBAJk92MvH/P2Q20LocW3i+Vgat5TxM11pGoaXNqfMXtRs +DR+ZujFlnznAGcBIG8KoEb9dXutO5whSQ/EQtmb1J7lr3b9h9OIMDxjukCMC/xfS +om4zoR/v3KaE1IBOiPDyjfegdhsfKy6SuhMv0xQWcvNy4LG5sYE3VS2ZV4WSa2xU +5OVCpGCsm0vxK3SVzbsSUnGFEn1zZZabLCh48L1BALHkszCsy575z9g1Hyh2jfuK +50lTrhIw5r4xyITCq6qA7nXSHREStp8ps39+U0qxYwEa9VDNNLPMkZ5iB7q0aJJR +xGdyRoqwbGKI7/DvXPEbM3VtLkdtgdbaap6gvZWnrIECgYEA9LVCRF6jJ5EDjEqg +CN+WahBeOMhiRhaQD0pCBAUqB0g1mq0FdunsKYzjwKWwGJkguCN6nw9AtSRVs2x/ +BuCWnL8yYvVEg04WLpV66GbffifImV9qEzRmWbAR0g6uOFNZJDAxk+CLm6NexBIK +UJgJeTzBs+pr4Gm37C4fXTBVm2MCgYEA321F6CZuZ1qvKUhidCYN7Vc7ntpKenFj +CysM8zbJABMaiaDWw7EQDHkm1VY3BnvS5YYmpwTnVVdIuzrosBWxemrd1JBqyxNI +o9o1kYzQMoRmKa1HEN1dUWLhIJXjGSk7o73Zo0G+mb1WwZvenFY2Of4RJ0c7Zw+g +qrQW2f/KPq0CgYAudfe1+W3qxjqxOT33UVRCoQbyqwEVo5UIgiXUk5JuPYSH8I/Y +CwPew7Q+UHcFxJUUwQ+4AXJcsiBfZ5samCugaSDM7xpp/7pwb8sdMuL+FdmdXSNL +sCg6oRZRFp53bUPAfjH7jKeVDkig23f/403xKdrxKPIAcrIL8pnb3KB0VwKBgEBF +CqrxAykv6NsTO17142O2iCv11x7Jpxf7VkpQJBmlZSjZ322DbX5pC0aq+kEfNVdY +851vx6vA4+cX1v9v/hGc1BrlQBMShP69MlOgEfO2Kj0q3xp20vUqYGAjPaRrPACq +CATyUIWg9WfUEoEeO5MLBpwp3WiUEj+IdlpXPjIxAoGBAJSBr2vITajfFfIMsafv +WnF6fB13FXkS/1+ndCWjwu04YDU7eUgiWLetaMntizDb1L303RjLax9wUZI8lBV3 +0etV7avvHZQLZmCqeikXgkYj+kbR4O7BgJI/P5OcKK1QfYSs4K9sYIjz/R4mJu6G +mZcrpcHTH5/k9ucLvJ3m/8ga +-----END PRIVATE KEY----- diff --git a/yudao-server/src/main/resources/2/apiclient_cert.p12 b/yudao-server/src/main/resources/2/apiclient_cert.p12 new file mode 100644 index 000000000..5fb55be2d Binary files /dev/null and b/yudao-server/src/main/resources/2/apiclient_cert.p12 differ diff --git a/yudao-server/src/main/resources/2/apiclient_cert.pem b/yudao-server/src/main/resources/2/apiclient_cert.pem new file mode 100644 index 000000000..d6da31a37 --- /dev/null +++ b/yudao-server/src/main/resources/2/apiclient_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEQDCCAyigAwIBAgIUR/BNUflY/+9Wpt/CW96Dz4k1PhkwDQYJKoZIhvcNAQEL +BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT +FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg +Q0EwHhcNMjMwNDEyMDYyMzI1WhcNMjgwNDEwMDYyMzI1WjCBmTETMBEGA1UEAwwK +MTY0MjA0MjU4OTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMUUwQwYDVQQL +DDzliJvnm4jkupHnvZHnu5zvvIjph43luobvvInmnInpmZDlhazlj7jmuJ3ljJfn +rKzkuozliIblhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANM2lFR09VB7Rbopa5uRUcLH +YugBRTBuh5R+ctf3uW0fZN2iMZdaqj8weJzg8IOC+rDknruKq3y6ofLWDL/qtJtR +m8vHYx5L0tSS1K8ODWVNZ5A6YOkI0Zebnw6vWva2gVlyTi7cKk/UIWEklXkSNFc9 +FootaXdQK6xtq0t1c+Cuq4LKDlrCMTXReg4Y/cuWA5/5RubIXe+6UUlY4Il1e/LN +GV0zeTtkT/sw09pd+/fWOoDXDqbUX3yNVUrf0rXAl2SZlCuRfoxzh42LXyEdLlbs +z0CKZIrntQ85zmp0P2AFolR9cBmtchsAIVtjYXFbKtBK6olW9JxKNqdWyyhiAHUC +AwEAAaOBuTCBtjAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQ +MIGNoIGKoIGHhoGEaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1 +c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQy +JnNnPUhBQ0M0NzFCNjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcx +MA0GCSqGSIb3DQEBCwUAA4IBAQB2ClqsShiW9SeWqJA4UGrc9quQUXfldQ827F7G +v64L9umRWSkttCFHxYaN8zfyGnxs3NgpKFKma1zyo3NIhrqMlOtiaYkeLihS3xl6 +wGOgOYs6TO/YkWqoO+6jszhAo+jZLRyMwm8GYP4wILGgBXKAyai9gkWbSq36kIHK +xRcGodCsWZzF7jR30Hry3knRuHkSFGEY5sTlAWrh/CoVuQTEuE5PUiu0flsoJUvy +A3bq6jkzpq+Pwcg2WOQMNNa2rJP0ABcfluUZn+WqvgMc771qVNSk0eQTeU4jWmrW +v5GGs8kv/SS50CBQ0RXZvyG9tM1fLiR1wLMTBuGWpeIjsL6S +-----END CERTIFICATE----- diff --git a/yudao-server/src/main/resources/2/apiclient_key.pem b/yudao-server/src/main/resources/2/apiclient_key.pem new file mode 100644 index 000000000..c39e40921 --- /dev/null +++ b/yudao-server/src/main/resources/2/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTNpRUdPVQe0W6 +KWubkVHCx2LoAUUwboeUfnLX97ltH2TdojGXWqo/MHic4PCDgvqw5J67iqt8uqHy +1gy/6rSbUZvLx2MeS9LUktSvDg1lTWeQOmDpCNGXm58Or1r2toFZck4u3CpP1CFh +JJV5EjRXPRaKLWl3UCusbatLdXPgrquCyg5awjE10XoOGP3LlgOf+UbmyF3vulFJ +WOCJdXvyzRldM3k7ZE/7MNPaXfv31jqA1w6m1F98jVVK39K1wJdkmZQrkX6Mc4eN +i18hHS5W7M9AimSK57UPOc5qdD9gBaJUfXAZrXIbACFbY2FxWyrQSuqJVvScSjan +VssoYgB1AgMBAAECggEBAL9TQ4413DopUIJQHv/u5WdRghCzhd9XYE1tNc7YwglN +VOtHjzCRmoJfAALr6DLZJQm0Lu2nsavsy+LTbv0yOKQxirVPSkQZX0PcNfjU++F1 ++og1ua+eo214NN7yja3KqOVDm/rqyRFDEXGT2CqyCOO1nINSm6TO5KDvPym9nVg6 +e7DIVE0k0kTh8JKM25NZ6qEOwqu8W9g+mHI4cGnNFbV4uL6jxPBO7L26piNaEsQk +av/0ZThDBizl72qvzbfCiZDGrWseKGI8VyF3KWfKa/666HXh6DpWcE6CsePZLlmn +XWomhdU+xybPyS/eV9X9ET6UDE5fRn6+R/2QIJ8nioECgYEA9BUYF1FzSjLr48zR +axLFCdDLihQRBgUfYGy+PykoXPXp6OxfxOOrWh5+b0wW/fXkq0lfVP+rYzTy4veg +aIsdwyrtzHXDhpqW7gdseB1BEAAWLck0lgmL/DuPLMwjw4lCZmA6YNsfnN9XZ3Gl +QYPmKO9fKsXGrSjq7GxRffhSdnECgYEA3YajFUaoZqeY6vQpfY59WC6/vgl6Iyzb +QleX/RIJUU8nhRnqgDCwUqH1T4MXKRGQ5m8s+wPUNIC/oBNGWNeFXujeCuvoXI5b +rxX+Jswp7eqfk1ybO65tR1Mj8y+vCqFuH5TtaPlq7ZKzp0bumqb7j5jrFMg2x39+ +sEABUPN7VEUCgYBP3HMEdib1uRGLeGFw2jRUENf39rbXNGfewdXBjrLhL6j4CBcR +sbhIBUAzJD9FmuXV0Wz6v6iRDisGbiUy74muaOZjhoiSCxSlDxLDfjbiiFS5aGLn +UHpX7hjbfHObL9bk7klLlYaTalQLyZhbhk+RRzjpIsrtrzymXI6RW+WHUQKBgE9a +T0jryp8bIhfn5oTnadcQx/aXBn1bMB+PqQ4qS9QoeoufQPUye7bd9TXKS52WgUVK +Rd6U/IriI8J/pQ9mBIx+9isLXmzpQcZyJlxXfh2PkiIDZkf2r4aBLbuLNTSlpwEB +JBoaXkdD6b7eFdKoRiymJm+HWLgV35fbFZ2d2mvRAoGBAJl6nSvzCeRzWe27pVAv +iqQrCfDTVQHpleCeHOUUQ9oD4H5+ez+ucFHtrf4Ed3PA48v8iQgEf67jdGFsl1F7 +W+o3fXruRlSjyUdoMDt3GiDxRhloxMs+1cS7seKV13HS5GJZ301vCgX7XuSLEjNu +mwEvp8boEFCZZphDYoaE2kG8 +-----END PRIVATE KEY----- diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 0b65e44d7..5e2e4f573 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -162,8 +162,8 @@ debug: false --- #################### 微信公众号、小程序相关配置 #################### wx: mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档 - app-id: wx041349c6f39b268b - secret: 5abee519483bc9f8cb37ce280e814bd0 + app-id: wxb1826c88da21d81e + secret: 1960c9cc785b094040a4fd4b2955c0cb # 存储配置,解决 AccessToken 的跨节点的共享 config-storage: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 @@ -176,7 +176,31 @@ wx: type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 key-prefix: wa # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置 http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 - + pay: + one: + enabled: true + app-id: wxb1826c88da21d81e + mch-id: 1641993417 + mch-key: qdn2I7Cmx4JeiKOt2CDjiu6UHgLTsOsM + apiv3-key: cyywl666666cyywl888888cyywl66666 + private-cert-path: classpath:/1/apiclient_cert.pem + private-key-path: classpath:/1/apiclient_key.pem + key-path: classpath:/1/apiclient_cert.p12 + cert-serial-no: 58FDB503F92B6C0E258C9940BB726C2BF6022E56 + notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/pay_notify + refund-notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/refund_notify + two: + enabled: true + app-id: wxb1826c88da21d81e + mch-id: 1642042589 + mch-key: qdn2I7Cmx4JeiKOt2CDjiu6UHgLTsOsM + apiv3-key: cyywl666666cyywl888888cyywl66666 + private-cert-path: classpath:/2/apiclient_cert.pem + private-key-path: classpath:/2/apiclient_key.pem + key-path: classpath:/2/apiclient_cert.p12 + cert-serial-no: 47F04D51F958FFEF56A6DFC25BDE83CF89353E19 + notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/pay_notify + refund-notify-url: http://yuxy.perrymake.com/app-api/pay/wxpay/refund_notify --- #################### 芋道相关配置 #################### # 芋道配置项,设置当前项目所有自定义的配置 diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 5567d8ce1..de757f06e 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -107,6 +107,7 @@ yudao: security: permit-all_urls: - /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,不需要登录 + - /admin-api/notice/wxpay/** websocket: enable: true # websocket的开关 path: /websocket/message # 路径 @@ -145,6 +146,7 @@ yudao: - /admin-api/pay/notify/callback/* # 支付回调通知,不携带租户编号 - /jmreport/* # 积木报表,无法携带租户编号 - /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,无法携带租户编号 + - /admin-api/notify/wxpay/** ignore-tables: - system_tenant - system_tenant_package diff --git a/yudao-ui-admin/.env.dev b/yudao-ui-admin/.env.dev index c8620abb5..26b38c703 100644 --- a/yudao-ui-admin/.env.dev +++ b/yudao-ui-admin/.env.dev @@ -20,4 +20,4 @@ VUE_APP_CAPTCHA_ENABLE = true VUE_APP_DOC_ENABLE = true # 百度统计 -VUE_APP_BAIDU_CODE = fadc1bd5db1a1d6f581df60a1807f8ab +VUE_APP_BAIDU_CODE = diff --git a/yudao-ui-admin/src/api/shop/phoneRecord.js b/yudao-ui-admin/src/api/shop/phoneRecord.js new file mode 100644 index 000000000..028958b07 --- /dev/null +++ b/yudao-ui-admin/src/api/shop/phoneRecord.js @@ -0,0 +1,54 @@ +import request from '@/utils/request' + +// 创建充值档位记录 +export function createPhoneRecord(data) { + return request({ + url: '/shop/phone-record/create', + method: 'post', + data: data + }) +} + +// 更新充值档位记录 +export function updatePhoneRecord(data) { + return request({ + url: '/shop/phone-record/update', + method: 'put', + data: data + }) +} + +// 删除充值档位记录 +export function deletePhoneRecord(id) { + return request({ + url: '/shop/phone-record/delete?id=' + id, + method: 'delete' + }) +} + +// 获得充值档位记录 +export function getPhoneRecord(id) { + return request({ + url: '/shop/phone-record/get?id=' + id, + method: 'get' + }) +} + +// 获得充值档位记录分页 +export function getPhoneRecordPage(query) { + return request({ + url: '/shop/phone-record/page', + method: 'get', + params: query + }) +} + +// 导出充值档位记录 Excel +export function exportPhoneRecordExcel(query) { + return request({ + url: '/shop/phone-record/export-excel', + method: 'get', + params: query, + responseType: 'blob' + }) +} diff --git a/yudao-ui-admin/src/api/shop/rechargeOrder.js b/yudao-ui-admin/src/api/shop/rechargeOrder.js new file mode 100644 index 000000000..6f9dbf5a1 --- /dev/null +++ b/yudao-ui-admin/src/api/shop/rechargeOrder.js @@ -0,0 +1,54 @@ +import request from '@/utils/request' + +// 创建订单 +export function createRechargeOrder(data) { + return request({ + url: '/shop/recharge-order/create', + method: 'post', + data: data + }) +} + +// 更新订单 +export function updateRechargeOrder(data) { + return request({ + url: '/shop/recharge-order/update', + method: 'put', + data: data + }) +} + +// 删除订单 +export function deleteRechargeOrder(id) { + return request({ + url: '/shop/recharge-order/delete?id=' + id, + method: 'delete' + }) +} + +// 获得订单 +export function getRechargeOrder(id) { + return request({ + url: '/shop/recharge-order/get?id=' + id, + method: 'get' + }) +} + +// 获得订单分页 +export function getRechargeOrderPage(query) { + return request({ + url: '/shop/recharge-order/page', + method: 'get', + params: query + }) +} + +// 导出订单 Excel +export function exportRechargeOrderExcel(query) { + return request({ + url: '/shop/recharge-order/export-excel', + method: 'get', + params: query, + responseType: 'blob' + }) +} diff --git a/yudao-ui-admin/src/views/shop/phoneRecord/index.vue b/yudao-ui-admin/src/views/shop/phoneRecord/index.vue new file mode 100644 index 000000000..37d5d04d2 --- /dev/null +++ b/yudao-ui-admin/src/views/shop/phoneRecord/index.vue @@ -0,0 +1,272 @@ + + + diff --git a/yudao-ui-admin/src/views/shop/rechargeOrder/index.vue b/yudao-ui-admin/src/views/shop/rechargeOrder/index.vue new file mode 100644 index 000000000..209203e56 --- /dev/null +++ b/yudao-ui-admin/src/views/shop/rechargeOrder/index.vue @@ -0,0 +1,441 @@ + + + diff --git a/yudao-ui-admin/src/views/system/dept/index.vue b/yudao-ui-admin/src/views/system/dept/index.vue index 3397a935b..8a822a874 100644 --- a/yudao-ui-admin/src/views/system/dept/index.vue +++ b/yudao-ui-admin/src/views/system/dept/index.vue @@ -1,8 +1,8 @@