From 368bcda83d4e4ce859dbc8501e4e9b9455d1a075 Mon Sep 17 00:00:00 2001 From: xinzirun Date: Fri, 20 Sep 2024 21:26:22 +0800 Subject: [PATCH] =?UTF-8?q?fix():=20=E4=BF=AE=E5=A4=8Dsass=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud-common/cloud-common-saas/pom.xml | 6 +- .../many/datasource/ManyDataSource.java | 127 ++++++++++++++++++ .../constents/DatasourceContent.java | 34 +++++ .../domain/model/DataSourceInfo.java | 12 +- .../factory/DruidDataSourceFactory.java | 10 +- .../holder/DynamicDataSourceHolder.java | 4 +- .../datasource/role/DynamicDataSource.java | 23 ++-- .../common/saas/contents/SaaSConstant.java | 25 ++++ .../common/saas/domain/model/EntInfo.java | 13 +- .../common/saas/exception/SaaSException.java | 8 +- .../saas/interceptor/SaaSInterceptor.java | 59 ++++++++ .../saas/interceptor/WebMvcSaaSConfig.java | 23 ++-- .../many/datasource/ManyDataSource.java | 82 ----------- .../constents/DatasourceContent.java | 20 --- .../common/saas/constants/SaaSConstant.java | 29 ---- .../saas/interceptor/SaaSInterceptor.java | 61 --------- ...ot.autoconfigure.AutoConfiguration.imports | 4 +- .../muyu/common/system/domain/SysUser.java | 4 + .../system/remote/RemoteUserService.java | 10 ++ .../factory/RemoteUserFallbackFactory.java | 7 + .../system/controller/SysUserController.java | 10 ++ .../muyu/system/service/SysUserService.java | 7 + .../service/impl/SysUserServiceImpl.java | 12 ++ .../resources/mapper/system/SysUserMapper.xml | 2 + 24 files changed, 356 insertions(+), 236 deletions(-) create mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/ManyDataSource.java create mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/constents/DatasourceContent.java rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/many/datasource/domain/model/DataSourceInfo.java (70%) rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/many/datasource/factory/DruidDataSourceFactory.java (84%) rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/many/datasource/holder/DynamicDataSourceHolder.java (93%) rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/many/datasource/role/DynamicDataSource.java (64%) create mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/contents/SaaSConstant.java rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/saas/domain/model/EntInfo.java (65%) rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/saas/exception/SaaSException.java (74%) create mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/SaaSInterceptor.java rename cloud-common/cloud-common-saas/src/main/java/com/muyu/{ => cloud}/common/saas/interceptor/WebMvcSaaSConfig.java (54%) delete mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/ManyDataSource.java delete mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/constents/DatasourceContent.java delete mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/constants/SaaSConstant.java delete mode 100644 cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/SaaSInterceptor.java diff --git a/cloud-common/cloud-common-saas/pom.xml b/cloud-common/cloud-common-saas/pom.xml index dc6beec..60b4041 100644 --- a/cloud-common/cloud-common-saas/pom.xml +++ b/cloud-common/cloud-common-saas/pom.xml @@ -10,7 +10,6 @@ cloud-common-saas - SaaS公共依赖 17 @@ -25,10 +24,11 @@ cloud-common-datasource - + com.muyu cloud-common-security - \ No newline at end of file + + diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/ManyDataSource.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/ManyDataSource.java new file mode 100644 index 0000000..08f2300 --- /dev/null +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/ManyDataSource.java @@ -0,0 +1,127 @@ +package com.muyu.cloud.common.many.datasource; + +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; +import com.muyu.cloud.common.many.datasource.constents.DatasourceContent; +import com.muyu.cloud.common.many.datasource.domain.model.DataSourceInfo; +import com.muyu.cloud.common.many.datasource.factory.DruidDataSourceFactory; +import com.muyu.cloud.common.many.datasource.role.DynamicDataSource; +import com.muyu.cloud.common.saas.domain.model.EntInfo; +import com.muyu.cloud.common.saas.exception.SaaSException; +import com.muyu.common.core.domain.Result; +import com.muyu.common.core.utils.SpringUtils; +import com.muyu.common.system.domain.SysUser; +import com.muyu.common.system.remote.RemoteUserService; +import lombok.extern.log4j.Log4j2; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author: zi run + * @Date 2024/9/20 14:52 + * @Description 多数据源 + */ +@Log4j2 +@Component +@AutoConfiguration(before = MybatisPlusAutoConfiguration.class) +public class ManyDataSource implements ApplicationRunner { + + /** + * 在应用启动时执行,初始化数据源连接池。 + * 获取 DruidDataSourceFactory 和 DynamicDataSource 实例, + * 遍历数据源信息列表,为每个数据源创建 Druid 数据源并存储到动态数据源中。 + * @param args 应用启动参数 + */ + @Override + public void run(ApplicationArguments args) { + DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class); + DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class); + dataSourceInfoList().stream() + .map(entInfo -> DataSourceInfo.hostAndPortBuild( + entInfo.getEntCode(), entInfo.getIp(), entInfo.getPort() + ) + ) + .forEach(dataSourceInfo -> { + DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo); + dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource); + log.info("存储数据连接池为:key:{}",dataSourceInfo.getKey()); + }); + } + + /** + * 获取数据源信息 + * @return 企业信息 + */ + private List dataSourceInfoList(){ + RemoteUserService remoteUserService = SpringUtils.getBean(RemoteUserService.class); + Result> entListResult = remoteUserService.entList(); + if (entListResult==null){ + throw new SaaSException("saas远调数据源错误"); + } + List data = entListResult.getData(); + if (entListResult.getCode() == Result.SUCCESS && data != null){ + return data.stream() + .map(d -> EntInfo.builder() + .entCode(d.getDatabaseName()) + .ip(DatasourceContent.IP) + .port(DatasourceContent.PORT) + .build() + ) + .toList(); + }else { + log.error("远调数据源错误,远调数据为:{}", JSON.toJSONString(data)); + return null; + } + } + + /** + * 创建一个 DynamicDataSource Bean,配置多个数据源。 + * 从数据源信息列表中获取配置,并使用 DruidDataSourceFactory 创建数据源实例。 + * @param druidDataSourceFactory 创建 Druid 数据源的工厂 + * @return 配置好的 DynamicDataSource 实例 + */ + @Bean + public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) { + Map dataSourceMap = dataSourceInfoList().stream() + .map(entInfo -> DataSourceInfo.hostAndPortBuild( + entInfo.getEntCode(), + entInfo.getIp(), + entInfo.getPort() + ) + ) + .collect(Collectors.toMap( + dataSourceInfo -> dataSourceInfo.getKey(), + dataSourceInfo -> druidDataSourceFactory.create(dataSourceInfo) + )); + + //设置动态数据源 + DynamicDataSource dynamicDataSource = new DynamicDataSource(); + dynamicDataSource.setTargetDataSources(dataSourceMap); + dynamicDataSource.setDefineTargetDataSources(dataSourceMap); + return dynamicDataSource; + } + + /** + * 创建 SqlSessionFactory Bean,用于 MyBatis 数据库操作。 + * 该方法接收动态数据源并配置 SqlSessionFactory,返回 + * 用于与数据库交互的 SqlSessionFactory 实例。 + * @param dataSource 动态数据源 + * @return 配置好的 SqlSessionFactory 实例 + * @throws Exception 可能抛出的异常 + */ + @Bean + public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception { + SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); + sessionFactory.setDataSource(dataSource); + return sessionFactory.getObject(); + } +} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/constents/DatasourceContent.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/constents/DatasourceContent.java new file mode 100644 index 0000000..34f0937 --- /dev/null +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/constents/DatasourceContent.java @@ -0,0 +1,34 @@ +package com.muyu.cloud.common.many.datasource.constents; + +/** + * @Author: zi run + * @Date 2024/9/20 14:52 + * @Description 数据源常量 + */ +public class DatasourceContent { + + /** + * 数据源地址 + */ + public final static String URL = "jdbc:mysql://{}:{}/{}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8"; + + /** + * 数据源用户名 + */ + public final static String USERNAME = "root"; + + /** + * 数据源密码 + */ + public final static String PASSWORD = "wx0713101x"; + + /** + * 数据源IP + */ + public final static String IP = "127.0.0.1"; + + /** + * 数据源端口号 + */ + public final static Integer PORT = 3307; +} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/domain/model/DataSourceInfo.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/domain/model/DataSourceInfo.java similarity index 70% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/domain/model/DataSourceInfo.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/domain/model/DataSourceInfo.java index 20b4226..c1af5f2 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/domain/model/DataSourceInfo.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/domain/model/DataSourceInfo.java @@ -1,7 +1,7 @@ -package com.muyu.common.many.datasource.domain.model; +package com.muyu.cloud.common.many.datasource.domain.model; +import com.muyu.cloud.common.many.datasource.constents.DatasourceContent; import com.muyu.common.core.utils.StringUtils; -import com.muyu.common.many.datasource.constents.DatasourceContent; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,7 +9,7 @@ import lombok.NoArgsConstructor; /** * @Author: zi run - * @Date 2024/9/18 22:01 + * @Date 2024/9/20 14:52 * @Description 数据源实体类 */ @Data @@ -39,12 +39,12 @@ public class DataSourceInfo { private String password; - public static DataSourceInfo hostAndPortBuild(String key, String host, Integer port){ + public static DataSourceInfo hostAndPortBuild(String key, String host, Integer port) { return DataSourceInfo.builder() .key(key) - .url(StringUtils.format(DatasourceContent.DATASOURCE_URL, host, port)) + .url(StringUtils.format(DatasourceContent.URL, host, port, key)) .password(DatasourceContent.PASSWORD) - .userName(DatasourceContent.USER_NAME) + .userName(DatasourceContent.USERNAME) .build(); } } diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/factory/DruidDataSourceFactory.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/factory/DruidDataSourceFactory.java similarity index 84% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/factory/DruidDataSourceFactory.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/factory/DruidDataSourceFactory.java index bf7832f..3edd2b2 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/factory/DruidDataSourceFactory.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/factory/DruidDataSourceFactory.java @@ -1,7 +1,7 @@ -package com.muyu.common.many.datasource.factory; +package com.muyu.cloud.common.many.datasource.factory; import com.alibaba.druid.pool.DruidDataSource; -import com.muyu.common.many.datasource.domain.model.DataSourceInfo; +import com.muyu.cloud.common.many.datasource.domain.model.DataSourceInfo; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Component; @@ -9,7 +9,7 @@ import java.sql.SQLException; /** * @Author: zi run - * @Date 2024/9/18 22:08 + * @Date 2024/9/20 14:52 * @Description Druid工厂 */ @Log4j2 @@ -19,7 +19,7 @@ public class DruidDataSourceFactory { /** * 根据传递的数据源信息测试数据库连接 * @param dataSourceInfo 数据源实体类 - * @return + * @return Druid连接池数据源 */ public DruidDataSource create(DataSourceInfo dataSourceInfo) { DruidDataSource druidDataSource = new DruidDataSource(); @@ -32,7 +32,7 @@ public class DruidDataSourceFactory { druidDataSource.getConnection(2000); log.info("{} -> 数据源连接成功", dataSourceInfo.getKey()); return druidDataSource; - } catch (SQLException sqlException) { + } catch (SQLException e) { log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword()); return null; } diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/holder/DynamicDataSourceHolder.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/holder/DynamicDataSourceHolder.java similarity index 93% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/holder/DynamicDataSourceHolder.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/holder/DynamicDataSourceHolder.java index fbf522b..9e5eb96 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/holder/DynamicDataSourceHolder.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/holder/DynamicDataSourceHolder.java @@ -1,11 +1,11 @@ -package com.muyu.common.many.datasource.holder; +package com.muyu.cloud.common.many.datasource.holder; import lombok.extern.slf4j.Slf4j; import org.springframework.util.Assert; /** * @Author: zi run - * @Date 2024/9/18 22:08 + * @Date 2024/9/20 14:52 * @Description 数据源切换处理 */ @Slf4j diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/role/DynamicDataSource.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/role/DynamicDataSource.java similarity index 64% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/role/DynamicDataSource.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/role/DynamicDataSource.java index 9a63b50..f135d0e 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/role/DynamicDataSource.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/many/datasource/role/DynamicDataSource.java @@ -1,26 +1,25 @@ -package com.muyu.common.many.datasource.role; +package com.muyu.cloud.common.many.datasource.role; import com.alibaba.druid.pool.DruidDataSource; -import com.muyu.common.many.datasource.holder.DynamicDataSourceHolder; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import com.muyu.cloud.common.many.datasource.holder.DynamicDataSourceHolder; +import lombok.*; +import lombok.experimental.SuperBuilder; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; - import java.util.Map; /** * @Author: zi run - * @Date 2024/9/18 22:14 - * @Description 动态数据源 调用AddDefineDataSource组件的addDefineDynamicDataSource()方法, - * 获取原来targetdatasources的map,并将新的数据源信息添加到map中,并替换targetdatasources中的map切换数据源时可以使用 - * @DataSource(value = "数据源名称"),或者DynamicDataSourceContextHolder.setContextKey("数据源名称") + * @Date 2024/9/20 14:56 + * @Description 动态数据源 + * 调用AddDefineDataSource组件的addDefineDynamicDataSource()方法,获取原来targetdatasources的map, + * 并将新的数据源信息添加到map中,并替换targetdatasources中的map + * 切换数据源时可以使用@DataSource(value = "数据源名称"),或者DynamicDataSourceContextHolder.setContextKey("数据源名称") */ -@EqualsAndHashCode(callSuper = true) @Data +@SuperBuilder @AllArgsConstructor @NoArgsConstructor +@EqualsAndHashCode(callSuper = true) public class DynamicDataSource extends AbstractRoutingDataSource { /** diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/contents/SaaSConstant.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/contents/SaaSConstant.java new file mode 100644 index 0000000..9499e4c --- /dev/null +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/contents/SaaSConstant.java @@ -0,0 +1,25 @@ +package com.muyu.cloud.common.saas.contents; + +/** + * @Author: zi run + * @Date 2024/9/20 19:40 + * @Description SAAS常量 + */ +public class SaaSConstant { + + /** + * SaaS键名 + */ + public final static String SAAS_KEY = "ent-code"; + + /** + * 拦截器白名单 + */ + public static final String[] EXCLUDE_URLS = {"/login", "/logout", "/refresh"}; + + /** + * 拦截器执行优先级 + */ + public static final Integer INTERCEPTOR_ORDER = -10; + +} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/domain/model/EntInfo.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/domain/model/EntInfo.java similarity index 65% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/domain/model/EntInfo.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/domain/model/EntInfo.java index 3427f49..cba7c04 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/domain/model/EntInfo.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/domain/model/EntInfo.java @@ -1,4 +1,4 @@ -package com.muyu.common.saas.domain.model; +package com.muyu.cloud.common.saas.domain.model; import lombok.AllArgsConstructor; import lombok.Builder; @@ -7,7 +7,7 @@ import lombok.NoArgsConstructor; /** * @Author: zi run - * @Date 2024/9/19 14:24 + * @Date 2024/9/20 19:41 * @Description 企业信息 */ @Data @@ -16,9 +16,18 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class EntInfo { + /** + * 企业编码 + */ private String entCode; + /** + * IP地址 + */ private String ip; + /** + * 端口号 + */ private Integer port; } diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/exception/SaaSException.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/exception/SaaSException.java similarity index 74% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/exception/SaaSException.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/exception/SaaSException.java index bf74366..231b86d 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/exception/SaaSException.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/exception/SaaSException.java @@ -1,10 +1,11 @@ -package com.muyu.common.saas.exception; +package com.muyu.cloud.common.saas.exception; + import com.muyu.common.core.exception.ServiceException; /** * @Author: zi run - * @Date 2024/9/18 21:28 + * @Date 2024/9/20 19:41 * @Description SaaS异常类 */ public class SaaSException extends ServiceException { @@ -17,6 +18,9 @@ public class SaaSException extends ServiceException { super(message); } + /** + * 空构造方法,避免反序列化问题 + */ public SaaSException () { super(); } diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/SaaSInterceptor.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/SaaSInterceptor.java new file mode 100644 index 0000000..e3b4bc4 --- /dev/null +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/SaaSInterceptor.java @@ -0,0 +1,59 @@ +package com.muyu.cloud.common.saas.interceptor; + +import com.muyu.cloud.common.saas.contents.SaaSConstant; +import com.muyu.cloud.common.many.datasource.holder.DynamicDataSourceHolder; +import com.muyu.cloud.common.saas.exception.SaaSException; +import com.muyu.cloud.common.many.datasource.role.DynamicDataSource; +import com.muyu.common.core.utils.ServletUtils; +import com.muyu.common.core.utils.SpringUtils; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.AsyncHandlerInterceptor; + +/** + * @Author: zi run + * @Date 2024/9/20 19:41 + * @Description SAAS拦截器 + */ +public class SaaSInterceptor implements AsyncHandlerInterceptor { + + /** + * 请求执行之前触发 + * @param request servlet请求对象 + * @param response servlet响应对象 + * @param handler 处理器 + * @return 是否放行 + * @throws Exception 可能抛出的异常 + */ + @Override + public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + if (!(handler instanceof HandlerMethod)) { + return true; + } + + String SaaSKey = ServletUtils.getHeader(request, SaaSConstant.SAAS_KEY); + if (SaaSKey == null) { + throw new SaaSException("SaaS非法访问"); + }else { + DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class); + if (!dynamicDataSource.hashKey(SaaSKey)){ + throw new SaaSException("SaaS非法访问"); + } + } + DynamicDataSourceHolder.setDynamicDataSourceKey(SaaSKey); + return true; + } + + /** + * 请求执行之后触发 + * @param request servlet请求对象 + * @param response servlet响应对象 + * @param handler 处理器 + * @throws Exception servlet响应对象 + */ + @Override + public void afterConcurrentHandlingStarted (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + DynamicDataSourceHolder.removeDynamicDataSourceKey(); + } +} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/WebMvcSaaSConfig.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/WebMvcSaaSConfig.java similarity index 54% rename from cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/WebMvcSaaSConfig.java rename to cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/WebMvcSaaSConfig.java index c14bb70..52795f0 100644 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/WebMvcSaaSConfig.java +++ b/cloud-common/cloud-common-saas/src/main/java/com/muyu/cloud/common/saas/interceptor/WebMvcSaaSConfig.java @@ -1,33 +1,34 @@ -package com.muyu.common.saas.interceptor; +package com.muyu.cloud.common.saas.interceptor; -import com.muyu.common.saas.constants.SaaSConstant; +import com.muyu.cloud.common.saas.contents.SaaSConstant; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** - * @Author: zi run - * @Date 2024/9/18 21:07 - * @Description 拦截器配置 + * 拦截器配置 + * + * @author muyu */ public class WebMvcSaaSConfig implements WebMvcConfigurer { + /** - * 添加拦截器 - * @param registry 注册器 + * 添加请求拦截器配置 + * @param registry 拦截器注册表,用于注册自定义拦截器 */ @Override - public void addInterceptors(InterceptorRegistry registry) { + public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(getHeaderInterceptor()) + .addPathPatterns("/**") .excludePathPatterns(SaaSConstant.EXCLUDE_URLS) .order(SaaSConstant.INTERCEPTOR_ORDER); - } /** * 自定义请求头拦截器 - * @return SAAS拦截器对象 + * @return SaaS拦截器 */ - public SaaSInterceptor getHeaderInterceptor() { + public SaaSInterceptor getHeaderInterceptor () { return new SaaSInterceptor(); } } diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/ManyDataSource.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/ManyDataSource.java deleted file mode 100644 index a661fd2..0000000 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/ManyDataSource.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.muyu.common.many.datasource; - -import com.alibaba.druid.pool.DruidDataSource; -import com.muyu.common.core.utils.SpringUtils; -import com.muyu.common.many.datasource.domain.model.DataSourceInfo; -import com.muyu.common.many.datasource.factory.DruidDataSourceFactory; -import com.muyu.common.many.datasource.role.DynamicDataSource; -import com.muyu.common.saas.domain.model.EntInfo; -import lombok.extern.log4j.Log4j2; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @Author: zi run - * @Date 2024/9/18 22:08 - * @Description 多数据源 - */ -@Log4j2 -@Component -public class ManyDataSource { - - @PostConstruct - public void init(){ - new Thread(() -> { - try { - Thread.sleep(10000); - } catch (InterruptedException ignored) {} - DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class); - DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class); - EntInfo entInfo = EntInfo.builder() - .entCode("ent_4588") - .ip("192.168.40.132") - .port(3308) - .build(); - DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(entInfo.getEntCode(), entInfo.getIp(), entInfo.getPort()); - DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo); - dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource); - }).start(); - } - - - private List dataSourceInfoList(){ - List list = new ArrayList<>(); - list.add( - EntInfo.builder() - .entCode("ent_4587") - .ip("192.168.40.132") - .port(3307) - .build() - ); - return list; - } - - @Bean - @Primary - public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) { - - // 企业列表 企业CODE,端口,IP - - Map dataSourceMap = new HashMap<>(); - dataSourceInfoList() - .stream() - .map(entInfo -> DataSourceInfo.hostAndPortBuild(entInfo.getEntCode(), entInfo.getIp(), entInfo.getPort())) - .forEach(dataSourceInfo -> { - dataSourceMap.put(dataSourceInfo.getKey(), druidDataSourceFactory.create(dataSourceInfo)); - }); - //设置动态数据源 - DynamicDataSource dynamicDataSource = new DynamicDataSource(); -// dynamicDataSource.setDefaultTargetDataSource(masterDataSource()); - dynamicDataSource.setTargetDataSources(dataSourceMap); - //将数据源信息备份在defineTargetDataSources中 - dynamicDataSource.setDefineTargetDataSources(dataSourceMap); - return dynamicDataSource; - } -} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/constents/DatasourceContent.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/constents/DatasourceContent.java deleted file mode 100644 index 44ee2f9..0000000 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/many/datasource/constents/DatasourceContent.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.muyu.common.many.datasource.constents; - -/** - * @Author: zi run - * @Date 2024/9/18 22:06 - * @Description 数据源常量 - */ -public class DatasourceContent { - - public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/{}?useUnicode=true&" + - "characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8"; - - public final static String USER_NAME = "root"; - - public final static String PASSWORD = "root"; - - public final static String IP = "127.0.0.1"; - - public final static Integer PORT = 3307; -} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/constants/SaaSConstant.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/constants/SaaSConstant.java deleted file mode 100644 index aa08900..0000000 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/constants/SaaSConstant.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.muyu.common.saas.constants; - -/** - * @Author: zi run - * @Date 2024/9/18 21:22 - * @Description SAAS常量 - */ -public class SaaSConstant { - - /** - * Saas键名 - */ - public static final String SAAS_KEY = "ent-code"; - - /** - * SaaS异常提示 - */ - public static final String SAAS_EXCEPTION_MSG = "SaaS非法访问"; - - /** - * 白名单地址 - */ - public static final String[] EXCLUDE_URLS = {"/login", "/logout", "/refresh"}; - - /** - * 拦截器优先级 - */ - public static final Integer INTERCEPTOR_ORDER = 10; -} diff --git a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/SaaSInterceptor.java b/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/SaaSInterceptor.java deleted file mode 100644 index a5cdb31..0000000 --- a/cloud-common/cloud-common-saas/src/main/java/com/muyu/common/saas/interceptor/SaaSInterceptor.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.muyu.common.saas.interceptor; - -import com.muyu.common.core.utils.ServletUtils; -import com.muyu.common.core.utils.SpringUtils; -import com.muyu.common.many.datasource.holder.DynamicDataSourceHolder; -import com.muyu.common.many.datasource.role.DynamicDataSource; -import com.muyu.common.saas.constants.SaaSConstant; -import com.muyu.common.saas.exception.SaaSException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.AsyncHandlerInterceptor; - -/** - * @Author: zi run - * @Date 2024/9/18 21:14 - * @Description SAAS拦截器 - */ -public class SaaSInterceptor implements AsyncHandlerInterceptor { - - /** - * 执行之前触发 - * @param request servlet请求 - * @param response servlet响应 - * @param handler 处理器 - * @return 是否放行 - * @throws Exception 最大异常 - */ - @Override - public boolean preHandle(HttpServletRequest request, - HttpServletResponse response, Object handler) throws Exception { - if(! (handler instanceof HandlerMethod)) { - return true; - } - - String SaaSKey = ServletUtils.getHeader(request, SaaSConstant.SAAS_KEY); - if(SaaSKey == null) { - throw new SaaSException(SaaSConstant.SAAS_EXCEPTION_MSG); - } else { - DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class); - if (!dynamicDataSource.hashKey(SaaSKey)){ - throw new SaaSException(SaaSConstant.SAAS_EXCEPTION_MSG); - } - } - DynamicDataSourceHolder.setDynamicDataSourceKey(SaaSKey); - return true; - } - - /** - * 执行之后触发 - * @param request servlet请求 - * @param response servlet响应 - * @param handler 处理器 - * @throws Exception 最大异常 - */ - @Override - public void afterConcurrentHandlingStarted(HttpServletRequest request, - HttpServletResponse response, Object handler) throws Exception { - DynamicDataSourceHolder.removeDynamicDataSourceKey(); - } -} diff --git a/cloud-common/cloud-common-saas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/cloud-common/cloud-common-saas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index ea575f4..70148cf 100644 --- a/cloud-common/cloud-common-saas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/cloud-common/cloud-common-saas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1 +1,3 @@ -com.muyu.common.saas.interceptor.WebMvcSaaSConfig \ No newline at end of file +com.muyu.cloud.common.saas.interceptor.WebMvcSaaSConfig +com.muyu.cloud.common.many.datasource.ManyDataSource +com.muyu.cloud.common.many.datasource.factory.DruidDataSourceFactory diff --git a/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/domain/SysUser.java b/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/domain/SysUser.java index 999b22c..738ee60 100644 --- a/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/domain/SysUser.java +++ b/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/domain/SysUser.java @@ -93,6 +93,10 @@ public class SysUser extends BaseEntity { * 删除标志(0代表存在 2代表删除) */ private String delFlag; + /** + * 数据库名称 + */ + private String databaseName; /** * 最后登录IP diff --git a/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/RemoteUserService.java b/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/RemoteUserService.java index cb968e0..c528ad5 100644 --- a/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/RemoteUserService.java +++ b/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/RemoteUserService.java @@ -9,6 +9,8 @@ import com.muyu.common.system.domain.LoginUser; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 用户服务 * @@ -37,4 +39,12 @@ public interface RemoteUserService { */ @PostMapping("/user/register") public Result registerUserInfo (@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); + + /** + * 获取企业信息 + * @return 用户信息 + */ + @GetMapping("/user/entList") + public Result> entList(); + } diff --git a/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/factory/RemoteUserFallbackFactory.java b/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/factory/RemoteUserFallbackFactory.java index b7f4d60..56e10c3 100644 --- a/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/factory/RemoteUserFallbackFactory.java +++ b/cloud-common/cloud-common-system/src/main/java/com/muyu/common/system/remote/factory/RemoteUserFallbackFactory.java @@ -9,6 +9,8 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; +import java.util.List; + /** * 用户服务降级处理 * @@ -31,6 +33,11 @@ public class RemoteUserFallbackFactory implements FallbackFactory registerUserInfo (SysUser sysUser, String source) { return Result.error("注册用户失败:" + throwable.getMessage()); } + + @Override + public Result> entList() { + return Result.error("获取企业信息失败:" + throwable.getMessage()); + } }; } } diff --git a/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/controller/SysUserController.java b/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/controller/SysUserController.java index bc0b5fe..0cc8c9b 100644 --- a/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/controller/SysUserController.java +++ b/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/controller/SysUserController.java @@ -1,5 +1,6 @@ package com.muyu.system.controller; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.muyu.common.core.domain.Result; import com.muyu.common.core.utils.StringUtils; import com.muyu.common.core.utils.poi.ExcelUtil; @@ -290,4 +291,13 @@ public class SysUserController extends BaseController { public Result deptTree (SysDept dept) { return success(deptService.selectDeptTreeList(dept)); } + + /** + * 获取企业信息 + * @return 用户信息 + */ + @GetMapping("/entList") + public Result> entList() { + return success(userService.entList()); + } } diff --git a/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/SysUserService.java b/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/SysUserService.java index f4c6167..7bd3ecc 100644 --- a/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/SysUserService.java +++ b/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/SysUserService.java @@ -1,6 +1,7 @@ package com.muyu.system.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.muyu.common.core.domain.Result; import com.muyu.common.system.domain.SysUser; import java.util.List; @@ -225,4 +226,10 @@ public interface SysUserService extends IService { * @return 结果 */ public String importUser (List userList, Boolean isUpdateSupport, String operName); + + /** + * 企业信息 + * @return 用户信息 + */ + List entList(); } diff --git a/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/impl/SysUserServiceImpl.java b/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/impl/SysUserServiceImpl.java index c1d3f18..caf56a4 100644 --- a/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/impl/SysUserServiceImpl.java +++ b/cloud-modules/cloud-modules-system/src/main/java/com/muyu/system/service/impl/SysUserServiceImpl.java @@ -1,7 +1,9 @@ package com.muyu.system.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.muyu.common.core.constant.UserConstants; +import com.muyu.common.core.domain.Result; import com.muyu.common.core.exception.ServiceException; import com.muyu.common.core.utils.SpringUtils; import com.muyu.common.core.utils.StringUtils; @@ -500,4 +502,14 @@ public class SysUserServiceImpl extends ServiceImpl impl return successMsg.toString(); } + /** + * 企业信息 + * @return 用户信息 + */ + @Override + public List entList() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.last("where database_name!=''"); + return this.list(queryWrapper); + } } diff --git a/cloud-modules/cloud-modules-system/src/main/resources/mapper/system/SysUserMapper.xml b/cloud-modules/cloud-modules-system/src/main/resources/mapper/system/SysUserMapper.xml index 6f633b7..9b7f925 100644 --- a/cloud-modules/cloud-modules-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/cloud-modules/cloud-modules-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -14,6 +14,7 @@ + @@ -57,6 +58,7 @@ u.password, u.sex, u.status, + u.database_name, u.del_flag, u.login_ip, u.login_date,