微服务版后端初始化
This commit is contained in:
153
xjrsoft-common/xjrsoft-common-mybatis/pom.xml
Normal file
153
xjrsoft-common/xjrsoft-common-mybatis/pom.xml
Normal file
@ -0,0 +1,153 @@
|
||||
<?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">
|
||||
<parent>
|
||||
<artifactId>xjrsoft-common</artifactId>
|
||||
<groupId>com.xjrsoft</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>xjrsoft-common-mybatis</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--引入Lombok依赖-->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
<!--引入mybatis-plus依赖-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis-plus 多表关联 -->
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xjrsoft</groupId>
|
||||
<artifactId>xjrsoft-common-core</artifactId>
|
||||
<version>${xjrsoft.framework.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--引入oracle依赖-->
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc7</artifactId>
|
||||
<version>12.1.0.1.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/ojdbc7.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入kingbase依赖 -->
|
||||
<dependency>
|
||||
<groupId>kingbase</groupId>
|
||||
<artifactId>kingbase</artifactId>
|
||||
<version>8.6.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/kingbase8-8.6.0.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<!--引入达梦依赖-->
|
||||
<dependency>
|
||||
<groupId>com.dm</groupId>
|
||||
<artifactId>DmJdbcDriver</artifactId>
|
||||
<version>8.1.2.192</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/resources/lib/DmJdbcDriver18-8.1.2.192.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xjrsoft</groupId>
|
||||
<artifactId>xjrsoft-common-satoken</artifactId>
|
||||
<version>${xjrsoft.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xjrsoft</groupId>
|
||||
<artifactId>xjrsoft-common-generate</artifactId>
|
||||
<version>${xjrsoft.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xjrsoft</groupId>
|
||||
<artifactId>xjrsoft-common-redis</artifactId>
|
||||
<version>${xjrsoft.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.xjrsoft</groupId>
|
||||
<artifactId>xjrsoft-common-tenant</artifactId>
|
||||
<version>${xjrsoft.framework.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ssssssss</groupId>
|
||||
<artifactId>magic-api-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,293 @@
|
||||
package com.xjrsoft.common.mybatis;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.GlobalDbConfig;
|
||||
import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
|
||||
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidConfig;
|
||||
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||
import com.xjrsoft.common.core.constant.GlobalConstant;
|
||||
import com.xjrsoft.common.mybatis.handler.MyLocalDateTimeTypeHandler;
|
||||
import com.xjrsoft.common.mybatis.handler.XjrLocalTimeTypeHandler;
|
||||
import com.xjrsoft.common.mybatis.interceptor.DataScopeInnerInterceptor;
|
||||
import com.xjrsoft.common.mybatis.utils.DatasourceUtil;
|
||||
import com.xjrsoft.tenant.config.TenantConfig;
|
||||
import com.xjrsoft.tenant.util.SecureUtil;
|
||||
import com.xjrsoft.tenant.util.TenantUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import org.apache.ibatis.type.BooleanTypeHandler;
|
||||
import org.apache.ibatis.type.EnumTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @Author: tzx
|
||||
* @Date: 2023/9/26 15:17
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class MybatisplusAutoConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private final DynamicDataSourceProperties dynamicDataSourceProperties;
|
||||
|
||||
private final Map<String, String> datasourceMap = new HashMap<>();
|
||||
|
||||
private final TenantConfig tenantConfig;
|
||||
|
||||
|
||||
/**
|
||||
* 新多租户插件配置,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存万一出现问题
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
|
||||
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
|
||||
if(!tenantConfig.getEnabled()){
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
// 如果用了分页插件注意先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
|
||||
// 用了分页插件必须设置 MybatisConfiguration#useDeprecatedExecutor = false
|
||||
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
|
||||
|
||||
@Override
|
||||
public Expression getTenantId() {
|
||||
if (TenantUtil.isNoTenant()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new LongValue(SecureUtil.getTenantId());
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("获取当前登录用户租户码失败");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件
|
||||
@Override
|
||||
public boolean ignoreTable(String tableName) {
|
||||
if (TenantUtil.isNoTenant()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return tenantConfig.getIgnoreTable().contains(tableName);
|
||||
}
|
||||
}));
|
||||
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页插件
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor paginationInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据权限插件
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor dataScopeInnerInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new DataScopeInnerInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 防止全表更新与删除
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor blockAttackInnerInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DynamicDataSourceProvider dynamicDataSourceProvider() {
|
||||
// 自定义表单hutool包配置,查询表单发布的菜单数据,设置返回的字段名大小写敏感
|
||||
GlobalDbConfig.setCaseInsensitive(false);
|
||||
DataSourceProperty datasource = dynamicDataSourceProperties.getDatasource().get(GlobalConstant.DEFAULT_DATASOURCE_KEY);
|
||||
return new AbstractJdbcDataSourceProvider(datasource.getDriverClassName(), datasource.getUrl(), datasource.getUsername(), datasource.getPassword()) {
|
||||
|
||||
@Override
|
||||
protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
|
||||
Map<String, DataSourceProperty> map = new HashMap<>(16);
|
||||
|
||||
// 数据库里的所有库
|
||||
ResultSet rs = statement.executeQuery("SELECT * FROM xjr_databaselink WHERE delete_mark = 0 AND enabled_mark = 1");
|
||||
while (rs.next()) {
|
||||
long id = rs.getLong("id");
|
||||
String host = rs.getString("host");
|
||||
String username = rs.getString("username");
|
||||
String password = rs.getString("password");
|
||||
String driver = rs.getString("driver");
|
||||
String dbType = rs.getString("db_type");
|
||||
|
||||
//缓存起来
|
||||
datasourceMap.put(Convert.toStr(id), rs.getString("db_name"));
|
||||
|
||||
DataSourceProperty property = new DataSourceProperty();
|
||||
property.setUsername(username);
|
||||
property.setPassword(password);
|
||||
property.setUrl(host);
|
||||
property.setDriverClassName(driver);
|
||||
// 测试连接,如果连接不上则跳过,避免启动失败
|
||||
if (!DatasourceUtil.testConnection(host, username, password)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DruidConfig druidConfig = property.getDruid();
|
||||
druidConfig.setInitialSize(10); // 初始化大小
|
||||
druidConfig.setMaxActive(100);// 最大连接池
|
||||
druidConfig.setMinIdle(10);// 最小连接池
|
||||
druidConfig.setMaxWait(60000); //最大等待超时时间
|
||||
druidConfig.setPoolPreparedStatements(false); // 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
|
||||
druidConfig.setMaxPoolPreparedStatementPerConnectionSize(20);//是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
|
||||
druidConfig.setTimeBetweenEvictionRunsMillis(60000L);// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
druidConfig.setMinEvictableIdleTimeMillis(300000L); // 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
if (StrUtil.equals(dbType, "oracle")) {
|
||||
druidConfig.setValidationQuery("SELECT 1 FROM DUAL");
|
||||
} else {
|
||||
druidConfig.setValidationQuery("SELECT 1 "); //测试链接 语句
|
||||
}
|
||||
druidConfig.setTestWhileIdle(true);
|
||||
druidConfig.setTestOnReturn(false);
|
||||
druidConfig.setTestOnBorrow(false);
|
||||
druidConfig.setFilters("stat,slf4j"); // # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
|
||||
druidConfig.setUseGlobalDataSourceStat(true);
|
||||
Properties properties = new Properties();
|
||||
properties.put("druid.stat.mergeSql", true); //打开mergeSql功能
|
||||
properties.put("druid.stat.slowSqlMillis", true); // 打开慢sql 记录功能
|
||||
druidConfig.setConnectionProperties(properties);
|
||||
|
||||
map.put(Long.toString(id), property);
|
||||
|
||||
}
|
||||
// yml配置的数据源
|
||||
Map<String, DataSourceProperty> datasourceMap = dynamicDataSourceProperties.getDatasource();
|
||||
for (DataSourceProperty dataSourceProperty : datasourceMap.values()) {
|
||||
// 测试连接,如果连接不上则跳过,避免启动失败
|
||||
if (!DatasourceUtil.testConnection(dataSourceProperty.getUrl(), dataSourceProperty.getUsername(), dataSourceProperty.getPassword())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DruidConfig druidConfig = dataSourceProperty.getDruid();
|
||||
druidConfig.setInitialSize(10); // 初始化大小
|
||||
druidConfig.setMaxActive(100);// 最大连接池
|
||||
druidConfig.setMinIdle(10);// 最小连接池
|
||||
druidConfig.setMaxWait(60000); //最大等待超时时间
|
||||
druidConfig.setPoolPreparedStatements(false); // 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
|
||||
druidConfig.setMaxPoolPreparedStatementPerConnectionSize(20);//是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
|
||||
druidConfig.setTimeBetweenEvictionRunsMillis(60000L);// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
druidConfig.setMinEvictableIdleTimeMillis(300000L); // 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||
if (dataSourceProperty.getUrl().contains("oracle")) {
|
||||
druidConfig.setValidationQuery("SELECT 1 FROM DUAL"); //测试链接 如果是oracle 语句不一样
|
||||
} else {
|
||||
druidConfig.setValidationQuery("SELECT 1 "); //测试链接 语句
|
||||
}
|
||||
druidConfig.setTestWhileIdle(true);
|
||||
druidConfig.setTestOnReturn(false);
|
||||
druidConfig.setTestOnBorrow(false);
|
||||
druidConfig.setFilters("stat,slf4j"); // # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
|
||||
druidConfig.setUseGlobalDataSourceStat(true);
|
||||
Properties properties = new Properties();
|
||||
properties.put("druid.stat.mergeSql", true); //打开mergeSql功能
|
||||
properties.put("druid.stat.slowSqlMillis", true); // 打开慢sql 记录功能
|
||||
druidConfig.setConnectionProperties(properties);
|
||||
}
|
||||
map.putAll(datasourceMap);
|
||||
|
||||
rs.close();
|
||||
return map;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置MagicApi多数据源
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public MagicDynamicDataSource magicDynamicDataSource() {
|
||||
|
||||
MagicDynamicDataSource dynamicDataSource = new MagicDynamicDataSource();
|
||||
|
||||
Map<String, DataSource> dataSources = dynamicDataSourceProvider().loadDataSources();
|
||||
for (String ds : dataSources.keySet()) {
|
||||
if (StrUtil.equals(GlobalConstant.DEFAULT_DATASOURCE_KEY, ds)) {
|
||||
dynamicDataSource.setDefault(dataSources.get(ds));
|
||||
} else {
|
||||
|
||||
//缓存起来的name
|
||||
if (datasourceMap.containsKey(ds)) {
|
||||
String name = MapUtil.getStr(datasourceMap, ds);
|
||||
dynamicDataSource.add(name, dataSources.get(ds));
|
||||
}
|
||||
//配置在yml上的 可能获取不到name
|
||||
else {
|
||||
dynamicDataSource.add("datasource_" + ds, dataSources.get(ds));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return dynamicDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* MybatisPlus数据库类型处理
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public ConfigurationCustomizer getConfig(){
|
||||
return new ConfigurationCustomizer() {
|
||||
@Override
|
||||
public void customize(MybatisConfiguration configuration) {
|
||||
configuration.setMapUnderscoreToCamelCase(true);
|
||||
configuration.setJdbcTypeForNull(JdbcType.NULL);
|
||||
configuration.getTypeAliasRegistry().registerAlias("EnumTypeHandler", EnumTypeHandler.class);
|
||||
configuration.getTypeAliasRegistry().registerAlias("BooleanTypeHandler", BooleanTypeHandler.class);
|
||||
configuration.getTypeAliasRegistry().registerAlias("AbstractJsonTypeHandler", AbstractJsonTypeHandler.class);
|
||||
configuration.getTypeHandlerRegistry().register(LocalDateTime.class, MyLocalDateTimeTypeHandler.class);
|
||||
configuration.getTypeHandlerRegistry().register(LocalTime.class, XjrLocalTimeTypeHandler.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,193 @@
|
||||
package com.xjrsoft.common.mybatis.config;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.excel.converters.ConverterKeyBuild;
|
||||
import com.alibaba.excel.converters.DefaultConverterLoader;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.xjrsoft.common.mybatis.handler.EasyExcelLocalDateTimeConverter;
|
||||
import com.xjrsoft.common.mybatis.handler.EasyExcelLocalTimeConverter;
|
||||
import com.xjrsoft.common.mybatis.utils.LocalDateTimeUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import oracle.sql.INTERVALDS;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* @Author: tzx
|
||||
* @Date: 2022/8/2 16:54
|
||||
*/
|
||||
@Configuration
|
||||
public class JacksonConfig {
|
||||
|
||||
@Value("${spring.jackson.date-format}")
|
||||
private String pattern;
|
||||
|
||||
/**
|
||||
* 默认设置所有long类型 序列化返回前端 全变成string
|
||||
* 所有LocalDatetime 序列号返回前端 全部格式化
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
|
||||
return builder -> {
|
||||
builder.serializerByType(Long.class, ToStringSerializer.instance);
|
||||
builder.serializerByType(Long.TYPE, ToStringSerializer.instance);
|
||||
builder.serializerByType(BigDecimal.class, bigDecimalSerializer());
|
||||
builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
|
||||
builder.serializerByType(INTERVALDS.class, intervalDSSerializer());
|
||||
builder.featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);
|
||||
builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
|
||||
builder.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||
builder.visibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
|
||||
builder.visibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
|
||||
builder.visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Jackson格式化BigDecimal类型数据
|
||||
* @return
|
||||
*/
|
||||
public ToStringSerializerBase bigDecimalSerializer() {
|
||||
return new ToStringSerializerBase(BigDecimal.class) {
|
||||
protected final static int MAX_BIG_DECIMAL_SCALE = 9999;
|
||||
@Override
|
||||
public String valueToString(Object value) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
if (gen.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN)) {
|
||||
final BigDecimal bd = (BigDecimal) value;
|
||||
// 24-Aug-2016, tatu: [core#315] prevent possible DoS vector, so we need this
|
||||
if (!_verifyBigDecimalRange(gen, bd)) {
|
||||
// ... but wouldn't it be nice to trigger error via generator? Alas,
|
||||
// no method to do that. So we'll do...
|
||||
final String errorMsg = String.format(
|
||||
"Attempt to write plain `java.math.BigDecimal` (see JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN) with illegal scale (%d): needs to be between [-%d, %d]",
|
||||
bd.scale(), MAX_BIG_DECIMAL_SCALE, MAX_BIG_DECIMAL_SCALE);
|
||||
provider.reportMappingProblem(errorMsg);
|
||||
}
|
||||
// text = bd.toPlainString();
|
||||
gen.writeNumber(bd);
|
||||
} else {
|
||||
gen.writeString(value.toString());
|
||||
}
|
||||
}
|
||||
// 24-Aug-2016, tatu: [core#315] prevent possible DoS vector, so we need this
|
||||
protected boolean _verifyBigDecimalRange(JsonGenerator gen, BigDecimal value) throws IOException {
|
||||
int scale = value.scale();
|
||||
return ((scale >= -MAX_BIG_DECIMAL_SCALE) && (scale <= MAX_BIG_DECIMAL_SCALE));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* localDatetime格式化
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public LocalDateTimeSerializer localDateTimeSerializer(){
|
||||
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* oracle字段类型INTERVALDS格式化
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public JsonSerializer<INTERVALDS> intervalDSSerializer() {
|
||||
return new JsonSerializer<INTERVALDS>() {
|
||||
@Override
|
||||
public void serialize(INTERVALDS time, JsonGenerator g, SerializerProvider provider) throws IOException {
|
||||
g.writeString(LocalDateTimeUtil.convertIntervalToLocalTime(time).format(DateTimeFormatter.ISO_LOCAL_TIME));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* localDatetime格式化
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public JsonDeserializer<LocalDateTime> localDateTimeDeserializer(){
|
||||
final String pattern = this.pattern;
|
||||
return new JsonDeserializer<LocalDateTime>(){
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public LocalDateTime deserialize(JsonParser p, DeserializationContext context) throws IOException {
|
||||
String value = p.getText();
|
||||
if (StrUtil.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
Class<?> aClass = p.getCurrentValue().getClass();
|
||||
Field field = ReflectUtil.getField(aClass, p.getCurrentName());
|
||||
String format = pattern;
|
||||
JsonFormat annotation = field.getAnnotation(JsonFormat.class);
|
||||
if (annotation != null) {
|
||||
format = StringUtils.defaultIfEmpty(annotation.pattern(), pattern);
|
||||
}
|
||||
return LocalDateTimeUtil.parseDate(value, format);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter<String, LocalDateTime> stringToLocalDateTimeConverter() {
|
||||
/** EasyExcel时间格式配置 */
|
||||
EasyExcelLocalDateTimeConverter dateTimeConverter = new EasyExcelLocalDateTimeConverter();
|
||||
DefaultConverterLoader.loadDefaultReadConverter().put(ConverterKeyBuild.buildKey(dateTimeConverter.supportJavaTypeKey(), dateTimeConverter.supportExcelTypeKey()), dateTimeConverter);
|
||||
DefaultConverterLoader.loadDefaultWriteConverter().put(ConverterKeyBuild.buildKey(dateTimeConverter.supportJavaTypeKey(), dateTimeConverter.supportExcelTypeKey()), dateTimeConverter);
|
||||
DefaultConverterLoader.loadDefaultWriteConverter().put(ConverterKeyBuild.buildKey(dateTimeConverter.supportJavaTypeKey()), dateTimeConverter);
|
||||
EasyExcelLocalTimeConverter timeConverter = new EasyExcelLocalTimeConverter();
|
||||
DefaultConverterLoader.loadDefaultReadConverter().put(ConverterKeyBuild.buildKey(timeConverter.supportJavaTypeKey(), timeConverter.supportExcelTypeKey()), timeConverter);
|
||||
DefaultConverterLoader.loadDefaultWriteConverter().put(ConverterKeyBuild.buildKey(timeConverter.supportJavaTypeKey(), timeConverter.supportExcelTypeKey()), timeConverter);
|
||||
DefaultConverterLoader.loadDefaultWriteConverter().put(ConverterKeyBuild.buildKey(timeConverter.supportJavaTypeKey()), timeConverter);
|
||||
/***/
|
||||
return new Converter<String, LocalDateTime>() {
|
||||
@Override
|
||||
public LocalDateTime convert(String value) {
|
||||
return LocalDateTimeUtil.parseDateByLength(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Converter<String, LocalTime> stringToLocalTimeConverter() {
|
||||
return new Converter<String, LocalTime>(){
|
||||
|
||||
@Override
|
||||
public LocalTime convert(String value) {
|
||||
if (StrUtil.isNotBlank(value)) {
|
||||
return LocalTime.parse(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
@Component
|
||||
@MappedTypes(Clob.class)
|
||||
public class ClobTypeHandler extends BaseTypeHandler<Clob> {
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, Clob parameter, JdbcType jdbcType) throws SQLException {
|
||||
ps.setCharacterStream(i, parameter.getCharacterStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
return rs.getClob(columnName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
return rs.getClob(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
return cs.getClob(columnIndex);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||
import com.alibaba.excel.metadata.data.ReadCellData;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.xjrsoft.common.mybatis.utils.LocalDateTimeUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Component
|
||||
public class EasyExcelLocalDateTimeConverter implements Converter<LocalDateTime> {
|
||||
|
||||
@Override
|
||||
public Class<LocalDateTime> supportJavaTypeKey() {
|
||||
return LocalDateTime.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellDataTypeEnum supportExcelTypeKey() {
|
||||
return CellDataTypeEnum.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
return LocalDateTimeUtil.parseDate(cellData.getStringValue(), getFormat(contentProperty));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteCellData<LocalDateTime> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
return new WriteCellData<>(value.format(DateTimeFormatter.ofPattern(getFormat(contentProperty))));
|
||||
}
|
||||
|
||||
private String getFormat(ExcelContentProperty contentProperty) {
|
||||
JsonFormat annotation = contentProperty.getField().getAnnotation(JsonFormat.class);
|
||||
String format = DatePattern.NORM_DATETIME_PATTERN;
|
||||
if (annotation != null) {
|
||||
format = annotation.pattern();
|
||||
}
|
||||
return format;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||
import com.alibaba.excel.metadata.data.ReadCellData;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||
import com.xjrsoft.common.mybatis.utils.LocalDateTimeUtil;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
@Component
|
||||
public class EasyExcelLocalTimeConverter implements Converter<LocalTime> {
|
||||
|
||||
@Override
|
||||
public Class<LocalTime> supportJavaTypeKey() {
|
||||
return LocalTime.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellDataTypeEnum supportExcelTypeKey() {
|
||||
return CellDataTypeEnum.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
return LocalDateTimeUtil.parseTime(cellData.getStringValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteCellData<LocalDateTime> convertToExcelData(LocalTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
|
||||
return new WriteCellData<>(LocalDateTimeUtil.format(value));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
@MappedTypes(Blob.class)
|
||||
@Component
|
||||
public class MyBlobTypeHandler extends BaseTypeHandler<Blob> {
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, Blob parameter, JdbcType jdbcType) throws SQLException {
|
||||
ps.setBinaryStream(i, parameter.getBinaryStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
return rs.getBlob(columnName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
return rs.getBlob(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
return cs.getBlob(columnIndex);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@MappedJdbcTypes(value = {JdbcType.CLOB, JdbcType.NCLOB})
|
||||
@Component
|
||||
public class MyClobTypeHandler extends BaseTypeHandler<String> {
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
ps.setNString(i, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet rs, String columnName)
|
||||
throws SQLException {
|
||||
return rs.getNString(columnName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet rs, int columnIndex)
|
||||
throws SQLException {
|
||||
return rs.getNString(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(CallableStatement cs, int columnIndex)
|
||||
throws SQLException {
|
||||
return cs.getNString(columnIndex);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import oracle.sql.TIMESTAMP;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.LocalDateTimeTypeHandler;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author Zexy
|
||||
*/
|
||||
public class MyLocalDateTimeTypeHandler extends LocalDateTimeTypeHandler {
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
ps.setObject(i, Timestamp.valueOf(parameter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
Object object = rs.getObject(columnName);
|
||||
return getLocalDateTime(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
Object object = rs.getObject(columnIndex);
|
||||
return getLocalDateTime(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
Object object = cs.getObject(columnIndex);
|
||||
return getLocalDateTime(object);
|
||||
}
|
||||
|
||||
private static LocalDateTime getLocalDateTime(Object object) throws SQLException {
|
||||
if (object instanceof LocalDateTime) {
|
||||
return (LocalDateTime) object;
|
||||
} else if(object instanceof Timestamp){//在这里强行转换,将sql的时间转换为LocalDateTime
|
||||
return ((Timestamp)object).toLocalDateTime();
|
||||
} else if (object instanceof TIMESTAMP) {
|
||||
return ((TIMESTAMP) object).timestampValue().toLocalDateTime();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.xjrsoft.common.core.constant.GlobalConstant;
|
||||
import com.xjrsoft.common.core.enums.DeleteMark;
|
||||
import com.xjrsoft.common.core.enums.EnabledMark;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
||||
/**
|
||||
* @title 数据审计处理器
|
||||
* @desc 用于新增或者更新 自动插入 相应字段
|
||||
* @author tzx
|
||||
* @create 2020年11月9日 11:30:59
|
||||
* */
|
||||
@Slf4j
|
||||
@Component
|
||||
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
|
||||
/**
|
||||
* @title 新增自动填充
|
||||
* @desc fieldName 使用实体类字段名 而不是数据库字段名
|
||||
* */
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
long userId = 0L;
|
||||
try {
|
||||
userId = StpUtil.getLoginIdAsLong();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("获取当前登录用户Id失败", e);
|
||||
}
|
||||
|
||||
//如果需要自定义主键生成策略 在此按照自己想法生成主键值
|
||||
//this.strictInsertFill(metaObject, {主键字段名}, {主键字段类型.class}, {自己生成的主键id值});
|
||||
//例如: this.strictInsertFill(metaObject, "id", Integer.class, 10000000000000);
|
||||
|
||||
//默认插入创建人Id
|
||||
this.strictInsertFill(metaObject, GlobalConstant.CREATE_USER_ID_PROPERTY, Long.class, userId);
|
||||
//默认插入创建时间
|
||||
this.strictInsertFill(metaObject, GlobalConstant.CREATE_DATE_PROPERTY, LocalDateTime.class, LocalDateTime.now());
|
||||
//默认插入未删除
|
||||
this.strictInsertFill(metaObject, GlobalConstant.DELETE_MARK_PROPERTY, Integer.class, DeleteMark.NODELETE.getCode());
|
||||
//默认插入已启用
|
||||
this.strictInsertFill(metaObject, GlobalConstant.ENABLED_MARK_PROPERTY, Integer.class, EnabledMark.ENABLED.getCode());
|
||||
//权限所属人id
|
||||
this.strictInsertFill(metaObject, GlobalConstant.AUTH_USER_ID_PROPERTY, Long.class, userId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title 修改自动填充
|
||||
* @desc fieldName 使用实体类字段名 而不是数据库字段名
|
||||
* */
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
long userId = 0L;
|
||||
try {
|
||||
userId = StpUtil.getLoginIdAsLong();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("获取当前登录用户Id失败", e);
|
||||
}
|
||||
//默认插入修改人Id
|
||||
this.strictUpdateFill(metaObject, GlobalConstant.MODIFY_USER_ID_PROPERTY, Long.class, userId);
|
||||
//默认插入修改时间
|
||||
this.strictUpdateFill(metaObject, GlobalConstant.MODIFY_DATE_PROPERTY, LocalDateTime.class, LocalDateTime.now());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@MappedJdbcTypes(value = JdbcType.NVARCHAR)
|
||||
@Component
|
||||
public class MyNVarCharTypeHandler extends BaseTypeHandler<String> {
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
ps.setNString(i, parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet rs, String columnName)
|
||||
throws SQLException {
|
||||
return rs.getString(columnName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet rs, int columnIndex)
|
||||
throws SQLException {
|
||||
return rs.getNString(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(CallableStatement cs, int columnIndex)
|
||||
throws SQLException {
|
||||
return cs.getNString(columnIndex);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.handler.RsHandler;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class XjrEntityHandler implements RsHandler<Entity> {
|
||||
/** 是否大小写不敏感 */
|
||||
private final boolean caseInsensitive;
|
||||
|
||||
/**
|
||||
* 创建一个 EntityHandler对象
|
||||
* @return EntityHandler对象
|
||||
*/
|
||||
public static XjrEntityHandler create() {
|
||||
return new XjrEntityHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public XjrEntityHandler() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param caseInsensitive 是否大小写不敏感
|
||||
*/
|
||||
public XjrEntityHandler(boolean caseInsensitive) {
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity handle(ResultSet rs) throws SQLException {
|
||||
final ResultSetMetaData meta = rs.getMetaData();
|
||||
final int columnCount = meta.getColumnCount();
|
||||
|
||||
return rs.next() ? XjrHandleHelper.handleRow(columnCount, meta, rs, this.caseInsensitive) : null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.handler.RsHandler;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class XjrEntityListHandler implements RsHandler<List<Entity>> {
|
||||
|
||||
/** 是否大小写不敏感 */
|
||||
private final boolean caseInsensitive;
|
||||
|
||||
/**
|
||||
* 创建一个 EntityListHandler对象
|
||||
* @return EntityListHandler对象
|
||||
*/
|
||||
public static XjrEntityListHandler create() {
|
||||
return new XjrEntityListHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public XjrEntityListHandler() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param caseInsensitive 是否大小写不敏感
|
||||
*/
|
||||
public XjrEntityListHandler(boolean caseInsensitive) {
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> handle(ResultSet rs) throws SQLException {
|
||||
return XjrHandleHelper.handleRs(rs, new ArrayList<>(), this.caseInsensitive);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,310 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.PropDesc;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.TypeUtil;
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.handler.HandleHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class XjrHandleHelper extends HandleHelper {
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
* @param bean 目标Bean
|
||||
* @return 每一行的Entity
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 3.3.1
|
||||
*/
|
||||
public static <T> T handleRow(int columnCount, ResultSetMetaData meta, ResultSet rs, T bean) throws SQLException {
|
||||
return handleRow(columnCount, meta, rs).toBeanIgnoreCase(bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
* @param beanClass 目标Bean类型
|
||||
* @return 每一行的Entity
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 3.3.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T handleRow(int columnCount, ResultSetMetaData meta, ResultSet rs, Class<T> beanClass) throws SQLException {
|
||||
Assert.notNull(beanClass, "Bean Class must be not null !");
|
||||
|
||||
if(beanClass.isArray()) {
|
||||
//返回数组
|
||||
final Class<?> componentType = beanClass.getComponentType();
|
||||
final Object[] result = ArrayUtil.newArray(componentType, columnCount);
|
||||
for(int i = 0,j = 1; i < columnCount; i++, j++) {
|
||||
result[i] = getColumnValue(rs, j, meta.getColumnType(j), componentType);
|
||||
}
|
||||
return (T) result;
|
||||
} else if(Iterable.class.isAssignableFrom(beanClass)) {
|
||||
//集合
|
||||
final Object[] objRow = handleRow(columnCount, meta, rs, Object[].class);
|
||||
return Convert.convert(beanClass, objRow);
|
||||
} else if(beanClass.isAssignableFrom(Entity.class)) {
|
||||
//Entity的父类都可按照Entity返回
|
||||
return (T) handleRow(columnCount, meta, rs);
|
||||
} else if(String.class == beanClass) {
|
||||
//字符串
|
||||
final Object[] objRow = handleRow(columnCount, meta, rs, Object[].class);
|
||||
return (T) StrUtil.join(", ", objRow);
|
||||
}
|
||||
|
||||
//普通bean
|
||||
final T bean = ReflectUtil.newInstanceIfPossible(beanClass);
|
||||
//忽略字段大小写
|
||||
final Map<String, PropDesc> propMap = BeanUtil.getBeanDesc(beanClass).getPropMap(true);
|
||||
String columnLabel;
|
||||
PropDesc pd;
|
||||
Method setter;
|
||||
Object value;
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
columnLabel = meta.getColumnLabel(i);
|
||||
pd = propMap.get(columnLabel);
|
||||
if(null == pd) {
|
||||
// 尝试驼峰命名风格
|
||||
pd = propMap.get(StrUtil.toCamelCase(columnLabel));
|
||||
}
|
||||
setter = (null == pd) ? null : pd.getSetter();
|
||||
if(null != setter) {
|
||||
value = getColumnValue(rs, i, meta.getColumnType(i), TypeUtil.getFirstParamType(setter));
|
||||
ReflectUtil.invokeWithCheck(bean, setter, value);
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
* @return 每一行的Entity
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public static Entity handleRow(int columnCount, ResultSetMetaData meta, ResultSet rs) throws SQLException {
|
||||
return handleRow(columnCount, meta, rs, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
* @param caseInsensitive 是否大小写不敏感
|
||||
* @return 每一行的Entity
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 4.5.16
|
||||
*/
|
||||
public static Entity handleRow(int columnCount, ResultSetMetaData meta, ResultSet rs, boolean caseInsensitive) throws SQLException {
|
||||
return handleRow(new Entity(null, caseInsensitive), columnCount, meta, rs, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param <T> Entity及其子对象
|
||||
* @param row Entity对象
|
||||
* @param columnCount 列数
|
||||
* @param meta ResultSetMetaData
|
||||
* @param rs 数据集
|
||||
* @param withMetaInfo 是否包含表名、字段名等元信息
|
||||
* @return 每一行的Entity
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 3.3.1
|
||||
*/
|
||||
public static <T extends Entity> T handleRow(T row, int columnCount, ResultSetMetaData meta, ResultSet rs, boolean withMetaInfo) throws SQLException {
|
||||
int type;
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
type = meta.getColumnType(i);
|
||||
row.put(meta.getColumnLabel(i), getColumnValue(rs, i, type, null));
|
||||
}
|
||||
if (withMetaInfo) {
|
||||
try {
|
||||
row.setTableName(meta.getTableName(1));
|
||||
} catch (SQLException ignore){
|
||||
//issue#I2AGLU@Gitee
|
||||
// Hive等NoSQL中无表的概念,此处报错,跳过。
|
||||
}
|
||||
row.setFieldNames(row.keySet());
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单条数据
|
||||
*
|
||||
* @param rs 数据集
|
||||
* @return 每一行的Entity
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public static Entity handleRow(ResultSet rs) throws SQLException {
|
||||
final ResultSetMetaData meta = rs.getMetaData();
|
||||
final int columnCount = meta.getColumnCount();
|
||||
return handleRow(columnCount, meta, rs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理单行数据
|
||||
*
|
||||
* @param rs 数据集(行)
|
||||
* @return 每一行的List
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 5.1.6
|
||||
*/
|
||||
public static List<Object> handleRowToList(ResultSet rs) throws SQLException {
|
||||
final ResultSetMetaData meta = rs.getMetaData();
|
||||
final int columnCount = meta.getColumnCount();
|
||||
final List<Object> row = new ArrayList<>(columnCount);
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
row.add(getColumnValue(rs, i, meta.getColumnType(i), null));
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理多条数据
|
||||
*
|
||||
* @param <T> 集合类型
|
||||
* @param rs 数据集
|
||||
* @param collection 数据集
|
||||
* @return Entity列表
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public static <T extends Collection<Entity>> T handleRs(ResultSet rs, T collection) throws SQLException {
|
||||
return handleRs(rs, collection, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理多条数据
|
||||
*
|
||||
* @param <T> 集合类型
|
||||
* @param rs 数据集
|
||||
* @param collection 数据集
|
||||
* @param caseInsensitive 是否大小写不敏感
|
||||
* @return Entity列表
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 4.5.16
|
||||
*/
|
||||
public static <T extends Collection<Entity>> T handleRs(ResultSet rs, T collection, boolean caseInsensitive) throws SQLException {
|
||||
final ResultSetMetaData meta = rs.getMetaData();
|
||||
final int columnCount = meta.getColumnCount();
|
||||
|
||||
while (rs.next()) {
|
||||
collection.add(handleRow(columnCount, meta, rs, caseInsensitive));
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理多条数据并返回一个Bean列表
|
||||
*
|
||||
* @param <E> 集合元素类型
|
||||
* @param <T> 集合类型
|
||||
* @param rs 数据集
|
||||
* @param collection 数据集
|
||||
* @param elementBeanType Bean类型
|
||||
* @return Entity列表
|
||||
* @throws SQLException SQL执行异常
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public static <E, T extends Collection<E>> T handleRsToBeanList(ResultSet rs, T collection, Class<E> elementBeanType) throws SQLException {
|
||||
final ResultSetMetaData meta = rs.getMetaData();
|
||||
final int columnCount = meta.getColumnCount();
|
||||
|
||||
while (rs.next()) {
|
||||
collection.add(handleRow(columnCount, meta, rs, elementBeanType));
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------- Private method start
|
||||
/**
|
||||
* 获取字段值<br>
|
||||
* 针对日期时间等做单独处理判断
|
||||
*
|
||||
* @param <T> 返回类型
|
||||
* @param rs {@link ResultSet}
|
||||
* @param columnIndex 字段索引
|
||||
* @param type 字段类型,默认Object
|
||||
* @param targetColumnType 结果要求的类型,需进行二次转换(null或者Object不转换)
|
||||
* @return 字段值
|
||||
* @throws SQLException SQL异常
|
||||
*/
|
||||
private static <T> Object getColumnValue(ResultSet rs, int columnIndex, int type, Type targetColumnType) throws SQLException {
|
||||
Object rawValue = null;
|
||||
switch (type) {
|
||||
case Types.TIMESTAMP:
|
||||
try{
|
||||
rawValue = rs.getTimestamp(columnIndex);
|
||||
} catch (SQLException ignore){
|
||||
// issue#776@Github
|
||||
// 当数据库中日期为0000-00-00 00:00:00报错,转为null
|
||||
}
|
||||
break;
|
||||
case Types.TIME:
|
||||
rawValue = rs.getTime(columnIndex);
|
||||
break;
|
||||
case Types.NCLOB:
|
||||
rawValue = rs.getNString(columnIndex);
|
||||
break;
|
||||
case Types.NUMERIC:
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
if (metaData.getScale(columnIndex) == 0) {
|
||||
// 没有小数点
|
||||
if (metaData.getPrecision(columnIndex) > 11) {
|
||||
// 长度大于11转换成Long类型
|
||||
rawValue = rs.getLong(columnIndex);
|
||||
} else {
|
||||
// 长度小于等于11转成Integer类型
|
||||
rawValue = rs.getInt(columnIndex);
|
||||
}
|
||||
} else {
|
||||
// 有小数点
|
||||
rawValue = rs.getObject(columnIndex);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rawValue = rs.getObject(columnIndex);
|
||||
}
|
||||
if (null == targetColumnType || Object.class == targetColumnType) {
|
||||
// 无需转换
|
||||
return rawValue;
|
||||
} else {
|
||||
// 按照返回值要求转换
|
||||
return Convert.convert(targetColumnType, rawValue);
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------------------- Private method end
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||
import com.xjrsoft.common.mybatis.utils.LocalDateTimeUtil;
|
||||
import oracle.sql.INTERVALDS;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalTime;
|
||||
|
||||
public class XjrLocalTimeTypeHandler extends BaseTypeHandler<LocalTime> {
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, LocalTime localTime, JdbcType jdbcType)
|
||||
throws SQLException {
|
||||
DbType dbType = JdbcUtils.getDbType(ps.getConnection().getMetaData().getURL());
|
||||
if (dbType == DbType.ORACLE || dbType == DbType.ORACLE_12C) {
|
||||
// oracle时间类型处理
|
||||
ps.setObject(i, new INTERVALDS(StringPool.ZERO + StringPool.SPACE + LocalDateTimeUtil.format(localTime) + StringPool.DOT + StringPool.ZERO));
|
||||
} else {
|
||||
ps.setObject(i, localTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
Object object = rs.getObject(columnName);
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (object instanceof INTERVALDS) {
|
||||
return convertIntervalToLocalTime((INTERVALDS) object);
|
||||
}
|
||||
return rs.getObject(columnName, LocalTime.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
Object object = rs.getObject(columnIndex);
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (object instanceof INTERVALDS) {
|
||||
return convertIntervalToLocalTime((INTERVALDS) object);
|
||||
}
|
||||
return rs.getObject(columnIndex, LocalTime.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
Object object = cs.getObject(columnIndex);
|
||||
if (object == null) {
|
||||
return null;
|
||||
}
|
||||
if (object instanceof INTERVALDS) {
|
||||
return convertIntervalToLocalTime((INTERVALDS) object);
|
||||
}
|
||||
return cs.getObject(columnIndex, LocalTime.class);
|
||||
}
|
||||
|
||||
public LocalTime convertIntervalToLocalTime(INTERVALDS intervalDS) {
|
||||
if (intervalDS == null) {
|
||||
return null;
|
||||
}
|
||||
String str = intervalDS.stringValue();
|
||||
String timeStr = str.substring(str.indexOf(StringPool.SPACE) + 1, str.indexOf(StringPool.DOT));
|
||||
String[] array = timeStr.split(StringPool.COLON);
|
||||
return LocalTime.of(Integer.parseInt(array[0]), Integer.parseInt(array[1]), Integer.parseInt(array[2]));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.xjrsoft.common.mybatis.handler;
|
||||
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.PageResult;
|
||||
import cn.hutool.db.handler.RsHandler;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class XjrPageResultHandler implements RsHandler<PageResult<Entity>> {
|
||||
|
||||
private final PageResult<Entity> pageResult;
|
||||
/**
|
||||
* 是否大小写不敏感
|
||||
*/
|
||||
private final boolean caseInsensitive;
|
||||
|
||||
/**
|
||||
* 创建一个 EntityHandler对象<br>
|
||||
* 结果集根据给定的分页对象查询数据库,填充结果
|
||||
*
|
||||
* @param pageResult 分页结果集空对象
|
||||
* @return EntityHandler对象
|
||||
*/
|
||||
public static XjrPageResultHandler create(PageResult<Entity> pageResult) {
|
||||
return new XjrPageResultHandler(pageResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造<br>
|
||||
* 结果集根据给定的分页对象查询数据库,填充结果
|
||||
*
|
||||
* @param pageResult 分页结果集空对象
|
||||
*/
|
||||
public XjrPageResultHandler(PageResult<Entity> pageResult) {
|
||||
this(pageResult, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造<br>
|
||||
* 结果集根据给定的分页对象查询数据库,填充结果
|
||||
*
|
||||
* @param pageResult 分页结果集空对象
|
||||
* @param caseInsensitive 是否大小写不敏感
|
||||
*/
|
||||
public XjrPageResultHandler(PageResult<Entity> pageResult, boolean caseInsensitive) {
|
||||
this.pageResult = pageResult;
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<Entity> handle(ResultSet rs) throws SQLException {
|
||||
return XjrHandleHelper.handleRs(rs, pageResult, this.caseInsensitive);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
package com.xjrsoft.common.mybatis.interceptor;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
||||
import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
|
||||
import com.xjrsoft.common.mybatis.utils.AuthorityUtil;
|
||||
import com.xjrsoft.common.redis.service.RedisUtil;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.schema.Table;
|
||||
import net.sf.jsqlparser.statement.select.*;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 数据权限处理器
|
||||
*
|
||||
* @author tzx
|
||||
* @Date: 2023/2/21 16:11
|
||||
* @since 3.4.1 +
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DataScopeInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
|
||||
|
||||
// private DataPermissionHandler dataPermissionHandler;
|
||||
|
||||
@Setter
|
||||
private static RedisUtil redisUtil;
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
|
||||
if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
|
||||
return;
|
||||
}
|
||||
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
|
||||
mpBs.sql(parserSingle(mpBs.sql(), ms.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processSelect(Select select, int index, String sql, Object obj) {
|
||||
SelectBody selectBody = select.getSelectBody();
|
||||
if (selectBody instanceof PlainSelect) {
|
||||
this.setWhere((PlainSelect) selectBody, (String) obj);
|
||||
} else if (selectBody instanceof SetOperationList) {
|
||||
SetOperationList setOperationList = (SetOperationList) selectBody;
|
||||
List<SelectBody> selectBodyList = setOperationList.getSelects();
|
||||
selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 where 条件
|
||||
*
|
||||
* @param plainSelect 查询对象
|
||||
* @param whereSegment 查询条件片段
|
||||
*/
|
||||
|
||||
protected void setWhere(PlainSelect plainSelect, String whereSegment) {
|
||||
//有可能是没有登录的非web请求(定时任务,初始运行) 所以必须要try catch一下
|
||||
//有可能是没有登录的非web请求(定时任务,初始运行) 所以必须要try catch一下
|
||||
try {
|
||||
//首先必须要登录 才需要判断数据权限的问题
|
||||
if (!StpUtil.isLogin()) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
FromItem fromItem = plainSelect.getFromItem();
|
||||
Table fromTable = (Table) fromItem;
|
||||
|
||||
String alias = null;
|
||||
if (ObjectUtil.isNotNull(fromTable.getAlias())) {
|
||||
alias = fromTable.getAlias().getName();
|
||||
}
|
||||
|
||||
Expression dataAuthExpression = AuthorityUtil.getDataAuthExpressionByTableName(fromTable.getName(), alias);
|
||||
|
||||
Expression currentExpression = plainSelect.getWhere();
|
||||
if (ObjectUtil.isNotNull(dataAuthExpression)) {
|
||||
if(currentExpression == null){
|
||||
currentExpression = dataAuthExpression;
|
||||
}
|
||||
else {
|
||||
currentExpression = new AndExpression(currentExpression, dataAuthExpression);
|
||||
}
|
||||
plainSelect.setWhere(currentExpression);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.github.yulichang.annotation.EntityMapping;
|
||||
import com.xjrsoft.common.core.domain.base.AuditEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据权限表
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2023-02-27
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("xjr_data_auth")
|
||||
@Tag(name = "DataAuth对象", description = "数据权限表")
|
||||
@Data
|
||||
public class DataAuth extends AuditEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(name="主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "名称")
|
||||
private String name;
|
||||
|
||||
@Schema(name = "编码")
|
||||
private String code;
|
||||
|
||||
@Schema(name = "类型 0 角色 1 用户")
|
||||
private Integer authType;
|
||||
|
||||
@Schema(name = "授权方式 0 简易 1 自定义")
|
||||
private Integer authMethod;
|
||||
|
||||
@Schema(name = "实现范围 如果是简易模式 就会有这个数据 ")
|
||||
private Integer authScope;
|
||||
|
||||
@Schema(name = "授权公式 如果是自定义模式 就会有这个数据")
|
||||
private String authFormula;
|
||||
|
||||
@Schema(name = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(name = "租户id")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(name = "授权对象")
|
||||
@TableField(exist = false)
|
||||
@EntityMapping(thisField = "id", joinField = "dataAuthId")
|
||||
private List<DataAuthRelation> authObjectList;
|
||||
|
||||
@Schema(name = "授权配置 授权方式为1 就会有")
|
||||
@TableField(exist = false)
|
||||
@EntityMapping(thisField = "id", joinField = "dataAuthId")
|
||||
private List<DataAuthConfig> authConfigList;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.OrderBy;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据权限自定义配置详情表
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2023-02-27
|
||||
*/
|
||||
@TableName("xjr_data_auth_config")
|
||||
@Tag(name = "DataAuthConfig对象", description = "数据权限自定义配置详情表")
|
||||
@Data
|
||||
public class DataAuthConfig implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(name ="主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="数据权限表id")
|
||||
private Long dataAuthId;
|
||||
|
||||
@Schema(name ="排序号")
|
||||
@OrderBy(asc = true)
|
||||
private Integer orderNumber;
|
||||
|
||||
@Schema(name ="字段名")
|
||||
private String fieldName;
|
||||
|
||||
@Schema(name ="条件")
|
||||
private Integer conditionType;
|
||||
|
||||
@Schema(name ="字段类型")
|
||||
private Integer fieldType;
|
||||
|
||||
@Schema(name ="根据字段类型区分 如果是 登陆人信息 默认不需要存储值")
|
||||
private String fieldValue;
|
||||
|
||||
@Schema(name = "租户id")
|
||||
private Long tenantId;
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据权限 对象类型关联表
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2023-02-27
|
||||
*/
|
||||
@TableName("xjr_data_auth_relation")
|
||||
@Tag(name = "DataAuthRelation对象", description = "数据权限 对象类型关联表")
|
||||
@Data
|
||||
public class DataAuthRelation implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(name = "主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="data_auth 表id")
|
||||
private Long dataAuthId;
|
||||
|
||||
@Schema(name ="对象id 如果data_auth 表中的类型是 角色 就是角色id 如果是用户 就是用户id")
|
||||
private Long objectId;
|
||||
|
||||
@Schema(name = "租户id")
|
||||
private Long tenantId;
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 数据权限 与 表 关联关系表
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2023-02-28
|
||||
*/
|
||||
@TableName("xjr_data_auth_table_relation")
|
||||
@Tag(name = "DataAuthTableRelation对象", description = "数据权限 与 表 关联关系表")
|
||||
@Data
|
||||
public class DataAuthTableRelation implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="表名")
|
||||
private String tableName;
|
||||
|
||||
@Schema(name ="数据权限id")
|
||||
private Long dataAuthId;
|
||||
|
||||
@Schema(name ="租户id")
|
||||
private Long tenantId;
|
||||
|
||||
}
|
||||
@ -0,0 +1,147 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.xjrsoft.common.core.domain.base.AuditEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 机构
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2022-03-02
|
||||
*/
|
||||
@TableName("xjr_department")
|
||||
@Tag(name = "Department对象", description = "机构")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Department extends AuditEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="机构名称")
|
||||
private String name;
|
||||
|
||||
@Schema(name ="机构名称")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(name ="编码")
|
||||
private String code;
|
||||
|
||||
public Department(){
|
||||
|
||||
}
|
||||
|
||||
public Department(Long id,String code,String name,Long parentId){
|
||||
this.id=id;
|
||||
this.code=code;
|
||||
this.name=name;
|
||||
this.parentId=parentId;
|
||||
setIsSync("Y");
|
||||
}
|
||||
|
||||
@Schema(name ="电话")
|
||||
private String mobile;
|
||||
|
||||
@Schema(name ="邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(name ="主页")
|
||||
private String website;
|
||||
|
||||
@Schema(name ="地址")
|
||||
private String address;
|
||||
|
||||
@Schema(name ="排序号")
|
||||
private Integer sortCode;
|
||||
|
||||
@Schema(name ="备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(name ="层级")
|
||||
private String hierarchy;
|
||||
|
||||
@Schema(name ="组织类别,3:总部,2:板块,1:公司,0:部门")
|
||||
private Integer departmentType;
|
||||
|
||||
@Schema(name ="租户id")
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(name ="是否同步")
|
||||
private String isSync;
|
||||
|
||||
@Schema(name ="对应企业微信部门id")
|
||||
private Long wechatDeptId;
|
||||
|
||||
@Schema(name ="对应钉钉部门id")
|
||||
private Long dingtalkDeptId;
|
||||
|
||||
private String dingAgentId;
|
||||
|
||||
private String dingAppKey;
|
||||
|
||||
private String dingAppSecret;
|
||||
|
||||
@Schema(name ="简称")
|
||||
private String shortName;
|
||||
|
||||
@Schema(name ="组织性质-数据字典id")
|
||||
private Long departmentNature;
|
||||
|
||||
@Schema(name ="成立时间")
|
||||
private LocalDateTime establishedTime;
|
||||
|
||||
@Schema(name ="管理人-用户id")
|
||||
private Long custodian;
|
||||
|
||||
@Schema(name ="传真")
|
||||
private String facsimile;
|
||||
|
||||
@Schema(name ="行政正职领导-用户id")
|
||||
private Long administrativeLeader;
|
||||
|
||||
@Schema(name ="党委正职领导-用户id")
|
||||
private Long partyCommitteeLeader;
|
||||
|
||||
@Schema(name ="部门领导-ids")
|
||||
private String departmentLeaders;
|
||||
|
||||
@Schema(name ="上级分管领导-ids")
|
||||
private String chargeOfLeaders;
|
||||
|
||||
@Schema(name ="部门标签-数据字典id")
|
||||
private String departmentLabel;
|
||||
|
||||
@Schema(name ="分机号")
|
||||
private String extensionNumber;
|
||||
|
||||
@Schema(name ="所属行业 - 数据字典id")
|
||||
private Long industry;
|
||||
|
||||
@Schema(name ="公司法人")
|
||||
private String corporateLegalPerson;
|
||||
|
||||
@Schema(name ="联系手机")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(name ="联系电话")
|
||||
private String contactNumber;
|
||||
|
||||
@Schema(name ="开户银行")
|
||||
private String depositBank;
|
||||
|
||||
@Schema(name ="银行账户")
|
||||
private String bankAccount;
|
||||
|
||||
@Schema(name ="经营范围")
|
||||
private String businessScope;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.xjrsoft.common.core.domain.base.AuditEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 岗位
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2022-03-02
|
||||
*/
|
||||
@TableName("xjr_post")
|
||||
@Tag(name = "Post对象", description = "岗位")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Post extends AuditEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
|
||||
@Schema(name ="名字")
|
||||
private String name;
|
||||
|
||||
@Schema(name ="编码")
|
||||
private String code;
|
||||
|
||||
@Schema(name ="父级")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(name ="排序号")
|
||||
private Integer sortCode;
|
||||
|
||||
@Schema(name ="备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(name ="岗位所属组织id")
|
||||
private Long deptId;
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.xjrsoft.common.core.domain.base.AuditEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 角色
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2022-03-02
|
||||
*/
|
||||
@TableName("xjr_role")
|
||||
@Tag(name = "Role对象", description = "角色")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Role extends AuditEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="名字")
|
||||
private String name;
|
||||
|
||||
@Schema(name ="编码")
|
||||
private String code;
|
||||
|
||||
public Role(){
|
||||
|
||||
}
|
||||
public Role(String code,String name){
|
||||
this.name=name;
|
||||
this.code=code;
|
||||
}
|
||||
|
||||
// @Schema(name ="数据权限")
|
||||
// private Integer dataAuthType;
|
||||
|
||||
@Schema(name ="排序号")
|
||||
private Integer sortCode;
|
||||
|
||||
@Schema(name ="备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(name = "租户id")
|
||||
private Long tenantId;
|
||||
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.xjrsoft.common.core.domain.base.AuditEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2022-03-02
|
||||
*/
|
||||
@TableName("xjr_user")
|
||||
@Tag(name = "User对象", description = "用户")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class User extends AuditEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="账户")
|
||||
private String userName;
|
||||
|
||||
@Schema(name ="姓名")
|
||||
private String name;
|
||||
|
||||
@Schema(name ="编号")
|
||||
private String code;
|
||||
|
||||
@Schema(name ="昵称")
|
||||
private String nickName;
|
||||
|
||||
@Schema(name ="密码")
|
||||
private String password;
|
||||
|
||||
@Schema(name ="性别")
|
||||
private Integer gender;
|
||||
|
||||
@Schema(name ="手机号")
|
||||
private String mobile;
|
||||
|
||||
@Schema(name ="角色Id")
|
||||
@TableField(exist = false)
|
||||
private Long postId;
|
||||
|
||||
@Schema(name ="头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(name ="邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(name ="地址")
|
||||
private String address;
|
||||
|
||||
@Schema(name ="经度")
|
||||
private Double longitude;
|
||||
|
||||
@Schema(name ="纬度")
|
||||
private Double latitude;
|
||||
|
||||
@Schema(name ="排序码")
|
||||
private Integer sortCode;
|
||||
|
||||
@Schema(name ="备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(name ="部门")
|
||||
@TableField(exist = false)
|
||||
private Long departmentId;
|
||||
|
||||
@Schema(name ="微信号码")
|
||||
private String wechatNumber;
|
||||
|
||||
@Schema(name ="qq号码")
|
||||
private String qqNumber;
|
||||
|
||||
private LocalDateTime birthDate;
|
||||
|
||||
private Long tenantId;
|
||||
|
||||
private String tenantCode;
|
||||
|
||||
@Schema(name ="是否开启密码验证")
|
||||
private Integer passwordAuthentication;
|
||||
|
||||
@Schema(name ="电话号码")
|
||||
private String phoneNumber;
|
||||
|
||||
@Schema(name ="身份证号")
|
||||
private String identityCardNumber;
|
||||
|
||||
@Schema(name ="政治面貌-数据字典id")
|
||||
private Long politicsStatus;
|
||||
|
||||
@Schema(name ="行政职务-数据字典id")
|
||||
private Long administrativePost;
|
||||
|
||||
@Schema(name ="行政职级-数据字典id")
|
||||
private Long administrativeRank;
|
||||
|
||||
@Schema(name ="用户密级-数据字典id")
|
||||
private Long secretLevel;
|
||||
|
||||
@Schema(name ="职称等级-数据字典id")
|
||||
private Long professionalTitleGrade;
|
||||
|
||||
@Schema(name ="技术职务-数据字典id")
|
||||
private Long technicalPosition;
|
||||
|
||||
@Schema(name ="管理职务-数据字典id")
|
||||
private Long managerialPosition;
|
||||
|
||||
@Schema(name ="职业技能-数据字典id")
|
||||
private Long vocationalSkill;
|
||||
|
||||
@Schema(name ="绑定ip")
|
||||
private String bindIp;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户关联部门表
|
||||
* </p>
|
||||
*/
|
||||
@TableName("xjr_user_dept_relation")
|
||||
@Tag(name = "UserDeptRelation对象", description = "用户关联部门表")
|
||||
@Data
|
||||
public class UserDeptRelation {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(name ="部门id")
|
||||
private Long deptId;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户关联岗位表
|
||||
* </p>
|
||||
*/
|
||||
@TableName("xjr_user_post_relation")
|
||||
@Tag(name = "UserPostRelation对象", description = "用户关联岗位表")
|
||||
@Data
|
||||
public class UserPostRelation implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(name ="岗位id")
|
||||
private Long postId;
|
||||
|
||||
@Schema(name ="租户id")
|
||||
private Long tenantId;
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package com.xjrsoft.common.mybatis.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户关联角色表
|
||||
* </p>
|
||||
*
|
||||
* @author tzx
|
||||
* @since 2022-03-02
|
||||
*/
|
||||
@TableName("xjr_user_role_relation")
|
||||
@Tag(name = "UserRoleRelation对象", description = "用户关联角色表")
|
||||
@Data
|
||||
public class UserRoleRelation implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Schema(name ="用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(name ="角色ID")
|
||||
private Long roleId;
|
||||
|
||||
public UserRoleRelation(){
|
||||
|
||||
}
|
||||
public UserRoleRelation(Long userId,Long roleId){
|
||||
this.userId=userId;
|
||||
this.roleId=roleId;
|
||||
}
|
||||
|
||||
|
||||
@Schema(name ="租户id")
|
||||
private Long tenantId;
|
||||
}
|
||||
@ -0,0 +1,896 @@
|
||||
package com.xjrsoft.common.mybatis.utils;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.TypeReference;
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.xjrsoft.common.core.constant.GlobalConstant;
|
||||
import com.xjrsoft.common.core.constant.StringPool;
|
||||
import com.xjrsoft.common.core.enums.*;
|
||||
import com.xjrsoft.common.core.exception.MyException;
|
||||
import com.xjrsoft.common.mybatis.model.*;
|
||||
import com.xjrsoft.common.redis.service.RedisUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import net.sf.jsqlparser.expression.Parenthesis;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.*;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 数据权限工具类
|
||||
*
|
||||
* @Author: tzx
|
||||
* @Date: 2023/3/1 10:22
|
||||
*/
|
||||
public class AuthorityUtil {
|
||||
|
||||
static RedisUtil redisUtil;
|
||||
|
||||
static {
|
||||
redisUtil = SpringUtil.getBean(RedisUtil.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表名 获取表达式解析
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param tableAlias 表别名
|
||||
* @return
|
||||
*/
|
||||
public static Expression getDataAuthExpressionByTableName(String tableName, String tableAlias) {
|
||||
Expression dataAuthExpression = null;
|
||||
|
||||
List<DataAuthTableRelation> dataAuthTableRelations = redisUtil.get(GlobalConstant.DATA_AUTH_TABLE_RELATION_CACHE_KEY, new TypeReference<List<DataAuthTableRelation>>() {
|
||||
});
|
||||
|
||||
//是否有设置权限
|
||||
if (CollectionUtil.isEmpty(dataAuthTableRelations) || dataAuthTableRelations.stream().noneMatch(x -> x.getTableName().equals(tableName))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//找到当前表所关联的 数据权限
|
||||
List<DataAuthTableRelation> tableDataAuths = dataAuthTableRelations.stream().filter(x -> x.getTableName().equals(tableName)).collect(Collectors.toList());
|
||||
|
||||
List<Long> allDataAuthId = tableDataAuths.stream().map(DataAuthTableRelation::getDataAuthId).collect(Collectors.toList());
|
||||
List<DataAuth> dataAuths = redisUtil.get(GlobalConstant.DATA_AUTH_CACHE_KEY, new TypeReference<List<DataAuth>>() {
|
||||
});
|
||||
|
||||
List<DataAuth> thisTableAuthDataList = dataAuths.stream().filter(x -> allDataAuthId.contains(x.getId())).collect(Collectors.toList());
|
||||
|
||||
List<DataAuthRelation> authRelationList = redisUtil.get(GlobalConstant.DATA_AUTH_RELATION_CACHE_KEY, new TypeReference<List<DataAuthRelation>>() {
|
||||
});
|
||||
|
||||
List<DataAuthConfig> authConfigList = redisUtil.get(GlobalConstant.DATA_AUTH_CONFIG_CACHE_KEY, new TypeReference<List<DataAuthConfig>>() {
|
||||
});
|
||||
|
||||
for (DataAuth dataAuth : thisTableAuthDataList) {
|
||||
Expression expression = null;
|
||||
List<Long> userIds = new ArrayList<>();
|
||||
//如果是用户权限
|
||||
if (dataAuth.getAuthType() == DataAuthTypeEnum.USER.getCode()) {
|
||||
//找出有那些用户被赋值了 此数据权限
|
||||
userIds = authRelationList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).map(DataAuthRelation::getObjectId).collect(Collectors.toList());
|
||||
} else {
|
||||
List<Long> roleIds = authRelationList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).map(DataAuthRelation::getObjectId).collect(Collectors.toList());
|
||||
|
||||
List<Long> currentRoleIdList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
|
||||
|
||||
//如果当前登陆人不包含 这些 角色id 默认不添加数据权限
|
||||
if (currentRoleIdList.stream().noneMatch(roleIds::contains)) {
|
||||
continue;
|
||||
}
|
||||
userIds.add(StpUtil.getLoginIdAsLong());
|
||||
}
|
||||
//判断当前用户是否包含此数据权限
|
||||
if (userIds.contains(StpUtil.getLoginIdAsLong())) {
|
||||
|
||||
//如果是简易模式
|
||||
if (dataAuth.getAuthMethod() == DataAuthMethodEnum.SIMPLE.getCode()) {
|
||||
//所有能查看的用户数据
|
||||
List<Long> dataAuthSimpleUserId = getDataAuthSimpleUserId(dataAuth.getAuthScope());
|
||||
|
||||
List<Expression> expressionList = new ArrayList<>();
|
||||
for (Long aLong : dataAuthSimpleUserId) {
|
||||
expressionList.add(new LongValue(aLong));
|
||||
}
|
||||
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, GlobalConstant.AUTH_USER_ID));
|
||||
inExpression.setRightItemsList(new ExpressionList(expressionList));
|
||||
|
||||
expression = inExpression;
|
||||
|
||||
}
|
||||
//如果是自定义模式
|
||||
else {
|
||||
List<DataAuthConfig> thisDataAuthConfig = authConfigList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).collect(Collectors.toList());
|
||||
expression = getDataAuthCustomExpression(thisDataAuthConfig, dataAuth, tableAlias);
|
||||
}
|
||||
// 组装数据权限,取并集,用or连接
|
||||
if (dataAuthExpression == null) {
|
||||
dataAuthExpression = expression;
|
||||
} else {
|
||||
dataAuthExpression = new OrExpression(dataAuthExpression, new Parenthesis(expression));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dataAuthExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义模式 根据数据权限 获取 Expression
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static Expression getDataAuthCustomExpression(List<DataAuthConfig> configs, DataAuth dataAuth, String tableAlias) {
|
||||
Expression dataAuthExpression = null;
|
||||
|
||||
if (StrUtil.isNotBlank(dataAuth.getAuthFormula())) {
|
||||
|
||||
StringBuilder resultExpresionString = new StringBuilder();
|
||||
String[] split = dataAuth.getAuthFormula().split("");
|
||||
|
||||
for (int i = 0 ; i < split.length ;i++) {
|
||||
//如果是数字 并且 包含当前
|
||||
if (StrUtil.isNumeric(split[i])) {
|
||||
Integer order = Convert.toInt(split[i]);
|
||||
|
||||
Optional<DataAuthConfig> configOptional = configs.stream().filter(x -> ObjectUtil.equals(x.getOrderNumber(), order)).findFirst();
|
||||
if (!configOptional.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
Expression expression = getExpression(tableAlias, configOptional.get());
|
||||
resultExpresionString.append(expression);
|
||||
} else {
|
||||
//有三种情况,(、)、and、or
|
||||
if ((split[i].equals("a") && split[i+1].equals("n") && split[i+2].equals("d"))
|
||||
|| (split[i].equals("A") && split[i+1].equals("N") && split[i+2].equals("D"))){
|
||||
i = i + 2;
|
||||
resultExpresionString.append(" and ");
|
||||
} else if ((split[i].equals("o") && split[i+1].equals("r"))
|
||||
|| (split[i].equals("O") && split[i+1].equals("R"))) {
|
||||
i = i + 1;
|
||||
resultExpresionString.append(" or ");
|
||||
}else {
|
||||
resultExpresionString.append(split[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
dataAuthExpression = CCJSqlParserUtil.parseExpression(resultExpresionString.toString());
|
||||
}
|
||||
|
||||
|
||||
// if (StrUtil.isNotBlank(dataAuth.getAuthFormula())) {
|
||||
// String OrString = "or";
|
||||
// String AndString = "and";
|
||||
// //首先根据 or 切割 字符串
|
||||
// String[] ors = dataAuth.getAuthFormula().toLowerCase().split(OrString);
|
||||
//
|
||||
// for (int i = 0; i < ors.length; i++) {
|
||||
// //去除左右括号 再根据 and 切割
|
||||
// String[] condition = ors[i].replace(StringPool.LEFT_BRACKET,StringPool.EMPTY).replace(StringPool.RIGHT_BRACKET,StringPool.EMPTY).toLowerCase().split(AndString);
|
||||
// Expression expression = null;
|
||||
// for (String index : condition) {
|
||||
// Optional<DataAuthConfig> configOptional = configs.stream().filter(x -> ObjectUtil.equals(x.getOrderNumber(), Integer.valueOf(index.trim()))).findFirst();
|
||||
//
|
||||
// if (!configOptional.isPresent()) {
|
||||
// continue;
|
||||
// }
|
||||
// expression = getExpression(tableAlias, expression, configOptional.get());
|
||||
// }
|
||||
// //如果是最后一个 不再需要拼接or
|
||||
// if(i != ors.length - 1){
|
||||
// //如果是第一个条件 直接赋值
|
||||
// if(ObjectUtil.isNull(dataAuthExpression)){
|
||||
// dataAuthExpression = new Parenthesis(expression);
|
||||
// }
|
||||
// else {
|
||||
// dataAuthExpression = new OrExpression(dataAuthExpression, new Parenthesis(expression));
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// dataAuthExpression = new AndExpression(dataAuthExpression,new Parenthesis(expression));
|
||||
// }
|
||||
//// //如果有括号
|
||||
//// if (ors[i].contains(StringPool.LEFT_BRACKET) && ors[i].contains(StringPool.RIGHT_BRACKET)) {
|
||||
////
|
||||
//// }
|
||||
////
|
||||
//
|
||||
// }
|
||||
//
|
||||
//// for (String or : ors) {
|
||||
//// //如果有括号
|
||||
//// if (or.contains(StringPool.LEFT_BRACKET) && or.contains(StringPool.RIGHT_BRACKET)) {
|
||||
//// //去除左右括号 再根据 and 切割
|
||||
//// String[] condition = or.replace(StringPool.LEFT_BRACKET,StringPool.EMPTY).replace(StringPool.LEFT_BRACKET,StringPool.EMPTY).toLowerCase().split(AndString);
|
||||
//// Expression expression = null;
|
||||
//// for (String index : condition) {
|
||||
//// Optional<DataAuthConfig> configOptional = configs.stream().filter(x -> ObjectUtil.equals(x.getOrderNumber(), Integer.valueOf(index))).findFirst();
|
||||
////
|
||||
//// if (!configOptional.isPresent()) {
|
||||
//// continue;
|
||||
//// }
|
||||
//// expression = getExpression(tableAlias, expression, configOptional.get());
|
||||
//// }
|
||||
////
|
||||
//// dataAuthExpression = new Parenthesis(dataAuthExpression);
|
||||
//// }
|
||||
////
|
||||
////
|
||||
//// }
|
||||
// }
|
||||
else {
|
||||
for (DataAuthConfig config : configs) {
|
||||
dataAuthExpression = getExpression(tableAlias, dataAuthExpression, config);
|
||||
}
|
||||
}
|
||||
|
||||
return dataAuthExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拼接所有的权限表达式
|
||||
* @param tableAlias
|
||||
* @param dataAuthExpression
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
private static Expression getExpression(String tableAlias, Expression dataAuthExpression, DataAuthConfig config) {
|
||||
Integer conditionType = config.getConditionType();
|
||||
if (config.getFieldType() == DataAuthFieldTypeEnum.STRING.getCode()) {
|
||||
//如果是第一个条件 直接赋值
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = getConditionType(conditionType, tableAlias, config.getFieldName(), config.getFieldValue());
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, getConditionType(conditionType, tableAlias, config.getFieldName(), config.getFieldValue()));
|
||||
}
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.INT.getCode()) {
|
||||
//如果是第一个条件 直接赋值
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = getConditionTypeLong(conditionType, tableAlias, config.getFieldName(), config.getFieldValue());
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, getConditionTypeLong(conditionType, tableAlias, config.getFieldName(), config.getFieldValue()));
|
||||
}
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_USER_ID.getCode()) {//存在包含、不包含几种情况
|
||||
User user = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());
|
||||
//如果是第一个条件 直接赋值
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = getConditionType(conditionType, tableAlias, config.getFieldName(), user.getId().toString());
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, getConditionType(conditionType, tableAlias, config.getFieldName(), user.getId().toString()));
|
||||
}
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_DEP_ID.getCode()) {//只存在包含于,不包含于这两种,其它全部按包含于处理
|
||||
InExpression inExpression = new InExpression();
|
||||
List<Department> departmentList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_DEPT_LIST_KEY, new ArrayList<>(0));
|
||||
List<Expression> list = new ArrayList<>();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
for (Department department : departmentList) {
|
||||
list.add(new StringValue(department.getId().toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属部门";
|
||||
inExpression = getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = inExpression;
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, inExpression);
|
||||
}
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_DEP_CHILD_ID.getCode()) {//只存在包含于,不包含于这两种,其它全部按包含于处理
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Department> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
|
||||
});
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
List<Department> currentDepartmentList = tokenSession.get(GlobalConstant.LOGIN_USER_DEPT_LIST_KEY, new ArrayList<>(0));
|
||||
List<Long> currentDepartmentIdList = currentDepartmentList.stream().map(Department::getId).collect(Collectors.toList());
|
||||
List<Long> myAndOrgAndChildOrgUserId = getAllOrgChildId(ListUtil.toList(currentDepartmentIdList), departmentList);
|
||||
myAndOrgAndChildOrgUserId.addAll(currentDepartmentIdList);
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Long id : myAndOrgAndChildOrgUserId) {
|
||||
list.add(new StringValue(id.toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属部门";
|
||||
inExpression = getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = inExpression;
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, inExpression);
|
||||
}
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_USER_NAME.getCode()) {
|
||||
User user = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());
|
||||
//如果是第一个条件 直接赋值
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = getConditionType(conditionType, tableAlias, config.getFieldName(), user.getUserName());
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, getConditionType(conditionType, tableAlias, config.getFieldName(), user.getUserName()));
|
||||
}
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_POST_ID.getCode()) {//只存在包含于,不包含于这两种,其它全部按包含于处理
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Post> postList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_POST_LIST_KEY, new ArrayList<>());
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Post post : postList) {
|
||||
list.add(new StringValue(post.getId().toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属岗位";
|
||||
inExpression = getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = inExpression;
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, inExpression);
|
||||
}
|
||||
} else {//只存在包含于,不包含于这两种,其它全部按包含于处理
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Long> roleIdList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Long id : roleIdList) {
|
||||
list.add(new LongValue(id));
|
||||
}
|
||||
String Message = "该登陆人没有所属角色";
|
||||
inExpression = getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
if (ObjectUtil.isNull(dataAuthExpression)) {
|
||||
dataAuthExpression = inExpression;
|
||||
} else {
|
||||
dataAuthExpression = new AndExpression(dataAuthExpression, inExpression);
|
||||
}
|
||||
}
|
||||
return dataAuthExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* 只返回一个权限表达式
|
||||
* @param tableAlias
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
private static Expression getExpression(String tableAlias, DataAuthConfig config) {
|
||||
Integer conditionType = config.getConditionType();
|
||||
if (config.getFieldType() == DataAuthFieldTypeEnum.STRING.getCode()) {
|
||||
return getConditionType(conditionType, tableAlias, config.getFieldName(), config.getFieldValue());
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.INT.getCode()) {
|
||||
return getConditionTypeLong(conditionType, tableAlias, config.getFieldName(), config.getFieldValue());
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_USER_ID.getCode()) {//存在包含、不包含两种情况
|
||||
User user = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());
|
||||
return getConditionType(conditionType, tableAlias, config.getFieldName(), user.getId().toString());
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_DEP_ID.getCode()) {
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Department> departmentList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_DEPT_LIST_KEY, new ArrayList<>(0));
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Department department : departmentList) {
|
||||
list.add(new StringValue(department.getId().toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属部门";
|
||||
return getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_DEP_CHILD_ID.getCode()) {
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Department> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
|
||||
});
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
List<Department> currentDepartmentList = tokenSession.get(GlobalConstant.LOGIN_USER_DEPT_LIST_KEY, new ArrayList<>(0));
|
||||
List<Long> currentDepartmentIdList = currentDepartmentList.stream().map(Department::getId).collect(Collectors.toList());
|
||||
List<Long> myAndOrgAndChildOrgUserId = getAllOrgChildId(currentDepartmentIdList, departmentList);
|
||||
myAndOrgAndChildOrgUserId.addAll(currentDepartmentIdList);
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Long id : myAndOrgAndChildOrgUserId) {
|
||||
list.add(new StringValue(id.toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属部门";
|
||||
return getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_USER_NAME.getCode()) {
|
||||
User user = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());
|
||||
return getConditionType(conditionType, tableAlias, config.getFieldName(), user.getUserName());
|
||||
} else if (config.getFieldType() == DataAuthFieldTypeEnum.LOGIN_POST_ID.getCode()) {
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Post> postList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_POST_LIST_KEY, new ArrayList<>());
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Post post : postList) {
|
||||
list.add(new StringValue(post.getId().toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属岗位";
|
||||
return getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
} else {
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, config.getFieldName()));
|
||||
List<Long> roleIdList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
|
||||
List<Expression> list = new ArrayList<>();
|
||||
for (Long id : roleIdList) {
|
||||
list.add(new StringValue(id.toString()));
|
||||
}
|
||||
String Message = "该登陆人没有所属角色";
|
||||
return getConditionTypeList(inExpression,conditionType,list,Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static InExpression getConditionTypeList(InExpression inExpression, Integer conditionType, List<Expression> list,String Message) {
|
||||
if (conditionType == DataAuthConditionTypeEnum.NO_CONTAINED_IN.getCode()) {//包含于,其它全部按包含于处理
|
||||
inExpression.setRightItemsList(new ExpressionList(list));
|
||||
inExpression.setNot(true);
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.EQUAL_TO.getCode()) {//等于,获取第一个部门id
|
||||
if (list.size() > 0) {
|
||||
inExpression.setRightItemsList(new ExpressionList(list.get(0)));
|
||||
} else {
|
||||
throw new MyException(Message);
|
||||
}
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_EQUAL_TO.getCode()) {//不等于,获取第一个部门id
|
||||
if (list.size() > 0) {
|
||||
inExpression.setRightItemsList(new ExpressionList(list.get(0)));
|
||||
inExpression.setNot(true);
|
||||
} else {
|
||||
throw new MyException(Message);
|
||||
}
|
||||
} else {
|
||||
inExpression.setRightItemsList(new ExpressionList(list));
|
||||
}
|
||||
return inExpression;
|
||||
}
|
||||
|
||||
public static Expression getConditionType(Integer conditionType, String tableAlias, String fieldName, String fieldValue) {
|
||||
if (conditionType == DataAuthConditionTypeEnum.EQUAL_TO.getCode()) {
|
||||
EqualsTo equalsTo = new EqualsTo(); //等于
|
||||
equalsTo.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
equalsTo.setRightExpression(new StringValue(fieldValue));
|
||||
return equalsTo;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.GREATER_THAN.getCode()) {
|
||||
GreaterThan greaterThan = new GreaterThan(); //大于
|
||||
greaterThan.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
greaterThan.setRightExpression(new StringValue(fieldValue));
|
||||
return greaterThan;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.GREATER_THAN_EQUAL.getCode()) {
|
||||
GreaterThanEquals greaterThanEquals = new GreaterThanEquals();//大于等于
|
||||
greaterThanEquals.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
greaterThanEquals.setRightExpression(new StringValue(fieldValue));
|
||||
return greaterThanEquals;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.MINOR_THAN.getCode()) {
|
||||
MinorThan minorThan = new MinorThan();//小于
|
||||
minorThan.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
minorThan.setRightExpression(new StringValue(fieldValue));
|
||||
return minorThan;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.MINOR_THAN_EQUAL.getCode()) {
|
||||
MinorThanEquals minorThanEquals = new MinorThanEquals();//小于等于
|
||||
minorThanEquals.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
minorThanEquals.setRightExpression(new StringValue(fieldValue));
|
||||
return minorThanEquals;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.CONTAIN.getCode()) {//包含
|
||||
LikeExpression likeExpression = new LikeExpression();
|
||||
likeExpression.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
likeExpression.setRightExpression(new StringValue("%" + fieldValue + "%"));
|
||||
return likeExpression;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.CONTAINED_IN.getCode()) {//包含于
|
||||
LikeExpression likeExpression = new LikeExpression();
|
||||
likeExpression.setLeftExpression(new StringValue(fieldValue));
|
||||
likeExpression.setRightExpression(buildColumn(tableAlias, fieldName));
|
||||
return likeExpression;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_EQUAL_TO.getCode()) {//不等于
|
||||
NotEqualsTo notEqualsTo = new NotEqualsTo();
|
||||
notEqualsTo.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
notEqualsTo.setRightExpression(new StringValue(fieldValue));
|
||||
return notEqualsTo;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_CONTAIN.getCode()) {//不包含
|
||||
LikeExpression likeExpression = new LikeExpression();
|
||||
likeExpression.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
likeExpression.setNot(true);
|
||||
likeExpression.setRightExpression(new StringValue("%" + fieldValue + "%"));
|
||||
return likeExpression;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_CONTAINED_IN.getCode()) {//不包含于
|
||||
LikeExpression likeExpression = new LikeExpression();
|
||||
likeExpression.setNot(true);
|
||||
likeExpression.setLeftExpression(new StringValue(fieldValue));
|
||||
likeExpression.setRightExpression(buildColumn(tableAlias, fieldName));
|
||||
return likeExpression;
|
||||
} else {
|
||||
throw new MyException("条件不成立");
|
||||
}
|
||||
}
|
||||
|
||||
public static Expression getConditionTypeLong(Integer conditionType, String tableAlias, String fieldName, String fieldValue) {
|
||||
if (conditionType == DataAuthConditionTypeEnum.EQUAL_TO.getCode()) {
|
||||
EqualsTo equalsTo = new EqualsTo(); //等于
|
||||
equalsTo.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
equalsTo.setRightExpression(new LongValue(fieldValue));
|
||||
return equalsTo;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.GREATER_THAN.getCode()) {
|
||||
GreaterThan greaterThan = new GreaterThan(); //大于
|
||||
greaterThan.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
greaterThan.setRightExpression(new LongValue(fieldValue));
|
||||
return greaterThan;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.GREATER_THAN_EQUAL.getCode()) {
|
||||
GreaterThanEquals greaterThanEquals = new GreaterThanEquals();//大于等于
|
||||
greaterThanEquals.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
greaterThanEquals.setRightExpression(new LongValue(fieldValue));
|
||||
return greaterThanEquals;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.MINOR_THAN.getCode()) {
|
||||
MinorThan minorThan = new MinorThan();//小于
|
||||
minorThan.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
minorThan.setRightExpression(new LongValue(fieldValue));
|
||||
return minorThan;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.MINOR_THAN_EQUAL.getCode()) {
|
||||
MinorThanEquals minorThanEquals = new MinorThanEquals();//小于等于
|
||||
minorThanEquals.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
minorThanEquals.setRightExpression(new LongValue(fieldValue));
|
||||
return minorThanEquals;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.CONTAIN.getCode()) {//包含
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
List<Expression> list = new ArrayList<>();
|
||||
list.add(new LongValue(fieldValue));
|
||||
inExpression.setRightItemsList(new ExpressionList(list));
|
||||
// LikeExpression likeExpression = new LikeExpression();
|
||||
// likeExpression.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
// likeExpression.setRightExpression(new StringValue("%" + fieldValue + "%"));
|
||||
return inExpression;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.CONTAINED_IN.getCode()) {//包含于
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(new LongValue(fieldValue));
|
||||
List<Expression> list = new ArrayList<>();
|
||||
list.add(buildColumn(tableAlias, fieldName));
|
||||
inExpression.setRightItemsList(new ExpressionList(list));
|
||||
return inExpression;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_EQUAL_TO.getCode()) {//不等于
|
||||
NotEqualsTo notEqualsTo = new NotEqualsTo();
|
||||
notEqualsTo.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
notEqualsTo.setRightExpression(new LongValue(fieldValue));
|
||||
return notEqualsTo;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_CONTAIN.getCode()) {//不包含
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(buildColumn(tableAlias, fieldName));
|
||||
List<Expression> list = new ArrayList<>();
|
||||
list.add(new LongValue(fieldValue));
|
||||
inExpression.setRightItemsList(new ExpressionList(list));
|
||||
inExpression.setNot(true);
|
||||
return inExpression;
|
||||
} else if (conditionType == DataAuthConditionTypeEnum.NO_CONTAINED_IN.getCode()) {//不包含于
|
||||
InExpression inExpression = new InExpression();
|
||||
inExpression.setLeftExpression(new LongValue(fieldValue));
|
||||
List<Expression> list = new ArrayList<>();
|
||||
list.add(buildColumn(tableAlias, fieldName));
|
||||
inExpression.setRightItemsList(new ExpressionList(list));
|
||||
inExpression.setNot(true);
|
||||
return inExpression;
|
||||
} else {
|
||||
throw new MyException("条件不成立");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建Column
|
||||
*
|
||||
* @param tableAlias 表别名
|
||||
* @param columnName 字段名称
|
||||
* @return 带表别名字段
|
||||
*/
|
||||
public static Column buildColumn(String tableAlias, String columnName) {
|
||||
if (StrUtil.isNotEmpty(tableAlias)) {
|
||||
columnName = tableAlias + StringPool.DOT + columnName;
|
||||
}
|
||||
return new Column(columnName);
|
||||
}
|
||||
|
||||
public static List<Long> getDataAuthByTableName(String tableName) {
|
||||
|
||||
List<Long> result = new ArrayList<>();
|
||||
|
||||
List<DataAuthTableRelation> dataAuthTableRelations = redisUtil.get(GlobalConstant.DATA_AUTH_TABLE_RELATION_CACHE_KEY, new TypeReference<List<DataAuthTableRelation>>() {
|
||||
});
|
||||
|
||||
//是否有设置权限
|
||||
if (dataAuthTableRelations.stream().noneMatch(x -> x.getTableName().equals(tableName))) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//找到当前表所关联的 数据权限
|
||||
List<DataAuthTableRelation> tableDataAuths = dataAuthTableRelations.stream().filter(x -> x.getTableName().equals(tableName)).collect(Collectors.toList());
|
||||
|
||||
List<Long> allDataAuthId = tableDataAuths.stream().map(DataAuthTableRelation::getDataAuthId).collect(Collectors.toList());
|
||||
List<DataAuth> dataAuths = redisUtil.get(GlobalConstant.DATA_AUTH_CACHE_KEY, new TypeReference<List<DataAuth>>() {
|
||||
});
|
||||
|
||||
List<DataAuth> thisTableAuthDataList = dataAuths.stream().filter(x -> allDataAuthId.contains(x.getId())).collect(Collectors.toList());
|
||||
|
||||
List<DataAuthRelation> authRelationList = redisUtil.get(GlobalConstant.DATA_AUTH_RELATION_CACHE_KEY, new TypeReference<List<DataAuthRelation>>() {
|
||||
});
|
||||
|
||||
for (DataAuth dataAuth : thisTableAuthDataList) {
|
||||
//如果是用户权限
|
||||
if (dataAuth.getAuthType() == DataAuthTypeEnum.USER.getCode()) {
|
||||
//找出有那些用户被赋值了 此数据权限
|
||||
List<Long> userIds = authRelationList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).map(DataAuthRelation::getObjectId).collect(Collectors.toList());
|
||||
|
||||
//判断当前用户是否包含此数据权限
|
||||
if (userIds.contains(StpUtil.getLoginIdAsLong())) {
|
||||
|
||||
//如果是简易模式
|
||||
if (dataAuth.getAuthMethod() == DataAuthMethodEnum.CUSTOM.getCode()) {
|
||||
List<Long> dataAuthSimpleUserId = getDataAuthSimpleUserId(dataAuth.getAuthScope());
|
||||
result.addAll(dataAuthSimpleUserId);
|
||||
}
|
||||
//如果是自定义模式
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取简易模式的所有用户id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static List<Long> getDataAuthSimpleUserId(Integer authScope) {
|
||||
DataAuthScopeEnum enumAt = EnumUtil.getEnumAt(DataAuthScopeEnum.class, authScope);
|
||||
switch (enumAt) {
|
||||
case MY:
|
||||
return ListUtil.toList(StpUtil.getLoginIdAsLong());
|
||||
case MY_AND_POST:
|
||||
return getMyAndPostUserId();
|
||||
case MY_AND_CHILD_POST:
|
||||
return getMyAndChildPostUserId();
|
||||
case MY_AND_POST_AND_CHILD_POST:
|
||||
return getMyAndPostAndChildPostUserId();
|
||||
case MY_AND_ORG:
|
||||
return getMyAndOrgUserId();
|
||||
case MY_AND_CHILD_ORG:
|
||||
return getMyAndChildOrgUserId();
|
||||
case MY_AND_ORG_AND_CHILD_ORG:
|
||||
return getMyAndOrgAndChildOrgUserId();
|
||||
default:
|
||||
return getRoleUserId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同岗位的用户id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static List<Long> getMyAndPostUserId() {
|
||||
List<UserPostRelation> userRelationList = redisUtil.get(GlobalConstant.USER_POST_RELATION_CACHE_KEY, new TypeReference<List<UserPostRelation>>() {
|
||||
});
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
List<Post> postList = tokenSession.get(GlobalConstant.LOGIN_USER_POST_LIST_KEY, new ArrayList<>(0));
|
||||
List<Long> postIdList = postList.stream().map(Post::getId).collect(Collectors.toList());
|
||||
|
||||
return userRelationList.stream()
|
||||
.filter(x -> postIdList.contains(x.getPostId()))
|
||||
.map(UserPostRelation::getUserId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同岗位的用户id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static List<Long> getMyAndChildPostUserId() {
|
||||
List<UserPostRelation> userRelationList = redisUtil.get(GlobalConstant.USER_POST_RELATION_CACHE_KEY, new TypeReference<List<UserPostRelation>>() {
|
||||
});
|
||||
|
||||
List<Post> postList = redisUtil.get(GlobalConstant.POST_CACHE_KEY, new TypeReference<List<Post>>() {
|
||||
});
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
List<Post> currentPostList = tokenSession.get(GlobalConstant.LOGIN_USER_POST_LIST_KEY, new ArrayList<>(0));
|
||||
List<Long> postIdList = currentPostList.stream().map(Post::getId).collect(Collectors.toList());
|
||||
|
||||
List<Long> resultList = new ArrayList<>();
|
||||
//如果有下级 则使用递归 找到所有下级post 求出所有用户id
|
||||
if (postList.stream().anyMatch(x -> postIdList.contains(x.getParentId()))) {
|
||||
List<Long> allPostId = getAllPostChildId(postIdList, postList);
|
||||
resultList.addAll(userRelationList.stream().filter(user -> allPostId.contains(user.getPostId())).map(UserPostRelation::getUserId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
//当前登录人id
|
||||
resultList.add(StpUtil.getLoginIdAsLong());
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private static List<Long> getMyAndPostAndChildPostUserId() {
|
||||
List<Long> result = new ArrayList<>();
|
||||
result.addAll(getMyAndPostUserId());
|
||||
result.addAll(getMyAndChildPostUserId());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<Long> getAllPostChildId(List<Long> postIds, List<Post> postList) {
|
||||
List<Long> resultList = new ArrayList<>();
|
||||
for (Long postId : postIds) {
|
||||
for (Post post : postList) {
|
||||
if (postId.equals(post.getParentId())) {
|
||||
resultList.add(post.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(resultList)) {
|
||||
resultList.addAll(getAllPostChildId(resultList, postList));
|
||||
}
|
||||
return resultList;
|
||||
|
||||
}
|
||||
|
||||
private static List<Long> getAllOrgChildId(List<Long> depIds, List<Department> departmentList) {
|
||||
List<Long> resultList = new ArrayList<>();
|
||||
for (Long depId : depIds) {
|
||||
for (Department department : departmentList) {
|
||||
if (depId.equals(department.getParentId())) {
|
||||
resultList.add(department.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(resultList)) {
|
||||
resultList.addAll(getAllOrgChildId(resultList, departmentList));
|
||||
}
|
||||
return resultList;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同机构/部门的数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static List<Long> getMyAndOrgUserId() {
|
||||
List<UserDeptRelation> userDeptRelations = redisUtil.get(GlobalConstant.USER_DEPT_RELATION_CACHE_KEY, new TypeReference<List<UserDeptRelation>>() {
|
||||
});
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
List<Department> departmentList = tokenSession.get(GlobalConstant.LOGIN_USER_DEPT_LIST_KEY, new ArrayList<>(0));
|
||||
List<Long> departmentIdList = departmentList.stream().map(Department::getId).collect(Collectors.toList());
|
||||
|
||||
return userDeptRelations.stream()
|
||||
.filter(x -> departmentIdList.contains(x.getDeptId()))
|
||||
.map(UserDeptRelation::getUserId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下属机构数据的用户id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static List<Long> getMyAndChildOrgUserId() {
|
||||
List<Long> resultList = new ArrayList<>();
|
||||
List<UserDeptRelation> userDeptRelations = redisUtil.get(GlobalConstant.USER_DEPT_RELATION_CACHE_KEY, new TypeReference<List<UserDeptRelation>>() {
|
||||
});
|
||||
|
||||
List<Department> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
|
||||
});
|
||||
SaSession tokenSession = StpUtil.getTokenSession();
|
||||
List<Department> currentDepartmentList = tokenSession.get(GlobalConstant.LOGIN_USER_DEPT_LIST_KEY, new ArrayList<>(0));
|
||||
List<Long> currentDepartmentIdList = currentDepartmentList.stream().map(Department::getId).collect(Collectors.toList());
|
||||
|
||||
//如果有下级 则使用递归 找到所有下级post 求出所有用户id
|
||||
if (departmentList.stream().anyMatch(x -> currentDepartmentIdList.contains(x.getParentId()))) {
|
||||
List<Long> allChildIdList = getAllOrgChildId(currentDepartmentIdList, departmentList);
|
||||
resultList.addAll(userDeptRelations.stream().filter(user -> allChildIdList.contains(user.getDeptId())).map(UserDeptRelation::getUserId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
//如果没有下级 直接使用当前登陆人岗位
|
||||
resultList.add(StpUtil.getLoginIdAsLong());
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前机构 和下属机构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static List<Long> getMyAndOrgAndChildOrgUserId() {
|
||||
List<Long> result = new ArrayList<>();
|
||||
result.addAll(getMyAndOrgUserId());
|
||||
result.addAll(getMyAndChildOrgUserId());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取同角色
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static List<Long> getRoleUserId() {
|
||||
List<UserRoleRelation> userRoleRelationList = redisUtil.get(GlobalConstant.USER_ROLE_RELATION_CACHE_KEY, new TypeReference<List<UserRoleRelation>>() {
|
||||
});
|
||||
|
||||
|
||||
List<Long> roleIdList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
|
||||
|
||||
|
||||
return userRoleRelationList.stream().filter(r -> roleIdList.contains(r.getRoleId())).map(UserRoleRelation::getUserId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 tableName 生成 expression 给自定义表单 生成sql
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @return
|
||||
*/
|
||||
// public static Expression getDataAuthEntityByTableName(String tableName) {
|
||||
// SelectUtils.buildSelectFromTable(new Table(tableName));
|
||||
//
|
||||
// List<DataAuthTableRelation> dataAuthTableRelations = redisUtil.get(GlobalConstant.DATA_AUTH_TABLE_RELATION_CACHE_KEY, new TypeReference<List<DataAuthTableRelation>>() {
|
||||
// });
|
||||
//
|
||||
// //是否有设置权限
|
||||
// if (dataAuthTableRelations.stream().noneMatch(x -> x.getTableName().equals(tableName))) {
|
||||
// return where;
|
||||
// }
|
||||
//
|
||||
// //找到当前表所关联的 数据权限
|
||||
// List<DataAuthTableRelation> tableDataAuths = dataAuthTableRelations.stream().filter(x -> x.getTableName().equals(tableName)).collect(Collectors.toList());
|
||||
//
|
||||
// List<Long> allDataAuthId = tableDataAuths.stream().map(DataAuthTableRelation::getDataAuthId).collect(Collectors.toList());
|
||||
// List<DataAuth> dataAuths = redisUtil.get(GlobalConstant.DATA_AUTH_CACHE_KEY, new TypeReference<List<DataAuth>>() {
|
||||
// });
|
||||
//
|
||||
// List<DataAuth> thisTableAuthDataList = dataAuths.stream().filter(x -> allDataAuthId.contains(x.getId())).collect(Collectors.toList());
|
||||
//
|
||||
// List<DataAuthRelation> authRelationList = redisUtil.get(GlobalConstant.DATA_AUTH_RELATION_CACHE_KEY, new TypeReference<List<DataAuthRelation>>() {
|
||||
// });
|
||||
//
|
||||
// List<DataAuthConfig> authConfigList = redisUtil.get(GlobalConstant.DATA_AUTH_CONFIG_CACHE_KEY, new TypeReference<List<DataAuthConfig>>() {
|
||||
// });
|
||||
//
|
||||
// for (DataAuth dataAuth : thisTableAuthDataList) {
|
||||
// List<Long> userIds = new ArrayList<>();
|
||||
// //如果是用户权限
|
||||
// if (dataAuth.getAuthType() == DataAuthTypeEnum.USER.getCode()) {
|
||||
// //找出有那些用户被赋值了 此数据权限
|
||||
// userIds = authRelationList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).map(DataAuthRelation::getObjectId).collect(Collectors.toList());
|
||||
// } else {
|
||||
// List<Long> roleIds = authRelationList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).map(DataAuthRelation::getObjectId).collect(Collectors.toList());
|
||||
//
|
||||
// List<Role> roleList = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new ArrayList<>());
|
||||
//
|
||||
// //如果当前登陆人不包含 这些 角色id 默认不添加数据权限
|
||||
// if (roleList.stream().map(Role::getId).noneMatch(roleIds::contains)) {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// //判断当前用户是否包含此数据权限
|
||||
// if (userIds.contains(StpUtil.getLoginIdAsLong())) {
|
||||
//
|
||||
// //如果是简易模式
|
||||
// if (dataAuth.getAuthMethod() == DataAuthMethodEnum.SIMPLE.getCode()) {
|
||||
// //所有能查看的用户数据
|
||||
// List<Long> dataAuthSimpleUserId = getDataAuthSimpleUserId(dataAuth.getAuthScope());
|
||||
//
|
||||
//// where.set(GlobalConstant.AUTH_USER_ID, new Condition(GlobalConstant.AUTH_USER_ID, "in", dataAuthSimpleUserId));
|
||||
// where.set(GlobalConstant.AUTH_USER_ID, dataAuthSimpleUserId);
|
||||
//
|
||||
// }
|
||||
// //如果是自定义模式
|
||||
// else {
|
||||
// List<DataAuthConfig> thisDataAuthConfig = authConfigList.stream().filter(x -> x.getDataAuthId().equals(dataAuth.getId())).collect(Collectors.toList());
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return where;
|
||||
// }
|
||||
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package com.xjrsoft.common.mybatis.utils;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.xjrsoft.common.core.constant.GlobalConstant;
|
||||
import com.xjrsoft.common.core.domain.page.PageInput;
|
||||
import com.xjrsoft.common.core.domain.page.PageOutput;
|
||||
import com.xjrsoft.common.core.xss.SQLFilter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: tzx
|
||||
* @Date:2022/3/7 14:51
|
||||
*/
|
||||
public class ConventPage {
|
||||
public ConventPage() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页入参 转换为 IPage
|
||||
*/
|
||||
public static <T> IPage<T> getPage(@NotNull PageInput input) {
|
||||
Page<T> page = new Page<>(input.getLimit(), input.getSize());
|
||||
String orderField = SQLFilter.sqlInject(StrUtil.toUnderlineCase(input.getField()));
|
||||
String order = SQLFilter.sqlInject(StrUtil.toUnderlineCase(input.getOrder()));
|
||||
|
||||
if (StrUtil.equalsIgnoreCase(GlobalConstant.ORDER_DESC, order)) {
|
||||
page.addOrder(OrderItem.desc(orderField));
|
||||
} else {
|
||||
page.addOrder(OrderItem.asc(orderField));
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据查询出来得分页 转换为 pageoutput
|
||||
*/
|
||||
public static <T> PageOutput<T> getPageOutput(IPage<T> page) {
|
||||
PageOutput<T> output = new PageOutput<>();
|
||||
output.setTotal(Convert.toInt(page.getTotal()));
|
||||
output.setList(page.getRecords());
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据查询出来得分页 转换为 pageoutput 并且重新隐射为vo
|
||||
*
|
||||
* @param page 查出来得page
|
||||
* @param clazz vo类型
|
||||
*/
|
||||
public static <T> PageOutput<T> getPageOutput(IPage<?> page, Class<T> clazz) {
|
||||
PageOutput<T> output = new PageOutput<>();
|
||||
output.setTotal(Convert.toInt(page.getTotal()));
|
||||
List<T> ts = BeanUtil.copyToList(page.getRecords(), clazz);
|
||||
output.setList(ts);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页入参 转换为 IPage
|
||||
*/
|
||||
public static String getOrder(@NotNull String order) {
|
||||
|
||||
String orderString = SQLFilter.sqlInject(StrUtil.toUnderlineCase(order));
|
||||
|
||||
if (StrUtil.equalsIgnoreCase(GlobalConstant.ORDER_DESC, orderString)) {
|
||||
return "desc";
|
||||
} else {
|
||||
return "asc";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,675 @@
|
||||
package com.xjrsoft.common.mybatis.utils;
|
||||
|
||||
import cn.hutool.core.util.PageUtil;
|
||||
import cn.hutool.db.DbUtil;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.db.ds.simple.SimpleDataSource;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
|
||||
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
|
||||
import com.xjrsoft.common.core.constant.GlobalConstant;
|
||||
import com.xjrsoft.common.core.enums.MySqlFieldsType;
|
||||
import com.xjrsoft.common.core.enums.OracleFieldsType;
|
||||
import com.xjrsoft.common.core.enums.PostgreSqlFieldsType;
|
||||
import com.xjrsoft.common.core.enums.SqlServerFieldsType;
|
||||
import com.xjrsoft.common.generate.model.TableFieldConfig;
|
||||
import com.xjrsoft.common.generate.model.TableStructureConfig;
|
||||
import com.xjrsoft.tenant.config.TenantConfig;
|
||||
import com.xjrsoft.common.core.enums.*;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @title: 数据源工具类
|
||||
* @Author tzx
|
||||
* @Date: 2022/4/17 14:55
|
||||
* @Version 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class DatasourceUtil {
|
||||
|
||||
private static final TenantConfig tenantConfig;
|
||||
|
||||
static {
|
||||
tenantConfig = SpringUtil.getBean(TenantConfig.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取主数据源
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static DataSource getDatasourceMaster() {
|
||||
DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtil.getBean(DynamicRoutingDataSource.class);
|
||||
return dynamicRoutingDataSource.getDataSource(GlobalConstant.DEFAULT_DATASOURCE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据源
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static DataSource getDataSource(String id) {
|
||||
DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtil.getBean(DynamicRoutingDataSource.class);
|
||||
try {
|
||||
return dynamicRoutingDataSource.getDataSource(id);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("获取数据源失败: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public static DbType getDataSourceMasterDbType() {
|
||||
DynamicDataSourceProperties dynamicDataSourceProperties = SpringUtil.getBean(DynamicDataSourceProperties.class);
|
||||
DataSourceProperty datasource = dynamicDataSourceProperties.getDatasource().get(dynamicDataSourceProperties.getPrimary());
|
||||
return JdbcUtils.getDbType(datasource.getUrl());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 关闭链接
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static void close(Connection connection, ResultSet resultSet) {
|
||||
if (resultSet != null) {
|
||||
resultSet.close();
|
||||
}
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建分页查询sql
|
||||
*
|
||||
* @param sql
|
||||
* @param page
|
||||
* @return
|
||||
*/
|
||||
public static String wrapperPageSql(String sql, Page page, DbType dbType) {
|
||||
switch (dbType) {
|
||||
case MYSQL:
|
||||
return wrapperPageSqlForMysql(sql, page);
|
||||
case ORACLE:
|
||||
case ORACLE_12C:
|
||||
return wrapperPageSqlForOracle(sql, page);
|
||||
case SQL_SERVER:
|
||||
return wrapperPageSqlForSqlServer(sql, page);
|
||||
case POSTGRE_SQL:
|
||||
return wrapperPageSqlForPostgreSql(sql, page);
|
||||
case DM:
|
||||
return wrapperPageSqlForDm(sql, page);
|
||||
case DB2:
|
||||
return wrapperPageSqlForDb2(sql, page);
|
||||
case KINGBASE_ES:
|
||||
return wrapperPageSqlForKingBaseEs(sql, page);
|
||||
case GAUSS:
|
||||
return wrapperPageSqlForGauss(sql, page);
|
||||
default:
|
||||
return sql;
|
||||
}
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForMysql(String sql, Page page) {
|
||||
return "select * from (" + sql + ") t" + " limit " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + "," +page.getPageSize();
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForOracle(String sql, Page page) {
|
||||
return "select * from ( SELECT row_.*, rownum rownum_ from ( " + sql + " ) row_ where rownum <= " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + ") table_alias where table_alias.rownum_ >" + PageUtil.getEnd(page.getPageNumber(), page.getPageSize());
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForSqlServer(String sql, Page page) {
|
||||
return "select * FROM ( " + sql + " ) t ORDER BY current_timestamp offset " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + " rows fetch next " + PageUtil.getEnd(page.getPageNumber(), page.getPageSize()) + " rows only";
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForPostgreSql(String sql, Page page) {
|
||||
return "select * FROM ( " + sql + " ) t limit " + page.getPageNumber() + " offset " + page.getPageSize();
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForDm(String sql, Page page) {
|
||||
return "select * from (" + sql + ") t" + " limit " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + "," + PageUtil.getEnd(page.getPageNumber(), page.getPageSize());
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForDb2(String sql, Page page) {
|
||||
return "select row_num() over() as rownum,* from ( " + sql + " ) where rownum > " + PageUtil.getStart(page.getPageNumber(), page.getPageSize()) + " and rownum < " + PageUtil.getEnd(page.getPageNumber(), page.getPageSize());
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForKingBaseEs(String sql, Page page) {
|
||||
return "select * FROM ( " + sql + " ) t limit " + page.getPageNumber() + " offset " + page.getPageSize();
|
||||
}
|
||||
|
||||
private static String wrapperPageSqlForGauss(String sql, Page page) {
|
||||
return "select * FROM ( " + sql + " ) t limit " + page.getPageNumber() + " offset " + page.getPageSize();
|
||||
}
|
||||
|
||||
private static String wrapperPageCount(String sql, Page page) {
|
||||
return "select count(*) from (" + sql + ") t";
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建测试sql
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String wrapperTestSql(DbType dbType) {
|
||||
switch (dbType) {
|
||||
case ORACLE:
|
||||
case ORACLE_12C:
|
||||
return "SELECT 1 FROM DUAL";
|
||||
default:
|
||||
return "select 1";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建测试sql
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String wrapperDropSql(String tableName) {
|
||||
return "drop table " + tableName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建建表sql语句
|
||||
*
|
||||
* @param tableStructureConfigs
|
||||
* @return
|
||||
*/
|
||||
public static List<String> wrapperCreateTableSql(List<TableStructureConfig> tableStructureConfigs, DbType dbType) {
|
||||
switch (dbType) {
|
||||
case ORACLE:
|
||||
case ORACLE_12C:
|
||||
case DM:
|
||||
return wrapperCreateTableSqlForOracle(tableStructureConfigs, dbType);
|
||||
case DB2:
|
||||
return wrapperCreateTableSqlForDB2(tableStructureConfigs);
|
||||
case SQL_SERVER2005:
|
||||
case SQL_SERVER:
|
||||
return wrapperCreateTableSqlForSqlServer(tableStructureConfigs);
|
||||
case POSTGRE_SQL:
|
||||
case KINGBASE_ES:
|
||||
case GAUSS:
|
||||
return wrapperCreateTableSqlForPostgreSql(tableStructureConfigs);
|
||||
default:
|
||||
return wrapperCreateTableSqlForMysql(tableStructureConfigs);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> wrapperCreateTableSqlForMysql(List<TableStructureConfig> tableStructureConfigs) {
|
||||
List<String> sqls = new ArrayList<>();
|
||||
//遍历所有表配置
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
// 创建新表和覆盖旧表才需要创建表
|
||||
Integer operator = tableStructureConfig.getOperator();
|
||||
if (operator == 1) {
|
||||
continue;
|
||||
}
|
||||
if (operator == 3) {
|
||||
sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("CREATE TABLE `").append(tableStructureConfig.getTableName()).append("` ( \n");
|
||||
sb.append(" `").append(GlobalConstant.DEFAULT_PK).append("` bigint NOT NULL, \n");
|
||||
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
MySqlFieldsType fieldType = MySqlFieldsType.getFieldType(tableFieldConfig.getFieldType());
|
||||
String type = fieldType.getType();
|
||||
switch (fieldType) {
|
||||
//普通文本
|
||||
case VARCHAR:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append(") COMMENT '" + tableFieldConfig.getFieldComment() + "', \n");
|
||||
break;
|
||||
//长文本
|
||||
case VARCHARMAX:
|
||||
//数字
|
||||
case INT:
|
||||
case FLOAT:
|
||||
//日期
|
||||
case DATE:
|
||||
//日期时间
|
||||
case DATETIME:
|
||||
//长数字
|
||||
case LONG:
|
||||
//时间
|
||||
case TIME:
|
||||
sb.append(" `").append(tableFieldConfig.getFieldName()).append("` ").append(type).append(" COMMENT '").append(tableFieldConfig.getFieldComment()).append("', \n");
|
||||
break;
|
||||
default:
|
||||
sb.append(" `").append(tableFieldConfig.getFieldName()).append("` ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append(") COMMENT '").append(tableFieldConfig.getFieldComment()).append("', \n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//如果不是主表 默认需要新增主表关联字段 用于关联主表 默认字段名为 parent + _id
|
||||
if(!tableStructureConfig.getIsMain()){
|
||||
sb.append(" `").append(GlobalConstant.DEFAULT_FK).append("` bigint , \n");
|
||||
}
|
||||
if (BooleanUtils.isTrue(tenantConfig.getEnabled())) {
|
||||
sb.append(" `").append(tenantConfig.getTenantField()).append("` bigint , \n");
|
||||
}
|
||||
|
||||
sb.append(" PRIMARY KEY (`").append(GlobalConstant.DEFAULT_PK).append("`) \n");
|
||||
sb.append(") ENGINE=`InnoDB` DEFAULT CHARACTER SET utf8mb4 COMMENT='").append(tableStructureConfig.getTableComment()).append("';\n");
|
||||
|
||||
sqls.add(sb.toString());
|
||||
}
|
||||
return sqls;
|
||||
}
|
||||
|
||||
private static List<String> wrapperCreateTableSqlForOracle(List<TableStructureConfig> tableStructureConfigs, DbType dbType) {
|
||||
List<String> sqls = new ArrayList<>();
|
||||
//遍历所有表配置
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
// 创建新表和覆盖旧表才需要创建表
|
||||
Integer operator = tableStructureConfig.getOperator();
|
||||
if (operator == 1) {
|
||||
continue;
|
||||
}
|
||||
if (operator == 3) {
|
||||
sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_PK).append(" NUMBER(20, 0) NOT NULL, \n");
|
||||
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
OracleFieldsType fieldType = OracleFieldsType.getFieldType(tableFieldConfig.getFieldType());
|
||||
String type = fieldType.getType();
|
||||
switch (fieldType) {
|
||||
//普通文本
|
||||
case VARCHAR:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("), \n");
|
||||
break;
|
||||
//数字
|
||||
case INT:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(11, 0), \n");
|
||||
break;
|
||||
//长数字
|
||||
case LONG:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(20, 0), \n");
|
||||
break;
|
||||
//小数
|
||||
case FLOAT:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(20, 10), \n");
|
||||
break;
|
||||
//长文本
|
||||
case VARCHARMAX:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(2000), \n");
|
||||
break;
|
||||
//日期
|
||||
case DATE:
|
||||
case DATETIME:
|
||||
// 时间
|
||||
case TIME:
|
||||
if (dbType == DbType.DM && fieldType == OracleFieldsType.TIME) {
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append("TIME").append(", \n");
|
||||
} else {
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(", \n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("), \n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
//如果不是主表 默认需要新增主表关联字段 用于关联主表 默认字段名为 parent + _id
|
||||
if(!tableStructureConfig.getIsMain()){
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_FK).append(" NUMBER(20, 0), \n");
|
||||
}
|
||||
if (BooleanUtils.isTrue(tenantConfig.getEnabled())) {
|
||||
sb.append(" ").append(tenantConfig.getTenantField()).append(" NUMBER(20,0) , \n");
|
||||
}
|
||||
|
||||
sb.append(" PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
|
||||
sb.append(") \n");
|
||||
|
||||
sqls.add(sb.toString());
|
||||
}
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
sqls.add("COMMENT ON COLUMN " + tableStructureConfig.getTableName() + "." + tableFieldConfig.getFieldName() + " IS '" + tableFieldConfig.getFieldComment() + "'");
|
||||
}
|
||||
|
||||
}
|
||||
return sqls;
|
||||
}
|
||||
|
||||
private static List<String> wrapperCreateTableSqlForDB2(List<TableStructureConfig> tableStructureConfigs) {
|
||||
List<String> sqls = new ArrayList<>();
|
||||
//遍历所有表配置
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
// 创建新表和覆盖旧表才需要创建表
|
||||
Integer operator = tableStructureConfig.getOperator();
|
||||
if (operator == 1) {
|
||||
continue;
|
||||
}
|
||||
if (operator == 3) {
|
||||
sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_PK).append(" BIGINT NOT NULL, \n");
|
||||
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
DB2FieldsType fieldType = DB2FieldsType.getFieldType(tableFieldConfig.getFieldType());
|
||||
String type = fieldType.getType();
|
||||
switch (fieldType) {
|
||||
//普通文本
|
||||
case VARCHAR:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("), \n");
|
||||
break;
|
||||
//数字
|
||||
case INT:
|
||||
//长数字
|
||||
case LONG:
|
||||
//小数
|
||||
case FLOAT:
|
||||
//长文本
|
||||
case VARCHARMAX:
|
||||
//日期
|
||||
case DATE:
|
||||
case DATETIME:
|
||||
// 时间
|
||||
case TIME:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(", \n");
|
||||
break;
|
||||
default:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("), \n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
//如果不是主表 默认需要新增主表关联字段 用于关联主表 默认字段名为 parent + _id
|
||||
if(!tableStructureConfig.getIsMain()){
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_FK).append(" BIGINT, \n");
|
||||
}
|
||||
|
||||
|
||||
sb.append(" PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
|
||||
sb.append(") \n");
|
||||
|
||||
sqls.add(sb.toString());
|
||||
}
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
sqls.add("COMMENT ON COLUMN " + tableStructureConfig.getTableName() + "." + tableFieldConfig.getFieldName() + " IS '" + tableFieldConfig.getFieldComment() + "'");
|
||||
}
|
||||
|
||||
}
|
||||
return sqls;
|
||||
}
|
||||
|
||||
private static List<String> wrapperCreateTableSqlForSqlServer(List<TableStructureConfig> tableStructureConfigs) {
|
||||
List<String> sqls = new ArrayList<>();
|
||||
//遍历所有表配置
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
// 创建新表和覆盖旧表才需要创建表
|
||||
Integer operator = tableStructureConfig.getOperator();
|
||||
if (operator == 1) {
|
||||
continue;
|
||||
}
|
||||
if (operator == 3) {
|
||||
sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_PK).append(" bigint NOT NULL, \n");
|
||||
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
SqlServerFieldsType fieldType = SqlServerFieldsType.getFieldType(tableFieldConfig.getFieldType());
|
||||
String type = fieldType.getType();
|
||||
switch (fieldType) {
|
||||
//普通文本
|
||||
case VARCHAR:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("), \n");
|
||||
break;
|
||||
//长文本
|
||||
case VARCHARMAX:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(max), \n");
|
||||
break;
|
||||
//数字
|
||||
case INT:
|
||||
//小数
|
||||
case FLOAT:
|
||||
//日期
|
||||
case DATE:
|
||||
case DATETIME:
|
||||
//长数字
|
||||
case LONG:
|
||||
// 时间
|
||||
case TIME:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(", \n");
|
||||
break;
|
||||
default:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("), \n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//如果不是主表 默认需要新增主表关联字段 用于关联主表 默认字段名为 parent + _id
|
||||
if(!tableStructureConfig.getIsMain()){
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_FK).append(" bigint , \n");
|
||||
}
|
||||
if (BooleanUtils.isTrue(tenantConfig.getEnabled())) {
|
||||
sb.append(" ").append(tenantConfig.getTenantField()).append(" bigint , \n");
|
||||
}
|
||||
|
||||
sb.append(" PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
|
||||
sb.append("); \n");
|
||||
|
||||
sqls.add(sb.toString());
|
||||
}
|
||||
return sqls;
|
||||
}
|
||||
|
||||
private static List<String> wrapperCreateTableSqlForPostgreSql(List<TableStructureConfig> tableStructureConfigs) {
|
||||
List<String> sqls = new ArrayList<>();
|
||||
//遍历所有表配置
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
// 创建新表和覆盖旧表才需要创建表
|
||||
Integer operator = tableStructureConfig.getOperator();
|
||||
if (operator == 1) {
|
||||
continue;
|
||||
}
|
||||
if (operator == 3) {
|
||||
sqls.add(wrapperDropSql(tableStructureConfig.getTableName()));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("CREATE TABLE ").append(tableStructureConfig.getTableName()).append(" ( \n");
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_PK).append(" bigint NOT NULL, \n");
|
||||
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
PostgreSqlFieldsType fieldType = PostgreSqlFieldsType.getFieldType(tableFieldConfig.getFieldType());
|
||||
String type = fieldType.getType();
|
||||
switch (fieldType) {
|
||||
//普通文本
|
||||
case VARCHAR:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(tableFieldConfig.getFieldLength()).append("), \n");
|
||||
break;
|
||||
//长文本
|
||||
case VARCHARMAX:
|
||||
//数字
|
||||
case INT:
|
||||
//长数字
|
||||
case LONG:
|
||||
//小数
|
||||
case FLOAT:
|
||||
//日期
|
||||
case DATE:
|
||||
case DATETIME:
|
||||
case TIME:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append(", \n");
|
||||
break;
|
||||
default:
|
||||
sb.append(tableFieldConfig.getFieldName()).append(" ").append(type).append("(").append(GlobalConstant.DEFAULT_TEXT_LENGTH).append("), \n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
//如果不是主表 默认需要新增主表关联字段 用于关联主表 默认字段名为 parent + _id
|
||||
if(!tableStructureConfig.getIsMain()){
|
||||
sb.append(" ").append(GlobalConstant.DEFAULT_FK).append(" ").append(PostgreSqlFieldsType.FK.getType()).append(" , \n");
|
||||
}
|
||||
if (BooleanUtils.isTrue(tenantConfig.getEnabled())) {
|
||||
sb.append(" `").append(tenantConfig.getTenantField()).append(PostgreSqlFieldsType.FK.getType()).append(", \n");
|
||||
}
|
||||
|
||||
sb.append(" PRIMARY KEY (").append(GlobalConstant.DEFAULT_PK).append(") \n");
|
||||
sb.append("); \n");
|
||||
sqls.add(sb.toString());
|
||||
}
|
||||
for (TableStructureConfig tableStructureConfig : tableStructureConfigs) {
|
||||
List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
|
||||
//遍历当前表配置的 字段配置
|
||||
for (TableFieldConfig tableFieldConfig : tableFieldConfigs) {
|
||||
sqls.add("COMMENT ON COLUMN " + tableStructureConfig.getTableName() + "." + tableFieldConfig.getFieldName() + " IS '" + tableFieldConfig.getFieldComment() + "'");
|
||||
}
|
||||
|
||||
}
|
||||
return sqls;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 判断表是否存在的sql
|
||||
* @param tableName
|
||||
* @param dbType
|
||||
* @return
|
||||
*/
|
||||
private static String wrapperExistTableSql(String tableName, DbType dbType) {
|
||||
switch (dbType) {
|
||||
case ORACLE:
|
||||
case ORACLE_12C:
|
||||
return wrapperExistTableSqlForOracle(tableName);
|
||||
case SQL_SERVER:
|
||||
return wrapperExistTableSqlForSqlServer(tableName);
|
||||
case POSTGRE_SQL:
|
||||
return wrapperExistTableSqlForPostgreSql(tableName);
|
||||
case DM:
|
||||
return wrapperExistTableSqlForDm(tableName);
|
||||
case DB2:
|
||||
return wrapperExistTableSqlForDb2(tableName);
|
||||
case KINGBASE_ES:
|
||||
return wrapperExistTableSqlForKingBaseEs(tableName);
|
||||
case GAUSS:
|
||||
return wrapperExistTableSqlForGauss(tableName);
|
||||
default:
|
||||
return wrapperExistTableSqlForMysql(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForMysql(String tableName) {
|
||||
return "select count(*) from information_schema.TABLES where TABLE_NAME = '" + tableName + "'";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForOracle(String tableName) {
|
||||
return "select count(*) from user_tables where table_name = '" + tableName + "'";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForSqlServer(String tableName) {
|
||||
return "select count(*) from sys.objects where object_id = OBJECT_ID('" + tableName + "')";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForPostgreSql(String tableName) {
|
||||
return "select count(*) from pg_catalog.pg_tables where tablename = '" + tableName + "'";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForDm(String tableName) {
|
||||
return "select count(*) from sysobjects where NAME = '" + tableName + "'";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForDb2(String tableName) {
|
||||
return "select count(*) from sysibm.systables where tablename = '" + tableName + "'";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForKingBaseEs(String tableName) {
|
||||
return "select count(*) from sys_tables where table_name = '" + tableName + "'";
|
||||
}
|
||||
|
||||
private static String wrapperExistTableSqlForGauss(String tableName) {
|
||||
return "select count(*) from sys_tables where table_name = '" + tableName + "'";
|
||||
}
|
||||
|
||||
public static Boolean testConnection(String url, String userName, String password) {
|
||||
try (SimpleDataSource ds = new SimpleDataSource(url, userName, password)) {
|
||||
DbUtil.use(ds).query(wrapperTestSql(JdbcUtils.getDbType(url)));
|
||||
} catch (Exception e) {
|
||||
log.error("数据库连接失败!url: " + url, e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String getDbType(DbType dbType, Integer typeCode) {
|
||||
switch (dbType) {
|
||||
case ORACLE:
|
||||
case ORACLE_12C:
|
||||
case DM:
|
||||
case DB2:
|
||||
return OracleFieldsType.getFieldType(typeCode).getType();
|
||||
case SQL_SERVER:
|
||||
return SqlServerFieldsType.getFieldType(typeCode).getType();
|
||||
case POSTGRE_SQL:
|
||||
case KINGBASE_ES:
|
||||
case GAUSS:
|
||||
return PostgreSqlFieldsType.getFieldType(typeCode).getType();
|
||||
default:
|
||||
return MySqlFieldsType.getFieldType(typeCode).getType();
|
||||
}
|
||||
}
|
||||
|
||||
public static DbType getDbType(String datasourceId) {
|
||||
DataSource dataSource = getDataSource(datasourceId);
|
||||
if (dataSource != null) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = dataSource.getConnection();
|
||||
return JdbcUtils.getDbType(connection.getMetaData().getURL());
|
||||
} catch (Exception e) {
|
||||
log.error("获取数据库类型失败!", e);
|
||||
} finally {
|
||||
DbUtil.close(connection);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,164 @@
|
||||
package com.xjrsoft.common.mybatis.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import oracle.sql.INTERVALDS;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public final class LocalDateTimeUtil {
|
||||
private LocalDateTimeUtil(){}
|
||||
|
||||
public final static String LOCAL_TIME_FORMAT = "HH:mm:ss";
|
||||
|
||||
public final static String LOCAL_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
public final static String LOCAL_DATE_FORMAT = "yyyy-MM-dd";
|
||||
|
||||
public final static String YEAR_MONTH_FORMAT = "yyyy-MM";
|
||||
|
||||
public final static String YEAR_FORMAT = "yyyy";
|
||||
|
||||
public static LocalTime parseTime(String value) {
|
||||
return parseTime(value, LOCAL_TIME_FORMAT);
|
||||
}
|
||||
|
||||
public static LocalTime parseTime(String value, String format) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return null;
|
||||
}
|
||||
return LocalTime.parse(value, DateTimeFormatter.ofPattern(format));
|
||||
}
|
||||
|
||||
public static LocalDateTime parseDate(String value) {
|
||||
return parseDate(value, LOCAL_DATE_TIME_FORMAT);
|
||||
}
|
||||
|
||||
public static LocalDateTime parseDate(String value, String format) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return null;
|
||||
}
|
||||
// 根据format切掉多余的时间
|
||||
value = StringUtils.substring(value, 0, format.length());
|
||||
LocalDateTime localDateTime = null;
|
||||
format = convertFontFormat(format);
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
|
||||
switch (format) {
|
||||
case YEAR_FORMAT:
|
||||
Year year = Year.parse(value, dateTimeFormatter);
|
||||
localDateTime = LocalDateTime.from(year.atDay(1).atStartOfDay());
|
||||
break;
|
||||
case YEAR_MONTH_FORMAT:
|
||||
YearMonth yearMonth = YearMonth.parse(value, dateTimeFormatter);
|
||||
localDateTime = LocalDateTime.from(yearMonth.atDay(1).atStartOfDay());
|
||||
break;
|
||||
case LOCAL_DATE_FORMAT:
|
||||
LocalDate localDate = LocalDate.parse(value, dateTimeFormatter);
|
||||
localDateTime = LocalDateTime.from(localDate.atStartOfDay());
|
||||
break;
|
||||
default:
|
||||
localDateTime = LocalDateTime.parse(value, dateTimeFormatter);
|
||||
break;
|
||||
}
|
||||
return localDateTime;
|
||||
}
|
||||
|
||||
public static String convertFontFormat(String fontFormat) {
|
||||
if (StrUtil.isEmpty(fontFormat)) {
|
||||
return fontFormat;
|
||||
}
|
||||
return fontFormat.replace("YYYY", "yyyy").replace("DD", "dd");
|
||||
}
|
||||
|
||||
public static String format(LocalDateTime dateTime, String format) {
|
||||
if (dateTime == null) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
return dateTime.format(DateTimeFormatter.ofPattern(format));
|
||||
}
|
||||
|
||||
public static String format(LocalTime time) {
|
||||
if (time == null) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
return time.format(DateTimeFormatter.ofPattern(LOCAL_TIME_FORMAT));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间字符串转换成数据库对应的时间类型
|
||||
* @param time 时间字符串 格式 HH:mm:ss
|
||||
* @param dbType 数据库类型
|
||||
* @return 据库对应的时间类型对象
|
||||
*/
|
||||
public static Object parseDbTime(String time, DbType dbType) {
|
||||
if (dbType == DbType.ORACLE || dbType == DbType.ORACLE_12C) {
|
||||
return new INTERVALDS("0 " + time + ".0");
|
||||
} else {
|
||||
return parseTime(time);
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalDateTime parseDateByLength(String value) {
|
||||
if (StrUtil.isNotBlank(value)) {
|
||||
value = value.trim();
|
||||
int length = value.length();
|
||||
if (LOCAL_DATE_FORMAT.length() == length) {
|
||||
LocalDate localDate = LocalDate.parse(value, DateTimeFormatter.ofPattern(LOCAL_DATE_FORMAT));
|
||||
return LocalDateTime.from(localDate.atStartOfDay());
|
||||
} else if (LOCAL_DATE_TIME_FORMAT.length() == length) {
|
||||
return LocalDateTime.parse(value, DateTimeFormatter.ofPattern(LOCAL_DATE_TIME_FORMAT));
|
||||
} else if (YEAR_MONTH_FORMAT.length() == length) {
|
||||
YearMonth yearMonth = YearMonth.parse(value, DateTimeFormatter.ofPattern(YEAR_MONTH_FORMAT));
|
||||
return LocalDateTime.from(yearMonth.atDay(1).atStartOfDay());
|
||||
} else if (YEAR_FORMAT.length() == length) {
|
||||
Year year = Year.parse(value, DateTimeFormatter.ofPattern(YEAR_FORMAT));
|
||||
return LocalDateTime.from(year.atDay(1).atStartOfDay());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static LocalTime convertIntervalToLocalTime(INTERVALDS intervalDS) {
|
||||
if (intervalDS == null) {
|
||||
return null;
|
||||
}
|
||||
String str = intervalDS.stringValue();
|
||||
String timeStr = str.substring(str.indexOf(StringPool.SPACE) + 1, str.indexOf(StringPool.DOT));
|
||||
String[] array = timeStr.split(StringPool.COLON);
|
||||
return LocalTime.of(Integer.parseInt(array[0]), Integer.parseInt(array[1]), Integer.parseInt(array[2]));
|
||||
}
|
||||
|
||||
public static String tranDurationToShow(Duration duration) {
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
long days = duration.toDays();
|
||||
if (days >= 1) {
|
||||
result.append(days).append("天");
|
||||
}
|
||||
long hours = duration.toHours();
|
||||
if (hours >= 1) {
|
||||
if (days >= 1) {
|
||||
long l = hours % 24;
|
||||
if (l > 0) result.append(l).append("小时");
|
||||
return result.toString();
|
||||
}
|
||||
result.append(hours).append("小时");
|
||||
}
|
||||
long minutes = duration.toMinutes();
|
||||
if (minutes >= 1) {
|
||||
if (hours >= 1) {
|
||||
long l = minutes % 60;
|
||||
if (l > 0) result.append(l).append("分钟");
|
||||
return result.toString();
|
||||
}
|
||||
result.append(minutes).append("分钟");
|
||||
}
|
||||
if (result.length() == 0) {
|
||||
result.append("1分钟内");
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.xjrsoft.common.mybatis.utils;
|
||||
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.hutool.db.Page;
|
||||
import cn.hutool.db.PageResult;
|
||||
import cn.hutool.db.SqlConnRunner;
|
||||
import cn.hutool.db.dialect.Dialect;
|
||||
import cn.hutool.db.sql.SqlBuilder;
|
||||
import com.xjrsoft.common.mybatis.handler.XjrPageResultHandler;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class XjrSqlConnRunner extends SqlConnRunner {
|
||||
public XjrSqlConnRunner(Dialect dialect) {
|
||||
super(dialect);
|
||||
}
|
||||
|
||||
public XjrSqlConnRunner(String driverClassName) {
|
||||
super(driverClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<Entity> page(Connection conn, SqlBuilder sqlBuilder, Page page) throws SQLException {
|
||||
final XjrPageResultHandler pageResultHandler = new XjrPageResultHandler(
|
||||
new PageResult<>(page.getPageNumber(), page.getPageSize(), (int) count(conn, sqlBuilder)),
|
||||
this.caseInsensitive);
|
||||
return page(conn, sqlBuilder, page, pageResultHandler);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
com.xjrsoft.common.mybatis.MybatisplusAutoConfiguration
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user