fix(): 项目修复配置

master
xinzirun 2024-09-20 11:05:33 +08:00
parent 63d2748be4
commit a258817f3f
25 changed files with 560 additions and 99 deletions

View File

@ -4,10 +4,10 @@ server:
# nacos线上地址
nacos:
addr: 47.116.173.119:8848
addr: 106.15.136.7:8848
user-name: nacos
password: nacos
namespace: six
namespace: xzr
# Spring
spring:
application:

View File

@ -5,7 +5,7 @@ package com.muyu.common.core.exception;
*
* @author muyu
*/
public final class ServiceException extends RuntimeException {
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.muyu</groupId>
<artifactId>cloud-common</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>cloud-common-saas</artifactId>
<description>SaaS公共依赖</description>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 多数据源依赖 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-datasource</artifactId>
</dependency>
<!-- 权限依赖 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-security</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,129 @@
package com.muyu.common.many.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson2.JSON;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.utils.SpringUtils;
import com.muyu.common.many.datasource.constents.DatasourceContent;
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 com.muyu.common.saas.exception.SaaSException;
import com.muyu.common.system.domain.SysUser;
import com.muyu.common.system.remote.RemoteUserService;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
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 implements ApplicationRunner {
@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<EntInfo> dataSourceInfoList(){
RemoteUserService remoteUserService = SpringUtils.getBean(RemoteUserService.class);
Result<List<SysUser>> tableDataInfoResult = remoteUserService.companyList();
if (tableDataInfoResult==null){
throw new SaaSException("saas远调数据源错误");
}
List<SysUser> data = tableDataInfoResult.getData();
if (tableDataInfoResult.getCode() ==Result.SUCCESS && data !=null){
List<EntInfo> list = new ArrayList<>();
for (SysUser row : data) {
list.add(
EntInfo.builder()
.entCode(row.getDatabaseName())
.ip(DatasourceContent.IP)
.port(DatasourceContent.PORT)
.build()
);
}
return list;
}else {
log.error("远调数据源错误,远调数据为:{}", JSON.toJSONString(data));
return null;
}
}
// private List<EntInfo> dataPrimarySourceInfoList(){
// List<EntInfo> list = new ArrayList<>();
// list.add(
// EntInfo.builder()
// .entCode()
// .ip(DatasourceContent.IP)
// .port(DatasourceContent.PORT)
// .build()
// );
// return list;
// }
@Bean
@Primary
public DynamicDataSource dynamicDataSource(DruidDataSourceFactory druidDataSourceFactory) {
// 企业列表 企业CODE端口IP
Map<Object, Object> 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;
}
@Override
public void run(ApplicationArguments args) throws Exception {
DruidDataSourceFactory druidDataSourceFactory = SpringUtils.getBean(DruidDataSourceFactory.class);
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
for (EntInfo entInfo : dataSourceInfoList()) {
DataSourceInfo dataSourceInfo = DataSourceInfo.hostAndPortBuild(
entInfo.getEntCode(), entInfo.getIp(), entInfo.getPort()
);
DruidDataSource druidDataSource = druidDataSourceFactory.create(dataSourceInfo);
dynamicDataSource.put(dataSourceInfo.getKey(), druidDataSource);
log.info("存储数据连接池为key:{}",dataSourceInfo.getKey());
}
}
}

View File

@ -0,0 +1,20 @@
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;
}

View File

@ -0,0 +1,50 @@
package com.muyu.common.many.datasource.domain.model;
import com.muyu.common.core.utils.StringUtils;
import com.muyu.common.many.datasource.constents.DatasourceContent;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: zi run
* @Date 2024/9/18 22:01
* @Description
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DataSourceInfo {
/**
*
*/
private String key;
/**
*
*/
private String url;
/**
*
*/
private String userName;
/**
*
*/
private String password;
public static DataSourceInfo hostAndPortBuild(String key, String host, Integer port){
return DataSourceInfo.builder()
.key(key)
.url(StringUtils.format(DatasourceContent.DATASOURCE_URL, host, port))
.password(DatasourceContent.PASSWORD)
.userName(DatasourceContent.USER_NAME)
.build();
}
}

View File

@ -0,0 +1,40 @@
package com.muyu.common.many.datasource.factory;
import com.alibaba.druid.pool.DruidDataSource;
import com.muyu.common.many.datasource.domain.model.DataSourceInfo;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import java.sql.SQLException;
/**
* @Author: zi run
* @Date 2024/9/18 22:08
* @Description Druid
*/
@Log4j2
@Component
public class DruidDataSourceFactory {
/**
*
* @param dataSourceInfo
* @return
*/
public DruidDataSource create(DataSourceInfo dataSourceInfo) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUrl(dataSourceInfo.getUrl());
druidDataSource.setUsername(dataSourceInfo.getUserName());
druidDataSource.setPassword(dataSourceInfo.getPassword());
druidDataSource.setBreakAfterAcquireFailure(true);
druidDataSource.setConnectionErrorRetryAttempts(0);
try {
druidDataSource.getConnection(2000);
log.info("{} -> 数据源连接成功", dataSourceInfo.getKey());
return druidDataSource;
} catch (SQLException sqlException) {
log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
return null;
}
}
}

View File

@ -0,0 +1,43 @@
package com.muyu.common.many.datasource.holder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
/**
* @Author: zi run
* @Date 2024/9/18 22:08
* @Description
*/
@Slf4j
public class DynamicDataSourceHolder {
/**
*
*/
private static final ThreadLocal<String> DYNAMIC_DATASOURCE_KEY = new ThreadLocal<>();
/**
* /线使
*/
public static void setDynamicDataSourceKey(String key){
log.info("数据源切换为:{}",key);
DYNAMIC_DATASOURCE_KEY.set(key);
}
/**
* 使mater
*/
public static String getDynamicDataSourceKey(){
String key = DYNAMIC_DATASOURCE_KEY.get();
Assert.notNull(key, "请携带数据标识");
return key;
}
/**
*
*/
public static void removeDynamicDataSourceKey(){
log.info("移除数据源:{}",DYNAMIC_DATASOURCE_KEY.get());
DYNAMIC_DATASOURCE_KEY.remove();
}
}

View File

@ -0,0 +1,57 @@
package com.muyu.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 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.util.Map;
/**
* @Author: zi run
* @Date 2024/9/18 22:14
* @Description AddDefineDataSourceaddDefineDynamicDataSource
* targetdatasourcesmapmaptargetdatasourcesmap使
* @DataSource(value = "数据源名称")DynamicDataSourceContextHolder.setContextKey("数据源名称")
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
*
*/
private Map<Object, Object> defineTargetDataSources;
/**
*
* @param key
* @return true false
*/
public boolean hashKey(String key){
return defineTargetDataSources.containsKey(key);
}
/**
*
* @param key
* @param value
*/
public void put(String key, DruidDataSource value) {
defineTargetDataSources.put(key, value);
this.afterPropertiesSet();
}
/**
* 线使
*/
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDynamicDataSourceKey();
}
}

View File

@ -0,0 +1,29 @@
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;
}

View File

@ -0,0 +1,24 @@
package com.muyu.common.saas.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: zi run
* @Date 2024/9/19 14:24
* @Description
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EntInfo {
private String entCode;
private String ip;
private Integer port;
}

View File

@ -0,0 +1,23 @@
package com.muyu.common.saas.exception;
import com.muyu.common.core.exception.ServiceException;
/**
* @Author: zi run
* @Date 2024/9/18 21:28
* @Description SaaS
*/
public class SaaSException extends ServiceException {
public SaaSException (String message, Integer code) {
super(message, code);
}
public SaaSException (String message) {
super(message);
}
public SaaSException () {
super();
}
}

View File

@ -0,0 +1,61 @@
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();
}
}

View File

@ -0,0 +1,33 @@
package com.muyu.common.saas.interceptor;
import com.muyu.common.saas.constants.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
*/
public class WebMvcSaaSConfig implements WebMvcConfigurer {
/**
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getHeaderInterceptor())
.excludePathPatterns(SaaSConstant.EXCLUDE_URLS)
.order(SaaSConstant.INTERCEPTOR_ORDER);
}
/**
*
* @return SAAS
*/
public SaaSInterceptor getHeaderInterceptor() {
return new SaaSInterceptor();
}
}

View File

@ -20,6 +20,7 @@
<module>cloud-common-system</module>
<module>cloud-common-xxl</module>
<module>cloud-common-rabbit</module>
<module>cloud-common-saas</module>
</modules>
<artifactId>cloud-common</artifactId>

View File

@ -50,7 +50,7 @@ public class ValidateCodeServiceImpl implements ValidateCodeService {
CaptchaCodeResp.CaptchaCodeRespBuilder respBuilder = CaptchaCodeResp.builder()
.captchaEnabled(captchaEnabled);
if (!captchaEnabled) {
return Result.success(respBuilder);
return Result.success(respBuilder.build());
}
// 保存验证码信息

View File

@ -4,10 +4,10 @@ server:
# nacos线上地址
nacos:
addr: 47.116.173.119:8848
addr: 106.15.136.7:8848
user-name: nacos
password: nacos
namespace: six
namespace: xzr
# Spring
spring:

View File

@ -4,10 +4,10 @@ server:
# nacos线上地址
nacos:
addr: 47.116.173.119:8848
addr: 106.15.136.7:8848
user-name: nacos
password: nacos
namespace: six
namespace: xzr
# Spring
spring:

View File

@ -65,12 +65,6 @@
<artifactId>cloud-common-api-doc</artifactId>
</dependency>
<!-- XllJob定时任务 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-xxl</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -4,15 +4,13 @@ server:
# nacos线上地址
nacos:
addr: 47.116.173.119:8848
addr: 106.15.136.7:8848
user-name: nacos
password: nacos
namespace: six
namespace: xzr
# Spring
spring:
main:
allow-bean-definition-overriding: true
application:
# 应用名称
name: cloud-gen
@ -47,5 +45,3 @@ spring:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 系统环境Config共享配置
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# xxl-job 配置文件
- application-xxl-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

View File

@ -71,16 +71,6 @@
<artifactId>cloud-common-api-doc</artifactId>
</dependency>
<!-- XllJob定时任务 -->
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-xxl</artifactId>
</dependency>
<dependency>
<groupId>com.muyu</groupId>
<artifactId>cloud-common-rabbit</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -1,53 +0,0 @@
package com.muyu.system.rabbit;
import com.alibaba.fastjson2.JSONObject;
import com.muyu.system.domain.SysConfig;
import jakarta.annotation.PostConstruct;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Log4j2
@RestController
@RequestMapping("/rabbit/test")
public class RabbitTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Bean
public Queue initQueue(){
return new Queue("rabbit.test.init");
}
@RabbitListener(queues = "rabbit.test.init")
public void msg(SysConfig sysConfig){
log.info("消息队列:[{}], 消息内容:[{}]", "rabbit.test.init", JSONObject.toJSONString(sysConfig));
}
@PostConstruct
public void init(){
new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
SysConfig sysConfig = SysConfig.builder()
.configId(1L)
.configKey("ceshi-key")
.configName("测试名称")
.configType("测试类型")
.configValue("测试值")
.build();
rabbitTemplate.convertAndSend("rabbit.test.init",sysConfig);
}).start();
}
}

View File

@ -4,19 +4,12 @@ server:
# nacos线上地址
nacos:
addr: 47.116.173.119:8848
addr: 106.15.136.7:8848
user-name: nacos
password: nacos
namespace: six
# SPRING_AMQP_DESERIALIZATION_TRUST_ALL=true spring.amqp.deserialization.trust.all
# Spring
namespace: xzr
spring:
amqp:
deserialization:
trust:
all: true
main:
allow-bean-definition-overriding: true
application:
# 应用名称
name: cloud-system
@ -51,10 +44,6 @@ spring:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 系统环境Config共享配置
- application-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# xxl-job 配置文件
- application-xxl-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# rabbit 配置文件
- application-rabbit-config-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
logging:
level:
com.muyu.system.mapper: DEBUG

View File

@ -4,10 +4,10 @@ server:
# nacos线上地址
nacos:
addr: 47.116.173.119:8848
addr: 106.15.136.7:8848
user-name: nacos
password: nacos
namespace: six
namespace: xzr
# Spring
spring: