diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml b/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml index cb960d5..2c8b083 100644 --- a/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/pom.xml @@ -164,6 +164,12 @@ 3.4.1 + + org.apache.commons + commons-compress + 1.24.0 + compile + diff --git a/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/alipay/KeyContent.java b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/alipay/KeyContent.java new file mode 100644 index 0000000..9949f3d --- /dev/null +++ b/ruoyi-vue-pro-master/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/alipay/KeyContent.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.framework.common.util.alipay; + +import cn.hutool.core.io.resource.ResourceUtil; +import org.apache.commons.compress.utils.IOUtils; +import org.springframework.core.io.ClassPathResource; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Base64; + +public class KeyContent { + + /** + * 读取并Base64编码文件 + * 该方法用于处理格式的文件,将其内容读取为字节数组后,转换为Base64编码的字符串 + * 这在需要将二进制数据作为文本信息进行传输或存储时非常有用 + * + * @param path 文件的路径,用于定位文件位置 + * @return 返回Base64编码的字符串,用于后续处理或传输 + */ + public static String getKeyContent(String path) { + String base64Encoded = ""; + try { + // 读取 文件的内容 + byte[] p12Bytes = Files.readAllBytes(Paths.get(path)); + + // 将字节数组转换为 Base64 编码的字符串 + base64Encoded = Base64.getEncoder().encodeToString(p12Bytes); + + // 输出 Base64 编码的字符串 + System.out.println(base64Encoded); + } catch (Exception e) { + e.printStackTrace(); + } + return base64Encoded; + } + /** + * 读取并Base64编码文件 + * 该方法用于处理格式的文件,将其内容读取为字节数组后,转换为Base64编码的字符串 + * 这在需要将二进制数据作为文本信息进行传输或存储时非常有用 + * + * @param fileName 文件的名称,用于定位静态文件位置 + * @return 返回Base64编码的字符串,用于后续处理或传输 + */ + public static String getKeyContentByFileName(String fileName) { + String base64Encoded = ""; + try { + ClassPathResource classPathResource = new ClassPathResource(fileName); + InputStream inputStream = classPathResource.getInputStream(); + // 读取 文件的内容 + byte[] p12Bytes = IOUtils.toByteArray(inputStream); + + // 将字节数组转换为 Base64 编码的字符串 + base64Encoded = Base64.getEncoder().encodeToString(p12Bytes); + + // 输出 Base64 编码的字符串 + System.out.println(base64Encoded); + } catch (Exception e) { + e.printStackTrace(); + } + return base64Encoded; + } + /** + * 读取并Base64编码文件 + * 该方法用于处理格式的文件,将其内容读取为字节数组后,转换为Base64编码的字符串 + * 这在需要将二进制数据作为文本信息进行传输或存储时非常有用 + * + * @param fileName 文件的名称,用于定位静态文件位置 + * @return 返回Base64编码的字符串,用于后续处理或传输 + */ + public static String getKeyContentByFileName1(String fileName) throws IOException { + URL resource = ResourceUtil.getResource(fileName); + InputStream inputStream = resource.openStream(); + String base64Encoded = ""; + try { + // 读取 文件的内容 + byte[] p12Bytes = IOUtils.toByteArray(inputStream); + + // 将字节数组转换为 Base64 编码的字符串 + base64Encoded = Base64.getEncoder().encodeToString(p12Bytes); + + // 输出 Base64 编码的字符串 + System.out.println(base64Encoded); + } catch (Exception e) { + e.printStackTrace(); + } + return base64Encoded; + } +} diff --git a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index 5c4211f..7531614 100644 --- a/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/ruoyi-vue-pro-master/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -2,9 +2,13 @@ package cn.iocoder.yudao.module.trade.service.brokerage; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.http.HttpUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.alipay.KeyContent; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; @@ -24,12 +28,19 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import javax.validation.Validator; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; import java.time.LocalDateTime; import java.util.Collection; import java.util.Collections; @@ -66,6 +77,25 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private Validator validator; + @Value("${alipay.appId}") + private String appId; + + @Value("${alipay.appPrivateKey}") + private String appPrivateKey; + + @Value("${alipay.gateway}") + private String gateway; + + @Value("${alipay.appCertPath}") + private String appCertPath; + + @Value("${alipay.alipayCertPath}") + private String alipayCertPath; + + @Value("${alipay.alipayRootCertPath}") + private String alipayRootCertPath; + + @Override @Transactional(rollbackFor = Exception.class) public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) { @@ -90,6 +120,28 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { // todo 疯狂: } + // 3.1 提现到支付宝---真正提现是到支付宝 + if (BrokerageWithdrawTypeEnum.ALIPAY.getType().equals(withdraw.getType())) { + System.out.println(); + // todo 疯狂: + //封装提现参数 + JSONObject paramMap = new JSONObject(); + paramMap.put("appid", appId); + paramMap.put("app_private_key", appPrivateKey); + String keyContent = KeyContent.getKeyContentByFileName(appCertPath); + String keyContent1 = KeyContent.getKeyContentByFileName(alipayCertPath); + String keyContent2 = KeyContent.getKeyContentByFileName(alipayRootCertPath); + paramMap.put("app_cert_path_string", keyContent); + paramMap.put("alipay_cert_path_string", keyContent1); + paramMap.put("alipay_root_cert_path_string", keyContent2); + paramMap.put("remark", "余额提现到支付宝"); + paramMap.put("out_biz_no", "111222333"); + paramMap.put("account", "13233904609");//账号 + paramMap.put("name", "马腾达"); + paramMap.put("amount", "0.1"); + String result= HttpUtil.post(gateway, JSON.toJSONString(paramMap)); + System.out.println(result); + } // TODO 疯狂:调用转账接口 } else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) { templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_REJECT; diff --git a/ruoyi-vue-pro-master/yudao-server/src/main/resources/alipayCertPublicKey_RSA2.crt b/ruoyi-vue-pro-master/yudao-server/src/main/resources/alipayCertPublicKey_RSA2.crt new file mode 100644 index 0000000..e69de29 diff --git a/ruoyi-vue-pro-master/yudao-server/src/main/resources/alipayRootCert.crt b/ruoyi-vue-pro-master/yudao-server/src/main/resources/alipayRootCert.crt new file mode 100644 index 0000000..e69de29 diff --git a/ruoyi-vue-pro-master/yudao-server/src/main/resources/appCertPublicKey_2021004170631369.crt b/ruoyi-vue-pro-master/yudao-server/src/main/resources/appCertPublicKey_2021004170631369.crt new file mode 100644 index 0000000..e69de29 diff --git a/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-dev.yaml b/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-dev.yaml index be93eb7..3182612 100644 --- a/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-dev.yaml +++ b/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-dev.yaml @@ -271,3 +271,10 @@ io: xor: massage: 151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515 type: mobile +alipay: + appPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCVtsGcFLqb4IKcNo5OoFmVkxp881AQgNQhJdM9AFIDdEaTcyNXtWabTdbJxNahBfeCOK01fpHbwMSMhRVwZmP+jiO/M/22QmyVLN6cUG7uN+rB1Sw5T1hCbUmSZpLgcfznaV1+2JIcx9dV4kPFJUSTokLapszCfBnmdlQ4oGUZD54zWCNHIEVckZGn/XC1PuiflxSscD9Sx2C6SBniG1sMz/BGFU8Sw5JwUKtzvGesUlKqeDLHQP1/WJjsajLfqPQV6SFxjDMEVZ0WSmJV0Tl80Ulup8vgNKHVD06U9VhqBnIYTf3JcCBMnV4jmM1NsOnlIbdS4GqwdoH5QmI3EmMFAgMBAAECggEAOP3dLgFmGDia/8R039GCyMG6753f+KhSGFxB0ZLxpYb55t+JsLXJXY2AGkboPVv8IIJazWZlN/Zl2+g9hRA1OI37ZanxBxS6KP9vrqmf0OdQYoE32Ikv2/mmbCjH+NDrqVwez066MGKSworjqYTKWjkGoh2lDNQZN/YLkZLdaXBHHAg8sAh66NROWgfnZBB7V93ScTWNcd2CYPOBK+jfLlWs9QmUjobn+NO2ihCvBDS5vX6lTrL4CDPMiEZHvnA71BLnRVaJl6wjdebVTao1TRo1njVSlvyArKYt/cfE366n/bfM1Ylhhnbgoj02g1JqQrS0wDH4Au86CLgepF8CgQKBgQDTCX8mxCX2hU96vEPxNVAS/Oh+TOTx0OLRvpowBlR3QEKheJZyNdcG2HG6cUTl0oihlUePcfiPkGKmhqeKXMt3ost5zO/axLfC06prEs6gPQftKJfYe+bIMvF7A41dt1m6oenXokHqg7BGSJ3k/CX/C8Q7nMsXhVYjKXBw/ErYTQKBgQC1nIj7RwofDPQcmiTwtAVVXXevoEXTpk+PslpdSLs+BmBJzvJ4oQtYP4thKxwWjIsJWT1AUWF66Ytismd/DEkK9MAJfiH1WPcDFFfbeAu4p+x3pYtyth3poQ+jgRfU3BgiwFDp4n0mZPn9na4vm93FkYFcy3soBT/Xm+AmiuIRmQKBgHzNX/GoDB9WxSL7VV6/PYSNJl0S0k4jTw/lHUALbkY7rWvaaXZPWsOEmvU8aRdUw1JzeqddKjaUl5KNjWUo7XbpwlVcmfgRX+8Kx/ycWa+viBF7cRkoZNm+Lsql1iM2/AyAFk9ceIjcqhFWfnHdoAbNiZYLapuVUdRnfESFHyn9AoGAJSN/t7MNVNA3U2oKR9boiE523UlvPhryhjY42H65G7P+GNnjJ9v3D/Les942/j17aUwAhJif0JzVzjchhw+iGEV4x/gtRZkN2mlclhr0eqyMZONLowevEknHgu4xS2w+20xsv4d7hFB99uk5565+KZrZ03ohE0wPhC3yJq+cD3ECgYEAnqgZN3KS0vcMb+LbWM0D+SI7z0LCK+zuZHWAqJBk/QQgWhLUniaNppTUVpmeiKxBMyL+o2wFhd8qM6ruSaPj18faZFnIXwCkOBdf2Ceawb6RFJpbQ916ihZsqo/6mWc6VSyezmko6Vdr7IVgRz8pehqcTv2nh7t+TOiuyz6jXm0= + appId: 2021004170631369 + gateway: http://alipay.huamar.com/pay/alipay/transferUser + appCertPath: appCertPublicKey_2021004170631369.crt #应用公钥 + alipayCertPath: alipayCertPublicKey_RSA2.crt #支付宝公钥 + alipayRootCertPath: alipayRootCert.crt #支付宝根证书 diff --git a/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-local.yaml b/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-local.yaml index 1897c41..860f605 100644 --- a/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-local.yaml +++ b/ruoyi-vue-pro-master/yudao-server/src/main/resources/application-local.yaml @@ -271,3 +271,10 @@ io: xor: massage: 151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515 type: mobile +alipay: + appPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCVtsGcFLqb4IKcNo5OoFmVkxp881AQgNQhJdM9AFIDdEaTcyNXtWabTdbJxNahBfeCOK01fpHbwMSMhRVwZmP+jiO/M/22QmyVLN6cUG7uN+rB1Sw5T1hCbUmSZpLgcfznaV1+2JIcx9dV4kPFJUSTokLapszCfBnmdlQ4oGUZD54zWCNHIEVckZGn/XC1PuiflxSscD9Sx2C6SBniG1sMz/BGFU8Sw5JwUKtzvGesUlKqeDLHQP1/WJjsajLfqPQV6SFxjDMEVZ0WSmJV0Tl80Ulup8vgNKHVD06U9VhqBnIYTf3JcCBMnV4jmM1NsOnlIbdS4GqwdoH5QmI3EmMFAgMBAAECggEAOP3dLgFmGDia/8R039GCyMG6753f+KhSGFxB0ZLxpYb55t+JsLXJXY2AGkboPVv8IIJazWZlN/Zl2+g9hRA1OI37ZanxBxS6KP9vrqmf0OdQYoE32Ikv2/mmbCjH+NDrqVwez066MGKSworjqYTKWjkGoh2lDNQZN/YLkZLdaXBHHAg8sAh66NROWgfnZBB7V93ScTWNcd2CYPOBK+jfLlWs9QmUjobn+NO2ihCvBDS5vX6lTrL4CDPMiEZHvnA71BLnRVaJl6wjdebVTao1TRo1njVSlvyArKYt/cfE366n/bfM1Ylhhnbgoj02g1JqQrS0wDH4Au86CLgepF8CgQKBgQDTCX8mxCX2hU96vEPxNVAS/Oh+TOTx0OLRvpowBlR3QEKheJZyNdcG2HG6cUTl0oihlUePcfiPkGKmhqeKXMt3ost5zO/axLfC06prEs6gPQftKJfYe+bIMvF7A41dt1m6oenXokHqg7BGSJ3k/CX/C8Q7nMsXhVYjKXBw/ErYTQKBgQC1nIj7RwofDPQcmiTwtAVVXXevoEXTpk+PslpdSLs+BmBJzvJ4oQtYP4thKxwWjIsJWT1AUWF66Ytismd/DEkK9MAJfiH1WPcDFFfbeAu4p+x3pYtyth3poQ+jgRfU3BgiwFDp4n0mZPn9na4vm93FkYFcy3soBT/Xm+AmiuIRmQKBgHzNX/GoDB9WxSL7VV6/PYSNJl0S0k4jTw/lHUALbkY7rWvaaXZPWsOEmvU8aRdUw1JzeqddKjaUl5KNjWUo7XbpwlVcmfgRX+8Kx/ycWa+viBF7cRkoZNm+Lsql1iM2/AyAFk9ceIjcqhFWfnHdoAbNiZYLapuVUdRnfESFHyn9AoGAJSN/t7MNVNA3U2oKR9boiE523UlvPhryhjY42H65G7P+GNnjJ9v3D/Les942/j17aUwAhJif0JzVzjchhw+iGEV4x/gtRZkN2mlclhr0eqyMZONLowevEknHgu4xS2w+20xsv4d7hFB99uk5565+KZrZ03ohE0wPhC3yJq+cD3ECgYEAnqgZN3KS0vcMb+LbWM0D+SI7z0LCK+zuZHWAqJBk/QQgWhLUniaNppTUVpmeiKxBMyL+o2wFhd8qM6ruSaPj18faZFnIXwCkOBdf2Ceawb6RFJpbQ916ihZsqo/6mWc6VSyezmko6Vdr7IVgRz8pehqcTv2nh7t+TOiuyz6jXm0= + appId: 2021004170631369 + gateway: http://alipay.huamar.com/pay/alipay/transferUser + appCertPath: /cert/appCertPublicKey_2021004170631369.crt #应用公钥 + alipayCertPath: /cert/alipayCertPublicKey_RSA2.crt #支付宝公钥 + alipayRootCertPath: /cert/alipayRootCert.crt #支付宝根证书 diff --git a/ruoyi-vue-pro-master/yudao-server/src/main/resources/application.yaml b/ruoyi-vue-pro-master/yudao-server/src/main/resources/application.yaml index 92a9ad4..13af738 100644 --- a/ruoyi-vue-pro-master/yudao-server/src/main/resources/application.yaml +++ b/ruoyi-vue-pro-master/yudao-server/src/main/resources/application.yaml @@ -3,8 +3,8 @@ spring: name: yudao-server profiles: -# active: dev - active: local + active: dev +# active: local main: allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。