();
+ map.put("code", e.code);
+ map.put("note", e.note);
+ ls.add(map);
+ }
+ }
+ return ls;
+ }
+
+
+}
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/es/JeecgElasticsearchTemplate.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/es/JeecgElasticsearchTemplate.java
index 7cca5774..8199f2a8 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/es/JeecgElasticsearchTemplate.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/es/JeecgElasticsearchTemplate.java
@@ -7,6 +7,7 @@ import org.apache.commons.lang.StringUtils;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -328,6 +329,39 @@ public class JeecgElasticsearchTemplate {
}
}
+ /**
+ * 批量保存数据
+ *
+ * @param indexName 索引名称
+ * @param typeName type,一个任意字符串,用于分类
+ * @param dataList 要存储的数据数组,每行数据必须包含id
+ * @return
+ */
+ public boolean saveBatch(String indexName, String typeName, JSONArray dataList) {
+ String url = this.getBaseUrl().append("/_bulk").append("?refresh=wait_for").toString();
+ StringBuilder bodySB = new StringBuilder();
+ for (int i = 0; i < dataList.size(); i++) {
+ JSONObject data = dataList.getJSONObject(i);
+ String id = data.getString("id");
+ // 该行的操作
+ // {"create": {"_id":"${id}", "_index": "${indexName}", "_type": "${typeName}"}}
+ JSONObject action = new JSONObject();
+ JSONObject actionInfo = new JSONObject();
+ actionInfo.put("_id", id);
+ actionInfo.put("_index", indexName);
+ actionInfo.put("_type", typeName);
+ action.put("create", actionInfo);
+ bodySB.append(action.toJSONString()).append("\n");
+ // 该行的数据
+ data.remove("id");
+ bodySB.append(data.toJSONString()).append("\n");
+ }
+ System.out.println("+-+-+-: bodySB.toString(): " + bodySB.toString());
+ HttpHeaders headers = RestUtil.getHeaderApplicationJson();
+ RestUtil.request(url, HttpMethod.PUT, headers, null, bodySB, JSONObject.class);
+ return true;
+ }
+
/**
* 删除索引数据
*
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryGenerator.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryGenerator.java
index 153638c2..de821345 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryGenerator.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryGenerator.java
@@ -151,7 +151,7 @@ public class QueryGenerator {
for (int k=1;k j.like(field,vals[0]));
@@ -241,7 +241,7 @@ public class QueryGenerator {
}
}
}
- return andWrapper;
+ //return andWrapper;
});
} catch (UnsupportedEncodingException e) {
log.error("--高级查询参数转码失败:" + superQueryParams, e);
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JwtUtil.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JwtUtil.java
index f44fcb9c..62a7e100 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JwtUtil.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JwtUtil.java
@@ -16,6 +16,7 @@ import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysUserCacheInfo;
+import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
@@ -181,11 +182,11 @@ public class JwtUtil {
}
//替换为当前系统时间(年月日)
else if (key.equals(DataBaseConstant.SYS_DATE)|| key.toLowerCase().equals(DataBaseConstant.SYS_DATE_TABLE)) {
- returnValue = user.getSysDate();
+ returnValue = DateUtils.formatDate();
}
//替换为当前系统时间(年月日时分秒)
else if (key.equals(DataBaseConstant.SYS_TIME)|| key.toLowerCase().equals(DataBaseConstant.SYS_TIME_TABLE)) {
- returnValue = user.getSysTime();
+ returnValue = DateUtils.now();
}
//流程状态默认值(默认未发起)
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) {
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/LoginUser.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/LoginUser.java
index b7c194d1..3f0e7361 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/LoginUser.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/LoginUser.java
@@ -110,4 +110,7 @@ public class LoginUser {
*/
private String telephone;
+ /**多租户id配置,编辑用户的时候设置*/
+ private String relTenantIds;
+
}
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/CommonUtils.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/CommonUtils.java
index 32842be0..946b37cb 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/CommonUtils.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/CommonUtils.java
@@ -58,7 +58,7 @@ public class CommonUtils {
fileName = fileName.substring(pos + 1);
}
//替换上传文件名字的特殊字符
- fileName = fileName.replace("=","").replace(",","").replace("&","");
+ fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
return fileName;
}
}
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MinioUtil.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MinioUtil.java
index 37d1c058..df8a3af5 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MinioUtil.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MinioUtil.java
@@ -72,6 +72,9 @@ public class MinioUtil {
InputStream stream = file.getInputStream();
// 获取文件名
String orgName = file.getOriginalFilename();
+ if("".equals(orgName)){
+ orgName=file.getName();
+ }
orgName = CommonUtils.getFileName(orgName);
String objectName = bizPath+"/"+orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/RestUtil.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/RestUtil.java
index 9716c3f7..b6581091 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/RestUtil.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/RestUtil.java
@@ -181,7 +181,7 @@ public class RestUtil {
* @param responseType 返回类型
* @return ResponseEntity
*/
- public static ResponseEntity request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, JSONObject params, Class responseType) {
+ public static ResponseEntity request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, Object params, Class responseType) {
if (StringUtils.isEmpty(url)) {
throw new RuntimeException("url 不能为空");
}
@@ -194,7 +194,12 @@ public class RestUtil {
// 请求体
String body = "";
if (params != null) {
- body = params.toJSONString();
+ if (params instanceof JSONObject) {
+ body = ((JSONObject) params).toJSONString();
+
+ } else {
+ body = params.toString();
+ }
}
// 拼接 url 参数
if (variables != null) {
@@ -208,14 +213,14 @@ public class RestUtil {
/**
* 获取JSON请求头
*/
- private static HttpHeaders getHeaderApplicationJson() {
+ public static HttpHeaders getHeaderApplicationJson() {
return getHeader(MediaType.APPLICATION_JSON_UTF8_VALUE);
}
/**
* 获取请求头
*/
- private static HttpHeaders getHeader(String mediaType) {
+ public static HttpHeaders getHeader(String mediaType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType(mediaType));
headers.add("Accept", mediaType);
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/dynamic/db/DbValidationQueryEnum.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/dynamic/db/DbValidationQueryEnum.java
deleted file mode 100644
index b60b9ee8..00000000
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/dynamic/db/DbValidationQueryEnum.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.jeecg.common.util.dynamic.db;
-
-public enum DbValidationQueryEnum {
- ORACLE("oracle", "SELECT 1 FROM DUAL"),
- MYSQL("mysql", "select 1"),
- SQLSERVER("sqlserver", "SELECT 1 FROM DUAL"),;
-
- DbValidationQueryEnum(String dbType, String validationQuerySql) {
- this.dbType = dbType;
- this.validationQuerySql = validationQuerySql;
- }
-
- private String dbType;
- private String validationQuerySql;
-
- public String getDbType() {
- return dbType;
- }
-
- public void setDbType(String dbType) {
- this.dbType = dbType;
- }
-
- public String getValidationQuerySql() {
- return validationQuerySql;
- }
-
- public void setValidationQuerySql(String validationQuerySql) {
- this.validationQuerySql = validationQuerySql;
- }
-}
diff --git a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
index 2591207a..6c3e670b 100644
--- a/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
+++ b/jeecg-boot/jeecg-boot-base-common/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
@@ -57,6 +57,26 @@ public class OssBootUtil {
return staticDomain;
}
+ public static String getEndPoint() {
+ return endPoint;
+ }
+
+ public static String getAccessKeyId() {
+ return accessKeyId;
+ }
+
+ public static String getAccessKeySecret() {
+ return accessKeySecret;
+ }
+
+ public static String getBucketName() {
+ return bucketName;
+ }
+
+ public static OSSClient getOssClient() {
+ return ossClient;
+ }
+
/**
* oss 工具客户端
*/
@@ -86,6 +106,9 @@ public class OssBootUtil {
}
// 获取文件名
String orgName = file.getOriginalFilename();
+ if("" == orgName){
+ orgName=file.getName();
+ }
orgName = CommonUtils.getFileName(orgName);
String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
if (!fileDir.endsWith("/")) {
diff --git a/jeecg-boot/jeecg-boot-module-system/Dockerfile b/jeecg-boot/jeecg-boot-module-system/Dockerfile
new file mode 100644
index 00000000..5cfee178
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/Dockerfile
@@ -0,0 +1,15 @@
+FROM anapsix/alpine-java:8_server-jre_unlimited
+
+MAINTAINER jeecgos@163.com
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+RUN mkdir -p /jeecg-boot
+
+WORKDIR /jeecg-boot
+
+EXPOSE 8080
+
+ADD ./target/jeecg-boot-module-system-2.2.1.jar ./
+
+CMD sleep 60;java -Djava.security.egd=file:/dev/./urandom -jar jeecg-boot-module-system-2.2.1.jar
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/pom.xml b/jeecg-boot/jeecg-boot-module-system/pom.xml
index 2b88c8a7..c8f8a142 100644
--- a/jeecg-boot/jeecg-boot-module-system/pom.xml
+++ b/jeecg-boot/jeecg-boot-module-system/pom.xml
@@ -7,7 +7,7 @@
org.jeecgframework.boot
jeecg-boot-parent
- 2.2.0
+ 2.2.1
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/JeecgApplication.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/JeecgApplication.java
index 54f4208e..fb3f55b0 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/JeecgApplication.java
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/JeecgApplication.java
@@ -5,46 +5,52 @@ import org.apache.catalina.Context;
import org.apache.tomcat.util.scan.StandardJarScanner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Slf4j
-@EnableSwagger2
@SpringBootApplication
-public class JeecgApplication {
+public class JeecgApplication extends SpringBootServletInitializer {
- public static void main(String[] args) throws UnknownHostException {
-
- ConfigurableApplicationContext application = SpringApplication.run(JeecgApplication.class, args);
- Environment env = application.getEnvironment();
- String ip = InetAddress.getLocalHost().getHostAddress();
- String port = env.getProperty("server.port");
- String path = env.getProperty("server.servlet.context-path");
- log.info("\n----------------------------------------------------------\n\t" +
- "Application Jeecg-Boot is running! Access URLs:\n\t" +
- "Local: \t\thttp://localhost:" + port + path + "/\n\t" +
- "External: \thttp://" + ip + ":" + port + path + "/\n\t" +
- "Swagger-UI: \t\thttp://" + ip + ":" + port + path + "/doc.html\n" +
- "----------------------------------------------------------");
-
- }
-
- /**
- * tomcat-embed-jasper引用后提示jar找不到的问题
- */
- @Bean
- public TomcatServletWebServerFactory tomcatFactory() {
- return new TomcatServletWebServerFactory() {
@Override
- protected void postProcessContext(Context context) {
- ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
+ return application.sources(JeecgApplication.class);
+ }
+
+ public static void main(String[] args) throws UnknownHostException {
+ //System.setProperty("spring.devtools.restart.enabled", "true");
+
+ ConfigurableApplicationContext application = SpringApplication.run(JeecgApplication.class, args);
+ Environment env = application.getEnvironment();
+ String ip = InetAddress.getLocalHost().getHostAddress();
+ String port = env.getProperty("server.port");
+ String path = env.getProperty("server.servlet.context-path");
+ log.info("\n----------------------------------------------------------\n\t" +
+ "Application Jeecg-Boot is running! Access URLs:\n\t" +
+ "Local: \t\thttp://localhost:" + port + path + "/\n\t" +
+ "External: \thttp://" + ip + ":" + port + path + "/\n\t" +
+ "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
+ "----------------------------------------------------------");
+
+ }
+
+ /**
+ * tomcat-embed-jasper引用后提示jar找不到的问题
+ */
+ @Bean
+ public TomcatServletWebServerFactory tomcatFactory() {
+ return new TomcatServletWebServerFactory() {
+ @Override
+ protected void postProcessContext(Context context) {
+ ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
+ }
+ };
}
- };
- }
}
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/MybatisPlusConfig.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/MybatisPlusConfig.java
index 581e1fcf..dcb15e84 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/MybatisPlusConfig.java
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/MybatisPlusConfig.java
@@ -1,10 +1,27 @@
package org.jeecg.config;
+import com.baomidou.mybatisplus.core.parser.ISqlParser;
+import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
+import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.LongValue;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.InExpression;
+import net.sf.jsqlparser.schema.Column;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.reflection.MetaObject;
+import org.jeecg.config.mybatis.JeecgTenantParser;
+import org.jeecg.modules.system.util.TenantContext;
import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* 单数据源配置(jeecg.datasource.open = false时生效)
@@ -16,14 +33,82 @@ import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
public class MybatisPlusConfig {
/**
- * 分页插件
+ * tenant_id 字段名
+ */
+ public static final String tenant_field = "tenant_id";
+
+ /**
+ * 有哪些表需要做多租户 这些表需要添加一个字段 ,字段名和tenant_field对应的值一样
+ */
+ private static final List tenantTable = new ArrayList();
+ static {
+ tenantTable.add("jee_bug_danbiao");
+ }
+
+ /**
+ * 多租户属于 SQL 解析部分,依赖 MP 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
- // 设置sql的limit为无限制,默认是500
- return new PaginationInterceptor().setLimit(-1);
+ PaginationInterceptor paginationInterceptor = new PaginationInterceptor().setLimit(-1);
+ /*
+ * 【测试多租户】 SQL 解析处理拦截器
+ * 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )
+ */
+ List sqlParserList = new ArrayList<>();
+ TenantSqlParser tenantSqlParser = new JeecgTenantParser();
+ tenantSqlParser.setTenantHandler(new TenantHandler() {
+
+ @Override
+ public Expression getTenantId(boolean select) {
+ String tenant_id = TenantContext.getTenant();
+ return new LongValue(tenant_id);
+ }
+ @Override
+ public String getTenantIdColumn() {
+ return tenant_field;
+ }
+
+ @Override
+ public boolean doTableFilter(String tableName) {
+ //true则不加租户条件查询 false则加
+ // return excludeTable.contains(tableName);
+ if(tenantTable.contains(tableName)){
+ return false;
+ }
+ return true;
+ }
+
+ private Expression in(String ids){
+ final InExpression inExpression = new InExpression();
+ inExpression.setLeftExpression(new Column(getTenantIdColumn()));
+ final ExpressionList itemsList = new ExpressionList();
+ final List inValues = new ArrayList<>(2);
+ for(String id:ids.split(",")){
+ inValues.add(new LongValue(id));
+ }
+ itemsList.setExpressions(inValues);
+ inExpression.setRightItemsList(itemsList);
+ return inExpression;
+ }
+
+ });
+
+ sqlParserList.add(tenantSqlParser);
+ paginationInterceptor.setSqlParserList(sqlParserList);
+ paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
+ @Override
+ public boolean doFilter(MetaObject metaObject) {
+ MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
+ // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
+ if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
+ return true;
+ }
+ return false;
+ }
+ });
+ return paginationInterceptor;
}
-
// /**
// * mybatis-plus SQL执行效率插件【生产环境可以关闭】
// */
@@ -31,6 +116,5 @@ public class MybatisPlusConfig {
// public PerformanceInterceptor performanceInterceptor() {
// return new PerformanceInterceptor();
// }
-
-
+
}
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
index 4b5139b4..3242f15e 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
@@ -8,7 +8,9 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.crazycake.shiro.IRedisManager;
import org.crazycake.shiro.RedisCacheManager;
+import org.crazycake.shiro.RedisClusterManager;
import org.crazycake.shiro.RedisManager;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.shiro.authc.ShiroRealm;
@@ -18,12 +20,14 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.util.StringUtils;
+import redis.clients.jedis.HostAndPort;
+import redis.clients.jedis.JedisCluster;
+import javax.annotation.Resource;
import javax.servlet.Filter;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
/**
* @author: Scott
@@ -37,19 +41,12 @@ public class ShiroConfig {
@Value("${jeecg.shiro.excludeUrls}")
private String excludeUrls;
-
- @Value("${spring.redis.port}")
- private String port;
-
- @Value("${spring.redis.host}")
- private String host;
-
- @Value("${spring.redis.password}")
- private String redisPassword;
+ @Resource
+ LettuceConnectionFactory lettuceConnectionFactory;
/**
- * Filter Chain定义说明
- *
+ * Filter Chain定义说明
+ *
* 1、一个URL可以配置多个Filter,使用逗号分隔
* 2、当设置多个过滤器时,全部验证通过,才视为通过
* 3、部分过滤器可指定参数,如perms,roles
@@ -78,7 +75,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/thirdLogin/**", "anon"); //第三方登录
filterChainDefinitionMap.put("/sys/getEncryptedString", "anon"); //获取加密串
filterChainDefinitionMap.put("/sys/sms", "anon");//短信验证码
- filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录
+ filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录
filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在
filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册
filterChainDefinitionMap.put("/sys/user/querySysUser", "anon");//根据手机号获取用户信息
@@ -110,21 +107,24 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/swagger**/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
filterChainDefinitionMap.put("/v2/**", "anon");
-
+
//性能监控
filterChainDefinitionMap.put("/actuator/metrics/**", "anon");
filterChainDefinitionMap.put("/actuator/httptrace/**", "anon");
filterChainDefinitionMap.put("/actuator/redis/**", "anon");
- //大屏设计器排除
- filterChainDefinitionMap.put("/big/screen/**", "anon");
//测试示例
filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面
filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试
+
+ //排除Online请求
+ filterChainDefinitionMap.put("/auto/cgform/**", "anon");
+
//websocket排除
filterChainDefinitionMap.put("/websocket/**", "anon");
+ filterChainDefinitionMap.put("/newsWebsocket/**", "anon");
// 添加自己的过滤器并且取名为jwt
Map filterMap = new HashMap(1);
@@ -214,16 +214,29 @@ public class ShiroConfig {
* @return
*/
@Bean
- public RedisManager redisManager() {
- log.info("===============(2)创建RedisManager,连接Redis..URL= " + host + ":" + port);
- RedisManager redisManager = new RedisManager();
- redisManager.setHost(host);
- redisManager.setPort(oConvertUtils.getInt(port));
- redisManager.setTimeout(0);
- if (!StringUtils.isEmpty(redisPassword)) {
- redisManager.setPassword(redisPassword);
- }
- return redisManager;
+ public IRedisManager redisManager() {
+ log.info("===============(2)创建RedisManager,连接Redis..");
+ IRedisManager manager;
+ // redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com
+ if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) {
+ RedisManager redisManager = new RedisManager();
+ redisManager.setHost(lettuceConnectionFactory.getHostName());
+ redisManager.setPort(lettuceConnectionFactory.getPort());
+ redisManager.setTimeout(0);
+ if (!StringUtils.isEmpty(lettuceConnectionFactory.getPassword())) {
+ redisManager.setPassword(lettuceConnectionFactory.getPassword());
+ }
+ manager = redisManager;
+ }else{
+ // redis 集群支持,优先使用集群配置 add by jzyadmin@163.com
+ RedisClusterManager redisManager = new RedisClusterManager();
+ Set portSet = new HashSet<>();
+ lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
+ JedisCluster jedisCluster = new JedisCluster(portSet);
+ redisManager.setJedisCluster(jedisCluster);
+ manager = redisManager;
+ }
+ return manager;
}
}
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/mybatis/JeecgTenantParser.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/mybatis/JeecgTenantParser.java
new file mode 100644
index 00000000..af0f9c37
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/mybatis/JeecgTenantParser.java
@@ -0,0 +1,130 @@
+package org.jeecg.config.mybatis;
+
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
+import net.sf.jsqlparser.expression.BinaryExpression;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.Parenthesis;
+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.schema.Column;
+import net.sf.jsqlparser.schema.Table;
+import net.sf.jsqlparser.statement.select.*;
+
+import java.util.List;
+
+/**
+ * 复写租户条件
+ */
+public class JeecgTenantParser extends TenantSqlParser {
+
+ /**
+ * @param expression
+ * @param table
+ * @return
+ */
+ protected Expression processTableAlias(Expression expression, Table table) {
+ String tableAliasName;
+ if (table.getAlias() == null) {
+ tableAliasName = table.getName();
+ } else {
+ tableAliasName = table.getAlias().getName();
+ }
+
+ // in
+ if (expression instanceof InExpression) {
+ InExpression in = (InExpression) expression;
+ if (in.getLeftExpression() instanceof Column) {
+ setTableAliasNameForColumn((Column) in.getLeftExpression(), tableAliasName);
+ }
+
+ // 比较操作
+ } else if (expression instanceof BinaryExpression) {
+ BinaryExpression compare = (BinaryExpression) expression;
+ if (compare.getLeftExpression() instanceof Column) {
+ setTableAliasNameForColumn((Column) compare.getLeftExpression(), tableAliasName);
+ } else if (compare.getRightExpression() instanceof Column) {
+ setTableAliasNameForColumn((Column) compare.getRightExpression(), tableAliasName);
+ }
+
+ // between
+ } else if (expression instanceof Between) {
+ Between between = (Between) expression;
+ if (between.getLeftExpression() instanceof Column) {
+ setTableAliasNameForColumn((Column) between.getLeftExpression(), tableAliasName);
+ }
+ }
+ return expression;
+ }
+
+ private void setTableAliasNameForColumn(Column column, String tableAliasName) {
+ column.setColumnName(tableAliasName + "." + column.getColumnName());
+ }
+
+ /**
+ * 默认是按 tenant_id=1 按等于条件追加
+ *
+ * @param currentExpression 现有的条件:比如你原来的sql查询条件
+ * @param table
+ * @return
+ */
+ @Override
+ protected Expression builderExpression(Expression currentExpression, Table table) {
+ final Expression tenantExpression = this.getTenantHandler().getTenantId(true);
+ Expression appendExpression;
+ if (!(tenantExpression instanceof SupportsOldOracleJoinSyntax)) {
+ appendExpression = new EqualsTo();
+ ((EqualsTo) appendExpression).setLeftExpression(this.getAliasColumn(table));
+ ((EqualsTo) appendExpression).setRightExpression(tenantExpression);
+ } else {
+ appendExpression = processTableAlias(tenantExpression, table);
+ }
+ if (currentExpression == null) {
+ return appendExpression;
+ }
+ if (currentExpression instanceof BinaryExpression) {
+ BinaryExpression binaryExpression = (BinaryExpression) currentExpression;
+ if (binaryExpression.getLeftExpression() instanceof FromItem) {
+ processFromItem((FromItem) binaryExpression.getLeftExpression());
+ }
+ if (binaryExpression.getRightExpression() instanceof FromItem) {
+ processFromItem((FromItem) binaryExpression.getRightExpression());
+ }
+ } else if (currentExpression instanceof InExpression) {
+ InExpression inExp = (InExpression) currentExpression;
+ ItemsList rightItems = inExp.getRightItemsList();
+ if (rightItems instanceof SubSelect) {
+ processSelectBody(((SubSelect) rightItems).getSelectBody());
+ }
+ }
+ if (currentExpression instanceof OrExpression) {
+ return new AndExpression(new Parenthesis(currentExpression), appendExpression);
+ } else {
+ return new AndExpression(currentExpression, appendExpression);
+ }
+ }
+
+ @Override
+ protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) {
+ FromItem fromItem = plainSelect.getFromItem();
+ if (fromItem instanceof Table) {
+ Table fromTable = (Table) fromItem;
+ if (!this.getTenantHandler().doTableFilter(fromTable.getName())) {
+ plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
+ if (addColumn) {
+ plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.getTenantHandler().getTenantIdColumn())));
+ }
+ }
+ } else {
+ processFromItem(fromItem);
+ }
+ List joins = plainSelect.getJoins();
+ if (joins != null && joins.size() > 0) {
+ joins.forEach(j -> {
+ processJoin(j);
+ processFromItem(j.getRightItem());
+ });
+ }
+ }
+
+}
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/test/controller/MinioController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/test/controller/MinioController.java
deleted file mode 100644
index 96dfd828..00000000
--- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/demo/test/controller/MinioController.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.jeecg.modules.demo.test.controller;
-
-import io.minio.MinioClient;
-import org.apache.tomcat.util.http.fileupload.IOUtils;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.InputStream;
-
-/**
- * @Author scott
- * @Date 2020/1/12 17:19
- * @Description: Minio文件服务测试
- */
-@RestController
-@RequestMapping("/test/minio")
-public class MinioController {
-
- //minio服务的IP端口
- private static String url = "http://111.225.222.176:9000";
- private static String accessKey = "admin";
- private static String secretKey = "jeecg1357";
- private static String bucketName = "jeecgtest";
-
- /**
- * 上传文件到minio服务
- *
- * @param file
- * @return
- */
- @PostMapping("upload")
- public String upload(@RequestParam("file") MultipartFile file) {
- try {
- MinioClient minioClient = new MinioClient(url, accessKey, secretKey);
- InputStream is = file.getInputStream(); //得到文件流
- String fileName = "/upload/img/" + file.getOriginalFilename(); //文件名
- String contentType = file.getContentType(); //类型
- minioClient.putObject(bucketName, fileName, is, contentType); //把文件放置Minio桶(文件夹)
- return "上传成功";
- } catch (Exception e) {
- return "上传失败";
- }
- }
-
- /**
- * 下载minio服务的文件
- *
- * @param response
- * @return
- */
- @GetMapping("download")
- public String download(HttpServletResponse response) {
- try {
- MinioClient minioClient = new MinioClient(url, accessKey, secretKey);
- InputStream fileInputStream = minioClient.getObject(bucketName, "11.jpg");
- response.setHeader("Content-Disposition", "attachment;filename=" + "11.jpg");
- response.setContentType("application/force-download");
- response.setCharacterEncoding("UTF-8");
- IOUtils.copy(fileInputStream, response.getOutputStream());
- return "下载完成";
- } catch (Exception e) {
- e.printStackTrace();
- return "下载失败";
- }
- }
-
- /**
- * 获取minio文件的下载地址
- *
- * @return
- */
- @GetMapping("url")
- public String getUrl() {
- try {
- MinioClient minioClient = new MinioClient(url, accessKey, secretKey);
- String url = minioClient.presignedGetObject(bucketName, "11.jpg");
- return url;
- } catch (Exception e) {
- e.printStackTrace();
- return "获取失败";
- }
- }
-}
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OSSFileController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OSSFileController.java
index 668ae728..949cb2e1 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OSSFileController.java
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OSSFileController.java
@@ -45,7 +45,7 @@ public class OSSFileController {
@ResponseBody
@PostMapping("/upload")
- //@RequiresRoles({"admin"})
+ @RequiresRoles("admin")
public Result upload(@RequestParam("file") MultipartFile multipartFile) {
Result result = new Result();
try {
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java
index 1efa9a28..13badc5d 100644
--- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java
@@ -86,7 +86,7 @@ public class QuartzJobController {
* @param quartzJob
* @return
*/
- //@RequiresRoles({"admin"})
+ @RequiresRoles("admin")
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Result> add(@RequestBody QuartzJob quartzJob) {
List list = quartzJobService.findByJobClassName(quartzJob.getJobClassName());
@@ -103,7 +103,7 @@ public class QuartzJobController {
* @param quartzJob
* @return
*/
- //@RequiresRoles({"admin"})
+ @RequiresRoles("admin")
@RequestMapping(value = "/edit", method = RequestMethod.PUT)
public Result> eidt(@RequestBody QuartzJob quartzJob) {
try {
@@ -121,7 +121,7 @@ public class QuartzJobController {
* @param id
* @return
*/
- //@RequiresRoles({"admin"})
+ @RequiresRoles("admin")
@RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public Result> delete(@RequestParam(name = "id", required = true) String id) {
QuartzJob quartzJob = quartzJobService.getById(id);
@@ -139,7 +139,7 @@ public class QuartzJobController {
* @param ids
* @return
*/
- //@RequiresRoles({"admin"})
+ @RequiresRoles("admin")
@RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
public Result> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
if (ids == null || "".equals(ids.trim())) {
@@ -158,22 +158,16 @@ public class QuartzJobController {
* @param jobClassName
* @return
*/
- //@RequiresRoles({"admin"})
+ @RequiresRoles("admin")
@GetMapping(value = "/pause")
@ApiOperation(value = "暂停定时任务")
public Result