jialuyu 3 долоо хоног өмнө
parent
commit
f5e60fb139

+ 6 - 6
ruoyi-admin/src/main/resources/application-prod.yml

@@ -4,7 +4,7 @@ spring.servlet.multipart.location: /ruoyi/server/temp
 --- # 监控中心配置
 spring.boot.admin.client:
   # 增加客户端开关
-  enabled: true
+  enabled: false
   url: http://localhost:9090/admin
   instance:
     service-host-type: IP
@@ -16,7 +16,7 @@ spring.boot.admin.client:
 
 --- # snail-job 配置
 snail-job:
-  enabled: true
+  enabled: false
   # 需要在 SnailJob 后台组管理创建对应名称的组,然后创建任务的时候选择对应的组,才能正确分派任务
   group: "ruoyi_group"
   # SnailJob 接入验证令牌 详见 script/sql/ry_job.sql `sj_group_config`表
@@ -50,9 +50,9 @@ spring:
           driverClassName: com.mysql.cj.jdbc.Driver
           # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
           # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
-          url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
-          username: root
-          password: root
+          url: jdbc:mysql://localhost:3306/sj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
+          username: sj
+          password: PTn87SF6mZCmS7ji
 #        # 从库数据源
 #        slave:
 #          lazy: true
@@ -105,7 +105,7 @@ spring.data:
     # 数据库索引
     database: 0
     # redis 密码必须配置
-    password: ruoyi123
+    # password: ruoyi123
     # 连接超时时间
     timeout: 10s
     # 是否开启ssl

+ 47 - 12
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/config/WxPayConfig.java

@@ -3,6 +3,7 @@ package org.dromara.main.config;
 import cn.hutool.crypto.PemUtil;
 import com.wechat.pay.java.core.Config;
 import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.core.RSAPublicKeyConfig;
 import com.wechat.pay.java.service.payments.jsapi.JsapiService;
 import com.wechat.pay.java.service.payments.jsapi.model.Amount;
 import com.wechat.pay.java.service.payments.jsapi.model.Payer;
@@ -134,12 +135,32 @@ public class WxPayConfig {
             }
 
             // 配置微信支付
-            Config config = new RSAAutoCertificateConfig.Builder()
-                .merchantId(mchId)
-                .privateKey(privateKey)
-                .merchantSerialNumber(certSerialNo)
-                .apiV3Key(apiV3Key)
-                .build();
+            Config config;
+            PaymentConfig dbConfigForInit = null;
+            if (paymentConfigService != null) {
+                dbConfigForInit = paymentConfigService.getEnabledWechatConfig();
+            }
+
+            if (dbConfigForInit != null && StringUtils.isNotBlank(dbConfigForInit.getPublicKeyId()) 
+                && StringUtils.isNotBlank(dbConfigForInit.getPublicKey())) {
+                log.info("检测到微信支付公钥配置,使用 RSAPublicKeyConfig 初始化");
+                config = new RSAPublicKeyConfig.Builder()
+                    .merchantId(mchId)
+                    .privateKey(privateKey)
+                    .merchantSerialNumber(certSerialNo)
+                    .publicKeyId(dbConfigForInit.getPublicKeyId())
+                    .publicKey(dbConfigForInit.getPublicKey())
+                    .apiV3Key(apiV3Key)
+                    .build();
+            } else {
+                log.info("未检测到微信支付公钥配置,使用 RSAAutoCertificateConfig 初始化(自动下载平台证书)");
+                config = new RSAAutoCertificateConfig.Builder()
+                    .merchantId(mchId)
+                    .privateKey(privateKey)
+                    .merchantSerialNumber(certSerialNo)
+                    .apiV3Key(apiV3Key)
+                    .build();
+            }
 
             // 初始化服务
             jsapiService = new JsapiService.Builder().config(config).build();
@@ -180,12 +201,26 @@ public class WxPayConfig {
             }
 
             // 动态构建微信支付服务(SDK 直接接收 PEM 字符串)
-            Config config = new RSAAutoCertificateConfig.Builder()
-                .merchantId(dbMchId)
-                .privateKey(pemContent)
-                .merchantSerialNumber(dbSerialNo)
-                .apiV3Key(dbApiV3Key)
-                .build();
+            Config config;
+            if (StringUtils.isNotBlank(dbConfig.getPublicKeyId()) && StringUtils.isNotBlank(dbConfig.getPublicKey())) {
+                log.info("微信支付预下单 - 使用微信支付公钥模式");
+                config = new RSAPublicKeyConfig.Builder()
+                    .merchantId(dbMchId)
+                    .privateKey(pemContent)
+                    .merchantSerialNumber(dbSerialNo)
+                    .publicKeyId(dbConfig.getPublicKeyId())
+                    .publicKey(dbConfig.getPublicKey())
+                    .apiV3Key(dbApiV3Key)
+                    .build();
+            } else {
+                log.info("微信支付预下单 - 使用自动下载平台证书模式");
+                config = new RSAAutoCertificateConfig.Builder()
+                    .merchantId(dbMchId)
+                    .privateKey(pemContent)
+                    .merchantSerialNumber(dbSerialNo)
+                    .apiV3Key(dbApiV3Key)
+                    .build();
+            }
             JsapiService currentJsapiService = new JsapiService.Builder().config(config).build();
 
             // 解析私钥对象(用于签名),兼容 PKCS#8 和 PKCS#1 格式

+ 8 - 1
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/controller/miniapp/MiniappPaymentConfigController.java

@@ -67,7 +67,14 @@ public class MiniappPaymentConfigController {
 
     @RepeatSubmit
     @PostMapping(value = "/uploadPublicKey", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
-    public R<String> uploadPublicKey(@RequestPart("file") MultipartFile file) {
+    public R<String> uploadPublicKey(@RequestPart("file") MultipartFile file) throws Exception {
+        // 读取公钥文件内容并存入数据库(避免运行时访问 OSS URL 权限问题)
+        String publicKeyContent = new String(file.getBytes(), StandardCharsets.UTF_8).trim();
+        if (!publicKeyContent.contains("-----BEGIN")) {
+            return R.fail("上传的文件不是合法的 PEM 格式公钥文件,请重新选择");
+        }
+        paymentConfigService.updateWechatPublicKey(publicKeyContent);
+        // 同时仍上传到 OSS 备份,并存储路径
         SysOssVo oss = ossService.upload(file);
         paymentConfigService.updateWechatPublicKeyPath(oss.getUrl());
         return R.ok(oss.getUrl());

+ 5 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/IPaymentConfigService.java

@@ -34,6 +34,11 @@ public interface IPaymentConfigService {
     void updateWechatCertPath(String certPath);
 
     void updateWechatPublicKeyPath(String publicKeyPath);
+    
+    /**
+     * 将微信支付公钥文本内容存入 public_key 字段(避免运行时访问 OSS)
+     */
+    void updateWechatPublicKey(String publicKeyContent);
 
     PaymentConfigVo getAlipayConfig();
 

+ 11 - 0
ruoyi-modules/ruoyi-main/src/main/java/org/dromara/main/service/impl/PaymentConfigServiceImpl.java

@@ -81,6 +81,7 @@ public class PaymentConfigServiceImpl implements IPaymentConfigService {
         vo.setCertPath(config.getCertPath());
         vo.setNotifyUrl(config.getPayNotifyUrl());
         vo.setPublicKeyId(config.getPublicKeyId());
+        vo.setPublicKeyPath(config.getPublicKeyPath());
         vo.setPrivateKeyUploaded(config.getPrivateKeyPath() != null && !config.getPrivateKeyPath().isEmpty());
         vo.setCertUploaded(config.getCertPath() != null && !config.getCertPath().isEmpty());
         vo.setPublicKeyUploaded(config.getPublicKeyPath() != null && !config.getPublicKeyPath().isEmpty());
@@ -99,6 +100,7 @@ public class PaymentConfigServiceImpl implements IPaymentConfigService {
         config.setCertPath(bo.getCertPath());
         config.setPayNotifyUrl(bo.getNotifyUrl());
         config.setPublicKeyId(bo.getPublicKeyId());
+        config.setPublicKeyPath(bo.getPublicKeyPath());
         saveOrUpdate(config);
     }
 
@@ -135,6 +137,15 @@ public class PaymentConfigServiceImpl implements IPaymentConfigService {
         saveOrUpdate(config);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateWechatPublicKey(String publicKeyContent) {
+        // 将微信支付公钥文本内容直接存入 public_key 字段,读取时无需再访问 OSS
+        PaymentConfig config = getOrCreateWechatConfig();
+        config.setPublicKey(publicKeyContent);
+        saveOrUpdate(config);
+    }
+
     private PaymentConfig getOrCreateWechatConfig() {
         PaymentConfig config = paymentConfigMapper.selectOne(
             Wrappers.<PaymentConfig>lambdaQuery()

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/PaymentConfigBo.java

@@ -21,6 +21,7 @@ public class PaymentConfigBo {
 
     // 微信支付公钥配置(新商户需要)
     private String publicKeyId;
+    private String publicKeyPath;
 
     // 支付宝支付配置
     private String appPrivateKey;

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/PaymentConfigVo.java

@@ -23,6 +23,7 @@ public class PaymentConfigVo {
 
     // 微信支付公钥配置(新商户需要)
     private String publicKeyId;
+    private String publicKeyPath;
     private Boolean publicKeyUploaded;
 
     // 支付宝支付配置