mirror of
https://github.com/thousmile/molly-multi-tenant.git
synced 2025-12-30 04:32:26 +00:00
太难了
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
README.md
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
|
||||
27
README.md
Normal file
27
README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Getting Started
|
||||
|
||||
### Reference Documentation
|
||||
|
||||
For further reference, please consider the following sections:
|
||||
|
||||
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
|
||||
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.0.0/maven-plugin/reference/html/)
|
||||
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.0.0/maven-plugin/reference/html/#build-image)
|
||||
* [Spring Configuration Processor](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#appendix.configuration-metadata.annotation-processor)
|
||||
* [Spring Web](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#web)
|
||||
* [Validation](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#io.validation)
|
||||
* [Spring Data Redis (Access+Driver)](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#data.nosql.redis)
|
||||
* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#using.devtools)
|
||||
* [Spring Boot Actuator](https://docs.spring.io/spring-boot/docs/3.0.0/reference/htmlsingle/#actuator)
|
||||
|
||||
### Guides
|
||||
|
||||
The following guides illustrate how to use some features concretely:
|
||||
|
||||
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
|
||||
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
|
||||
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
|
||||
* [Validation](https://spring.io/guides/gs/validating-form-input/)
|
||||
* [Messaging with Redis](https://spring.io/guides/gs/messaging-redis/)
|
||||
* [Building a RESTful Web Service with Spring Boot Actuator](https://spring.io/guides/gs/actuator-service/)
|
||||
|
||||
24
REST API/全局配置API.http
Normal file
24
REST API/全局配置API.http
Normal file
@@ -0,0 +1,24 @@
|
||||
### 获取全局配置列表
|
||||
GET {{baseUrl}}/sys/config/query
|
||||
Content-Type: application/json
|
||||
#x-tenant-id: {{tenantId}}
|
||||
x-tenant-id: google
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
|
||||
### 获取用户列表
|
||||
GET {{baseUrl}}/pms/user
|
||||
Content-Type: application/json
|
||||
#x-tenant-id: {{tenantId}}
|
||||
x-tenant-id: apple
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
|
||||
|
||||
### 获取局配置数据
|
||||
GET {{baseUrl}}/pms/role
|
||||
Content-Type: application/json
|
||||
# x-tenant-id: {{tenantId}}
|
||||
x-tenant-id: google
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
@@ -10,9 +10,30 @@ Authorization: Bearer {{tokenValue}}
|
||||
"name": "apple",
|
||||
"email": "apple@gmail.com",
|
||||
"linkman": "乔布斯",
|
||||
"contactNumber": "1521332423",
|
||||
"contactNumber": "15999999999",
|
||||
"areaCode": "123123221311",
|
||||
"address": "美国硅谷"
|
||||
"address": "美国硅谷",
|
||||
"templateIds": [
|
||||
1
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
### 创建租户
|
||||
POST {{baseUrl}}/sys/tenant
|
||||
Content-Type: application/json
|
||||
x-tenant-id: {{tenantId}}
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
{
|
||||
"tenantId": "google",
|
||||
"logo": "https://google.com/google.png",
|
||||
"name": "google",
|
||||
"email": "google@gmail.com",
|
||||
"linkman": "拉里·佩奇",
|
||||
"contactNumber": "1521332466",
|
||||
"areaCode": "123123221311",
|
||||
"address": "美国加利福尼亚州圣克拉拉县山景市"
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +55,16 @@ Authorization: Bearer {{tokenValue}}
|
||||
}
|
||||
|
||||
|
||||
|
||||
### 获取租户列表
|
||||
GET {{baseUrl}}/sys/tenant/query
|
||||
Content-Type: application/json
|
||||
#x-tenant-id: {{tenantId}}
|
||||
x-tenant-id: apple
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
|
||||
|
||||
### 获取租户详情
|
||||
GET {{baseUrl}}/sys/tenant/apple
|
||||
Content-Type: application/json
|
||||
|
||||
@@ -16,7 +16,7 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Fi
|
||||
"username": "admin",
|
||||
"password": "123456",
|
||||
"codeKey": "5jXzuwcoUzbtnHNh",
|
||||
"codeText": "tj2yf"
|
||||
"codeText": "ry2oo"
|
||||
}
|
||||
|
||||
> {%
|
||||
@@ -46,18 +46,3 @@ x-tenant-id: {{tenantId}}
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
|
||||
|
||||
### 获取用户列表
|
||||
GET {{baseUrl}}/pms/user
|
||||
Content-Type: application/json
|
||||
x-tenant-id: {{tenantId}}
|
||||
#x-tenant-id: apple
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
|
||||
### 获取用户列表
|
||||
GET {{baseUrl}}/sys/config/query
|
||||
Content-Type: application/json
|
||||
x-tenant-id: {{tenantId}}
|
||||
# x-tenant-id: apple
|
||||
Authorization: Bearer {{tokenValue}}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
<?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>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>molly-admin</artifactId>
|
||||
|
||||
<name>molly-admin</name>
|
||||
|
||||
<description>
|
||||
后台管理
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-perms</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-system</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.xaaef.molly.controller;
|
||||
|
||||
import com.xaaef.molly.common.util.JsonResult;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 中国行政地区 Controller
|
||||
* </p>
|
||||
*
|
||||
* @author Wang Chen Chen
|
||||
* @version 1.0
|
||||
* @date 2021/7/5 16:37
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/china/area")
|
||||
public class ChinaAreaController {
|
||||
|
||||
@GetMapping()
|
||||
public JsonResult<String> findById() {
|
||||
return JsonResult.success();
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/hello")
|
||||
public JsonResult<String> hello() {
|
||||
return JsonResult.success();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.xaaef.molly.common;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 测试类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:26
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class CommonTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
<?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>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>molly-common</artifactId>
|
||||
|
||||
<name>molly-common</name>
|
||||
|
||||
<description>
|
||||
通用模块,核心工具,函数
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-jwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-captcha</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.annotation</groupId>
|
||||
<artifactId>jakarta.annotation-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.msgpack</groupId>
|
||||
<artifactId>msgpack-core</artifactId>
|
||||
<version>${msgpack.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.msgpack</groupId>
|
||||
<artifactId>jackson-dataformat-msgpack</artifactId>
|
||||
<version>${msgpack.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,87 +0,0 @@
|
||||
package com.xaaef.molly.common.consts;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 全局配置文件 key
|
||||
* </p>
|
||||
*
|
||||
* @author Wang Chen Chen
|
||||
* @version 1.0.1
|
||||
* @date 2021/7/16 15:15
|
||||
*/
|
||||
|
||||
public class ConfigName {
|
||||
|
||||
/**
|
||||
* 用户默认密码
|
||||
*/
|
||||
public static final String REDIS_CACHE_KEY = "sys_config_cache";
|
||||
|
||||
|
||||
/**
|
||||
* 用户默认密码
|
||||
*/
|
||||
public static final String USER_DEFAULT_PASSWORD = "user_default_password";
|
||||
|
||||
|
||||
/**
|
||||
* 租户默认logo
|
||||
*/
|
||||
public static final String TENANT_DEFAULT_LOGO = "tenant_default_logo";
|
||||
|
||||
|
||||
/**
|
||||
* 租户默认角色名称
|
||||
*/
|
||||
public static final String TENANT_DEFAULT_ROLE_NAME = "tenant_default_role_name";
|
||||
|
||||
|
||||
/**
|
||||
* [旧的] 获取法定节假日的接口
|
||||
*/
|
||||
public static final String LEGAL_HOLIDAY_URL = "legal_holiday_url";
|
||||
|
||||
|
||||
/**
|
||||
* 获取法定节假日的接口
|
||||
*/
|
||||
public static final String GET_HOLIDAY_URL = "get_holiday_url";
|
||||
|
||||
|
||||
/**
|
||||
* 顶级 租户ID
|
||||
*/
|
||||
public static final String SYS_TENANT_ID = "root_tenant_id";
|
||||
|
||||
|
||||
/**
|
||||
* 引导灯RGB初始化配置
|
||||
*/
|
||||
public static final String GUIDE_LIGHT_RGB = "guide_light_rgb";
|
||||
|
||||
|
||||
/**
|
||||
* 日期模式 初始化配置
|
||||
*/
|
||||
public static final String INIT_DATE_MODE = "init_date_mode";
|
||||
|
||||
|
||||
/**
|
||||
* 区域 点位最大数量
|
||||
*/
|
||||
public static final String AREA_POINT_MAX_NUMBER = "area_point_max_number";
|
||||
|
||||
|
||||
/**
|
||||
* 产品制造商
|
||||
*/
|
||||
public static final String MANUFACTURER = "manufacturer";
|
||||
|
||||
|
||||
/**
|
||||
* 碳排放的 默认 0.785
|
||||
*/
|
||||
public static final String CARBON_EMISSION = "carbon_emission";
|
||||
|
||||
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package com.xaaef.molly.common.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.msgpack.jackson.dataformat.MessagePackFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* jackson Json 工具类
|
||||
* </p>
|
||||
*
|
||||
* @author Wang Chen Chen <932560435@qq.com>
|
||||
* @version 2.0
|
||||
* @date 2019/4/18 11:45
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class MsgpackUtils {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper(new MessagePackFactory())
|
||||
.registerModules(new Jdk8Module(), new JavaTimeModule())
|
||||
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
|
||||
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
|
||||
public static ObjectMapper getMapper() {
|
||||
return MAPPER;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 对象 转换成 二进制
|
||||
*
|
||||
* @param data
|
||||
* @return java.util.List<T>
|
||||
* @author Wang Chen Chen <932560435@qq.com>
|
||||
* @date 2019/4/18 15:26
|
||||
*/
|
||||
public static byte[] toBytes(Object data) {
|
||||
try {
|
||||
return MAPPER.writeValueAsBytes(data);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 二进制 结果集转化为对象
|
||||
*
|
||||
* @param data
|
||||
* @param beanType
|
||||
* @return java.util.List<T>
|
||||
* @author Wang Chen Chen <932560435@qq.com>
|
||||
* @date 2019/4/18 15:26
|
||||
*/
|
||||
public static <T> T toPojo(byte[] data, Class<T> beanType) {
|
||||
try {
|
||||
return MAPPER.readValue(data, 0, data.length, beanType);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将 二进制 数据转换成 pojo 对象 list
|
||||
*
|
||||
* @param data
|
||||
* @param beanType
|
||||
* @return java.util.List<T>
|
||||
* @author Wang Chen Chen <932560435@qq.com>
|
||||
* @date 2019/4/18 15:26
|
||||
*/
|
||||
public static <T> List<T> toListPojo(byte[] data, Class<T> beanType) {
|
||||
try {
|
||||
return MAPPER.readValue(data, MAPPER.getTypeFactory().constructCollectionType(ArrayList.class, beanType));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将 二进制 数据转换成 Map
|
||||
*
|
||||
* @param data
|
||||
* @param keyType
|
||||
* @param valueType
|
||||
* @return java.util.List<T>
|
||||
* @author Wang Chen Chen <932560435@qq.com>
|
||||
* @date 2019/4/18 15:26
|
||||
*/
|
||||
public static <K, V> Map<K, V> toMap(byte[] data, Class<K> keyType, Class<V> valueType) {
|
||||
try {
|
||||
return MAPPER.readValue(data, MAPPER.getTypeFactory().constructMapType(HashMap.class, keyType, valueType));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将二进制数据转换成 pojo对象list
|
||||
*
|
||||
* @param data
|
||||
* @param keyType
|
||||
* @param valueType
|
||||
* @return java.util.List<T>
|
||||
* @author Wang Chen Chen <932560435@qq.com>
|
||||
* @date 2019/4/18 15:26
|
||||
*/
|
||||
public static <K, V> List<Map<K, V>> toListMap(byte[] data, Class<K> keyType, Class<V> valueType) {
|
||||
try {
|
||||
return MAPPER.readValue(
|
||||
data,
|
||||
MAPPER.getTypeFactory().constructCollectionType(ArrayList.class,
|
||||
MAPPER.getTypeFactory().constructMapType(HashMap.class, keyType, valueType)
|
||||
)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package com.xaaef.molly.common;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.jwt.JWT;
|
||||
import cn.hutool.jwt.JWTUtil;
|
||||
import com.xaaef.molly.common.domain.RectPoint;
|
||||
import com.xaaef.molly.common.util.RectRangeUtils;
|
||||
import com.xaaef.molly.common.util.ServletUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 测试类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:26
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class CommonTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
var ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0";
|
||||
var userAgent = ServletUtils.getUserAgent(ua);
|
||||
var browser = StrUtil.format("{} {}", userAgent.getBrowser(), userAgent.getVersion());
|
||||
System.out.println(browser);
|
||||
var os = StrUtil.format("{} {}", userAgent.getPlatform(), Objects.requireNonNullElse(userAgent.getOsVersion(), ""));
|
||||
System.out.println(os);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
// 需要检测的点位
|
||||
var points = List.of(
|
||||
new RectPoint<>(618.33D, 334.99D, 1L),
|
||||
new RectPoint<>(265D, 653D, 2L),
|
||||
new RectPoint<>(406.25D, 501.25D, 2L)
|
||||
);
|
||||
|
||||
var topLeft = new RectPoint<Long>(289D, 209D);
|
||||
|
||||
var bottomRight = new RectPoint<Long>(1029D, 549D);
|
||||
|
||||
points.forEach(target -> {
|
||||
boolean a = RectRangeUtils.isIn(target, topLeft, bottomRight);
|
||||
System.out.printf("%s => %b\r\n", target.getId(), a);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
int i = (19 / 100) + 1;
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void test4() {
|
||||
var jwt = JWTUtil.parseToken("654wq1e45qw");
|
||||
var loginId = jwt.getPayloads().getStr(JWT.SUBJECT);
|
||||
System.out.println(loginId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
<?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>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>molly-core</artifactId>
|
||||
|
||||
<name>molly-core</name>
|
||||
|
||||
<description>
|
||||
核心模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,126 +0,0 @@
|
||||
package com.xaaef.molly.core.tenant;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.CallbackException;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||
import org.hibernate.type.Type;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.INTERCEPTOR;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/12 18:25
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class CustomInterceptor implements Interceptor, HibernatePropertiesCustomizer, java.io.Serializable {
|
||||
|
||||
@Override
|
||||
public boolean onLoad(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
|
||||
log.info("onLoad...");
|
||||
return Interceptor.super.onLoad(entity, id, state, propertyNames, types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFlushDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException {
|
||||
log.info("onFlushDirty...");
|
||||
return Interceptor.super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
|
||||
log.info("onSave...");
|
||||
return Interceptor.super.onSave(entity, id, state, propertyNames, types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDelete(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException {
|
||||
log.info("onDelete...");
|
||||
Interceptor.super.onDelete(entity, id, state, propertyNames, types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCollectionRecreate(Object collection, Object key) throws CallbackException {
|
||||
log.info("onCollectionRecreate...");
|
||||
Interceptor.super.onCollectionRecreate(collection, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCollectionRemove(Object collection, Object key) throws CallbackException {
|
||||
log.info("onCollectionRemove...");
|
||||
Interceptor.super.onCollectionRemove(collection, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCollectionUpdate(Object collection, Object key) throws CallbackException {
|
||||
log.info("onCollectionUpdate...");
|
||||
Interceptor.super.onCollectionUpdate(collection, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preFlush(Iterator<Object> entities) throws CallbackException {
|
||||
log.info("preFlush...");
|
||||
Interceptor.super.preFlush(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFlush(Iterator<Object> entities) throws CallbackException {
|
||||
log.info("postFlush...");
|
||||
Interceptor.super.postFlush(entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isTransient(Object entity) {
|
||||
log.info("isTransient...");
|
||||
return Interceptor.super.isTransient(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] findDirty(Object entity, Object id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
|
||||
log.info("findDirty...");
|
||||
return Interceptor.super.findDirty(entity, id, currentState, previousState, propertyNames, types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiate(String entityName, EntityRepresentationStrategy representationStrategy, Object id) throws CallbackException {
|
||||
log.info("instantiate...");
|
||||
return Interceptor.super.instantiate(entityName, representationStrategy, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiate(String entityName, RepresentationMode representationMode, Object id) throws CallbackException {
|
||||
log.info("instantiate...");
|
||||
return Interceptor.super.instantiate(entityName, representationMode, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityName(Object object) throws CallbackException {
|
||||
log.info("getEntityName...");
|
||||
return Interceptor.super.getEntityName(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getEntity(String entityName, Object id) throws CallbackException {
|
||||
log.info("getEntity...");
|
||||
return Interceptor.super.getEntity(entityName, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(Map<String, Object> hibernateProperties) {
|
||||
hibernateProperties.put(INTERCEPTOR, this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.xaaef.molly.core;
|
||||
|
||||
import com.xaaef.molly.core.auth.jwt.JwtSecurityUtils;
|
||||
import com.xaaef.molly.core.tenant.enums.DbStyle;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 测试类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:26
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class CoreTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
String admin = JwtSecurityUtils.encryptPassword("admin");
|
||||
System.out.println(admin);
|
||||
|
||||
String apple = JwtSecurityUtils.encryptPassword("apple");
|
||||
System.out.println(apple);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
int i = 2 % 100;
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?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>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>molly-perms</artifactId>
|
||||
|
||||
<name>molly-perms</name>
|
||||
|
||||
<description>
|
||||
权限管理模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.xaaef.molly.perms.repository;
|
||||
|
||||
import com.xaaef.molly.perms.entity.SysUser;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface SysUserRepository extends JpaRepository<SysUser, Long> {
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.xaaef.molly.perms.repository;
|
||||
|
||||
import com.xaaef.molly.perms.entity.SysUserSocial;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface SysUserSocialRepository extends JpaRepository<SysUserSocial, Long> {
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.xaaef.molly.common;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 测试类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:26
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class CommonTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?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>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>molly-quartz</artifactId>
|
||||
|
||||
<name>molly-quartz</name>
|
||||
|
||||
<description>
|
||||
quartz 定时任务
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.xaaef.molly.common;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 测试类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:26
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
public class CommonTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?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>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<version>1.0.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>molly-system</artifactId>
|
||||
|
||||
<name>molly-system</name>
|
||||
|
||||
<description>
|
||||
系统模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.xaaef.molly.system.controller;
|
||||
|
||||
|
||||
import com.xaaef.molly.common.util.JsonResult;
|
||||
import com.xaaef.molly.system.entity.SysTenant;
|
||||
import com.xaaef.molly.system.service.SysTenantService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/sys/tenant")
|
||||
public class TenantController {
|
||||
|
||||
public final SysTenantService baseService;
|
||||
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public JsonResult<SysTenant> findById(@PathVariable("id") String id) {
|
||||
return JsonResult.success(baseService.getById(id));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/exist/{id}")
|
||||
public JsonResult<Boolean> existById(@PathVariable("id") String id) {
|
||||
return JsonResult.success(baseService.existsById(id));
|
||||
}
|
||||
|
||||
|
||||
@PostMapping
|
||||
public JsonResult<SysTenant> save(@RequestBody SysTenant tenant) {
|
||||
return JsonResult.success(
|
||||
baseService.save(tenant)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@PutMapping
|
||||
public JsonResult<SysTenant> updateById(@RequestBody SysTenant tenant) {
|
||||
return JsonResult.success(
|
||||
baseService.updateById(tenant)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public JsonResult<String> deleteById(@PathVariable("id") String id) {
|
||||
baseService.deleteById(id);
|
||||
return JsonResult.success();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.xaaef.molly.system.repository;
|
||||
|
||||
import com.xaaef.molly.system.entity.ChinaArea;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface ChinaAreaRepository extends JpaRepository<ChinaArea, Long> {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.xaaef.molly.system.repository;
|
||||
|
||||
import com.xaaef.molly.system.entity.SysDictData;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
|
||||
public interface SysDictDataRepository extends JpaRepository<SysDictData, Long> {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.xaaef.molly.system.repository;
|
||||
|
||||
import com.xaaef.molly.system.entity.SysDictType;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
|
||||
|
||||
public interface SysDictTypeRepository extends JpaRepository<SysDictType, Long> {
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.xaaef.molly.system.repository;
|
||||
|
||||
import com.xaaef.molly.system.entity.SysMenu;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
|
||||
|
||||
public interface SysMenuRepository extends JpaRepository<SysMenu, Long> {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.xaaef.molly.system.service;
|
||||
|
||||
import com.xaaef.molly.system.entity.ChinaArea;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ChinaAreaService {
|
||||
|
||||
|
||||
Optional<ChinaArea> findById(Long id);
|
||||
|
||||
|
||||
ChinaArea save(ChinaArea entity);
|
||||
|
||||
|
||||
Collection<ChinaArea> saveBatch(Collection<ChinaArea> entity);
|
||||
|
||||
|
||||
ChinaArea updateById(ChinaArea entity);
|
||||
|
||||
|
||||
Collection<ChinaArea> updateByIdBatch(Collection<ChinaArea> arr);
|
||||
|
||||
|
||||
void deleteById(Long id);
|
||||
|
||||
|
||||
void deleteAllById(Collection<Long> ids);
|
||||
|
||||
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package com.xaaef.molly.system.service.impl;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.xaaef.molly.core.tenant.DataSourceManager;
|
||||
import com.xaaef.molly.core.tenant.base.service.impl.BaseServiceImpl;
|
||||
import com.xaaef.molly.core.tenant.service.MultiTenantManager;
|
||||
import com.xaaef.molly.system.entity.SysTenant;
|
||||
import com.xaaef.molly.system.repository.SysTenantRepository;
|
||||
import com.xaaef.molly.system.service.SysConfigService;
|
||||
import com.xaaef.molly.system.service.SysTenantService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.xaaef.molly.common.consts.ConfigName.TENANT_DEFAULT_LOGO;
|
||||
import static com.xaaef.molly.core.auth.jwt.JwtSecurityUtils.isAdminUser;
|
||||
import static com.xaaef.molly.core.auth.jwt.JwtSecurityUtils.isMasterUser;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 15:36
|
||||
*/
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysTenantServiceImpl extends BaseServiceImpl<SysTenantRepository, SysTenant, String>
|
||||
implements SysTenantService {
|
||||
|
||||
private final MultiTenantManager tenantManager;
|
||||
|
||||
private final DataSourceManager dataSourceManager;
|
||||
|
||||
private final SysConfigService configService;
|
||||
|
||||
|
||||
/**
|
||||
* uuid
|
||||
*/
|
||||
public static String getUUIDSuffix() {
|
||||
return IdUtil.fastUUID().split("-")[4];
|
||||
}
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public SysTenant save(SysTenant entity) {
|
||||
if (!isMasterUser()) {
|
||||
throw new RuntimeException("只有系统用户,才能创建租户!");
|
||||
}
|
||||
if (StringUtils.isBlank(entity.getTenantId())) {
|
||||
do {
|
||||
entity.setTenantId(getUUIDSuffix());
|
||||
}
|
||||
while (tenantManager.existById(entity.getTenantId()));
|
||||
} else {
|
||||
if (tenantManager.existById(entity.getTenantId())) {
|
||||
throw new RuntimeException(String.format("租户ID %s 已经存在了!", entity.getTenantId()));
|
||||
}
|
||||
}
|
||||
if (entity.getExpired() == null) {
|
||||
entity.setExpired(LocalDateTime.now().plusYears(10));
|
||||
}
|
||||
if (entity.getStatus() == null) {
|
||||
entity.setStatus((byte) 0);
|
||||
}
|
||||
if (entity.getLogo() == null) {
|
||||
var defaultLogoPath = configService.findValueByKey(TENANT_DEFAULT_LOGO);
|
||||
entity.setLogo(defaultLogoPath);
|
||||
}
|
||||
var save = super.save(entity);
|
||||
// 将 新创建的 租户ID 保存到 redis 中
|
||||
tenantManager.addTenantId(entity.getTenantId());
|
||||
// 新创建的 租户 创建表结构
|
||||
dataSourceManager.createTable(entity.getTenantId());
|
||||
return save;
|
||||
}
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void deleteById(String id) {
|
||||
if (isMasterUser() && isAdminUser()) {
|
||||
if (!existsById(id)) {
|
||||
return;
|
||||
}
|
||||
super.deleteById(id);
|
||||
tenantManager.removeTenantId(id);
|
||||
dataSourceManager.deleteTable(id);
|
||||
} else {
|
||||
throw new RuntimeException("非系统管理员,无法删除租户!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.xaaef.molly.system;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 测试类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:26
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
public class SystemTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
102
pom.xml
102
pom.xml
@@ -2,7 +2,7 @@
|
||||
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<packaging>jar</packaging>
|
||||
<groupId>com.xaaef.molly</groupId>
|
||||
<artifactId>molly-multi-tenant</artifactId>
|
||||
<version>1.0.1</version>
|
||||
@@ -12,15 +12,6 @@
|
||||
molly jpa multi tenant sass platform
|
||||
</description>
|
||||
|
||||
<modules>
|
||||
<module>molly-common</module>
|
||||
<module>molly-core</module>
|
||||
<module>molly-perms</module>
|
||||
<module>molly-quartz</module>
|
||||
<module>molly-system</module>
|
||||
<module>molly-admin</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
@@ -30,6 +21,7 @@
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<hutool.version>5.8.10</hutool.version>
|
||||
<knife4j.version>3.0.3</knife4j.version>
|
||||
<msgpack.version>0.9.2</msgpack.version>
|
||||
|
||||
<spring-boot.version>3.0.0</spring-boot.version>
|
||||
@@ -43,11 +35,89 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-jwt</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-captcha</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--引入Knife4j的官方start包,Swagger2基于Springfox2.10.5项目-->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-json</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
@@ -108,6 +178,18 @@
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@@ -2,24 +2,29 @@ package com.xaaef.molly;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* spring boot jpa 多租户 启动类
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/9 10:49
|
||||
* @version 1.0.1
|
||||
* @date 2021/10/14 14:24
|
||||
*/
|
||||
|
||||
|
||||
@EnableAsync
|
||||
@EnableCaching
|
||||
@EnableScheduling
|
||||
@SpringBootApplication
|
||||
public class MollyAdminApplication {
|
||||
public class MollyApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MollyAdminApplication.class, args);
|
||||
SpringApplication.run(MollyApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
46
src/main/java/com/xaaef/molly/common/consts/ConfigName.java
Normal file
46
src/main/java/com/xaaef/molly/common/consts/ConfigName.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.xaaef.molly.common.consts;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 全局配置文件 key
|
||||
* </p>
|
||||
*
|
||||
* @author Wang Chen Chen
|
||||
* @version 1.0.1
|
||||
* @date 2021/7/16 15:15
|
||||
*/
|
||||
|
||||
public class ConfigName {
|
||||
|
||||
/**
|
||||
* 系统配置
|
||||
*/
|
||||
public static final String REDIS_CACHE_KEY = "sys_config_cache";
|
||||
|
||||
|
||||
/**
|
||||
* 用户默认密码
|
||||
*/
|
||||
public static final String USER_DEFAULT_PASSWORD = "user_default_password";
|
||||
|
||||
|
||||
/**
|
||||
* 租户默认logo
|
||||
*/
|
||||
public static final String TENANT_DEFAULT_LOGO = "default_tenant_logo";
|
||||
|
||||
|
||||
/**
|
||||
* 租户默认角色名称
|
||||
*/
|
||||
public static final String TENANT_DEFAULT_ROLE_NAME = "default_role_name";
|
||||
|
||||
|
||||
/**
|
||||
* 获取法定节假日的接口
|
||||
*/
|
||||
public static final String GET_HOLIDAY_URL = "get_holiday_url";
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -20,19 +20,19 @@ import lombok.ToString;
|
||||
@ToString
|
||||
public enum GenderType {
|
||||
|
||||
FEMALE(0, "女"),
|
||||
FEMALE((byte) 0, "女"),
|
||||
|
||||
MALE(1, "男"),
|
||||
MALE((byte) 1, "男"),
|
||||
|
||||
UNKNOWN(2, "未知");
|
||||
UNKNOWN((byte) 2, "未知");
|
||||
|
||||
GenderType(int code, String description) {
|
||||
GenderType(byte code, String description) {
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static GenderType get(int code) {
|
||||
public static GenderType get(byte code) {
|
||||
if (FEMALE.code == code) {
|
||||
return FEMALE;
|
||||
} else if (MALE.code == code) {
|
||||
@@ -43,7 +43,7 @@ public enum GenderType {
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
private final int code;
|
||||
private final byte code;
|
||||
|
||||
private final String description;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.xaaef.molly.core.tenant;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.xaaef.molly.core.auth.jwt.JwtSecurityUtils;
|
||||
import com.xaaef.molly.core.tenant.props.MultiTenantProperties;
|
||||
import com.xaaef.molly.core.tenant.util.TenantUtils;
|
||||
@@ -37,7 +38,7 @@ public class CustomTenantResolver implements CurrentTenantIdentifierResolver,
|
||||
|
||||
@Override
|
||||
public String resolveCurrentTenantIdentifier() {
|
||||
log.info("resolveCurrentTenantIdentifier {} ................", TenantUtils.getTenantId());
|
||||
log.debug("2.CustomTenantResolver.resolveCurrentTenantIdentifier(): {} ", TenantUtils.getTenantId());
|
||||
// 如果当前是 master 库,直接放过。任何用户都可以进入 master 库,读取一些公共的数据,如: 全局配置,权限菜单
|
||||
if (StringUtils.equals(props.getDefaultTenantId(), TenantUtils.getTenantId())) {
|
||||
return TenantUtils.getTenantId();
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.xaaef.molly.core.tenant;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 所有租户的 EntityManager
|
||||
* 比如: 全局配置,字典集合,之类的表,使用的是公有的数据库
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/13 11:37
|
||||
*/
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
public class DataSourceConfig {
|
||||
|
||||
private final DataSourceProperties dataSourceProperties;
|
||||
|
||||
|
||||
@Primary
|
||||
@Bean(name = "multiTenantDataSource")
|
||||
public DataSource multiTenantDataSource() {
|
||||
return dataSourceProperties.initializeDataSourceBuilder().build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Bean(name = "commonTenantDataSource")
|
||||
public DataSource commonTenantDataSource() {
|
||||
return dataSourceProperties.initializeDataSourceBuilder().build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import com.xaaef.molly.core.tenant.props.MultiTenantProperties;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public interface DataSourceManager {
|
||||
public interface DatabaseManager {
|
||||
|
||||
default String getOldDbName(String url) {
|
||||
var startInx = url.lastIndexOf("?");
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.xaaef.molly.core.tenant;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 所有租户的 EntityManager
|
||||
* 比如: 全局配置,字典集合,之类的表,使用的是公有的数据库
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/13 11:37
|
||||
*/
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableTransactionManagement
|
||||
@EnableJpaRepositories(
|
||||
basePackages = {
|
||||
"com.xaaef.molly.system.repository",
|
||||
},
|
||||
entityManagerFactoryRef = "commonTenantEntityManagerFactory",
|
||||
transactionManagerRef = "commonTenantTransactionManager")
|
||||
public class JpaCommonTenantConfig {
|
||||
|
||||
private final JpaProperties jpaProperties;
|
||||
|
||||
private final HibernateProperties hibernateProperties;
|
||||
|
||||
private final List<HibernatePropertiesCustomizer> customizers;
|
||||
|
||||
private Map<String, Object> getVendorProperties() {
|
||||
// 公共的库,是不需要做租户拦截的
|
||||
customizers.removeIf(r -> r instanceof CurrentTenantIdentifierResolver);
|
||||
customizers.removeIf(r -> r instanceof MultiTenantConnectionProvider);
|
||||
var hibernateSettings = new HibernateSettings();
|
||||
if (customizers.size() > 0) {
|
||||
hibernateSettings.hibernatePropertiesCustomizers(this.customizers);
|
||||
}
|
||||
log.info("JpaCommonTenantConfig............");
|
||||
return new LinkedHashMap<>(
|
||||
this.hibernateProperties
|
||||
.determineHibernateProperties(
|
||||
jpaProperties.getProperties(),
|
||||
hibernateSettings
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "commonTenantEntityManagerFactory")
|
||||
public LocalContainerEntityManagerFactoryBean commonTenantEntityManagerFactory(
|
||||
@Qualifier("commonTenantDataSource") DataSource dataSource, EntityManagerFactoryBuilder builder) {
|
||||
return builder
|
||||
// 设置数据源
|
||||
.dataSource(dataSource)
|
||||
// 设置jpa配置
|
||||
.properties(getVendorProperties())
|
||||
// 设置实体包名
|
||||
.packages(
|
||||
"com.xaaef.molly.system.entity"
|
||||
)
|
||||
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
|
||||
.persistenceUnit("commonTenantPersistenceUnit")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "commonTenantEntityManager")
|
||||
public EntityManager commonTenantEntityManager(
|
||||
@Qualifier("commonTenantEntityManagerFactory") EntityManagerFactory factory) {
|
||||
return factory.createEntityManager();
|
||||
}
|
||||
|
||||
|
||||
@Bean(name = "commonTenantTransactionManager")
|
||||
public PlatformTransactionManager commonTenantTransactionManager(
|
||||
@Qualifier("commonTenantEntityManagerFactory") EntityManagerFactory factory) {
|
||||
return new JpaTransactionManager(factory);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.xaaef.molly.core.tenant;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 多租户的 EntityManager
|
||||
* 比如: 用户,角色,部门。等. 每个租户独有的数据
|
||||
* </p>
|
||||
*
|
||||
* @author WangChenChen
|
||||
* @version 1.1
|
||||
* @date 2022/12/13 11:37
|
||||
*/
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableTransactionManagement
|
||||
@EnableJpaRepositories(
|
||||
basePackages = {
|
||||
"com.xaaef.molly.perms.repository",
|
||||
},
|
||||
entityManagerFactoryRef = "multiTenantEntityManagerFactory",
|
||||
transactionManagerRef = "multiTenantTransactionManager")
|
||||
public class JpaMultiTenantConfig {
|
||||
|
||||
private final JpaProperties jpaProperties;
|
||||
|
||||
private final HibernateProperties hibernateProperties;
|
||||
|
||||
private final List<HibernatePropertiesCustomizer> customizers;
|
||||
|
||||
private Map<String, Object> getVendorProperties() {
|
||||
var hibernateSettings = new HibernateSettings();
|
||||
if (customizers.size() > 0) {
|
||||
hibernateSettings.hibernatePropertiesCustomizers(this.customizers);
|
||||
}
|
||||
log.info("JpaMultiTenantConfig............");
|
||||
return new LinkedHashMap<>(
|
||||
this.hibernateProperties
|
||||
.determineHibernateProperties(
|
||||
jpaProperties.getProperties(),
|
||||
hibernateSettings
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Primary
|
||||
@Bean(name = "multiTenantEntityManagerFactory")
|
||||
public LocalContainerEntityManagerFactoryBean multiTenantEntityManagerFactory(
|
||||
@Qualifier("multiTenantDataSource") DataSource dataSource, EntityManagerFactoryBuilder builder) {
|
||||
return builder
|
||||
// 设置数据源
|
||||
.dataSource(dataSource)
|
||||
// 设置jpa配置
|
||||
.properties(getVendorProperties())
|
||||
// 设置实体包名
|
||||
.packages(
|
||||
"com.xaaef.molly.perms.entity"
|
||||
)
|
||||
// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
|
||||
.persistenceUnit("multiTenantPersistenceUnit")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Primary
|
||||
@Bean(name = "multiTenantEntityManager")
|
||||
public EntityManager multiTenantEntityManager(
|
||||
@Qualifier("multiTenantEntityManagerFactory") EntityManagerFactory factory) {
|
||||
return factory.createEntityManager();
|
||||
}
|
||||
|
||||
|
||||
@Primary
|
||||
@Bean(name = "multiTenantTransactionManager")
|
||||
public PlatformTransactionManager multiTenantTransactionManager(
|
||||
@Qualifier("multiTenantEntityManagerFactory") EntityManagerFactory factory) {
|
||||
return new JpaTransactionManager(factory);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -61,6 +61,7 @@ public class MultiTenantTenantIdInterceptor implements HandlerInterceptor {
|
||||
return false;
|
||||
}
|
||||
TenantUtils.setTenantId(tenantId);
|
||||
log.debug("1.MultiTenantTenantIdInterceptor.preHandle(): {} ", tenantId);
|
||||
return HandlerInterceptor.super.preHandle(request, response, handler);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import jakarta.persistence.Column;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedBy;
|
||||
@@ -23,6 +24,7 @@ import java.time.LocalDateTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@MappedSuperclass
|
||||
public class BaseEntity implements java.io.Serializable {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class BaseServiceImpl<R extends JpaRepository<T, ID>, T extends BaseEntit
|
||||
/**
|
||||
* 插入时 填写
|
||||
*/
|
||||
protected void saveFill(T entity) {
|
||||
protected <F extends BaseEntity> void saveFill(F entity) {
|
||||
var userId = JwtSecurityUtils.getLoginUser().getUserId();
|
||||
if (null == entity.getCreateUser() && userId != null) {
|
||||
entity.setCreateUser(userId);
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.xaaef.molly.core.tenant.database;
|
||||
|
||||
import com.xaaef.molly.core.tenant.DataSourceManager;
|
||||
import com.xaaef.molly.core.tenant.DatabaseManager;
|
||||
import com.xaaef.molly.core.tenant.props.MultiTenantProperties;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
import liquibase.Liquibase;
|
||||
@@ -15,7 +15,6 @@ import org.springframework.stereotype.Component;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -35,7 +34,7 @@ import static org.springframework.util.ResourceUtils.CLASSPATH_URL_PREFIX;
|
||||
@Slf4j
|
||||
@Component
|
||||
@ConditionalOnProperty(prefix = "multi.tenant", name = "db-style", havingValue = "DataBase")
|
||||
public class DatabaseDataSourceManager implements DataSourceManager {
|
||||
public class DatabaseDataSourceManager implements DatabaseManager {
|
||||
|
||||
private static final Map<String, DataSource> DATA_SOURCE_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.xaaef.molly.core.tenant.database;
|
||||
|
||||
import com.xaaef.molly.core.tenant.DataSourceManager;
|
||||
import com.xaaef.molly.core.tenant.DatabaseManager;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -39,19 +38,19 @@ public class DatabaseTenantProvider extends AbstractDataSourceBasedMultiTenantCo
|
||||
log.info("multi tenant use DataBase .....");
|
||||
}
|
||||
|
||||
private final DataSourceManager dataSourceManager;
|
||||
private final DatabaseManager databaseManager;
|
||||
|
||||
|
||||
@Override
|
||||
protected DataSource selectAnyDataSource() {
|
||||
return dataSourceManager.getDefaultDataSource();
|
||||
return databaseManager.getDefaultDataSource();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected DataSource selectDataSource(String tenantId) {
|
||||
if (StringUtils.isNotBlank(tenantId)) {
|
||||
return dataSourceManager.getDataSource(tenantId);
|
||||
return databaseManager.getDataSource(tenantId);
|
||||
} else {
|
||||
return this.selectAnyDataSource();
|
||||
}
|
||||
@@ -1,25 +1,19 @@
|
||||
package com.xaaef.molly.core.tenant.schema;
|
||||
|
||||
import com.xaaef.molly.core.tenant.DataSourceManager;
|
||||
import com.xaaef.molly.core.tenant.DatabaseManager;
|
||||
import com.xaaef.molly.core.tenant.props.MultiTenantProperties;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.database.jvm.JdbcConnection;
|
||||
import liquibase.resource.ClassLoaderResourceAccessor;
|
||||
import liquibase.resource.DirectoryResourceAccessor;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
|
||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.springframework.util.ResourceUtils.CLASSPATH_URL_PREFIX;
|
||||
|
||||
@@ -38,7 +32,7 @@ import static org.springframework.util.ResourceUtils.CLASSPATH_URL_PREFIX;
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
@ConditionalOnProperty(prefix = "multi.tenant", name = "db-style", havingValue = "Schema")
|
||||
public class SchemaDataSourceManager implements DataSourceManager {
|
||||
public class SchemaDataSourceManager implements DatabaseManager {
|
||||
|
||||
// 默认租户的数据源
|
||||
private final DataSource dataSource;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user