mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-09 09:47:32 +00:00
2.0版本
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
package org.ruoyi.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付配置信息
|
||||
*
|
||||
* @author Admin
|
||||
*/
|
||||
@Data
|
||||
public class PayConfig {
|
||||
|
||||
/**
|
||||
* 商户ID
|
||||
*/
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 接口地址
|
||||
*/
|
||||
private String payUrl;
|
||||
|
||||
/**
|
||||
* 私钥
|
||||
*/
|
||||
private String key ;
|
||||
|
||||
/**
|
||||
* 服务器异步通知地址
|
||||
*/
|
||||
private String notify_url;
|
||||
|
||||
/**
|
||||
* 页面跳转通知地址
|
||||
*/
|
||||
private String return_url;
|
||||
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 设备类型
|
||||
*/
|
||||
private String device;
|
||||
|
||||
/**
|
||||
* 加密方式默认MD5
|
||||
*/
|
||||
private String sign_type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.ruoyi.common.config;
|
||||
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
/**
|
||||
* 支付配置信息
|
||||
*
|
||||
* @author Admin
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class PayInit {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
private PayConfig payConfig;
|
||||
|
||||
@Bean
|
||||
@Scope("singleton")
|
||||
public PayConfig payConfig() {
|
||||
if (payConfig == null) {
|
||||
payConfig = new PayConfig();
|
||||
updatePayConfig();
|
||||
}
|
||||
return payConfig;
|
||||
}
|
||||
|
||||
@Scheduled(fixedDelay = 10000) // 每10秒检查一次
|
||||
public void updatePayConfig() {
|
||||
payConfig.setType("wxpay");
|
||||
payConfig.setDevice("pc");
|
||||
payConfig.setSign_type("MD5");
|
||||
payConfig.setPid(getKey("pid"));
|
||||
payConfig.setKey(getKey("key"));
|
||||
payConfig.setPayUrl(getKey("payUrl"));
|
||||
payConfig.setNotify_url(getKey("notify_url"));
|
||||
payConfig.setReturn_url(getKey("return_url"));
|
||||
}
|
||||
|
||||
public String getKey(String key){
|
||||
return configService.getConfigValue("pay", key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.ruoyi.common.config;
|
||||
|
||||
import com.github.binarywang.wxpay.config.WxPayConfig;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
||||
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Binary Wang
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class WxPayConfiguration {
|
||||
|
||||
private final ConfigService configService;
|
||||
|
||||
private WxPayService wxPayService;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
WxPayConfig payConfig = new WxPayConfig();
|
||||
payConfig.setAppId(StringUtils.trimToNull(getKey("appId")));
|
||||
payConfig.setMchId(StringUtils.trimToNull(getKey("mchId")));
|
||||
payConfig.setMchKey(StringUtils.trimToNull(getKey("appSecret")));
|
||||
payConfig.setUseSandboxEnv(false);
|
||||
wxPayService = new WxPayServiceImpl();
|
||||
wxPayService.setConfig(payConfig);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WxPayService wxService() {
|
||||
return wxPayService;
|
||||
}
|
||||
|
||||
public String getKey(String key) {
|
||||
return configService.getConfigValue("weixin", key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.ruoyi.common.listener;
|
||||
|
||||
import com.github.binarywang.wxpay.config.WxPayConfig;
|
||||
import com.github.binarywang.wxpay.service.WxPayService;
|
||||
import org.ruoyi.common.core.event.ConfigChangeEvent;
|
||||
import org.ruoyi.common.core.service.ConfigService;
|
||||
import org.ruoyi.common.core.utils.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 描述:创建一个监听器,用于处理配置变化事件
|
||||
*
|
||||
* @author ageerle@163.com
|
||||
* date 2024/5/19
|
||||
*/
|
||||
@Component
|
||||
public class ConfigChangeListener implements ApplicationListener<ConfigChangeEvent> {
|
||||
private final WxPayService wxPayService;
|
||||
private final ConfigService configService;
|
||||
|
||||
public ConfigChangeListener(WxPayService wxPayService, ConfigService configService) {
|
||||
this.wxPayService = wxPayService;
|
||||
this.configService = configService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NotNull ConfigChangeEvent event) {
|
||||
WxPayConfig newConfig = new WxPayConfig();
|
||||
newConfig.setAppId(StringUtils.trimToNull(configService.getConfigValue("weixin", "appId")));
|
||||
newConfig.setMchId(StringUtils.trimToNull(configService.getConfigValue("weixin", "mchId")));
|
||||
newConfig.setMchKey(StringUtils.trimToNull(configService.getConfigValue("weixin", "mchKey")));
|
||||
newConfig.setUseSandboxEnv(false);
|
||||
wxPayService.setConfig(newConfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.ruoyi.common.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 支付结果响应
|
||||
*
|
||||
* @author: wangle
|
||||
* @date: 2023/7/3
|
||||
*/
|
||||
@Data
|
||||
public class PayResponse {
|
||||
|
||||
/**
|
||||
* 商户ID
|
||||
*/
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 易支付订单号
|
||||
*/
|
||||
|
||||
@JsonProperty("trade_no")
|
||||
private String trade_no;
|
||||
|
||||
/**
|
||||
* 商户订单号
|
||||
*/
|
||||
@JsonProperty("out_trade_no")
|
||||
private String out_trade_no;
|
||||
|
||||
/**
|
||||
* 支付方式
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 商品金额
|
||||
*/
|
||||
private String money;
|
||||
|
||||
/**
|
||||
* 支付状态
|
||||
*/
|
||||
@JsonProperty("trade_status")
|
||||
private String trade_status;
|
||||
|
||||
/**
|
||||
* 业务扩展参数
|
||||
*/
|
||||
private String param;
|
||||
|
||||
/**
|
||||
* 签名字符串
|
||||
*/
|
||||
private String sign;
|
||||
|
||||
/**
|
||||
* 签名类型
|
||||
*/
|
||||
@JsonProperty("sign_type")
|
||||
private String signType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.ruoyi.common.service;
|
||||
|
||||
/**
|
||||
* 支付服务
|
||||
*
|
||||
* @author: wangle
|
||||
* @date: 2023/7/3
|
||||
*/
|
||||
public interface PayService {
|
||||
|
||||
/**
|
||||
* 获取支付地址
|
||||
*
|
||||
* @Date 2023/7/3
|
||||
* @param orderNo
|
||||
* @param name
|
||||
* @param money
|
||||
* @param clientIp
|
||||
* @return String
|
||||
**/
|
||||
String getPayUrl(String orderNo, String name, double money, String clientIp);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.ruoyi.common.service.impl;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
|
||||
import org.ruoyi.common.config.PayConfig;
|
||||
import org.ruoyi.common.service.PayService;
|
||||
import org.ruoyi.common.utils.MD5Util;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 支付服务
|
||||
* @author Admin
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class PayServiceImpl implements PayService {
|
||||
|
||||
private final PayConfig payConfig;
|
||||
|
||||
@Override
|
||||
public String getPayUrl(String orderNo, String name, double money, String clientIp) {
|
||||
String out_trade_no = orderNo, sign = "";
|
||||
//封装请求参数
|
||||
String mdString = "clientip=" + clientIp + "&device=" + payConfig.getDevice() + "&money=" + money + "&name=" + name + "&" +
|
||||
"notify_url=" + payConfig.getNotify_url() + "&out_trade_no=" + out_trade_no + "&pid=" + payConfig.getPid() + "&return_url=" + payConfig.getReturn_url() +
|
||||
"&type=" + payConfig.getType() + payConfig.getKey();
|
||||
sign = MD5Util.GetMD5Code(mdString);
|
||||
Map<String, Object> map = new HashMap<>(10);
|
||||
map.put("clientip", clientIp);
|
||||
map.put("device", payConfig.getDevice());
|
||||
map.put("money", money);
|
||||
map.put("name", name);
|
||||
map.put("notify_url", payConfig.getNotify_url());
|
||||
map.put("out_trade_no", out_trade_no);
|
||||
map.put("pid", payConfig.getPid());
|
||||
map.put("return_url", payConfig.getReturn_url());
|
||||
map.put("sign_type", payConfig.getSign_type());
|
||||
map.put("type", payConfig.getType());
|
||||
map.put("sign", sign);
|
||||
String body = HttpUtil.post(payConfig.getPayUrl(), map);
|
||||
log.info("支付返回信息:{},配置信息: {}",body,payConfig);
|
||||
JSONObject jsonObject = new JSONObject(body);
|
||||
return (String) jsonObject.get("qrcode");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package org.ruoyi.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* MD5 算法
|
||||
*
|
||||
* @author Admin
|
||||
*/
|
||||
public class MD5Util {
|
||||
|
||||
/**
|
||||
* 全局数组
|
||||
*/
|
||||
public final static String[] strDigits = { "0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
|
||||
|
||||
public MD5Util() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回形式为数字跟字符串
|
||||
*
|
||||
* @Date 2023/7/3
|
||||
* @param bByte
|
||||
* @return String
|
||||
**/
|
||||
public static String byteToArrayString(byte bByte) {
|
||||
int iRet = bByte;
|
||||
if (iRet < 0) {
|
||||
iRet += 256;
|
||||
}
|
||||
int iD1 = iRet / 16;
|
||||
int iD2 = iRet % 16;
|
||||
return strDigits[iD1] + strDigits[iD2];
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字节数组为16进制字串
|
||||
*
|
||||
* @Date 2023/7/3
|
||||
* @param bByte
|
||||
* @return String
|
||||
**/
|
||||
public static String byteToString(byte[] bByte) {
|
||||
StringBuffer sBuffer = new StringBuffer();
|
||||
for (int i = 0; i < bByte.length; i++) {
|
||||
sBuffer.append(byteToArrayString(bByte[i]));
|
||||
}
|
||||
return sBuffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成md5代码
|
||||
*
|
||||
* @Date 2023/7/3
|
||||
* @param strObj
|
||||
* @return String
|
||||
**/
|
||||
public static String GetMD5Code(String strObj) {
|
||||
String resultString = null;
|
||||
try {
|
||||
resultString = new String(strObj);
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
resultString = byteToString(md.digest(strObj.getBytes()));
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装签名的字段
|
||||
*
|
||||
* @param params 参数
|
||||
* @param urlEncoder 是否urlEncoder
|
||||
* @return {String}
|
||||
*/
|
||||
public static String packageSign(Map<String, Object> params, boolean urlEncoder) {
|
||||
// 先将参数以其参数名的字典序升序进行排序
|
||||
TreeMap<String, Object> sortedParams = new TreeMap<String, Object>(params);
|
||||
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, Object> param : sortedParams.entrySet()) {
|
||||
String value = String.valueOf(param.getValue());
|
||||
if (StrUtil.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
sb.append("&");
|
||||
}
|
||||
sb.append(param.getKey()).append("=");
|
||||
sb.append(value);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user