Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/saas-api' into saas-api

ct 1 settimana fa
parent
commit
e4c624f5fe

+ 17 - 18
fs-admin-saas/src/main/java/com/fs/course/controller/FsCoursePlaySourceConfigController.java

@@ -98,24 +98,23 @@ public class FsCoursePlaySourceConfigController extends BaseController {
     @Log(title = "点播播放源配置", businessType = BusinessType.INSERT)
     @Log(title = "点播播放源配置", businessType = BusinessType.INSERT)
     @PostMapping
     @PostMapping
     public AjaxResult add(@Valid @RequestBody FsCoursePlaySourceConfigCreateParam param) {
     public AjaxResult add(@Valid @RequestBody FsCoursePlaySourceConfigCreateParam param) {
-//        Wrapper<FsCoursePlaySourceConfig> queryWrapper = Wrappers.<FsCoursePlaySourceConfig>lambdaQuery()
-//                .eq(FsCoursePlaySourceConfig::getAppid, param.getAppid())
-//                .eq(FsCoursePlaySourceConfig::getIsDel, 0);
-//        if (fsCoursePlaySourceConfigService.count(queryWrapper) > 0) {
-//            return AjaxResult.error("appid已存在");
-//        }
-//        com.fs.framework.security.LoginUser loginUser = (com.fs.framework.security.LoginUser) tokenService.getLoginUser(ServletUtils.getRequest());
-//        FsCoursePlaySourceConfig config = new FsCoursePlaySourceConfig();
-//        config.setCreateUserId(loginUser.getUserId());
-//        config.setCreateDeptId(loginUser.getDeptId());
-//        BeanUtils.copyProperties(param, config);
-//
-//        config.setIsDel(0);
-//        config.setCreateTime(LocalDateTime.now());
-//        config.setUpdateTime(LocalDateTime.now());
-//        fsCoursePlaySourceConfigService.save(config);
-//        return AjaxResult.success();
-        throw new RuntimeException("未实现");
+        Wrapper<FsCoursePlaySourceConfig> queryWrapper = Wrappers.<FsCoursePlaySourceConfig>lambdaQuery()
+                .eq(FsCoursePlaySourceConfig::getAppid, param.getAppid())
+                .eq(FsCoursePlaySourceConfig::getIsDel, 0);
+        if (fsCoursePlaySourceConfigService.count(queryWrapper) > 0) {
+            return AjaxResult.error("appid已存在");
+        }
+        LoginUser loginUser =  tokenService.getLoginUser(ServletUtils.getRequest());
+        FsCoursePlaySourceConfig config = new FsCoursePlaySourceConfig();
+        config.setCreateUserId(loginUser.getUserId());
+        config.setCreateDeptId(loginUser.getDeptId());
+        BeanUtils.copyProperties(param, config);
+
+        config.setIsDel(0);
+        config.setCreateTime(LocalDateTime.now());
+        config.setUpdateTime(LocalDateTime.now());
+        fsCoursePlaySourceConfigService.save(config);
+        return AjaxResult.success();
     }
     }
 
 
     @PreAuthorize("@ss.hasPermi('course:playSourceConfig:edit')")
     @PreAuthorize("@ss.hasPermi('course:playSourceConfig:edit')")

+ 2 - 8
fs-admin/src/main/java/com/fs/FSApplication.java

@@ -2,6 +2,7 @@ package com.fs;
 
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import org.redisson.spring.starter.RedissonAutoConfiguration;
 import org.redisson.spring.starter.RedissonAutoConfiguration;
 import org.springframework.boot.SpringBootConfiguration;
 import org.springframework.boot.SpringBootConfiguration;
@@ -12,14 +13,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 
 
-@SpringBootConfiguration
-@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, RedissonAutoConfiguration.class})
-@ComponentScan(
-    basePackages = "com.fs",
-    excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = {
-        "com\\.fs\\.framework\\.service\\.UserDetailsServiceImpl" // 这个地方用的是company_user 所以要排除掉
-    })
-)
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, RedissonAutoConfiguration.class})
 @Transactional
 @Transactional
 @EnableCaching
 @EnableCaching
 @EnableAsync
 @EnableAsync

+ 47 - 0
fs-admin/src/main/java/com/fs/admin/config/StubWxPayConfiguration.java

@@ -0,0 +1,47 @@
+package com.fs.admin.config;
+
+import com.fs.core.config.WxPayProperties;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * fs-admin 模块的微信支付 Stub 配置
+ * <p>
+ * 仅在 fs.startup.init-wechat-config=false 时激活(即 fs-admin),
+ * 提供不查 DB 的 WxPayService 和 WxPayProperties,避免启动时查 DB。
+ * 其他模块 matchIfMissing=true,不会加载此 Stub。
+ *
+ * @author fs
+ * @date 2026-06-01
+ */
+@Slf4j
+@Configuration
+@ConditionalOnProperty(prefix = "fs.startup", name = "init-wechat-config", havingValue = "false")
+public class StubWxPayConfiguration {
+
+    /**
+     * 空的微信支付服务,不连接任何支付通道
+     */
+    @Bean
+    @ConditionalOnMissingBean
+    public WxPayService wxService() {
+        log.info("[fs-admin] 创建空的微信支付服务(Stub)");
+        return new WxPayServiceImpl();
+    }
+
+    /**
+     * 微信支付配置 Stub,不会在启动时查询数据库。
+     * 手动注入 SysConfigMapper 和 RedisCache,确保运行时调用 getter 不 NPE。
+     */
+    @Bean
+    @ConditionalOnMissingBean
+    public WxPayProperties wxPayProperties() {
+        log.info("[fs-admin] 创建微信支付配置(Stub,不查 DB)");
+        return new WxPayProperties();
+    }
+}

+ 6 - 0
fs-admin/src/main/resources/application-dev.yml

@@ -130,3 +130,9 @@ spring:
                     wall:
                     wall:
                         config:
                         config:
                             multi-statement-allow: true
                             multi-statement-allow: true
+
+# 启动时跳过微信支付和商户配置初始化(fs-admin 模块不需要)
+fs:
+  startup:
+    init-wechat-config: false
+    init-merchant-config: false

+ 1 - 2
fs-company/src/main/java/com/fs/FsSaasApplication.java

@@ -20,8 +20,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
         // fs-framework.jar 与 fs-company 本地 framework 重复的 web 层 Bean(保留 TokenService 供 SysLoginService 等使用)
         // fs-framework.jar 与 fs-company 本地 framework 重复的 web 层 Bean(保留 TokenService 供 SysLoginService 等使用)
         "com\\.fs\\.framework\\.web\\.service\\.PermissionService",
         "com\\.fs\\.framework\\.web\\.service\\.PermissionService",
         "com\\.fs\\.framework\\.web\\.service\\.UserDetailsServiceImpl",
         "com\\.fs\\.framework\\.web\\.service\\.UserDetailsServiceImpl",
-        "com\\.fs\\.framework\\.web\\.exception\\.GlobalExceptionHandler",
-        "com\\.fs\\.admin\\.controller\\..*"
+        "com\\.fs\\.framework\\.web\\.exception\\.GlobalExceptionHandler"
     })
     })
 )
 )
 @EnableTransactionManagement
 @EnableTransactionManagement

+ 87 - 87
fs-service/src/main/java/com/fs/company/utils/JwtUtils.java

@@ -1,87 +1,87 @@
-package com.fs.company.utils;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-import java.util.Date;
-
-/**
- * jwt工具类
-
- */
-@ConfigurationProperties(prefix = "fs.jwt")
-@Component
-public class JwtUtils {
-    private Logger logger = LoggerFactory.getLogger(getClass());
-
-
-    private String secret;
-    private long expire;
-    private String header;
-
-    /**
-     * 生成jwt token
-     */
-    public String generateToken(long userId) {
-        Date nowDate = new Date();
-        //过期时间
-        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
-
-        return Jwts.builder()
-                .setHeaderParam("typ", "JWT")
-                .setSubject(userId+"")
-                .setIssuedAt(nowDate)
-                .setExpiration(expireDate)
-                .signWith(SignatureAlgorithm.HS512, secret)
-                .compact();
-    }
-
-    public Claims getClaimByToken(String token) {
-        try {
-            return Jwts.parser()
-                    .setSigningKey(secret)
-                    .parseClaimsJws(token)
-                    .getBody();
-        }catch (Exception e){
-            logger.debug("validate is token error ", e);
-            return null;
-        }
-    }
-
-    /**
-     * token是否过期
-     * @return  true:过期
-     */
-    public boolean isTokenExpired(Date expiration) {
-        return expiration.before(new Date());
-    }
-
-    public String getSecret() {
-        return secret;
-    }
-
-    public void setSecret(String secret) {
-        this.secret = secret;
-    }
-
-    public long getExpire() {
-        return expire;
-    }
-
-    public void setExpire(long expire) {
-        this.expire = expire;
-    }
-
-    public String getHeader() {
-        return header;
-    }
-
-    public void setHeader(String header) {
-        this.header = header;
-    }
-}
+//package com.fs.company.utils;
+//
+//import io.jsonwebtoken.Claims;
+//import io.jsonwebtoken.Jwts;
+//import io.jsonwebtoken.SignatureAlgorithm;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.boot.context.properties.ConfigurationProperties;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.Date;
+//
+///**
+// * jwt工具类
+//
+// */
+//@ConfigurationProperties(prefix = "fs.jwt")
+//@Component
+//public class JwtUtils {
+//    private Logger logger = LoggerFactory.getLogger(getClass());
+//
+//
+//    private String secret;
+//    private long expire;
+//    private String header;
+//
+//    /**
+//     * 生成jwt token
+//     */
+//    public String generateToken(long userId) {
+//        Date nowDate = new Date();
+//        //过期时间
+//        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
+//
+//        return Jwts.builder()
+//                .setHeaderParam("typ", "JWT")
+//                .setSubject(userId+"")
+//                .setIssuedAt(nowDate)
+//                .setExpiration(expireDate)
+//                .signWith(SignatureAlgorithm.HS512, secret)
+//                .compact();
+//    }
+//
+//    public Claims getClaimByToken(String token) {
+//        try {
+//            return Jwts.parser()
+//                    .setSigningKey(secret)
+//                    .parseClaimsJws(token)
+//                    .getBody();
+//        }catch (Exception e){
+//            logger.debug("validate is token error ", e);
+//            return null;
+//        }
+//    }
+//
+//    /**
+//     * token是否过期
+//     * @return  true:过期
+//     */
+//    public boolean isTokenExpired(Date expiration) {
+//        return expiration.before(new Date());
+//    }
+//
+//    public String getSecret() {
+//        return secret;
+//    }
+//
+//    public void setSecret(String secret) {
+//        this.secret = secret;
+//    }
+//
+//    public long getExpire() {
+//        return expire;
+//    }
+//
+//    public void setExpire(long expire) {
+//        this.expire = expire;
+//    }
+//
+//    public String getHeader() {
+//        return header;
+//    }
+//
+//    public void setHeader(String header) {
+//        this.header = header;
+//    }
+//}

+ 2 - 2
fs-service/src/main/java/com/fs/config/tencent/TencentProperties.java

@@ -89,9 +89,9 @@ public class TencentProperties {
         try {
         try {
             String configJson = JSONObject.toJSONString(config);
             String configJson = JSONObject.toJSONString(config);
             redisCache.setCacheObject(PROJECT_CONFIG_CACHE_KEY, configJson, CACHE_EXPIRE_TIME, CACHE_EXPIRE_UNIT);
             redisCache.setCacheObject(PROJECT_CONFIG_CACHE_KEY, configJson, CACHE_EXPIRE_TIME, CACHE_EXPIRE_UNIT);
-            log.debug("微信支付配置已存入Redis缓存,有效期{}分钟", CACHE_EXPIRE_TIME);
+            log.debug("tencentCloudConfig已存入Redis缓存,有效期{}分钟", CACHE_EXPIRE_TIME);
         } catch (Exception e) {
         } catch (Exception e) {
-            log.warn("保存微信支付配置到Redis缓存失败", e);
+            log.warn("tencentCloudConfig到Redis缓存失败", e);
         }
         }
     }
     }
     /**
     /**

+ 2 - 0
fs-service/src/main/java/com/fs/core/config/WxMaConfiguration.java

@@ -28,6 +28,7 @@ import me.chanjar.weixin.common.error.WxRuntimeException;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import org.yaml.snakeyaml.events.Event;
 import org.yaml.snakeyaml.events.Event;
@@ -44,6 +45,7 @@ import java.util.stream.Collectors;
 @Slf4j
 @Slf4j
 @Configuration
 @Configuration
 @ComponentScan("com.fs.system.mapper")
 @ComponentScan("com.fs.system.mapper")
+@ConditionalOnProperty(prefix = "fs.startup", name = "init-wechat-config", havingValue = "true", matchIfMissing = true)
 public class WxMaConfiguration {
 public class WxMaConfiguration {
     private final WxMaConfig properties;
     private final WxMaConfig properties;
 
 

+ 2 - 0
fs-service/src/main/java/com/fs/core/config/WxMpConfiguration.java

@@ -6,6 +6,7 @@ import me.chanjar.weixin.mp.api.WxMpMessageRouter;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
 import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
 import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
 import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
@@ -25,6 +26,7 @@ import static me.chanjar.weixin.mp.constant.WxMpEventConstants.POI_CHECK_NOTIFY;
 
 
 @AllArgsConstructor
 @AllArgsConstructor
 @Configuration
 @Configuration
+@ConditionalOnProperty(prefix = "fs.startup", name = "init-wechat-config", havingValue = "true", matchIfMissing = true)
 public class WxMpConfiguration {
 public class WxMpConfiguration {
     private final LogHandler logHandler;
     private final LogHandler logHandler;
     private final NullHandler nullHandler;
     private final NullHandler nullHandler;

+ 2 - 0
fs-service/src/main/java/com/fs/core/config/WxPayConfiguration.java

@@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.Scope;
@@ -15,6 +16,7 @@ import org.springframework.context.annotation.Scope;
 @Slf4j
 @Slf4j
 @Configuration
 @Configuration
 @ConditionalOnClass(WxPayService.class)
 @ConditionalOnClass(WxPayService.class)
+@ConditionalOnProperty(prefix = "fs.startup", name = "init-wechat-config", havingValue = "true", matchIfMissing = true)
 @AllArgsConstructor
 @AllArgsConstructor
 public class WxPayConfiguration {
 public class WxPayConfiguration {
   private WxPayProperties properties;
   private WxPayProperties properties;

+ 2 - 0
fs-service/src/main/java/com/fs/his/service/impl/MerchantAppConfigServiceImpl.java

@@ -18,6 +18,7 @@ import com.fs.system.mapper.SysDictTypeMapper;
 import com.google.gson.Gson;
 import com.google.gson.Gson;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
@@ -32,6 +33,7 @@ import javax.annotation.PostConstruct;
  */
  */
 @Service
 @Service
 @Slf4j
 @Slf4j
+@ConditionalOnProperty(prefix = "fs.startup", name = "init-merchant-config", havingValue = "true", matchIfMissing = true)
 public class MerchantAppConfigServiceImpl extends ServiceImpl<MerchantAppConfigMapper, MerchantAppConfig> implements IMerchantAppConfigService {
 public class MerchantAppConfigServiceImpl extends ServiceImpl<MerchantAppConfigMapper, MerchantAppConfig> implements IMerchantAppConfigService {
 
 
     @Autowired
     @Autowired

+ 2 - 0
fs-service/src/main/java/com/fs/wx/cp/config/WxCpConfiguration.java

@@ -11,6 +11,7 @@ import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
 import me.chanjar.weixin.cp.constant.WxCpConsts;
 import me.chanjar.weixin.cp.constant.WxCpConsts;
 import me.chanjar.weixin.cp.message.WxCpMessageRouter;
 import me.chanjar.weixin.cp.message.WxCpMessageRouter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PostConstruct;
@@ -19,6 +20,7 @@ import java.util.stream.Collectors;
 
 
 @Slf4j
 @Slf4j
 @Configuration
 @Configuration
+@ConditionalOnProperty(prefix = "fs.startup", name = "init-wechat-config", havingValue = "true", matchIfMissing = true)
 public class WxCpConfiguration {
 public class WxCpConfiguration {
     private LogHandler logHandler;
     private LogHandler logHandler;
     private NullHandler nullHandler;
     private NullHandler nullHandler;