Compare commits
105 Commits
Author | SHA1 | Date |
---|---|---|
|
214962ff9a | |
|
08fc9623bc | |
|
ee6da76129 | |
|
89c2fc33fa | |
|
1e86779560 | |
|
5c4e0cde3e | |
|
4f0fa2e95c | |
|
b13931317c | |
|
dcd9ce68df | |
|
65d7fb3de1 | |
|
a993b30e6e | |
|
92c2d7b11b | |
|
75b6097fed | |
|
c86f2732b0 | |
|
553d5933ed | |
|
ff98f1cc1b | |
|
1468206f1d | |
|
47222f5f68 | |
|
0c8a13439f | |
|
492be37314 | |
|
5a0f5e28d2 | |
|
e1d45db36e | |
|
e50219f9fb | |
|
54d216b144 | |
|
293cb42bcf | |
|
9ba5f8e14a | |
|
83756518ad | |
|
44ec3e9eed | |
|
45cb6b2a17 | |
|
6dde202353 | |
|
3b2e16a39e | |
|
39432a1270 | |
|
c7c51c2305 | |
|
11ab968c8d | |
|
4e3dce703d | |
|
b29b1f18db | |
|
226c427255 | |
|
5ac1ef17a3 | |
|
04450b84e6 | |
|
dfdcbdbd86 | |
|
536c40a8e2 | |
|
761fd61725 | |
|
c5f79db964 | |
|
bfb3b98684 | |
|
c37e762dd6 | |
|
cd4a07e637 | |
|
a138c0dacd | |
|
eea7db374d | |
|
4396e30dfd | |
|
d6167ebfed | |
|
e9e32c2ad0 | |
|
d7f31e3482 | |
|
a88e91c139 | |
|
06a35cd645 | |
|
6fbff659c5 | |
|
443350c8f4 | |
|
19f99ac116 | |
|
e5b5222c39 | |
|
d24110090c | |
|
14cc2afd35 | |
|
afdc7b3421 | |
|
535eae941e | |
|
bd2865ebc5 | |
|
eef2467a61 | |
|
a66329500c | |
|
f98c11e825 | |
|
c241897dfe | |
|
6f9079ec5f | |
|
eff427473f | |
|
c87bf8a2fa | |
|
0bb5a912f7 | |
|
1d43fa7888 | |
|
61dc7f9277 | |
|
6eff930c84 | |
|
ecf81cc79e | |
|
63ebaee731 | |
|
dd94f2e39e | |
|
2084013449 | |
|
3ac5b84ef6 | |
|
5f391234e2 | |
|
127c941d1c | |
|
f3428404a2 | |
|
491ecec44a | |
|
efd7a46c68 | |
|
1e19d99748 | |
|
93f78cdc3e | |
|
3953642310 | |
|
29f08cbb46 | |
|
05e6ecb947 | |
|
1f98e4ea26 | |
|
6eb46f53ae | |
|
db16c57199 | |
|
90195a9226 | |
|
70ee6d0628 | |
|
7971b67277 | |
|
49a7e0df4d | |
|
e491c7de89 | |
|
0303b4fe72 | |
|
1b982ed5a2 | |
|
244ceb5b46 | |
|
0ae1ddbbca | |
|
5994bf1550 | |
|
aa39403714 | |
|
7ae5082c3d | |
|
40e3a1ceb7 |
|
@ -34,7 +34,7 @@ public class TokenController {
|
||||||
@PostMapping("login")
|
@PostMapping("login")
|
||||||
public Result<?> login (@RequestBody LoginBody form) {
|
public Result<?> login (@RequestBody LoginBody form) {
|
||||||
// 用户登录
|
// 用户登录
|
||||||
LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
|
LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword(), form.getFirmId());
|
||||||
// 获取登录token
|
// 获取登录token
|
||||||
return Result.success(tokenService.createToken(userInfo));
|
return Result.success(tokenService.createToken(userInfo));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
package com.muyu.auth.form;
|
package com.muyu.auth.form;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户登录对象
|
* 用户登录对象
|
||||||
*
|
*
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class LoginBody {
|
public class LoginBody {
|
||||||
/**
|
/**
|
||||||
* 用户名
|
* 用户名
|
||||||
|
@ -16,19 +26,9 @@ public class LoginBody {
|
||||||
*/
|
*/
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
public String getUsername () {
|
/**
|
||||||
return username;
|
* 公司数据信息id
|
||||||
}
|
*/
|
||||||
|
private Long firmId;
|
||||||
|
|
||||||
public void setUsername (String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword () {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword (String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ public class SysLoginService {
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
*/
|
*/
|
||||||
public LoginUser login (String username, String password) {
|
public LoginUser login(String username, String password, Long firmId) {
|
||||||
// 用户名或密码为空 错误
|
// 用户名或密码为空 错误
|
||||||
if (StringUtils.isAnyBlank(username, password)) {
|
if (StringUtils.isAnyBlank(username, password, String.valueOf(firmId))) {
|
||||||
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
|
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
|
||||||
throw new ServiceException("用户/密码必须填写");
|
throw new ServiceException("用户/密码必须填写");
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,9 @@ public class SysLoginService {
|
||||||
throw new ServiceException("很遗憾,访问IP已被列入系统黑名单");
|
throw new ServiceException("很遗憾,访问IP已被列入系统黑名单");
|
||||||
}
|
}
|
||||||
// 查询用户信息
|
// 查询用户信息
|
||||||
Result<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
|
Result<LoginUser> userResult = null;
|
||||||
|
// 查询用户信息
|
||||||
|
userResult = remoteUserService.getUserInfo(username, firmId, SecurityConstants.INNER);
|
||||||
|
|
||||||
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) {
|
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) {
|
||||||
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
|
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
# Tomcat
|
# Tomcat
|
||||||
server:
|
server:
|
||||||
port: 9500
|
port: 19500
|
||||||
|
|
||||||
# nacos线上地址
|
# nacos线上地址
|
||||||
nacos:
|
nacos:
|
||||||
addr: 123.57.152.124:8848
|
addr: 123.57.152.124:8848
|
||||||
user-name: nacos
|
user-name: nacos
|
||||||
password: nacos
|
password: nacos
|
||||||
namespace: yan1
|
namespace: wx
|
||||||
# Spring
|
# Spring
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?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>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
cloud-common-cache 缓存基准
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<artifactId>cloud-common-cache</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
|
<maven.compiler.target>23</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- redis 缓存模块-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.muyu</groupId>
|
||||||
|
<artifactId>cloud-common-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.muyu.common.cache;
|
||||||
|
|
||||||
|
import com.muyu.common.redis.service.RedisService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 抽象缓存层
|
||||||
|
* * @className: CacheAbsBasic ️✈️
|
||||||
|
* * @author: Yang 鹏 🦅
|
||||||
|
* * @date: 2024/9/29 16:08 ⏰
|
||||||
|
* * @Version: 1.0
|
||||||
|
* * @description:
|
||||||
|
*/
|
||||||
|
public abstract class CacheAbsBasic <K, V> implements CacheBasic<K, V>{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(K key, V value) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
redisService.setCacheObject(encode(key), value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("运行时异常,异常信息为:{}"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V get(K key) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return redisService.getCacheObject(encode(key));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("运行时异常,异常信息为:{}"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(K key) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
redisService.deleteObject(encode(key));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("运行时异常,异常信息为:{}"+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hashKey(K key){
|
||||||
|
Boolean b = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
b = redisService.hasKey(encode(key));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("运行时异常,异常信息为:{}"+e.getMessage());
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.muyu.common.cache;
|
||||||
|
|
||||||
|
import org.springframework.data.redis.core.TimeoutUtils;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基础
|
||||||
|
* * @className: CacheBasic ️✈️
|
||||||
|
* * @author: Yang 鹏 🦅
|
||||||
|
* * @date: 2024/9/29 16:08 ⏰
|
||||||
|
* * @Version: 1.0
|
||||||
|
* * @description:
|
||||||
|
*/
|
||||||
|
public interface CacheBasic<K, V> extends PrimaryKeyBasic<K> {
|
||||||
|
void put(K key, V value);
|
||||||
|
|
||||||
|
V get(K key);
|
||||||
|
|
||||||
|
void remove(K key);
|
||||||
|
|
||||||
|
boolean hashKey(K key);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.muyu.common.cache;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键基础
|
||||||
|
* * @className: PrimaryKeyBasic ️✈️
|
||||||
|
* * @author: Yang 鹏 🦅
|
||||||
|
* * @date: 2024/9/29 16:08 ⏰
|
||||||
|
* * @Version: 1.0
|
||||||
|
* * @description:
|
||||||
|
*/
|
||||||
|
public interface PrimaryKeyBasic<K> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键前缀
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String keyPre();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键编码
|
||||||
|
*
|
||||||
|
* @param key 缓存建
|
||||||
|
* @return 装修建
|
||||||
|
*/
|
||||||
|
public default String encode(K key) {
|
||||||
|
return key.toString() + keyPre();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键解码
|
||||||
|
*
|
||||||
|
* @param key 缓存建
|
||||||
|
* @return 装修建
|
||||||
|
*/
|
||||||
|
public default K decode(String key) {
|
||||||
|
return (K) key.substring(0, key.lastIndexOf(keyPre()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?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-caffeine</artifactId>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
cloud-common-caffeine 本地缓存服务
|
||||||
|
</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.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.muyu</groupId>
|
||||||
|
<artifactId>cloud-common-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.muyu.common.caffeine.bean;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
import com.muyu.common.caffeine.enums.CacheNameEnums;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.caffeine.CaffeineCache;
|
||||||
|
import org.springframework.cache.support.SimpleCacheManager;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caffeine管理器
|
||||||
|
* @Author: WangXin
|
||||||
|
* @Name: CaffeineCacheConfig
|
||||||
|
* @Description: Caffeine管理器
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class CaffeineManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建缓存管理器
|
||||||
|
* @return 缓存管理器实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CacheManager cacheManager() {
|
||||||
|
SimpleCacheManager cacheManager = new SimpleCacheManager();
|
||||||
|
List<String> cacheNames = CacheNameEnums.getCodes();
|
||||||
|
cacheManager.setCaches(cacheNames.stream()
|
||||||
|
.map(name -> new CaffeineCache(
|
||||||
|
name,
|
||||||
|
Caffeine.newBuilder()
|
||||||
|
.recordStats()
|
||||||
|
.build()))
|
||||||
|
.toList());
|
||||||
|
log.info("缓存管理器初始化完成,缓存分区:{}", cacheNames);
|
||||||
|
return cacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.muyu.common.caffeine.constents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caffeine常量
|
||||||
|
* @Author: WangXin
|
||||||
|
* @Name: CaffeineContent
|
||||||
|
* @Description: Caffeine常量
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class CaffeineContent {
|
||||||
|
|
||||||
|
public static final String CAR_VIN_KEY = "car:vin";
|
||||||
|
|
||||||
|
public static final String VIN = "vin";
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.muyu.common.caffeine.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存分区枚举
|
||||||
|
*
|
||||||
|
* @Author: WangXin
|
||||||
|
* @Name: CacheNameEnums
|
||||||
|
* @Description: 缓存分区枚举
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum CacheNameEnums {
|
||||||
|
STORAGE("storage", "持久化"),
|
||||||
|
FAULT("fault", "故障"),
|
||||||
|
FENCE("fence", "围栏"),
|
||||||
|
WARMING("warming", "预警"),
|
||||||
|
REALTIME("realTime", "实时信息");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String info;
|
||||||
|
|
||||||
|
CacheNameEnums(String code, String info) {
|
||||||
|
this.code = code;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 鉴别参数是否是枚举的值
|
||||||
|
*
|
||||||
|
* @param code 需鉴别参数
|
||||||
|
* @return 如果存在返回结果turn, 否则返回false
|
||||||
|
*/
|
||||||
|
public static boolean isCode(String code) {
|
||||||
|
return Arrays.stream(values())
|
||||||
|
.map(CacheNameEnums::getCode)
|
||||||
|
.anyMatch(c -> c.equals(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取枚举Value
|
||||||
|
* @param code 编码
|
||||||
|
* @return Value
|
||||||
|
*/
|
||||||
|
public static String getInfo(String code) {
|
||||||
|
return Arrays.stream(values())
|
||||||
|
.filter(c -> c.getCode().equals(code))
|
||||||
|
.map(CacheNameEnums::getInfo)
|
||||||
|
.findFirst()
|
||||||
|
.orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有code
|
||||||
|
* @return code集合
|
||||||
|
*/
|
||||||
|
public static List<String> getCodes() {
|
||||||
|
return Arrays.stream(values())
|
||||||
|
.map(CacheNameEnums::getCode)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.muyu.common.caffeine.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import com.muyu.common.caffeine.enums.CacheNameEnums;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caffeine缓存工具
|
||||||
|
* @Author: WangXin
|
||||||
|
* @Name: CaffeineUtils
|
||||||
|
* @Description: 缓存工具类
|
||||||
|
* @CreatedDate: 2024/9/26 下午2:53
|
||||||
|
* @FilePath: com.muyu.common.caffeine
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class CaffeineCacheUtils {
|
||||||
|
@Resource
|
||||||
|
private CacheManager cacheManager;
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆上线 - 新增缓存
|
||||||
|
*/
|
||||||
|
public void addCarCache(String vin) {
|
||||||
|
// 从Redis中获取缓存信息
|
||||||
|
for (String name : CacheNameEnums.getCodes()) {
|
||||||
|
String value = redisTemplate.opsForValue().get(name+":"+vin);
|
||||||
|
cacheManager.getCache(name).put(vin, value);
|
||||||
|
log.info("存储缓存, 缓存分区:[{}], 车辆编码:[{}], 存储值:[{}]", name, vin, value);
|
||||||
|
}
|
||||||
|
log.info("车辆编码:{},本地缓存完成...",vin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆下线 - 删除缓存
|
||||||
|
*/
|
||||||
|
public void deleteCarCache(String cacheName) {
|
||||||
|
if (!hasCarVinCache(cacheName,null)) {
|
||||||
|
log.warn("车辆编码:{},本地缓存不存在该车辆信息...", cacheName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cacheManager.getCache(cacheName).invalidate();
|
||||||
|
log.info("车辆编码:{},本地缓存删除完成...", cacheName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取车辆信息缓存
|
||||||
|
*/
|
||||||
|
public Object getCarCache(String cacheName, String key) {
|
||||||
|
if (!hasCarVinCache(cacheName, key)){
|
||||||
|
log.warn("车辆编码:{},本地缓存不存在该车辆信息...",cacheName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return cacheManager.getCache(cacheName).get(key).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取车辆信息缓存
|
||||||
|
*/
|
||||||
|
public <T> T getCarCache(String cacheName, String key, Class<T> type) {
|
||||||
|
if (!hasCarVinCache(cacheName,key)){
|
||||||
|
log.warn("车辆编码:{},本地缓存不存在该车辆信息...",cacheName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return cacheManager.getCache(cacheName).get(key, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断缓存存在与否
|
||||||
|
*/
|
||||||
|
public Boolean hasCarVinCache(String cacheName,String key) {
|
||||||
|
boolean notEmpty = ObjectUtils.isNotEmpty(cacheManager.getCache(cacheName));
|
||||||
|
if (notEmpty && StringUtils.isNotEmpty(key)){
|
||||||
|
return ObjectUtils.isNotEmpty(cacheManager.getCache(cacheName).get(key).get());
|
||||||
|
}
|
||||||
|
return notEmpty;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
com.muyu.common.caffeine.utils.CaffeineCacheUtils
|
||||||
|
com.muyu.common.caffeine.bean.CaffeineManager
|
|
@ -9,12 +9,12 @@ public class CacheConstants {
|
||||||
/**
|
/**
|
||||||
* 缓存有效期,默认720(分钟)
|
* 缓存有效期,默认720(分钟)
|
||||||
*/
|
*/
|
||||||
public final static long EXPIRATION = 720;
|
public final static Long EXPIRATION = 720L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存刷新时间,默认120(分钟)
|
* 缓存刷新时间,默认120(分钟)
|
||||||
*/
|
*/
|
||||||
public final static long REFRESH_TIME = 120;
|
public final static Long REFRESH_TIME = 120L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 密码最大错误次数
|
* 密码最大错误次数
|
||||||
|
@ -24,7 +24,7 @@ public class CacheConstants {
|
||||||
/**
|
/**
|
||||||
* 密码锁定时间,默认10(分钟)
|
* 密码锁定时间,默认10(分钟)
|
||||||
*/
|
*/
|
||||||
public final static long PASSWORD_LOCK_TIME = 10;
|
public final static Long PASSWORD_LOCK_TIME = 10L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限缓存前缀
|
* 权限缓存前缀
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class Constants {
|
||||||
/**
|
/**
|
||||||
* 验证码有效期(分钟)
|
* 验证码有效期(分钟)
|
||||||
*/
|
*/
|
||||||
public static final long CAPTCHA_EXPIRATION = 2;
|
public static final Long CAPTCHA_EXPIRATION = 2L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资源映射路径 前缀
|
* 资源映射路径 前缀
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class GenConstants {
|
||||||
/**
|
/**
|
||||||
* 数据库文本类型
|
* 数据库文本类型
|
||||||
*/
|
*/
|
||||||
public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"};
|
public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "Longtext"};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据库时间类型
|
* 数据库时间类型
|
||||||
|
|
|
@ -45,4 +45,13 @@ public class SecurityConstants {
|
||||||
* 角色权限
|
* 角色权限
|
||||||
*/
|
*/
|
||||||
public static final String ROLE_PERMISSION = "role_permission";
|
public static final String ROLE_PERMISSION = "role_permission";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司key
|
||||||
|
*/
|
||||||
|
public static final String FIRM_KEY = "firm_key";
|
||||||
|
/**
|
||||||
|
* 公司Id
|
||||||
|
*/
|
||||||
|
public static final String FIRM_ID = "firm_id";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,4 +20,10 @@ public class ServiceNameConstants {
|
||||||
* 文件服务的serviceid
|
* 文件服务的serviceid
|
||||||
*/
|
*/
|
||||||
public static final String FILE_SERVICE = "cloud-file";
|
public static final String FILE_SERVICE = "cloud-file";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆服务的serviceid
|
||||||
|
*/
|
||||||
|
public static final String ENTERPRISE_SERVICE = "cloud-enterprise";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,6 @@ public class TokenConstants {
|
||||||
/**
|
/**
|
||||||
* 令牌秘钥
|
* 令牌秘钥
|
||||||
*/
|
*/
|
||||||
public final static String SECRET = "abcdefghijklmnsalieopadfaqawefwerstuvwxyz";
|
public final static String SECRET = "abcdefghijklmnsalieopadfaqawefwerstuvxyryz";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ package com.muyu.common.core.domain;
|
||||||
import com.muyu.common.core.constant.Constants;
|
import com.muyu.common.core.constant.Constants;
|
||||||
import com.muyu.common.core.constant.HttpStatus;
|
import com.muyu.common.core.constant.HttpStatus;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import java.io.Serializable;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@SuperBuilder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Result<T> implements Serializable {
|
public class Result<T> implements Serializable {
|
||||||
|
@ -32,7 +32,8 @@ public class Result<T> implements Serializable {
|
||||||
*/
|
*/
|
||||||
public static final int WARN = HttpStatus.WARN;
|
public static final int WARN = HttpStatus.WARN;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
private int code;
|
private int code;
|
||||||
|
|
||||||
private String msg;
|
private String msg;
|
||||||
|
@ -96,8 +97,8 @@ public class Result<T> implements Serializable {
|
||||||
private static <T> Result<T> restResult (T data, int code, String msg) {
|
private static <T> Result<T> restResult (T data, int code, String msg) {
|
||||||
return Result.<T>builder()
|
return Result.<T>builder()
|
||||||
.code(code)
|
.code(code)
|
||||||
.data(data)
|
|
||||||
.msg(msg)
|
.msg(msg)
|
||||||
|
.data(data)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class CaptchaException extends RuntimeException {
|
public class CaptchaException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public CaptchaException (String msg) {
|
public CaptchaException (String msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class CheckedException extends RuntimeException {
|
public class CheckedException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public CheckedException (String message) {
|
public CheckedException (String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class DemoModeException extends RuntimeException {
|
public class DemoModeException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public DemoModeException () {
|
public DemoModeException () {
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class GlobalException extends RuntimeException {
|
public class GlobalException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误提示
|
* 错误提示
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class InnerAuthException extends RuntimeException {
|
public class InnerAuthException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public InnerAuthException (String message) {
|
public InnerAuthException (String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class PreAuthorizeException extends RuntimeException {
|
public class PreAuthorizeException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public PreAuthorizeException () {
|
public PreAuthorizeException () {
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ package com.muyu.common.core.exception;
|
||||||
*
|
*
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public final class ServiceException extends RuntimeException {
|
public class ServiceException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误码
|
* 错误码
|
||||||
|
@ -21,7 +21,7 @@ public final class ServiceException extends RuntimeException {
|
||||||
/**
|
/**
|
||||||
* 错误明细,内部调试错误
|
* 错误明细,内部调试错误
|
||||||
* <p>
|
* <p>
|
||||||
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
|
* 和 {@link #()} 一致的设计
|
||||||
*/
|
*/
|
||||||
private String detailMessage;
|
private String detailMessage;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class UtilException extends RuntimeException {
|
public class UtilException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 8247610319171014183L;
|
private static final Long serialVersionUID = 8247610319171014183L;
|
||||||
|
|
||||||
public UtilException (Throwable e) {
|
public UtilException (Throwable e) {
|
||||||
super(e.getMessage(), e);
|
super(e.getMessage(), e);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception.auth;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class NotLoginException extends RuntimeException {
|
public class NotLoginException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public NotLoginException (String message) {
|
public NotLoginException (String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class NotPermissionException extends RuntimeException {
|
public class NotPermissionException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public NotPermissionException (String permission) {
|
public NotPermissionException (String permission) {
|
||||||
super(permission);
|
super(permission);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class NotRoleException extends RuntimeException {
|
public class NotRoleException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public NotRoleException (String role) {
|
public NotRoleException (String role) {
|
||||||
super(role);
|
super(role);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception.base;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class BaseException extends RuntimeException {
|
public class BaseException extends RuntimeException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 所属模块
|
* 所属模块
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.muyu.common.core.exception.base.BaseException;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class FileException extends BaseException {
|
public class FileException extends BaseException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public FileException (String code, Object[] args, String msg) {
|
public FileException (String code, Object[] args, String msg) {
|
||||||
super("file", code, args, msg);
|
super("file", code, args, msg);
|
||||||
|
|
|
@ -6,9 +6,9 @@ package com.muyu.common.core.exception.file;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class FileNameLengthLimitExceededException extends FileException {
|
public class FileNameLengthLimitExceededException extends FileException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public FileNameLengthLimitExceededException (int defaultFileNameLength) {
|
public FileNameLengthLimitExceededException (int defaultFileNameLength) {
|
||||||
super("upload.filename.exceed.length", new Object[]{defaultFileNameLength}, "the filename is too long");
|
super("upload.filename.exceed.length", new Object[]{defaultFileNameLength}, "the filename is too Long");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ package com.muyu.common.core.exception.file;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class FileSizeLimitExceededException extends FileException {
|
public class FileSizeLimitExceededException extends FileException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public FileSizeLimitExceededException (long defaultMaxSize) {
|
public FileSizeLimitExceededException (Long defaultMaxSize) {
|
||||||
super("upload.exceed.maxSize", new Object[]{defaultMaxSize}, "the filesize is too large");
|
super("upload.exceed.maxSize", new Object[]{defaultMaxSize}, "the filesize is too large");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import java.io.PrintWriter;
|
||||||
*/
|
*/
|
||||||
public class FileUploadException extends Exception {
|
public class FileUploadException extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final Throwable cause;
|
private final Throwable cause;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.Arrays;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class InvalidExtensionException extends FileUploadException {
|
public class InvalidExtensionException extends FileUploadException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String[] allowedExtension;
|
private String[] allowedExtension;
|
||||||
private String extension;
|
private String extension;
|
||||||
|
@ -34,7 +34,7 @@ public class InvalidExtensionException extends FileUploadException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidImageExtensionException extends InvalidExtensionException {
|
public static class InvalidImageExtensionException extends InvalidExtensionException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public InvalidImageExtensionException (String[] allowedExtension, String extension, String filename) {
|
public InvalidImageExtensionException (String[] allowedExtension, String extension, String filename) {
|
||||||
super(allowedExtension, extension, filename);
|
super(allowedExtension, extension, filename);
|
||||||
|
@ -42,7 +42,7 @@ public class InvalidExtensionException extends FileUploadException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidFlashExtensionException extends InvalidExtensionException {
|
public static class InvalidFlashExtensionException extends InvalidExtensionException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public InvalidFlashExtensionException (String[] allowedExtension, String extension, String filename) {
|
public InvalidFlashExtensionException (String[] allowedExtension, String extension, String filename) {
|
||||||
super(allowedExtension, extension, filename);
|
super(allowedExtension, extension, filename);
|
||||||
|
@ -50,7 +50,7 @@ public class InvalidExtensionException extends FileUploadException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidMediaExtensionException extends InvalidExtensionException {
|
public static class InvalidMediaExtensionException extends InvalidExtensionException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public InvalidMediaExtensionException (String[] allowedExtension, String extension, String filename) {
|
public InvalidMediaExtensionException (String[] allowedExtension, String extension, String filename) {
|
||||||
super(allowedExtension, extension, filename);
|
super(allowedExtension, extension, filename);
|
||||||
|
@ -58,7 +58,7 @@ public class InvalidExtensionException extends FileUploadException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidVideoExtensionException extends InvalidExtensionException {
|
public static class InvalidVideoExtensionException extends InvalidExtensionException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public InvalidVideoExtensionException (String[] allowedExtension, String extension, String filename) {
|
public InvalidVideoExtensionException (String[] allowedExtension, String extension, String filename) {
|
||||||
super(allowedExtension, extension, filename);
|
super(allowedExtension, extension, filename);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception.job;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class TaskException extends Exception {
|
public class TaskException extends Exception {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Code code;
|
private Code code;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception.user;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class CaptchaExpireException extends UserException {
|
public class CaptchaExpireException extends UserException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public CaptchaExpireException () {
|
public CaptchaExpireException () {
|
||||||
super("user.jcaptcha.expire", null);
|
super("user.jcaptcha.expire", null);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.muyu.common.core.exception.base.BaseException;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class UserException extends BaseException {
|
public class UserException extends BaseException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public UserException (String code, Object[] args) {
|
public UserException (String code, Object[] args) {
|
||||||
super("user", code, args, null);
|
super("user", code, args, null);
|
||||||
|
|
|
@ -6,7 +6,7 @@ package com.muyu.common.core.exception.user;
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class UserPasswordNotMatchException extends UserException {
|
public class UserPasswordNotMatchException extends UserException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
public UserPasswordNotMatchException () {
|
public UserPasswordNotMatchException () {
|
||||||
super("user.password.not.match", null);
|
super("user.password.not.match", null);
|
||||||
|
|
|
@ -313,12 +313,12 @@ public class Convert {
|
||||||
return new Long[]{};
|
return new Long[]{};
|
||||||
}
|
}
|
||||||
String[] arr = str.split(split);
|
String[] arr = str.split(split);
|
||||||
final Long[] longs = new Long[arr.length];
|
final Long[] Longs = new Long[arr.length];
|
||||||
for (int i = 0 ; i < arr.length ; i++) {
|
for (int i = 0 ; i < arr.length ; i++) {
|
||||||
final Long v = toLong(arr[i], null);
|
final Long v = toLong(arr[i], null);
|
||||||
longs[i] = v;
|
Longs[i] = v;
|
||||||
}
|
}
|
||||||
return longs;
|
return Longs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -345,7 +345,7 @@ public class Convert {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为long<br>
|
* 转换为Long<br>
|
||||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
|
@ -377,7 +377,7 @@ public class Convert {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为long<br>
|
* 转换为Long<br>
|
||||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
* 转换失败不会报错
|
* 转换失败不会报错
|
||||||
*
|
*
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
|
||||||
* 获取服务器启动时间
|
* 获取服务器启动时间
|
||||||
*/
|
*/
|
||||||
public static Date getServerStartDate () {
|
public static Date getServerStartDate () {
|
||||||
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
|
Long time = ManagementFactory.getRuntimeMXBean().getStartTime();
|
||||||
return new Date(time);
|
return new Date(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,20 +122,20 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
|
||||||
* @return 时间差(天/小时/分钟)
|
* @return 时间差(天/小时/分钟)
|
||||||
*/
|
*/
|
||||||
public static String timeDistance (Date endDate, Date startTime) {
|
public static String timeDistance (Date endDate, Date startTime) {
|
||||||
long nd = 1000 * 24 * 60 * 60;
|
Long nd = 1000 * 24 * 60 * 60L;
|
||||||
long nh = 1000 * 60 * 60;
|
Long nh = 1000 * 60 * 60L;
|
||||||
long nm = 1000 * 60;
|
Long nm = 1000 * 60L;
|
||||||
// long ns = 1000;
|
// Long ns = 1000;
|
||||||
// 获得两个时间的毫秒时间差异
|
// 获得两个时间的毫秒时间差异
|
||||||
long diff = endDate.getTime() - startTime.getTime();
|
Long diff = endDate.getTime() - startTime.getTime();
|
||||||
// 计算差多少天
|
// 计算差多少天
|
||||||
long day = diff / nd;
|
Long day = diff / nd;
|
||||||
// 计算差多少小时
|
// 计算差多少小时
|
||||||
long hour = diff % nd / nh;
|
Long hour = diff % nd / nh;
|
||||||
// 计算差多少分钟
|
// 计算差多少分钟
|
||||||
long min = diff % nd % nh / nm;
|
Long min = diff % nd % nh / nm;
|
||||||
// 计算差多少秒//输出结果
|
// 计算差多少秒//输出结果
|
||||||
// long sec = diff % nd % nh % nm / ns;
|
// Long sec = diff % nd % nh % nm / ns;
|
||||||
return day + "天" + hour + "小时" + min + "分钟";
|
return day + "天" + hour + "小时" + min + "分钟";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,4 +162,21 @@ public class JwtUtils {
|
||||||
public static String getValue (Claims claims, String key) {
|
public static String getValue (Claims claims, String key) {
|
||||||
return Convert.toStr(claims.get(key), "");
|
return Convert.toStr(claims.get(key), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据
|
||||||
|
* @param claims
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getFirmKey(Claims claims) {
|
||||||
|
return getValue(claims, SecurityConstants.FIRM_KEY);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 根据
|
||||||
|
* @param claims
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getFirmId(Claims claims) {
|
||||||
|
return getValue(claims, SecurityConstants.FIRM_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public final class HTMLFilter {
|
||||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
|
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set of allowed html elements, along with allowed attributes for each element
|
* set of allowed html elements, aLong with allowed attributes for each element
|
||||||
**/
|
**/
|
||||||
private final Map<String, List<String>> vAllowed;
|
private final Map<String, List<String>> vAllowed;
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -127,7 +127,7 @@ public class IpUtils {
|
||||||
byte[] bytes = new byte[4];
|
byte[] bytes = new byte[4];
|
||||||
String[] elements = text.split("\\.", -1);
|
String[] elements = text.split("\\.", -1);
|
||||||
try {
|
try {
|
||||||
long l;
|
Long l;
|
||||||
int i;
|
int i;
|
||||||
switch (elements.length) {
|
switch (elements.length) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -141,12 +141,12 @@ public class IpUtils {
|
||||||
bytes[3] = (byte) (int) (l & 0xFF);
|
bytes[3] = (byte) (int) (l & 0xFF);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
l = Integer.parseInt(elements[0]);
|
l = (long) Integer.parseInt(elements[0]);
|
||||||
if ((l < 0L) || (l > 255L)) {
|
if ((l < 0L) || (l > 255L)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
bytes[0] = (byte) (int) (l & 0xFF);
|
bytes[0] = (byte) (int) (l & 0xFF);
|
||||||
l = Integer.parseInt(elements[1]);
|
l = (long) Integer.parseInt(elements[1]);
|
||||||
if ((l < 0L) || (l > 16777215L)) {
|
if ((l < 0L) || (l > 16777215L)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -156,13 +156,13 @@ public class IpUtils {
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
for (i = 0; i < 2 ; ++i) {
|
for (i = 0; i < 2 ; ++i) {
|
||||||
l = Integer.parseInt(elements[i]);
|
l = (long) Integer.parseInt(elements[i]);
|
||||||
if ((l < 0L) || (l > 255L)) {
|
if ((l < 0L) || (l > 255L)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
bytes[i] = (byte) (int) (l & 0xFF);
|
bytes[i] = (byte) (int) (l & 0xFF);
|
||||||
}
|
}
|
||||||
l = Integer.parseInt(elements[2]);
|
l = (long) Integer.parseInt(elements[2]);
|
||||||
if ((l < 0L) || (l > 65535L)) {
|
if ((l < 0L) || (l > 65535L)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ public class IpUtils {
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
for (i = 0; i < 4 ; ++i) {
|
for (i = 0; i < 4 ; ++i) {
|
||||||
l = Integer.parseInt(elements[i]);
|
l = (long) Integer.parseInt(elements[i]);
|
||||||
if ((l < 0L) || (l > 255L)) {
|
if ((l < 0L) || (l > 255L)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -290,14 +290,14 @@ public class IpUtils {
|
||||||
String[] sips = iparea.substring(0, idx).split("\\.");
|
String[] sips = iparea.substring(0, idx).split("\\.");
|
||||||
String[] sipe = iparea.substring(idx + 1).split("\\.");
|
String[] sipe = iparea.substring(idx + 1).split("\\.");
|
||||||
String[] sipt = ip.split("\\.");
|
String[] sipt = ip.split("\\.");
|
||||||
long ips = 0L, ipe = 0L, ipt = 0L;
|
Long ips = 0L, ipe = 0L, ipt = 0L;
|
||||||
for (int i = 0 ; i < 4 ; ++i) {
|
for (int i = 0 ; i < 4 ; ++i) {
|
||||||
ips = ips << 8 | Integer.parseInt(sips[i]);
|
ips = ips << 8 | Integer.parseInt(sips[i]);
|
||||||
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
|
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
|
||||||
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
|
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
|
||||||
}
|
}
|
||||||
if (ips > ipe) {
|
if (ips > ipe) {
|
||||||
long t = ips;
|
Long t = ips;
|
||||||
ips = ipe;
|
ips = ipe;
|
||||||
ipe = t;
|
ipe = t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||||
* @param data 数据
|
* @param data 数据
|
||||||
*/
|
*/
|
||||||
private UUID (byte[] data) {
|
private UUID (byte[] data) {
|
||||||
long msb = 0;
|
long msb = 0L;
|
||||||
long lsb = 0;
|
long lsb = 0L;
|
||||||
assert data.length == 16 : "data must be 16 bytes in length";
|
assert data.length == 16 : "data must be 16 bytes in length";
|
||||||
for (int i = 0 ; i < 8 ; i++) {
|
for (int i = 0 ; i < 8 ; i++) {
|
||||||
msb = (msb << 8) | (data[i] & 0xff);
|
msb = (msb << 8) | (data[i] & 0xff);
|
||||||
|
@ -131,15 +131,15 @@ public final class UUID implements java.io.Serializable, Comparable<UUID> {
|
||||||
components[i] = "0x" + components[i];
|
components[i] = "0x" + components[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
long mostSigBits = Long.decode(components[0]).longValue();
|
long mostSigBits = Long.decode(components[0]);
|
||||||
mostSigBits <<= 16;
|
mostSigBits <<= 16;
|
||||||
mostSigBits |= Long.decode(components[1]).longValue();
|
mostSigBits |= Long.decode(components[1]);
|
||||||
mostSigBits <<= 16;
|
mostSigBits <<= 16;
|
||||||
mostSigBits |= Long.decode(components[2]).longValue();
|
mostSigBits |= Long.decode(components[2]);
|
||||||
|
|
||||||
long leastSigBits = Long.decode(components[3]).longValue();
|
long leastSigBits = Long.decode(components[3]);
|
||||||
leastSigBits <<= 48;
|
leastSigBits <<= 48;
|
||||||
leastSigBits |= Long.decode(components[4]).longValue();
|
leastSigBits |= Long.decode(components[4]);
|
||||||
|
|
||||||
return new UUID(mostSigBits, leastSigBits);
|
return new UUID(mostSigBits, leastSigBits);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package com.muyu.common.core.web.controller;
|
package com.muyu.common.core.web.controller;
|
||||||
|
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
|
|
||||||
import com.muyu.common.core.utils.DateUtils;
|
import com.muyu.common.core.utils.DateUtils;
|
||||||
import com.muyu.common.core.utils.PageUtils;
|
import com.muyu.common.core.utils.PageUtils;
|
||||||
import com.muyu.common.core.domain.Result;
|
import com.muyu.common.core.domain.Result;
|
||||||
|
import com.muyu.common.core.web.domain.BaseEntity;
|
||||||
import com.muyu.common.core.web.page.TableDataInfo;
|
import com.muyu.common.core.web.page.TableDataInfo;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -19,7 +21,7 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author muyu
|
* @author muyu
|
||||||
*/
|
*/
|
||||||
public class BaseController {
|
public class BaseController<M extends BaseEntity> {
|
||||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.util.Map;
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class BaseEntity implements Serializable {
|
public class BaseEntity implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索值
|
* 搜索值
|
||||||
|
|
|
@ -17,7 +17,7 @@ import java.util.List;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class TreeEntity extends BaseEntity {
|
public class TreeEntity extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 父菜单名称
|
* 父菜单名称
|
||||||
|
|
|
@ -20,12 +20,12 @@ import java.util.List;
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class TableDataInfo<T> implements Serializable {
|
public class TableDataInfo<T> implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 总记录数
|
* 总记录数
|
||||||
*/
|
*/
|
||||||
private long total;
|
private Long total;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表数据
|
* 列表数据
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?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-iotdb</artifactId>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
cloud-common-iotdb 时序性数据存储服务
|
||||||
|
</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>org.apache.iotdb</groupId>
|
||||||
|
<artifactId>iotdb-session</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,180 @@
|
||||||
|
|
||||||
|
package com.muyu.common.iotdb.config;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.apache.iotdb.isession.SessionDataSet;
|
||||||
|
import org.apache.iotdb.isession.pool.SessionDataSetWrapper;
|
||||||
|
import org.apache.iotdb.rpc.IoTDBConnectionException;
|
||||||
|
import org.apache.iotdb.rpc.StatementExecutionException;
|
||||||
|
import org.apache.iotdb.session.pool.SessionPool;
|
||||||
|
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
|
||||||
|
import org.apache.iotdb.tsfile.read.common.Field;
|
||||||
|
import org.apache.iotdb.tsfile.read.common.RowRecord;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.muyu.common.iotdb.constant.IotdbConstant.ROOT_DATA_DATAJSON;
|
||||||
|
import static com.muyu.common.iotdb.constant.IotdbConstant.SELECT_ROOT_DATA_DATAJSON_DATASOURCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/9/30
|
||||||
|
* @Description IotDBSessionConfig配置类
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
@Component
|
||||||
|
@Configuration
|
||||||
|
public class IotDBSessionConfig {
|
||||||
|
|
||||||
|
@Value("${spring.iotdb.username:root}")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Value("${spring.iotdb.password:root}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Value("${spring.iotdb.ip:127.0.0.1}")
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
@Value("${spring.iotdb.port:6667}")
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@Value("${spring.iotdb.maxSize:10}")
|
||||||
|
private int maxSize;
|
||||||
|
|
||||||
|
private static SessionPool sessionPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取IotDBSession对象
|
||||||
|
* @return iotDBSession对象
|
||||||
|
*/
|
||||||
|
public SessionPool getSessionPool() {
|
||||||
|
if (sessionPool == null) {
|
||||||
|
sessionPool = new SessionPool(ip, port, username, password, maxSize);
|
||||||
|
}
|
||||||
|
return sessionPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加数据
|
||||||
|
* @param deviceId
|
||||||
|
* @param time
|
||||||
|
* @param measurements
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
public void insertRecord(SessionPool sessionPool,String deviceId,
|
||||||
|
Long time, List<String> measurements,List<TSDataType> dataTypeList, JSONObject value) {
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:device_id:[{}], measurements:[{}], values:[{}]", deviceId, measurements, value);
|
||||||
|
sessionPool.insertRecord(deviceId, time, measurements,dataTypeList,new Object[]{value.toJSONString()});
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertRecord失败: deviceId={}, time={}, measurements={}, values={}, error={}",
|
||||||
|
deviceId, time, measurements, value, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void JSONObject(JSONObject value){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sql查数据
|
||||||
|
* @param sessionPool
|
||||||
|
* @param sql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SessionDataSet selectRecord(SessionPool sessionPool,String sql) {
|
||||||
|
log.info("iotdb数据查询:sql:[{}]",sql);
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb SQL查询:sql:[{}]", sql);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeQueryStatement失败:sql:[{}],error={}", sql, e.getMessage());
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public JSONObject getJsonFindByTime(SessionPool sessionPool,String fieldName,String deviceId,Long timestamp) {
|
||||||
|
String sql = String.format("SELECT %s FROM %s WHERE time = %d", fieldName, deviceId, timestamp);
|
||||||
|
SessionDataSet sessionDataSet = selectRecord(sessionPool, sql);
|
||||||
|
try {
|
||||||
|
while (sessionDataSet.hasNext()){
|
||||||
|
RowRecord next = sessionDataSet.next();
|
||||||
|
for (Field field : next.getFields()) {
|
||||||
|
String stringValue = field.getStringValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (StatementExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (IoTDBConnectionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SessionPool sessionPool = new SessionPool("127.0.0.1", 6667, "root", "root", 10);
|
||||||
|
|
||||||
|
|
||||||
|
String jsonValue = """
|
||||||
|
{
|
||||||
|
"name": "张三",
|
||||||
|
"age": 28,
|
||||||
|
"email": "zhangsan@example.com",
|
||||||
|
"isStudent": false,
|
||||||
|
"hobbies": ["阅读", "旅行", "编程"],
|
||||||
|
"address": {
|
||||||
|
"street": "长安街100号",
|
||||||
|
"city": "北京",
|
||||||
|
"postalCode": "100000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
JSONObject value = JSONObject.parseObject(jsonValue);
|
||||||
|
|
||||||
|
IotDBSessionConfig iotDBSessionConfig = new IotDBSessionConfig();
|
||||||
|
|
||||||
|
List<String> measurements = List.of("datasource");
|
||||||
|
List<TSDataType> datatypeList = List.of(TSDataType.TEXT);
|
||||||
|
iotDBSessionConfig.insertRecord(sessionPool,ROOT_DATA_DATAJSON,System.currentTimeMillis(),measurements,datatypeList,value);
|
||||||
|
|
||||||
|
SessionDataSet sessionDataSet = iotDBSessionConfig.selectRecord(sessionPool,SELECT_ROOT_DATA_DATAJSON_DATASOURCE);
|
||||||
|
|
||||||
|
HashMap<Long, Map<String, String>> LongMapHashMap = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (sessionDataSet.hasNext()){
|
||||||
|
RowRecord next = sessionDataSet.next();
|
||||||
|
Long timestamp = next.getTimestamp();
|
||||||
|
Map<String, String> fieldMap = new HashMap<>();
|
||||||
|
for (Field field : next.getFields()) {
|
||||||
|
TSDataType dataType = field.getDataType();
|
||||||
|
String stringValue = field.getStringValue();
|
||||||
|
fieldMap.put(dataType.name(), stringValue);
|
||||||
|
}
|
||||||
|
LongMapHashMap.put(timestamp, fieldMap);
|
||||||
|
}
|
||||||
|
} catch (StatementExecutionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (IoTDBConnectionException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
log.info("数据为:{}", JSONObject.toJSONString(LongMapHashMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.muyu.common.iotdb.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/9/30
|
||||||
|
* @Description iotdb数据库常量
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
public interface IotdbConstant {
|
||||||
|
|
||||||
|
String ROOT_DATA_DATAJSON = "root.car.data.datajson";
|
||||||
|
|
||||||
|
String SELECT_ROOT_DATA_DATAJSON_DATASOURCE = "select * from root.car.data.datajson";
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.muyu.common.iotdb.domain;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class InsertDataDTO {
|
||||||
|
private Float temperature;
|
||||||
|
private String hardware;
|
||||||
|
private Boolean status;
|
||||||
|
|
||||||
|
public InsertDataDTO buildOne() {
|
||||||
|
InsertDataDTO insertDataDTO = new InsertDataDTO();
|
||||||
|
insertDataDTO.setHardware("ss");
|
||||||
|
insertDataDTO.setStatus(true);
|
||||||
|
insertDataDTO.setTemperature(12.0F);
|
||||||
|
return insertDataDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InsertDataDTO> buildList() {
|
||||||
|
List<InsertDataDTO> insertDataDTOS = new ArrayList<>();
|
||||||
|
int buildNum = 10;
|
||||||
|
for (int i = 0; i < buildNum; i++) {
|
||||||
|
InsertDataDTO insertDataDTO = new InsertDataDTO();
|
||||||
|
insertDataDTO.setHardware(i % 2 == 0 ? "pp" + i : null);
|
||||||
|
insertDataDTO.setStatus(i % 2 == 0);
|
||||||
|
insertDataDTO.setTemperature(12.0F + i);
|
||||||
|
insertDataDTOS.add(insertDataDTO);
|
||||||
|
}
|
||||||
|
return insertDataDTOS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.muyu.common.iotdb.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/9/30
|
||||||
|
* @Description IotDBServiceImpl业务实现层
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class IotDbRecordAble {
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.muyu.common.iotdb.domain.dto;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class MeasurementSchemaValuesDTO {
|
||||||
|
|
||||||
|
private List<MeasurementSchema> schemaList;
|
||||||
|
|
||||||
|
private List<Object> values;
|
||||||
|
|
||||||
|
private List<Integer> valueIsNullIndex;
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.muyu.common.iotdb.service;
|
||||||
|
|
||||||
|
import com.muyu.common.iotdb.domain.dto.IotDbRecordAble;
|
||||||
|
import com.muyu.common.iotdb.domain.dto.MeasurementSchemaValuesDTO;
|
||||||
|
import org.apache.iotdb.common.rpc.thrift.TAggregationType;
|
||||||
|
import org.apache.iotdb.isession.SessionDataSet;
|
||||||
|
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
|
||||||
|
import org.apache.iotdb.tsfile.write.record.Tablet;
|
||||||
|
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/9/28
|
||||||
|
* @Description IotDBServiceImpl业务层
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
public interface IotDBService {
|
||||||
|
|
||||||
|
void insertTablet(Tablet tablet);
|
||||||
|
|
||||||
|
void insertTablets(Map<String, Tablet> tablets);
|
||||||
|
|
||||||
|
void insertStringRecord(String deviceId, Long time, List<String> measurements, List<String> values);
|
||||||
|
|
||||||
|
void insertRecord(String deviceId, Long time, List<String> measurements, List<TSDataType> types, List<Object> values);
|
||||||
|
|
||||||
|
void insertStringRecords(List<String> deviceIds, List<Long> times, List<List<String>> measurementsList, List<List<String>> valuesList);
|
||||||
|
|
||||||
|
void insertRecords(List<String> deviceIds, List<Long> times, List<List<String>> measurementsList, List<List<TSDataType>> typesList, List<List<Object>> valuesList);
|
||||||
|
|
||||||
|
void insertStringRecordsOfOneDevice(String deviceId, List<Long> times, List<List<String>> measurementsList, List<List<String>> valuesList);
|
||||||
|
|
||||||
|
void insertRecordsOfOneDevice(String deviceId, List<Long> times, List<List<String>> measurementsList, List<List<TSDataType>> typesList, List<List<Object>> valuesList);
|
||||||
|
|
||||||
|
void deleteData(String path, Long endTime);
|
||||||
|
|
||||||
|
void deleteData(List<String> paths, Long endTime);
|
||||||
|
|
||||||
|
SessionDataSet executeRawDataQuery(List<String> paths, Long startTime, Long endTime, Long timeOut);
|
||||||
|
|
||||||
|
<T> List<T> executeRawDataQuery(List<String> paths, Long startTime, Long endTime, Long timeOut, Class<? extends IotDbRecordAble> clazz);
|
||||||
|
|
||||||
|
SessionDataSet executeLastDataQuery(List<String> paths, Long lastTime);
|
||||||
|
|
||||||
|
<T> List<T> executeLastDataQuery(List<String> paths, Long lastTime, Class<? extends IotDbRecordAble> clazz);
|
||||||
|
|
||||||
|
SessionDataSet executeLastDataQueryForOneDevice(String db, String device, List<String> sensors, boolean isLegalPathNodes);
|
||||||
|
|
||||||
|
<T> List<T> executeLastDataQueryForOneDevice(String db, String device, List<String> sensors, boolean isLegalPathNodes, Class<? extends IotDbRecordAble> clazz);
|
||||||
|
|
||||||
|
SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations);
|
||||||
|
|
||||||
|
SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations, Long startTime, Long endTime);
|
||||||
|
|
||||||
|
SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations, Long startTime, Long endTime, Long interval);
|
||||||
|
|
||||||
|
SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations, Long startTime, Long endTime, Long interval, Long slidingStep);
|
||||||
|
|
||||||
|
SessionDataSet executeQueryStatement(String sql);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL非查询
|
||||||
|
*
|
||||||
|
* @param sql
|
||||||
|
*/
|
||||||
|
void executeNonQueryStatement(String sql);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装处理数据
|
||||||
|
*
|
||||||
|
* @param sessionDataSet
|
||||||
|
* @param titleList
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> packagingMapData(SessionDataSet sessionDataSet, List<String> columnNames);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装处理数据(不支持聚合查询)
|
||||||
|
*
|
||||||
|
* @param sessionDataSet 查询返回的结果集
|
||||||
|
* @param titleList 查询返回的结果集内的字段名
|
||||||
|
* @param clazz 返回数据对应的对象(对象属性必须与字段名对应)
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
<T> List<T> packagingObjectData(SessionDataSet sessionDataSet, List<String> titleList, Class<? extends IotDbRecordAble> clazz);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据对象构建MeasurementSchemas
|
||||||
|
*
|
||||||
|
* @param object 对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<MeasurementSchema> buildMeasurementSchemas(Object object);
|
||||||
|
/**
|
||||||
|
* 根据对象构建MeasurementSchemaValuesDTO
|
||||||
|
*
|
||||||
|
* @param object 对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
MeasurementSchemaValuesDTO buildMeasurementSchemasAndValues(Object object);
|
||||||
|
}
|
|
@ -0,0 +1,711 @@
|
||||||
|
package com.muyu.common.iotdb.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.muyu.common.iotdb.config.IotDBSessionConfig;
|
||||||
|
import com.muyu.common.iotdb.domain.dto.IotDbRecordAble;
|
||||||
|
import com.muyu.common.iotdb.domain.dto.MeasurementSchemaValuesDTO;
|
||||||
|
import com.muyu.common.iotdb.service.IotDBService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.iotdb.common.rpc.thrift.TAggregationType;
|
||||||
|
import org.apache.iotdb.isession.SessionDataSet;
|
||||||
|
import org.apache.iotdb.isession.pool.SessionDataSetWrapper;
|
||||||
|
import org.apache.iotdb.session.pool.SessionPool;
|
||||||
|
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
|
||||||
|
import org.apache.iotdb.tsfile.read.common.Field;
|
||||||
|
import org.apache.iotdb.tsfile.read.common.RowRecord;
|
||||||
|
import org.apache.iotdb.tsfile.write.record.Tablet;
|
||||||
|
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/9/28
|
||||||
|
* @Description IotDBServiceImpl业务实现层
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class IotDBServiceImpl implements IotDBService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IotDBSessionConfig iotDBSessionConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单设备批量插入数据
|
||||||
|
*
|
||||||
|
* @param tablet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertTablet(Tablet tablet) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:tablet:[{}]", tablet);
|
||||||
|
sessionPool.insertTablet(tablet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertTablet失败: tablet={}, error={}", tablet, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多设备批量插入数据
|
||||||
|
*
|
||||||
|
* @param tablets
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertTablets(Map<String, Tablet> tablets) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:tablets:[{}]", tablets);
|
||||||
|
sessionPool.insertTablets(tablets);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertTablets失败: tablets={}, error={}", tablets, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单条数据插入(string类型数据项)
|
||||||
|
*
|
||||||
|
* @param deviceId 设备名(表名)root.ln.wf01.wt01
|
||||||
|
* @param time 时间戳
|
||||||
|
* @param measurements 数据项列表
|
||||||
|
* @param values 数据项对应值列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertStringRecord(String deviceId, Long time, List<String> measurements, List<String> values) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:device_id:[{}], measurements:[{}], values:[{}]", deviceId, measurements, values);
|
||||||
|
sessionPool.insertRecord(deviceId, time, measurements, values);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertRecord失败: deviceId={}, time={}, measurements={}, values={}, error={}",
|
||||||
|
deviceId, time, measurements, values, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单条数据插入(不同类型数据项)
|
||||||
|
*
|
||||||
|
* @param deviceId 设备名(表名)root.ln.wf01.wt01
|
||||||
|
* @param time 时间戳
|
||||||
|
* @param measurements 数据项列表
|
||||||
|
* @param types 数据项对应类型列表
|
||||||
|
* @param values 数据项对应值列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertRecord(String deviceId, Long time, List<String> measurements, List<TSDataType> types, List<Object> values) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:device_id:[{}], measurements:[{}], types:[{}], values:[{}]", deviceId, measurements, types, values);
|
||||||
|
sessionPool.insertRecord(deviceId, time, measurements, types, values);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertRecordHasTypes失败: deviceId={}, time={}, measurements={},types={}, values={}, error={}",
|
||||||
|
deviceId, time, measurements, types, values, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个设备多条数据插入(string类型数据项)
|
||||||
|
*
|
||||||
|
* @param deviceIds 多个设备名(表名)root.ln.wf01.wt01
|
||||||
|
* @param times 时间戳的列表
|
||||||
|
* @param measurementsList 数据项列表的列表
|
||||||
|
* @param valuesList 数据项对应值列表的列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertStringRecords(List<String> deviceIds, List<Long> times, List<List<String>> measurementsList, List<List<String>> valuesList) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:deviceIds:[{}], measurementsList:[{}], valuesList:[{}]", deviceIds, measurementsList, valuesList);
|
||||||
|
sessionPool.insertRecords(deviceIds, times, measurementsList, valuesList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertRecords失败: deviceIds={}, times={}, measurementsList={}, valuesList={}, error={}",
|
||||||
|
deviceIds, times, measurementsList, valuesList, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多个设备多条数据插入(不同类型数据项)
|
||||||
|
*
|
||||||
|
* @param deviceIds 多个设备名(表名))root.ln.wf01.wt01
|
||||||
|
* @param times 时间戳的列表
|
||||||
|
* @param measurementsList 数据项列表的列表
|
||||||
|
* @param typesList 数据项对应类型列表的列表
|
||||||
|
* @param valuesList 数据项对应值列表的列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertRecords(List<String> deviceIds, List<Long> times, List<List<String>> measurementsList, List<List<TSDataType>> typesList, List<List<Object>> valuesList) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:deviceIds:[{}], measurementsList:[{}], typesList:[{}], valuesList:[{}]", deviceIds, measurementsList, typesList, valuesList);
|
||||||
|
sessionPool.insertRecords(deviceIds, times, measurementsList, typesList, valuesList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertRecords失败: deviceIds={}, times={}, measurementsList={}, typesList=[],valuesList={}, error={}",
|
||||||
|
deviceIds, times, measurementsList, typesList, valuesList, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个设备多条数据插入(string类型数据项)
|
||||||
|
*
|
||||||
|
* @param deviceId 单个设备名(表名))root.ln.wf01.wt01
|
||||||
|
* @param times 时间戳的列表
|
||||||
|
* @param measurementsList 数据项列表的列表
|
||||||
|
* @param valuesList 数据项对应值列表的列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertStringRecordsOfOneDevice(String deviceId, List<Long> times, List<List<String>> measurementsList, List<List<String>> valuesList) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:deviceId:[{}], measurementsList:[{}], valuesList:[{}]", deviceId, measurementsList, valuesList);
|
||||||
|
sessionPool.insertStringRecordsOfOneDevice(deviceId, times, measurementsList, valuesList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertStringRecordsOfOneDevice失败: deviceId={}, times={}, measurementsList={}, valuesList={}, error={}",
|
||||||
|
deviceId, times, measurementsList, valuesList, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单个设备多条数据插入(不同类型数据项)
|
||||||
|
*
|
||||||
|
* @param deviceId 单个设备名(表名))root.ln.wf01.wt01
|
||||||
|
* @param times 时间戳的列表
|
||||||
|
* @param measurementsList 数据项列表的列表
|
||||||
|
* @param typesList 数据项对应类型列表的列表
|
||||||
|
* @param valuesList 数据项对应值列表的列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insertRecordsOfOneDevice(String deviceId, List<Long> times, List<List<String>> measurementsList, List<List<TSDataType>> typesList, List<List<Object>> valuesList) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据入库:deviceId:[{}], measurementsList:[{}], typesList:[{}], valuesList:[{}]", deviceId, measurementsList, typesList, valuesList);
|
||||||
|
sessionPool.insertRecordsOfOneDevice(deviceId, times, measurementsList, typesList, valuesList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession insertRecordsOfOneDevice失败: deviceId={}, times={}, measurementsList={}, typesList=[],valuesList={}, error={}", deviceId, times, measurementsList, typesList, valuesList, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数据(删除一个时间序列在某个时间点前或这个时间点的数据)
|
||||||
|
*
|
||||||
|
* @param path 单个字段 root.ln.wf01.wt01.temperature
|
||||||
|
* @param endTime 删除时间点
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void deleteData(String path, Long endTime) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据删除:path:[{}], endTime:[{}]", path, endTime);
|
||||||
|
sessionPool.deleteData(path, endTime);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession deleteData失败: deviceId={}, times={},error={}", path, endTime, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数据(删除多个时间序列在某个时间点前或这个时间点的数据)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param endTime 删除时间点
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void deleteData(List<String> paths, Long endTime) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据删除:paths:[{}], endTime:[{}]", paths, endTime);
|
||||||
|
sessionPool.deleteData(paths, endTime);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession deleteData失败: paths={}, times={},error={}", paths, endTime, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据查询(时间序列原始数据范围查询,时间范围为左闭右开区间,包含开始时间但不包含结束时间)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param startTime 开始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @param outTime 超时时间
|
||||||
|
* @return SessionDataSet (Time,paths)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeRawDataQuery(List<String> paths, Long startTime, Long endTime, Long outTime) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据查询:paths:[{}], startTime:[{}], endTime:[{}],outTime:[{}]", paths, startTime, endTime, outTime);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeRawDataQuery(paths, startTime, endTime, outTime);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeRawDataQuery失败: paths={}, startTime:[{}], endTime:[{}],outTime:[{}],error={}", paths, startTime, endTime, outTime, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据查询(时间序列原始数据范围查询,时间范围为左闭右开区间,包含开始时间但不包含结束时间)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param startTime 开始时间
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @param outTime 超时时间
|
||||||
|
* @param clazz 返回数据对应的对象(对象属性必须与字段名对应)
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> List<T> executeRawDataQuery(List<String> paths, Long startTime, Long endTime, Long outTime, Class<? extends IotDbRecordAble> clazz) {
|
||||||
|
SessionDataSet sessionDataSet = executeRawDataQuery(paths, startTime, endTime, outTime);
|
||||||
|
List<String> columnNames = sessionDataSet.getColumnNames();
|
||||||
|
List<T> resultEntities = null;
|
||||||
|
try {
|
||||||
|
resultEntities = packagingObjectData(sessionDataSet, columnNames, clazz);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeRawDataQuery失败: paths={}, startTime:[{}], endTime:[{}],outTime:[{}],error={}", paths, startTime, endTime, outTime, e.getMessage());
|
||||||
|
}
|
||||||
|
return resultEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最新点查询(查询最后一条时间戳大于等于某个时间点的数据)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param lastTime 结束时间
|
||||||
|
* @return SessionDataSet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeLastDataQuery(List<String> paths, Long lastTime) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据查询:paths:[{}], lastTime:[{}]", paths, lastTime);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeLastDataQuery(paths, lastTime);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeLastDataQuery失败: paths={}, lastTime:[{}], error={}", paths, lastTime, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最新点查询(查询最后一条时间戳大于等于某个时间点的数据)
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param lastTime 结束时间
|
||||||
|
* @param clazz 返回数据对应的对象(对象属性必须与字段名对应)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> List<T> executeLastDataQuery(List<String> paths, Long lastTime, Class<? extends IotDbRecordAble> clazz) {
|
||||||
|
SessionDataSet sessionDataSet = executeLastDataQuery(paths, lastTime);
|
||||||
|
List<String> columnNames = sessionDataSet.getColumnNames();
|
||||||
|
List<T> resultEntities = null;
|
||||||
|
try {
|
||||||
|
resultEntities = packagingObjectData(sessionDataSet, columnNames, clazz);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeLastDataQuery失败: paths={}, lastTime:[{}], error={}", paths, lastTime, e.getMessage());
|
||||||
|
}
|
||||||
|
return resultEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最新点查询(快速查询单设备下指定序列最新点)
|
||||||
|
*
|
||||||
|
* @param db root.ln.wf01
|
||||||
|
* @param device root.ln.wf01.wt01
|
||||||
|
* @param sensors temperature,status(字段名)
|
||||||
|
* @param isLegalPathNodes true(避免路径校验)
|
||||||
|
* @return SessionDataSet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeLastDataQueryForOneDevice(String db, String device, List<String> sensors, boolean isLegalPathNodes) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb数据查询:db:[{}], device:[{}],sensors:[{}], isLegalPathNodes:[{}]", db, device, sensors, isLegalPathNodes);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeLastDataQueryForOneDevice(db, device, sensors, isLegalPathNodes);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeLastDataQueryForOneDevice失败: db:[{}], device:[{}],sensors:[{}], isLegalPathNodes:[{}], error={}", db, device, sensors, isLegalPathNodes, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param db root.ln.wf01
|
||||||
|
* @param device root.ln.wf01.wt01
|
||||||
|
* @param sensors temperature,status(字段名)
|
||||||
|
* @param isLegalPathNodes true(避免路径校验)
|
||||||
|
* @param clazz 返回数据对应的对象(对象属性必须与字段名对应)
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> List<T> executeLastDataQueryForOneDevice(String db, String device, List<String> sensors, boolean isLegalPathNodes, Class<? extends IotDbRecordAble> clazz) {
|
||||||
|
SessionDataSet sessionDataSet = executeLastDataQueryForOneDevice(db, device, sensors, isLegalPathNodes);
|
||||||
|
List<String> columnNames = sessionDataSet.getColumnNames();
|
||||||
|
List<T> resultEntities = null;
|
||||||
|
try {
|
||||||
|
resultEntities = packagingObjectData(sessionDataSet, columnNames, clazz);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeLastDataQueryForOneDevice失败: db:[{}], device:[{}],sensors:[{}], isLegalPathNodes:[{}], error={}", db, device, sensors, isLegalPathNodes, e.getMessage());
|
||||||
|
}
|
||||||
|
return resultEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合查询
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param aggregations 聚合操作 TAggregationType.SUM,TAggregationType.COUNT
|
||||||
|
* @return SessionDataSet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb聚合查询:paths:[{}], aggregations:[{}]", paths, aggregations);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeAggregationQuery(paths, aggregations);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeAggregationQuery失败: paths:[{}], aggregations:[{}] ,error={}", paths, aggregations, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合查询(时间序列原始数据范围查询,时间范围为左闭右开区间,包含开始时间但不包含结束时间)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param aggregations 聚合操作 TAggregationType.SUM,TAggregationType.COUNT
|
||||||
|
* @param startTime 开始时间(包含)
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @return SessionDataSet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations, Long startTime, Long endTime) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb聚合查询:paths:[{}], aggregations:[{}],startTime:[{}], endTime:[{}]", paths, aggregations, startTime, endTime);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeAggregationQuery(paths, aggregations, startTime, endTime);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeAggregationQuery失败: paths:[{}], aggregations:[{}] ,startTime:[{}], endTime:[{}],error={}", paths, aggregations, startTime, endTime, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合查询(支持按照时间区间分段查询)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param aggregations 聚合操作 TAggregationType.SUM,TAggregationType.COUNT
|
||||||
|
* @param startTime 开始时间(包含)
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @param interval
|
||||||
|
* @return SessionDataSet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations, Long startTime, Long endTime, Long interval) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
try {
|
||||||
|
log.info("iotdb聚合查询:paths:[{}], aggregations:[{}],startTime:[{}], endTime:[{}] ,interval:[{}]", paths, aggregations, startTime, endTime, interval);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeAggregationQuery(paths, aggregations, startTime, endTime, interval);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeAggregationQuery失败: paths:[{}], aggregations:[{}] ,startTime:[{}], endTime:[{}], interval:[{}], error={}", paths, aggregations, startTime, endTime, interval, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合查询(支持按照时间区间分段查询)
|
||||||
|
*
|
||||||
|
* @param paths 多个字段(表名)) root.ln.wf01.wt01.temperature
|
||||||
|
* @param aggregations 聚合操作 TAggregationType.SUM,TAggregationType.COUNT
|
||||||
|
* @param startTime 开始时间(包含)
|
||||||
|
* @param endTime 结束时间
|
||||||
|
* @param interval
|
||||||
|
* @param slidingStep
|
||||||
|
* @return SessionDataSet
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeAggregationQuery(List<String> paths, List<TAggregationType> aggregations, Long startTime, Long endTime, Long interval, Long slidingStep) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("iotdb聚合查询:paths:[{}], aggregations:[{}],startTime:[{}], endTime:[{}] ,interval:[{}], slidingStep:[{}]", paths, aggregations, startTime, endTime, interval, slidingStep);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeAggregationQuery(paths, aggregations, startTime, endTime, interval, slidingStep);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeAggregationQuery失败: paths:[{}], aggregations:[{}] ,startTime:[{}], endTime:[{}], interval:[{}], slidingStep:[{}] ,error={}", paths, aggregations, startTime, endTime, interval, slidingStep, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL查询
|
||||||
|
*
|
||||||
|
* @param sql
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SessionDataSet executeQueryStatement(String sql) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
SessionDataSetWrapper sessionDataSetWrapper = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info("iotdb SQL查询:sql:[{}]", sql);
|
||||||
|
sessionDataSetWrapper = sessionPool.executeQueryStatement(sql);
|
||||||
|
return sessionDataSetWrapper.getSessionDataSet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeQueryStatement失败:sql:[{}],error={}", sql, e.getMessage());
|
||||||
|
} finally {
|
||||||
|
sessionPool.closeResultSet(sessionDataSetWrapper);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL非查询
|
||||||
|
*
|
||||||
|
* @param sql
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void executeNonQueryStatement(String sql) {
|
||||||
|
SessionPool sessionPool = iotDBSessionConfig.getSessionPool();
|
||||||
|
try {
|
||||||
|
log.info("iotdb SQL无查询:sql:[{}]", sql);
|
||||||
|
sessionPool.executeNonQueryStatement(sql);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IotDBSession executeNonQueryStatement失败:sql:[{}],error={}", sql, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装处理数据
|
||||||
|
*
|
||||||
|
* @param sessionDataSet
|
||||||
|
* @param titleList
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> packagingMapData(SessionDataSet sessionDataSet, List<String> titleList) {
|
||||||
|
int fetchSize = sessionDataSet.getFetchSize();
|
||||||
|
List<Map<String, Object>> resultList = new ArrayList<>();
|
||||||
|
titleList.remove("Time");
|
||||||
|
if (fetchSize > 0) {
|
||||||
|
while (sessionDataSet.hasNext()) {
|
||||||
|
Map<String, Object> resultMap = new HashMap<>();
|
||||||
|
RowRecord next = sessionDataSet.next();
|
||||||
|
List<Field> fields = next.getFields();
|
||||||
|
String timeString = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(next.getTimestamp());
|
||||||
|
resultMap.put("time", timeString);
|
||||||
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
|
Field field = fields.get(i);
|
||||||
|
if (field.getDataType() == null || field.getObjectValue(field.getDataType()) == null) {
|
||||||
|
resultMap.put(splitString(titleList.get(i)), null);
|
||||||
|
} else {
|
||||||
|
resultMap.put(splitString(titleList.get(i)), field.getObjectValue(field.getDataType()).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resultList.add(resultMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装处理数据(不支持聚合查询)
|
||||||
|
*
|
||||||
|
* @param sessionDataSet 查询返回的结果集
|
||||||
|
* @param titleList 查询返回的结果集内的字段名
|
||||||
|
* @param clazz 返回数据对应的对象(对象属性必须与字段名对应)
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public <T> List<T> packagingObjectData(SessionDataSet sessionDataSet, List<String> titleList, Class<? extends IotDbRecordAble> clazz) {
|
||||||
|
int fetchSize = sessionDataSet.getFetchSize();
|
||||||
|
List<T> resultList = new ArrayList<>();
|
||||||
|
titleList.remove("Time");
|
||||||
|
if (fetchSize > 0) {
|
||||||
|
while (sessionDataSet.hasNext()) {
|
||||||
|
Map<String, Object> resultMap = new HashMap<>();
|
||||||
|
RowRecord next = sessionDataSet.next();
|
||||||
|
List<Field> fields = next.getFields();
|
||||||
|
String timeString = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(next.getTimestamp());
|
||||||
|
resultMap.put("time", timeString);
|
||||||
|
if (titleList.stream().anyMatch(str -> str.contains("."))) {
|
||||||
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
|
Field field = fields.get(i);
|
||||||
|
String title = titleList.get(i);
|
||||||
|
if (field.getDataType() == null || field.getObjectValue(field.getDataType()) == null) {
|
||||||
|
resultMap.put(splitString(title), null);
|
||||||
|
} else {
|
||||||
|
resultMap.put(splitString(title), field.getObjectValue(field.getDataType()).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Field fieldName = fields.get(0);
|
||||||
|
Field fieldValue = fields.get(1);
|
||||||
|
Field fieldDataType = fields.get(2);
|
||||||
|
if (fieldName.getDataType() != null && fieldName.getObjectValue(fieldName.getDataType()) != null) {
|
||||||
|
String mapKey = fieldName.getObjectValue(fieldName.getDataType()).toString();
|
||||||
|
Object mapValue = convertStringToType(fieldValue.getObjectValue(fieldValue.getDataType()).toString(), fieldDataType.getObjectValue(fieldDataType.getDataType()).toString());
|
||||||
|
resultMap.put(splitString(mapKey), mapValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String jsonString = JSON.toJSONString(resultMap);
|
||||||
|
resultList.add(JSON.parseObject(jsonString, (Type) clazz));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分割获取字段名
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* @return 字段名
|
||||||
|
*/
|
||||||
|
public static String splitString(String str) {
|
||||||
|
String[] parts = str.split("\\.");
|
||||||
|
if (parts.length <= 0) {
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
return parts[parts.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据数据值和数据类型返回对应数据类型数据
|
||||||
|
*
|
||||||
|
* @param value 数据值
|
||||||
|
* @param typeName 数据类型
|
||||||
|
* @return 转换后的数据值
|
||||||
|
*/
|
||||||
|
public static Object convertStringToType(String value, String typeName) {
|
||||||
|
String type = typeName.toLowerCase();
|
||||||
|
if (type.isEmpty()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if ("boolean".equals(type)) {
|
||||||
|
return Boolean.parseBoolean(value);
|
||||||
|
} else if ("double".equals(type)) {
|
||||||
|
return Double.parseDouble(value);
|
||||||
|
} else if ("int32".equals(type)) {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
} else if ("int64".equals(type)) {
|
||||||
|
return Long.parseLong(value);
|
||||||
|
} else if ("float".equals(type)) {
|
||||||
|
return Float.parseFloat(value);
|
||||||
|
} else if ("text".equals(type)) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据对象属性的数据类型返回对应的TSDataType
|
||||||
|
*
|
||||||
|
* @param type 属性的数据类型
|
||||||
|
* @return TSDataType
|
||||||
|
*/
|
||||||
|
public static TSDataType getTsDataTypeByString(String type) {
|
||||||
|
String typeName = splitString(type).toLowerCase();
|
||||||
|
if ("boolean".equals(typeName)) {
|
||||||
|
return TSDataType.BOOLEAN;
|
||||||
|
} else if ("double".equals(typeName)) {
|
||||||
|
return TSDataType.DOUBLE;
|
||||||
|
} else if ("int".equals(typeName) || "integer".equals(typeName)) {
|
||||||
|
return TSDataType.INT32;
|
||||||
|
} else if ("Long".equals(typeName)) {
|
||||||
|
return TSDataType.INT64;
|
||||||
|
} else if ("float".equals(typeName)) {
|
||||||
|
return TSDataType.FLOAT;
|
||||||
|
} else if ("text".equals(typeName)) {
|
||||||
|
return TSDataType.TEXT;
|
||||||
|
} else if ("string".equals(typeName)) {
|
||||||
|
return TSDataType.TEXT;
|
||||||
|
} else {
|
||||||
|
return TSDataType.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据对象构建MeasurementSchemas
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<MeasurementSchema> buildMeasurementSchemas(Object obj) {
|
||||||
|
java.lang.reflect.Field[] fields = obj.getClass().getDeclaredFields();
|
||||||
|
List<MeasurementSchema> schemaList = Arrays.stream(fields).map(field ->
|
||||||
|
new MeasurementSchema(field.getName(),
|
||||||
|
getTsDataTypeByString(
|
||||||
|
field.getType().getName()
|
||||||
|
))).
|
||||||
|
collect(Collectors.toList());
|
||||||
|
return schemaList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据对象构建MeasurementSchemaValuesDTO
|
||||||
|
*
|
||||||
|
* @param obj 对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public MeasurementSchemaValuesDTO buildMeasurementSchemasAndValues(Object obj) {
|
||||||
|
MeasurementSchemaValuesDTO measurementSchemaValuesDTO = new MeasurementSchemaValuesDTO();
|
||||||
|
java.lang.reflect.Field[] fields = obj.getClass().getDeclaredFields();
|
||||||
|
List<MeasurementSchema> schemaList = new ArrayList<>();
|
||||||
|
List<Object> values = new ArrayList<>();
|
||||||
|
List<Integer> valuesIsNullIndex = new ArrayList<>();
|
||||||
|
int valueIndex = 0;
|
||||||
|
for (java.lang.reflect.Field field : fields) {
|
||||||
|
MeasurementSchema measurementSchema = new MeasurementSchema(field.getName(), getTsDataTypeByString(field.getType().getName()));
|
||||||
|
schemaList.add(measurementSchema);
|
||||||
|
Object value = field.get(obj);
|
||||||
|
if (value == null) {
|
||||||
|
valuesIsNullIndex.add(valueIndex);
|
||||||
|
}
|
||||||
|
values.add(value);
|
||||||
|
valueIndex++;
|
||||||
|
}
|
||||||
|
measurementSchemaValuesDTO.setSchemaList(schemaList);
|
||||||
|
measurementSchemaValuesDTO.setValues(values);
|
||||||
|
return measurementSchemaValuesDTO;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
com.muyu.common.iotdb.config.IotDBSessionConfig
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?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-kafka</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
cloud-common-kafka kafka公共模块
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- 项目公共核心模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.muyu</groupId>
|
||||||
|
<artifactId>cloud-common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- kafka客户端 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.kafka</groupId>
|
||||||
|
<artifactId>kafka-clients</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,102 @@
|
||||||
|
package com.muyu.common.kafka.config;
|
||||||
|
|
||||||
|
import com.muyu.common.core.text.StrFormatter;
|
||||||
|
import com.muyu.common.kafka.constant.KafkaConfigConstants;
|
||||||
|
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||||
|
import org.apache.kafka.common.serialization.Deserializer;
|
||||||
|
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: wangXin
|
||||||
|
* @Date 2024/9/28 20:32
|
||||||
|
* @Description Kafka消费者配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class KafkaConsumerConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端IP
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.bootstrap-servers-ip}")
|
||||||
|
private String bootstrapServersIP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端口号
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.bootstrap-servers-port}")
|
||||||
|
private String bootstrapServersPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启消费者偏移量
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.enable-auto-commit}")
|
||||||
|
private Boolean enableAutoCommit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动提交时间间隔
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.auto-commit-interval}")
|
||||||
|
private Integer autoCommitInterval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动重置偏移量
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.auto-offset-reset}")
|
||||||
|
private String autoOffsetReset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求阻塞的最大时间
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.fetch-max-wait}")
|
||||||
|
private Integer fetchMaxWait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求应答的最小字节数
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.fetch-min-size}")
|
||||||
|
private Integer fetchMinSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 心跳间隔时间
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.heartbeat-interval}")
|
||||||
|
private Integer heartbeatInterval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一次调用poll返回的最大记录条数
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.max-poll-records}")
|
||||||
|
private Integer maxPollRecords;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定消费组
|
||||||
|
*/
|
||||||
|
@Value("${kafka.consumer.group-id}")
|
||||||
|
private String groupId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kafka消费者初始化配置
|
||||||
|
* @return Kafka消费者实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public KafkaConsumer<String, String> kafkaConsumer() {
|
||||||
|
HashMap<String, Object> configs = new HashMap<>();
|
||||||
|
configs.put(KafkaConfigConstants.BOOTSTRAP_SERVERS,
|
||||||
|
StrFormatter.format("{}:{}", bootstrapServersIP, bootstrapServersPort));
|
||||||
|
configs.put(KafkaConfigConstants.ENABLE_AUTO_COMMIT, enableAutoCommit);
|
||||||
|
configs.put(KafkaConfigConstants.AUTO_COMMIT_INTERVAL, autoCommitInterval);
|
||||||
|
configs.put(KafkaConfigConstants.AUTO_OFFSET_RESET, autoOffsetReset);
|
||||||
|
configs.put(KafkaConfigConstants.FETCH_MAX_WAIT, fetchMaxWait);
|
||||||
|
configs.put(KafkaConfigConstants.FETCH_MIN_SIZE, fetchMinSize);
|
||||||
|
configs.put(KafkaConfigConstants.HEARTBEAT_INTERVAL, heartbeatInterval);
|
||||||
|
configs.put(KafkaConfigConstants.MAX_POLL_RECORDS, maxPollRecords);
|
||||||
|
configs.put(KafkaConfigConstants.GROUP_ID, groupId);
|
||||||
|
Deserializer<String> keyDeserializer = new StringDeserializer();
|
||||||
|
Deserializer<String> valueDeserializer = new StringDeserializer();
|
||||||
|
return new KafkaConsumer<>(configs, keyDeserializer, valueDeserializer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.muyu.common.kafka.config;
|
||||||
|
|
||||||
|
import com.muyu.common.core.text.StrFormatter;
|
||||||
|
import com.muyu.common.kafka.constant.KafkaConfigConstants;
|
||||||
|
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||||
|
import org.apache.kafka.common.serialization.Serializer;
|
||||||
|
import org.apache.kafka.common.serialization.StringSerializer;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: wangXin
|
||||||
|
* @Date 2024/9/28 16:35
|
||||||
|
* @Description Kafka生产者配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class KafkaProducerConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端IP
|
||||||
|
*/
|
||||||
|
@Value("${kafka.producer.bootstrap-servers-ip}")
|
||||||
|
private String bootstrapServersIP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端口号
|
||||||
|
*/
|
||||||
|
@Value("${kafka.producer.bootstrap-servers-port}")
|
||||||
|
private String bootstrapServersPort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重试次数
|
||||||
|
*/
|
||||||
|
@Value("${kafka.producer.retries}")
|
||||||
|
private Integer retries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认批量大小
|
||||||
|
*/
|
||||||
|
@Value("${kafka.producer.batch-size}")
|
||||||
|
private Integer batchSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总内存字节数
|
||||||
|
*/
|
||||||
|
@Value("${kafka.producer.buffer-memory}")
|
||||||
|
private Integer bufferMemory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 偏移量
|
||||||
|
*/
|
||||||
|
@Value("${kafka.producer.acks}")
|
||||||
|
private String acks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kafka生产者初始化配置
|
||||||
|
* @return kafka生产者实例
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public KafkaProducer<String, String> kafkaProducer() {
|
||||||
|
HashMap<String, Object> configs = new HashMap<>();
|
||||||
|
configs.put(KafkaConfigConstants.BOOTSTRAP_SERVERS,
|
||||||
|
StrFormatter.format("{}:{}", bootstrapServersIP, bootstrapServersPort));
|
||||||
|
configs.put(KafkaConfigConstants.RETRIES, retries);
|
||||||
|
configs.put(KafkaConfigConstants.BATCH_SIZE, batchSize);
|
||||||
|
configs.put(KafkaConfigConstants.BUFFER_MEMORY, bufferMemory);
|
||||||
|
configs.put(KafkaConfigConstants.ACKS, acks);
|
||||||
|
Serializer<String> keySerializer = new StringSerializer();
|
||||||
|
Serializer<String> valueSerializer = new StringSerializer();
|
||||||
|
return new KafkaProducer<>(configs, keySerializer, valueSerializer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.muyu.common.kafka.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: wangXin
|
||||||
|
* @Date 2024/9/28 20:07
|
||||||
|
* @Description Kafka配置通用常量
|
||||||
|
*/
|
||||||
|
public class KafkaConfigConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务端ip+端口号
|
||||||
|
*/
|
||||||
|
public static final String BOOTSTRAP_SERVERS = "bootstrap.servers";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重试次数
|
||||||
|
*/
|
||||||
|
public static final String RETRIES = "retries";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认批量大小
|
||||||
|
*/
|
||||||
|
public static final String BATCH_SIZE = "batch.size";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总内存字节数
|
||||||
|
*/
|
||||||
|
public static final String BUFFER_MEMORY = "buffer-memory";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 偏移量
|
||||||
|
*/
|
||||||
|
public static final String ACKS = "acks";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启消费者偏移量
|
||||||
|
*/
|
||||||
|
public static final String ENABLE_AUTO_COMMIT = "enable.auto.commit";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动提交时间间隔
|
||||||
|
*/
|
||||||
|
public static final String AUTO_COMMIT_INTERVAL = "auto.commit.interval";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动重置偏移量
|
||||||
|
*/
|
||||||
|
public static final String AUTO_OFFSET_RESET = "auto.offset.reset";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求阻塞的最大时间
|
||||||
|
*/
|
||||||
|
public static final String FETCH_MAX_WAIT = "fetch.max.wait";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求应答的最小字节数
|
||||||
|
*/
|
||||||
|
public static final String FETCH_MIN_SIZE = "fetch.min.size";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 心跳间隔时间
|
||||||
|
*/
|
||||||
|
public static final String HEARTBEAT_INTERVAL = "heartbeat-interval";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一次调用poll返回的最大记录条数
|
||||||
|
*/
|
||||||
|
public static final String MAX_POLL_RECORDS = "max.poll.records";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定消费组
|
||||||
|
*/
|
||||||
|
public static final String GROUP_ID = "group.id";
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.muyu.common.kafka.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: WangXin
|
||||||
|
* @date: 2024/7/10
|
||||||
|
* @Description: kafka常量
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
public class KafkaConstants {
|
||||||
|
|
||||||
|
public final static String KafkaTopic = "kafka_topic";
|
||||||
|
|
||||||
|
public final static String KafkaGrop = "kafka_grop";
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
com.muyu.common.kafka.config.KafkaProducerConfig
|
||||||
|
com.muyu.common.kafka.config.KafkaConsumerConfig
|
|
@ -17,6 +17,10 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
cloud-common-rabbit 消息队列服务
|
||||||
|
</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- rabbitMq 消息队列 -->
|
<!-- rabbitMq 消息队列 -->
|
||||||
|
@ -28,7 +32,7 @@
|
||||||
<!-- 项目公共核心 -->
|
<!-- 项目公共核心 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.muyu</groupId>
|
<groupId>com.muyu</groupId>
|
||||||
<artifactId>cloud-common-core</artifactId>
|
<artifactId>cloud-common-redis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.muyu.common.rabbit.config;
|
||||||
|
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.amqp.rabbit.connection.CorrelationData;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送确认配置
|
||||||
|
* 消息发送到交换机的回调
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2
|
||||||
|
public class ConfirmCallbackConfig implements RabbitTemplate.ConfirmCallback {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
rabbitTemplate.setConfirmCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 交换机不管是否收到消息的一个回调方法
|
||||||
|
*
|
||||||
|
* @param correlationData 消息相关数据
|
||||||
|
* @param ack 交换机是否收到消息
|
||||||
|
* @param cause 失败原因
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
|
||||||
|
if (!ack) {
|
||||||
|
String exchange = correlationData.getReturned().getExchange();
|
||||||
|
String message = correlationData.getReturned().getMessage().getBody().toString();
|
||||||
|
// 发送异常
|
||||||
|
log.error("消息:{},发送到交换机:{}失败,原因是:{}", message, exchange, cause);
|
||||||
|
// TODO 可以把异常信息 以及 消息的内容直接添加到 MYSQL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
package com.muyu.common.rabbit;
|
package com.muyu.common.rabbit.config;
|
||||||
|
|
||||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
|
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
|
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
|
||||||
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
|
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class RabbitListenerConfigurer implements org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer {
|
public class RabbitListenerConfigurer implements org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer {
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ public class RabbitListenerConfigurer implements org.springframework.amqp.rabbit
|
||||||
}
|
}
|
||||||
|
|
||||||
//以下配置RabbitMQ消息服务
|
//以下配置RabbitMQ消息服务
|
||||||
@Autowired
|
@Resource
|
||||||
public ConnectionFactory connectionFactory;
|
public ConnectionFactory connectionFactory;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.muyu.common.rabbit.config;
|
||||||
|
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.amqp.core.ReturnedMessage;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送到队列的确认
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Log4j2
|
||||||
|
public class ReturnCallbackConfig implements RabbitTemplate.ReturnsCallback {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @PostContruct是spring框架的注解,在⽅法上加该注解会在项⽬启动的时候执⾏该⽅法,也可以理解为在spring容器初始化的时候执
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
rabbitTemplate.setReturnsCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息发送失败 则会执行这个方法
|
||||||
|
*
|
||||||
|
* @param returnedMessage the returned message and metadata.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void returnedMessage(ReturnedMessage returnedMessage) {
|
||||||
|
log.error("消息:{},被交换机:{} 回退!退回原因为:{}",
|
||||||
|
returnedMessage.getMessage().toString(), returnedMessage.getExchange(), returnedMessage.getReplyText());
|
||||||
|
// TODO 回退了所有的信息,可做补偿机制
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.muyu.common.rabbit.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rabbit常量
|
||||||
|
* @Author: WangXin
|
||||||
|
* @date: 2024/7/10
|
||||||
|
* @Description: rabbit常量
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
public interface RabbitConstants {
|
||||||
|
/**
|
||||||
|
* 上线队列
|
||||||
|
*/
|
||||||
|
String GO_ONLINE_QUEUE= "GoOnline";
|
||||||
|
/**
|
||||||
|
* 下线队列
|
||||||
|
*/
|
||||||
|
String DOWN_LINE_QUEUE= "DownLine";
|
||||||
|
/**
|
||||||
|
* 交换机
|
||||||
|
*/
|
||||||
|
String ONLINE_EXCHANGE = "online_exchange";
|
||||||
|
}
|
|
@ -1 +1,3 @@
|
||||||
com.muyu.common.rabbit.RabbitListenerConfigurer
|
com.muyu.common.rabbit.config.RabbitListenerConfigurer
|
||||||
|
com.muyu.common.rabbit.config.ConfirmCallbackConfig
|
||||||
|
com.muyu.common.rabbit.config.ReturnCallbackConfig
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class RedisService {
|
||||||
*
|
*
|
||||||
* @return true=设置成功;false=设置失败
|
* @return true=设置成功;false=设置失败
|
||||||
*/
|
*/
|
||||||
public boolean expire (final String key, final long timeout) {
|
public boolean expire (final String key, final Long timeout) {
|
||||||
return expire(key, timeout, TimeUnit.SECONDS);
|
return expire(key, timeout, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class RedisService {
|
||||||
*
|
*
|
||||||
* @return true=设置成功;false=设置失败
|
* @return true=设置成功;false=设置失败
|
||||||
*/
|
*/
|
||||||
public boolean expire (final String key, final long timeout, final TimeUnit unit) {
|
public boolean expire (final String key, final Long timeout, final TimeUnit unit) {
|
||||||
return redisTemplate.expire(key, timeout, unit);
|
return redisTemplate.expire(key, timeout, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public class RedisService {
|
||||||
*
|
*
|
||||||
* @return 有效时间
|
* @return 有效时间
|
||||||
*/
|
*/
|
||||||
public long getExpire (final String key) {
|
public Long getExpire (final String key) {
|
||||||
return redisTemplate.getExpire(key);
|
return redisTemplate.getExpire(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ public class RedisService {
|
||||||
*
|
*
|
||||||
* @return 缓存的对象
|
* @return 缓存的对象
|
||||||
*/
|
*/
|
||||||
public <T> long setCacheList (final String key, final List<T> dataList) {
|
public <T> Long setCacheList (final String key, final List<T> dataList) {
|
||||||
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
||||||
return count == null ? 0 : count;
|
return count == null ? 0 : count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?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>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
cloud-common-saas saas公共模块
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<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>
|
|
@ -0,0 +1,107 @@
|
||||||
|
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.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.constant.SecurityConstants;
|
||||||
|
import com.muyu.common.core.domain.Result;
|
||||||
|
import com.muyu.common.core.utils.SpringUtils;
|
||||||
|
import com.muyu.common.system.domain.SysFirmDatasource;
|
||||||
|
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.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: DongZeLiang
|
||||||
|
* @date: 2024/6/3
|
||||||
|
* @Description: 多数据源
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
@Configuration
|
||||||
|
@AutoConfiguration(before = MybatisPlusAutoConfiguration.class)
|
||||||
|
public class ManyDataSource implements ApplicationRunner {
|
||||||
|
|
||||||
|
|
||||||
|
private List<EntInfo> dataSourceInfoList(){
|
||||||
|
RemoteUserService RemoteUserService = SpringUtils.getBean(RemoteUserService.class);
|
||||||
|
Result<List<SysFirmDatasource>> listResult = RemoteUserService.selectFirmDatabaseList(SecurityConstants.INNER);
|
||||||
|
if (listResult==null){
|
||||||
|
throw new SaaSException("saas远调数据源错误");
|
||||||
|
}
|
||||||
|
List<SysFirmDatasource> data = listResult.getData();
|
||||||
|
if (listResult.getCode() ==Result.SUCCESS && data !=null){
|
||||||
|
List<EntInfo> list = new ArrayList<>();
|
||||||
|
for (SysFirmDatasource row : data) {
|
||||||
|
list.add(
|
||||||
|
EntInfo.builder()
|
||||||
|
.entCode(row.getDatabaseName())
|
||||||
|
.ip(row.getIp())
|
||||||
|
.port(row.getPort())
|
||||||
|
.userName(row.getUsername())
|
||||||
|
.password(row.getPassword())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}else {
|
||||||
|
log.error("远调数据源错误,远调数据为:{}", JSON.toJSONString(data));
|
||||||
|
throw new RuntimeException("远调数据源错误,远调--》 firmList ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DynamicDataSource dynamicDataSource() {
|
||||||
|
// 企业列表 企业CODE,端口,IP
|
||||||
|
Map<Object, Object> dataSourceMap = new HashMap<>();
|
||||||
|
dataSourceInfoList()
|
||||||
|
.stream()
|
||||||
|
.map(entInfo -> DataSourceInfo.hostAndPortBuild(
|
||||||
|
entInfo.getEntCode(),
|
||||||
|
entInfo.getIp(),
|
||||||
|
entInfo.getPort(),
|
||||||
|
entInfo.getUserName(),
|
||||||
|
entInfo.getPassword()))
|
||||||
|
.map(DruidDataSourceFactory::create)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(druidDataSource -> {
|
||||||
|
dataSourceMap.put(druidDataSource.getName(), druidDataSource);
|
||||||
|
});
|
||||||
|
//设置动态数据源
|
||||||
|
DynamicDataSource dynamicDataSource = new DynamicDataSource();
|
||||||
|
// dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
|
||||||
|
dynamicDataSource.setTargetDataSources(dataSourceMap);
|
||||||
|
//将数据源信息备份在defineTargetDataSources中
|
||||||
|
dynamicDataSource.setDefineTargetDataSources(dataSourceMap);
|
||||||
|
return dynamicDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
|
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
|
||||||
|
dataSourceInfoList()
|
||||||
|
.stream()
|
||||||
|
.map(entInfo -> DataSourceInfo.hostAndPortBuild(
|
||||||
|
entInfo.getEntCode(),
|
||||||
|
entInfo.getIp(),
|
||||||
|
entInfo.getPort(),
|
||||||
|
entInfo.getUserName(),
|
||||||
|
entInfo.getPassword()))
|
||||||
|
.map(DruidDataSourceFactory::create)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(druidDataSource -> {
|
||||||
|
dynamicDataSource.put(druidDataSource.getName(), druidDataSource);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.muyu.cloud.common.many.datasource.constents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author DongZl
|
||||||
|
* @description: 数据源常量
|
||||||
|
* @Date 2023-8-1 上午 11:02
|
||||||
|
*/
|
||||||
|
public class DatasourceContent {
|
||||||
|
|
||||||
|
public final static String DATASOURCE_URL = "jdbc:mysql://{}:{}/{}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
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 lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author DongZl
|
||||||
|
* @description: 数据源实体类
|
||||||
|
* @Date 2023-8-1 上午 11:15
|
||||||
|
*/
|
||||||
|
@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,String userName,String password) {
|
||||||
|
return DataSourceInfo.builder()
|
||||||
|
.key(key)
|
||||||
|
.url(StringUtils.format(DatasourceContent.DATASOURCE_URL, host, port, key))
|
||||||
|
.password(password)
|
||||||
|
.userName(userName)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.muyu.cloud.common.many.datasource.factory;
|
||||||
|
|
||||||
|
import com.alibaba.druid.pool.DruidDataSource;
|
||||||
|
import com.muyu.cloud.common.many.datasource.domain.model.DataSourceInfo;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: DongZeLiang
|
||||||
|
* @date: 2024/6/3
|
||||||
|
* @Description: Druid工厂
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
@Component
|
||||||
|
public class DruidDataSourceFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 根据传递的数据源信息测试数据库连接
|
||||||
|
*/
|
||||||
|
public static DruidDataSource create(DataSourceInfo dataSourceInfo) {
|
||||||
|
DruidDataSource druidDataSource = new DruidDataSource();
|
||||||
|
druidDataSource.setName(dataSourceInfo.getKey());
|
||||||
|
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 throwables) {
|
||||||
|
log.error("数据源 {} 连接失败,用户名:{},密码 {}",dataSourceInfo.getUrl(),dataSourceInfo.getUserName(),dataSourceInfo.getPassword());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.muyu.cloud.common.many.datasource.holder;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据源切换处理
|
||||||
|
*
|
||||||
|
* @author Dongzl
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.muyu.cloud.common.many.datasource.role;
|
||||||
|
|
||||||
|
import com.alibaba.druid.pool.DruidDataSource;
|
||||||
|
import com.muyu.cloud.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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态数据源
|
||||||
|
* 调用AddDefineDataSource组件的addDefineDynamicDataSource()方法,获取原来targetdatasources的map,并将新的数据源信息添加到map中,并替换targetdatasources中的map
|
||||||
|
* 切换数据源时可以使用@DataSource(value = "数据源名称"),或者DynamicDataSourceContextHolder.setContextKey("数据源名称")
|
||||||
|
* @author Dongzl
|
||||||
|
*/
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.muyu.cloud.common.saas.contents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: DongZeLiang
|
||||||
|
* @date: 2024/6/3
|
||||||
|
* @Description: SAAS常量
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class SaaSConstant {
|
||||||
|
|
||||||
|
public final static String SAAS_KEY = "ent-code";
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.muyu.cloud.common.saas.domain.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: DongZeLiang
|
||||||
|
* @date: 2024/6/3
|
||||||
|
* @Description: 企业信息
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EntInfo {
|
||||||
|
|
||||||
|
private String entCode;
|
||||||
|
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
private Integer port;
|
||||||
|
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.muyu.cloud.common.saas.exception;
|
||||||
|
|
||||||
|
|
||||||
|
import com.muyu.common.core.exception.ServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: DongZeLiang
|
||||||
|
* @date: 2024/6/3
|
||||||
|
* @Description: SaaS异常类
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class SaaSException extends ServiceException {
|
||||||
|
|
||||||
|
public SaaSException (String message, Integer code) {
|
||||||
|
super(message, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaaSException (String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空构造方法,避免反序列化问题
|
||||||
|
*/
|
||||||
|
public SaaSException () {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.muyu.cloud.common.saas.interceptor;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
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.constant.SecurityConstants;
|
||||||
|
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 lombok.extern.log4j.Log4j2;
|
||||||
|
import org.springframework.web.method.HandlerMethod;
|
||||||
|
import org.springframework.web.servlet.AsyncHandlerInterceptor;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: DongZeLiang
|
||||||
|
* @date: 2024/6/3
|
||||||
|
* @Description: SAAS拦截器
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
public class SaaSInterceptor implements AsyncHandlerInterceptor {
|
||||||
|
|
||||||
|
private Boolean flag = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 之前
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
if (!(handler instanceof HandlerMethod)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String SaaSKey = ServletUtils.getHeader(request, SecurityConstants.FIRM_KEY);
|
||||||
|
if (SaaSKey == null) {
|
||||||
|
throw new SaaSException("SaaS非法访问");
|
||||||
|
}
|
||||||
|
if (SaaSKey.equals("1")){
|
||||||
|
log.info("使用 [ nacos ] 配置数据库 ");
|
||||||
|
flag = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicDataSource dynamicDataSource = SpringUtils.getBean(DynamicDataSource.class);
|
||||||
|
if (!dynamicDataSource.hashKey(SaaSKey)){
|
||||||
|
throw new SaaSException("SaaS非法访问");
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicDataSourceHolder.setDynamicDataSourceKey(SaaSKey);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 之后
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterConcurrentHandlingStarted (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
if (flag){
|
||||||
|
DynamicDataSourceHolder.removeDynamicDataSourceKey();
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.muyu.cloud.common.saas.interceptor;
|
||||||
|
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截器配置
|
||||||
|
*
|
||||||
|
* @author muyu
|
||||||
|
*/
|
||||||
|
public class WebMvcSaaSConfig implements WebMvcConfigurer {
|
||||||
|
/**
|
||||||
|
* 不需要拦截的地址
|
||||||
|
*/
|
||||||
|
public static final String[] excludeUrls = {"/login", "/logout", "/refresh"};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors (InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(getHeaderInterceptor())
|
||||||
|
.addPathPatterns("/**")
|
||||||
|
.excludePathPatterns(excludeUrls)
|
||||||
|
.order(-10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义请求头拦截器
|
||||||
|
*/
|
||||||
|
public SaaSInterceptor getHeaderInterceptor () {
|
||||||
|
return new SaaSInterceptor();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
com.muyu.cloud.common.saas.interceptor.WebMvcSaaSConfig
|
||||||
|
com.muyu.cloud.common.many.datasource.ManyDataSource
|
||||||
|
com.muyu.cloud.common.many.datasource.factory.DruidDataSourceFactory
|
|
@ -27,11 +27,11 @@ import java.util.concurrent.TimeUnit;
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class TokenService {
|
public class TokenService {
|
||||||
protected static final long MILLIS_SECOND = 1000;
|
protected static final Long MILLIS_SECOND = 1000L;
|
||||||
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
protected static final Long MILLIS_MINUTE = 60 * MILLIS_SECOND;
|
||||||
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
|
private final static Long MILLIS_MINUTE_TEN = CacheConstants.REFRESH_TIME * MILLIS_MINUTE;
|
||||||
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
|
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
|
||||||
private final static long expireTime = CacheConstants.EXPIRATION;
|
private final static Long expireTime = CacheConstants.EXPIRATION;
|
||||||
|
|
||||||
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
|
private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -43,6 +43,7 @@ public class TokenService {
|
||||||
public Map<String, Object> createToken (LoginUser loginUser) {
|
public Map<String, Object> createToken (LoginUser loginUser) {
|
||||||
String token = IdUtils.fastUUID();
|
String token = IdUtils.fastUUID();
|
||||||
Long userId = loginUser.getSysUser().getUserId();
|
Long userId = loginUser.getSysUser().getUserId();
|
||||||
|
Long firmId = loginUser.getSysUser().getFirmId();
|
||||||
String userName = loginUser.getSysUser().getUserName();
|
String userName = loginUser.getSysUser().getUserName();
|
||||||
loginUser.setToken(token);
|
loginUser.setToken(token);
|
||||||
loginUser.setUserid(userId);
|
loginUser.setUserid(userId);
|
||||||
|
@ -55,7 +56,8 @@ public class TokenService {
|
||||||
claimsMap.put(SecurityConstants.USER_KEY, token);
|
claimsMap.put(SecurityConstants.USER_KEY, token);
|
||||||
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
|
claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
|
||||||
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
|
claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
|
||||||
|
claimsMap.put(SecurityConstants.FIRM_KEY, loginUser.getSysUser().getDatabaseName());
|
||||||
|
claimsMap.put(SecurityConstants.FIRM_ID, loginUser.getSysUser().getFirmId());
|
||||||
// 接口返回信息
|
// 接口返回信息
|
||||||
Map<String, Object> rspMap = new HashMap<String, Object>();
|
Map<String, Object> rspMap = new HashMap<String, Object>();
|
||||||
rspMap.put("access_token", JwtUtils.createToken(claimsMap));
|
rspMap.put("access_token", JwtUtils.createToken(claimsMap));
|
||||||
|
@ -127,8 +129,8 @@ public class TokenService {
|
||||||
* @param loginUser
|
* @param loginUser
|
||||||
*/
|
*/
|
||||||
public void verifyToken (LoginUser loginUser) {
|
public void verifyToken (LoginUser loginUser) {
|
||||||
long expireTime = loginUser.getExpireTime();
|
Long expireTime = loginUser.getExpireTime();
|
||||||
long currentTime = System.currentTimeMillis();
|
Long currentTime = System.currentTimeMillis();
|
||||||
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
|
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
|
||||||
refreshToken(loginUser);
|
refreshToken(loginUser);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,5 +25,9 @@
|
||||||
<groupId>com.muyu</groupId>
|
<groupId>com.muyu</groupId>
|
||||||
<artifactId>cloud-common-core</artifactId>
|
<artifactId>cloud-common-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger.core.v3</groupId>
|
||||||
|
<artifactId>swagger-annotations-jakarta</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -16,7 +16,7 @@ import java.util.Set;
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class LoginUser implements Serializable {
|
public class LoginUser implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户唯一标识
|
* 用户唯一标识
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysDept extends BaseEntity {
|
public class SysDept extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门ID
|
* 部门ID
|
||||||
|
@ -79,6 +79,11 @@ public class SysDept extends BaseEntity {
|
||||||
*/
|
*/
|
||||||
private String parentName;
|
private String parentName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司Id
|
||||||
|
*/
|
||||||
|
private Long firmId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 子部门
|
* 子部门
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -21,7 +21,7 @@ import jakarta.validation.constraints.Size;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysDictData extends BaseEntity {
|
public class SysDictData extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典编码
|
* 字典编码
|
||||||
|
|
|
@ -21,7 +21,7 @@ import jakarta.validation.constraints.Size;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysDictType extends BaseEntity {
|
public class SysDictType extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典主键
|
* 字典主键
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.muyu.common.system.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司信息
|
||||||
|
*
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/10/9
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Tag(name = "公司信息")
|
||||||
|
@TableName("sys_firm")
|
||||||
|
public class SysFirm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司Id
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
@Schema(name = "公司Id")
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 公司名称
|
||||||
|
*/
|
||||||
|
@Schema(name = "公司名称")
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 公司数据源
|
||||||
|
*/
|
||||||
|
@Schema(name = "公司数据源")
|
||||||
|
private Long did;
|
||||||
|
/**
|
||||||
|
* 公司logo
|
||||||
|
*/
|
||||||
|
@Schema(name = "公司logo")
|
||||||
|
private String logo;
|
||||||
|
/**
|
||||||
|
* 唯一标识
|
||||||
|
*/
|
||||||
|
@Schema(name = "唯一标识")
|
||||||
|
private String sole;
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
@Schema(name = "车辆状态")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.muyu.common.system.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/10/2
|
||||||
|
* @Description 数据源信息
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Tag(name = "数据源信息")
|
||||||
|
@TableName("sys_firm_datasource")
|
||||||
|
public class SysFirmDatasource {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据源Id
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源Id")
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 数据源url
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源url")
|
||||||
|
private String datasourceUrl;
|
||||||
|
/**
|
||||||
|
* 数据源用户名
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源用户名")
|
||||||
|
private String username;
|
||||||
|
/**
|
||||||
|
* 数据源密码
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源密码")
|
||||||
|
private String password;
|
||||||
|
/**
|
||||||
|
* 数据源IP
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源IP")
|
||||||
|
private String ip;
|
||||||
|
/**
|
||||||
|
* 数据源端口号
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源端口号")
|
||||||
|
private Integer port;
|
||||||
|
/**
|
||||||
|
* 数据源库名
|
||||||
|
*/
|
||||||
|
@Schema(name = "数据源库名")
|
||||||
|
private String databaseName;
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ import java.util.Date;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysLogininfor extends BaseEntity {
|
public class SysLogininfor extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID
|
* ID
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Date;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysOperLog extends BaseEntity {
|
public class SysOperLog extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志主键
|
* 日志主键
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.Set;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysRole extends BaseEntity {
|
public class SysRole extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色ID
|
* 角色ID
|
||||||
|
|
|
@ -29,7 +29,7 @@ import java.util.List;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class SysUser extends BaseEntity {
|
public class SysUser extends BaseEntity {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final Long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户ID
|
* 用户ID
|
||||||
|
@ -134,6 +134,15 @@ public class SysUser extends BaseEntity {
|
||||||
* 角色ID
|
* 角色ID
|
||||||
*/
|
*/
|
||||||
private Long roleId;
|
private Long roleId;
|
||||||
|
/**
|
||||||
|
* 公司Id
|
||||||
|
*/
|
||||||
|
private Long firmId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司数据库
|
||||||
|
*/
|
||||||
|
private String databaseName;
|
||||||
|
|
||||||
public SysUser (Long userId) {
|
public SysUser (Long userId) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.muyu.common.system.domain.resp;
|
||||||
|
|
||||||
|
import com.muyu.common.system.domain.SysFirm;
|
||||||
|
import com.muyu.common.system.domain.SysFirmDatasource;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公司信息响应对象
|
||||||
|
*
|
||||||
|
* @Author WangXin
|
||||||
|
* @Data 2024/10/9
|
||||||
|
* @Version 1.0.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Tag(name = "公司信息响应对象")
|
||||||
|
public class SysFirmResp {
|
||||||
|
/**
|
||||||
|
* 公司信息
|
||||||
|
*/
|
||||||
|
@Schema(name = "公司信息")
|
||||||
|
private SysFirm firm;
|
||||||
|
/**
|
||||||
|
* 公司数据源信息
|
||||||
|
*/
|
||||||
|
@Schema(name = "公司数据源信息")
|
||||||
|
private SysFirmDatasource firmDatasource;
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue