Jeecg-Boot 2.1.4 版本发布 | 重构较大,较多新功能

This commit is contained in:
zhangdaiscott
2020-02-24 02:44:53 +08:00
parent f342b18ddf
commit 9d8c7da31f
269 changed files with 15734 additions and 24855 deletions

View File

@ -171,20 +171,42 @@ public interface CommonConstant {
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
/**
* 表单设计器URL授权未通过
* 表单设计器新增 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
/**
* 表单设计器URL授权未通过
* 表单设计器修改 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
/**
* 表单设计器URL授权未通过
* 表单设计器详情 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
/**
* 表单设计器URL授权未通过
* 表单设计器复用数据 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
/**
* 表单设计器编辑 Flag (已弃用)
*/
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
/**
* online参数值设置Y, 否N
*/
public static final String ONLINE_PARAM_VAL_IS_TURE = "Y";
public static final String ONLINE_PARAM_VAL_IS_FALSE = "N";
/**
* 文件上传类型本地localMiniominio阿里云alioss
*/
public static final String UPLOAD_TYPE_LOCAL = "local";
public static final String UPLOAD_TYPE_MINIO = "minio";
public static final String UPLOAD_TYPE_OSS = "alioss";
/**
* 员工身份 1:普通员工 2:上级)
*/
public static final Integer USER_IDENTITY_1 = 1;
public static final Integer USER_IDENTITY_2 = 2;
}

View File

@ -8,7 +8,12 @@ public interface DataBaseConstant {
public static final String DB_TYPE_ORACLE = "ORACLE";
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
// 数据库类型,对应 database_type 字典
public static final String DB_TYPE_MYSQL_NUM = "1";
public static final String DB_TYPE_ORACLE_NUM = "2";
public static final String DB_TYPE_SQLSERVER_NUM = "3";
public static final String DB_TYPE_POSTGRESQL_NUM = "4";
//*********系统上下文变量****************************************
/**
* 数据-所属机构编码

View File

@ -1,398 +1,398 @@
package org.jeecg.common.es;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.util.RestUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等)
*
* @author sunjianlei
*/
@Slf4j
@Component
public class JeecgElasticsearchTemplate {
/**
* 用户配置是否通过,未通过就不走任何方法
*/
private static boolean configIsPassed = true;
/**
* 是否已检测过配置
*/
private static boolean configIsChecked = false;
private String baseUrl;
private final String FORMAT_JSON = "format=json";
public JeecgElasticsearchTemplate(@Value("${jeecg.elasticsearch.cluster-nodes}") String baseUrl) {
log.debug("JeecgElasticsearchTemplate BaseURL" + baseUrl);
// 未检测过配置,进行检测操作
if (!configIsChecked) {
configIsChecked = true;
// 为空则代表未配置 baseUrl
if (StringUtils.isEmpty(baseUrl)) {
configIsPassed = false;
} else {
this.baseUrl = baseUrl;
// 判断配置的地址是否有效
try {
RestUtil.get(this.getBaseUrl().toString());
} catch (Exception e) {
configIsPassed = false;
}
}
if (configIsPassed) {
log.info("ElasticSearch服务连接成功");
} else {
log.warn("ElasticSearch 服务连接失败原因配置未通过。可能是BaseURL未配置或配置有误也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法");
}
}
}
/**
* 检查配置是否通过,未通过就抛出异常,中断执行
*/
private void checkConfig() {
if (!configIsPassed) {
throw new RuntimeException("配置未通过,拒绝执行该方法");
}
}
public StringBuilder getBaseUrl(String indexName, String typeName) {
typeName = typeName.trim().toLowerCase();
return this.getBaseUrl(indexName).append("/").append(typeName);
}
public StringBuilder getBaseUrl(String indexName) {
indexName = indexName.trim().toLowerCase();
return this.getBaseUrl().append("/").append(indexName);
}
public StringBuilder getBaseUrl() {
return new StringBuilder("http://").append(this.baseUrl);
}
/**
* cat 查询ElasticSearch系统数据返回json
*/
public <T> ResponseEntity<T> _cat(String urlAfter, Class<T> responseType) {
this.checkConfig();
String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString();
return RestUtil.request(url, HttpMethod.GET, null, null, null, responseType);
}
/**
* 查询所有索引
* <p>
* 查询地址GET http://{baseUrl}/_cat/indices
*/
public JSONArray getIndices() {
this.checkConfig();
return getIndices(null);
}
/**
* 查询单个索引
* <p>
* 查询地址GET http://{baseUrl}/_cat/indices/{indexName}
*/
public JSONArray getIndices(String indexName) {
this.checkConfig();
StringBuilder urlAfter = new StringBuilder("/indices");
if (!StringUtils.isEmpty(indexName)) {
urlAfter.append("/").append(indexName.trim().toLowerCase());
}
return _cat(urlAfter.toString(), JSONArray.class).getBody();
}
/**
* 索引是否存在
*/
public boolean indexExists(String indexName) {
this.checkConfig();
try {
JSONArray array = getIndices(indexName);
return array != null;
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
return false;
} else {
throw ex;
}
}
}
/**
* 创建索引
* <p>
* 查询地址PUT http://{baseUrl}/{indexName}
*/
public boolean createIndex(String indexName) {
this.checkConfig();
String url = this.getBaseUrl(indexName).toString();
/* 返回结果 (仅供参考)
"createIndex": {
"shards_acknowledged": true,
"acknowledged": true,
"index": "hello_world"
}
*/
try {
return RestUtil.put(url).getBoolean("acknowledged");
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.BAD_REQUEST == ex.getStatusCode()) {
log.warn("索引创建失败:" + indexName + " 已存在,无需再创建");
} else {
ex.printStackTrace();
}
}
return false;
}
/**
* 删除索引
* <p>
* 查询地址DELETE http://{baseUrl}/{indexName}
*/
public boolean removeIndex(String indexName) {
this.checkConfig();
String url = this.getBaseUrl(indexName).toString();
try {
return RestUtil.delete(url).getBoolean("acknowledged");
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
log.warn("索引删除失败:" + indexName + " 不存在,无需删除");
} else {
ex.printStackTrace();
}
}
return false;
}
/**
* 保存数据详见saveOrUpdate
*/
public boolean save(String indexName, String typeName, String dataId, JSONObject data) {
this.checkConfig();
return this.saveOrUpdate(indexName, typeName, dataId, data);
}
/**
* 更新数据详见saveOrUpdate
*/
public boolean update(String indexName, String typeName, String dataId, JSONObject data) {
this.checkConfig();
return this.saveOrUpdate(indexName, typeName, dataId, data);
}
/**
* 保存或修改索引数据
* <p>
* 查询地址PUT http://{baseUrl}/{indexName}/{typeName}/{dataId}
*
* @param indexName 索引名称
* @param typeName type一个任意字符串用于分类
* @param dataId 数据id
* @param data 要存储的数据
* @return
*/
public boolean saveOrUpdate(String indexName, String typeName, String dataId, JSONObject data) {
this.checkConfig();
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
/* 返回结果(仅供参考)
"createIndexA2": {
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_index": "test_index_1",
"_type": "test_type_1",
"_id": "a2",
"_version": 1,
"_primary_term": 1
}
*/
try {
// 去掉 data 中为空的值
Set<String> keys = data.keySet();
List<String> emptyKeys = new ArrayList<>(keys.size());
for (String key : keys) {
String value = data.getString(key);
if (StringUtils.isEmpty(value)) {
emptyKeys.add(key);
}
}
for (String key : emptyKeys) {
data.remove(key);
}
} catch (Exception e) {
e.printStackTrace();
}
String result = RestUtil.put(url, data).getString("result");
return "created".equals(result) || "updated".equals(result);
}
/**
* 删除索引数据
* <p>
* 请求地址DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId}
*/
public boolean delete(String indexName, String typeName, String dataId) {
this.checkConfig();
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
/* 返回结果(仅供参考)
{
"_index": "es_demo",
"_type": "docs",
"_id": "001",
"_version": 3,
"result": "deleted",
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"_seq_no": 28,
"_primary_term": 18
}
*/
try {
return "deleted".equals(RestUtil.delete(url).getString("result"));
} catch (org.springframework.web.client.HttpClientErrorException ex) {
if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
return false;
} else {
throw ex;
}
}
}
/* = = = 以下关于查询和查询条件的方法 = = =*/
/**
* 查询数据
* <p>
* 请求地址POST http://{baseUrl}/{indexName}/{typeName}/_search
*/
public JSONObject search(String indexName, String typeName, JSONObject queryObject) {
this.checkConfig();
String url = this.getBaseUrl(indexName, typeName).append("/_search").toString();
log.info("search: " + queryObject.toJSONString());
return RestUtil.post(url, queryObject);
}
/**
* @return { "query": query }
*/
public JSONObject buildQuery(JSONObject query) {
JSONObject json = new JSONObject();
json.put("query", query);
return json;
}
/**
* @return { "bool" : { "must": must, "must_not": mustNot, "should": should } }
*/
public JSONObject buildBoolQuery(JSONArray must, JSONArray mustNot, JSONArray should) {
JSONObject bool = new JSONObject();
if (must != null) {
bool.put("must", must);
}
if (mustNot != null) {
bool.put("must_not", mustNot);
}
if (should != null) {
bool.put("should", should);
}
JSONObject json = new JSONObject();
json.put("bool", bool);
return json;
}
/**
* @param field 要查询的字段
* @param args 查询参数,参考: *哈哈* OR *哒* NOT *呵* OR *啊*
* @return
*/
public JSONObject buildQueryString(String field, String... args) {
if (field == null) {
return null;
}
StringBuilder sb = new StringBuilder(field).append(":(");
if (args != null) {
for (String arg : args) {
sb.append(arg).append(" ");
}
}
sb.append(")");
return this.buildQueryString(sb.toString());
}
/**
* @return { "query_string": { "query": query } }
*/
public JSONObject buildQueryString(String query) {
JSONObject queryString = new JSONObject();
queryString.put("query", query);
JSONObject json = new JSONObject();
json.put("query_string", queryString);
return json;
}
/**
* @param field 查询字段
* @param min 最小值
* @param max 最大值
* @param containMin 范围内是否包含最小值
* @param containMax 范围内是否包含最大值
* @return { "range" : { field : { 『 "gt『e』?containMin" : min 』?min!=null , 『 "lt『e』?containMax" : max 』}} }
*/
public JSONObject buildRangeQuery(String field, Object min, Object max, boolean containMin, boolean containMax) {
JSONObject inner = new JSONObject();
if (min != null) {
if (containMin) {
inner.put("gte", min);
} else {
inner.put("gt", min);
}
}
if (max != null) {
if (containMax) {
inner.put("lte", max);
} else {
inner.put("lt", max);
}
}
JSONObject range = new JSONObject();
range.put(field, inner);
JSONObject json = new JSONObject();
json.put("range", range);
return json;
}
}
//package org.jeecg.common.es;
//
//import com.alibaba.fastjson.JSONArray;
//import com.alibaba.fastjson.JSONObject;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.jeecg.common.util.RestUtil;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.http.HttpMethod;
//import org.springframework.http.HttpStatus;
//import org.springframework.http.ResponseEntity;
//import org.springframework.stereotype.Component;
//
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Set;
//
///**
// * 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等)
// *
// * @author sunjianlei
// */
//@Slf4j
//@Component
//public class JeecgElasticsearchTemplate {
//
// /**
// * 用户配置是否通过,未通过就不走任何方法
// */
// private static boolean configIsPassed = true;
// /**
// * 是否已检测过配置
// */
// private static boolean configIsChecked = false;
//
// private String baseUrl;
//
// private final String FORMAT_JSON = "format=json";
//
// public JeecgElasticsearchTemplate(@Value("${jeecg.elasticsearch.cluster-nodes}") String baseUrl) {
// log.debug("JeecgElasticsearchTemplate BaseURL" + baseUrl);
//
// // 未检测过配置,进行检测操作
// if (!configIsChecked) {
// configIsChecked = true;
// // 为空则代表未配置 baseUrl
// if (StringUtils.isEmpty(baseUrl)) {
// configIsPassed = false;
// } else {
// this.baseUrl = baseUrl;
// // 判断配置的地址是否有效
// try {
// RestUtil.get(this.getBaseUrl().toString());
// } catch (Exception e) {
// configIsPassed = false;
// }
// }
// if (configIsPassed) {
// log.info("ElasticSearch服务连接成功");
// } else {
// log.warn("ElasticSearch 服务连接失败原因配置未通过。可能是BaseURL未配置或配置有误也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法");
// }
// }
// }
//
// /**
// * 检查配置是否通过,未通过就抛出异常,中断执行
// */
// private void checkConfig() {
// if (!configIsPassed) {
// throw new RuntimeException("配置未通过,拒绝执行该方法");
// }
// }
//
// public StringBuilder getBaseUrl(String indexName, String typeName) {
// typeName = typeName.trim().toLowerCase();
// return this.getBaseUrl(indexName).append("/").append(typeName);
// }
//
// public StringBuilder getBaseUrl(String indexName) {
// indexName = indexName.trim().toLowerCase();
// return this.getBaseUrl().append("/").append(indexName);
// }
//
// public StringBuilder getBaseUrl() {
// return new StringBuilder("http://").append(this.baseUrl);
// }
//
// /**
// * cat 查询ElasticSearch系统数据返回json
// */
// public <T> ResponseEntity<T> _cat(String urlAfter, Class<T> responseType) {
// this.checkConfig();
// String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString();
// return RestUtil.request(url, HttpMethod.GET, null, null, null, responseType);
// }
//
// /**
// * 查询所有索引
// * <p>
// * 查询地址GET http://{baseUrl}/_cat/indices
// */
// public JSONArray getIndices() {
// this.checkConfig();
// return getIndices(null);
// }
//
//
// /**
// * 查询单个索引
// * <p>
// * 查询地址GET http://{baseUrl}/_cat/indices/{indexName}
// */
// public JSONArray getIndices(String indexName) {
// this.checkConfig();
// StringBuilder urlAfter = new StringBuilder("/indices");
// if (!StringUtils.isEmpty(indexName)) {
// urlAfter.append("/").append(indexName.trim().toLowerCase());
// }
// return _cat(urlAfter.toString(), JSONArray.class).getBody();
// }
//
// /**
// * 索引是否存在
// */
// public boolean indexExists(String indexName) {
// this.checkConfig();
// try {
// JSONArray array = getIndices(indexName);
// return array != null;
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
// return false;
// } else {
// throw ex;
// }
// }
// }
//
// /**
// * 创建索引
// * <p>
// * 查询地址PUT http://{baseUrl}/{indexName}
// */
// public boolean createIndex(String indexName) {
// this.checkConfig();
// String url = this.getBaseUrl(indexName).toString();
//
// /* 返回结果 (仅供参考)
// "createIndex": {
// "shards_acknowledged": true,
// "acknowledged": true,
// "index": "hello_world"
// }
// */
// try {
// return RestUtil.put(url).getBoolean("acknowledged");
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
// if (HttpStatus.BAD_REQUEST == ex.getStatusCode()) {
// log.warn("索引创建失败:" + indexName + " 已存在,无需再创建");
// } else {
// ex.printStackTrace();
// }
// }
// return false;
// }
//
// /**
// * 删除索引
// * <p>
// * 查询地址DELETE http://{baseUrl}/{indexName}
// */
// public boolean removeIndex(String indexName) {
// this.checkConfig();
// String url = this.getBaseUrl(indexName).toString();
// try {
// return RestUtil.delete(url).getBoolean("acknowledged");
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
// log.warn("索引删除失败:" + indexName + " 不存在,无需删除");
// } else {
// ex.printStackTrace();
// }
// }
// return false;
// }
//
// /**
// * 保存数据详见saveOrUpdate
// */
// public boolean save(String indexName, String typeName, String dataId, JSONObject data) {
// this.checkConfig();
// return this.saveOrUpdate(indexName, typeName, dataId, data);
// }
//
// /**
// * 更新数据详见saveOrUpdate
// */
// public boolean update(String indexName, String typeName, String dataId, JSONObject data) {
// this.checkConfig();
// return this.saveOrUpdate(indexName, typeName, dataId, data);
// }
//
// /**
// * 保存或修改索引数据
// * <p>
// * 查询地址PUT http://{baseUrl}/{indexName}/{typeName}/{dataId}
// *
// * @param indexName 索引名称
// * @param typeName type一个任意字符串用于分类
// * @param dataId 数据id
// * @param data 要存储的数据
// * @return
// */
// public boolean saveOrUpdate(String indexName, String typeName, String dataId, JSONObject data) {
// this.checkConfig();
// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
// /* 返回结果(仅供参考)
// "createIndexA2": {
// "result": "created",
// "_shards": {
// "total": 2,
// "successful": 1,
// "failed": 0
// },
// "_seq_no": 0,
// "_index": "test_index_1",
// "_type": "test_type_1",
// "_id": "a2",
// "_version": 1,
// "_primary_term": 1
// }
// */
//
// try {
// // 去掉 data 中为空的值
// Set<String> keys = data.keySet();
// List<String> emptyKeys = new ArrayList<>(keys.size());
// for (String key : keys) {
// String value = data.getString(key);
// if (StringUtils.isEmpty(value)) {
// emptyKeys.add(key);
// }
// }
// for (String key : emptyKeys) {
// data.remove(key);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// String result = RestUtil.put(url, data).getString("result");
// return "created".equals(result) || "updated".equals(result);
// }
//
// /**
// * 删除索引数据
// * <p>
// * 请求地址DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId}
// */
// public boolean delete(String indexName, String typeName, String dataId) {
// this.checkConfig();
// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
// /* 返回结果(仅供参考)
// {
// "_index": "es_demo",
// "_type": "docs",
// "_id": "001",
// "_version": 3,
// "result": "deleted",
// "_shards": {
// "total": 1,
// "successful": 1,
// "failed": 0
// },
// "_seq_no": 28,
// "_primary_term": 18
// }
// */
// try {
// return "deleted".equals(RestUtil.delete(url).getString("result"));
// } catch (org.springframework.web.client.HttpClientErrorException ex) {
// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) {
// return false;
// } else {
// throw ex;
// }
// }
// }
//
//
// /* = = = 以下关于查询和查询条件的方法 = = =*/
//
// /**
// * 查询数据
// * <p>
// * 请求地址POST http://{baseUrl}/{indexName}/{typeName}/_search
// */
// public JSONObject search(String indexName, String typeName, JSONObject queryObject) {
// this.checkConfig();
// String url = this.getBaseUrl(indexName, typeName).append("/_search").toString();
//
// log.info("search: " + queryObject.toJSONString());
//
// return RestUtil.post(url, queryObject);
// }
//
// /**
// * @return { "query": query }
// */
// public JSONObject buildQuery(JSONObject query) {
// JSONObject json = new JSONObject();
// json.put("query", query);
// return json;
// }
//
// /**
// * @return { "bool" : { "must": must, "must_not": mustNot, "should": should } }
// */
// public JSONObject buildBoolQuery(JSONArray must, JSONArray mustNot, JSONArray should) {
// JSONObject bool = new JSONObject();
// if (must != null) {
// bool.put("must", must);
// }
// if (mustNot != null) {
// bool.put("must_not", mustNot);
// }
// if (should != null) {
// bool.put("should", should);
// }
// JSONObject json = new JSONObject();
// json.put("bool", bool);
// return json;
// }
//
// /**
// * @param field 要查询的字段
// * @param args 查询参数,参考: *哈哈* OR *哒* NOT *呵* OR *啊*
// * @return
// */
// public JSONObject buildQueryString(String field, String... args) {
// if (field == null) {
// return null;
// }
// StringBuilder sb = new StringBuilder(field).append(":(");
// if (args != null) {
// for (String arg : args) {
// sb.append(arg).append(" ");
// }
// }
// sb.append(")");
// return this.buildQueryString(sb.toString());
// }
//
// /**
// * @return { "query_string": { "query": query } }
// */
// public JSONObject buildQueryString(String query) {
// JSONObject queryString = new JSONObject();
// queryString.put("query", query);
// JSONObject json = new JSONObject();
// json.put("query_string", queryString);
// return json;
// }
//
// /**
// * @param field 查询字段
// * @param min 最小值
// * @param max 最大值
// * @param containMin 范围内是否包含最小值
// * @param containMax 范围内是否包含最大值
// * @return { "range" : { field : { 『 "gt『e』?containMin" : min 』?min!=null , 『 "lt『e』?containMax" : max 』}} }
// */
// public JSONObject buildRangeQuery(String field, Object min, Object max, boolean containMin, boolean containMax) {
// JSONObject inner = new JSONObject();
// if (min != null) {
// if (containMin) {
// inner.put("gte", min);
// } else {
// inner.put("gt", min);
// }
// }
// if (max != null) {
// if (containMax) {
// inner.put("lte", max);
// } else {
// inner.put("lt", max);
// }
// }
// JSONObject range = new JSONObject();
// range.put(field, inner);
// JSONObject json = new JSONObject();
// json.put("range", range);
// return json;
// }
//
//}
//

View File

@ -4,10 +4,9 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.jeecg.common.system.vo.ComboModel;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysDepartModel;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.system.vo.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @Description: 底层共通业务API提供其他独立模块调用
@ -77,6 +76,12 @@ public interface ISysBaseAPI {
/** 查询所有的父级字典按照create_time排序 */
public List<DictModel> queryAllDict();
/**
* 查询所有分类字典
* @return
*/
public List<SysCategoryModel> queryAllDSysCategory();
/**
* 获取表数据字典
* @param table
@ -111,6 +116,18 @@ public interface ISysBaseAPI {
*/
public void sendSysAnnouncement(String fromUser, String toUser,String title, Map<String, String> map, String templateCode);
/**
*
* @param fromUser 发送人(用户登录账户)
* @param toUser 发送给(用户登录账户)
* @param title 通知标题
* @param map 模板参数
* @param templateCode 模板编码
* @param busType 业务类型
* @param busId 业务id
*/
public void sendSysAnnouncement(String fromUser, String toUser,String title, Map<String, String> map, String templateCode,String busType,String busId);
/**
* 通过消息中心模板,生成推送内容
*
@ -131,6 +148,24 @@ public interface ISysBaseAPI {
*/
public void sendSysAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory);
/**queryTableDictByKeys
* 发送系统消息
* @param fromUser 发送人(用户登录账户)
* @param toUser 发送给(用户登录账户)
* @param title 消息主题
* @param msgContent 消息内容
* @param setMsgCategory 消息类型 1:消息2:系统消息
* @param busType 业务类型
* @param busId 业务id
*/
public void sendSysAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory,String busType,String busId);
/**
* 根据业务类型及业务id修改消息已读
* @param busType
* @param busId
*/
public void updateSysAnnounReadFlag(String busType,String busId);
/**
* 查询表字典 支持过滤数据
* @param table
@ -141,6 +176,16 @@ public interface ISysBaseAPI {
*/
public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql);
/**
* 查询指定table的 text code 获取字典包含text和value
* @param table
* @param text
* @param code
* @param keyArray
* @return
*/
public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray);
/**
* 获取所有有效用户
* @return
@ -152,7 +197,7 @@ public interface ISysBaseAPI {
* userIds 默认选中用户
* @return
*/
public List<ComboModel> queryAllUser(String[] userIds);
public JSONObject queryAllUser(String[] userIds, int pageNo, int pageSize);
/**
* 获取所有角色
@ -193,5 +238,37 @@ public interface ISysBaseAPI {
* @return
*/
public List<SysDepartModel> getAllSysDepart();
/**
* 根据 id 查询数据库中存储的 DynamicDataSourceModel
*
* @param dbSourceId
* @return
*/
DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId);
/**
* 根据 code 查询数据库中存储的 DynamicDataSourceModel
*
* @param dbSourceCode
* @return
*/
DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode);
/**
* 根据部门Id获取部门负责人
* @param deptId
* @return
*/
public List<String> getDeptHeadByDepId(String deptId);
/**
* 文件上传
* @param file 文件
* @param bizPath 自定义路径
* @param uploadType 上传方式
* @return
*/
public String upload(MultipartFile file,String bizPath,String uploadType);
}

View File

@ -13,6 +13,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.FileCopyUtils;
@ -40,9 +44,18 @@ import lombok.extern.slf4j.Slf4j;
@RequestMapping("/sys/common")
public class CommonController {
@Autowired
private ISysBaseAPI sysBaseAPI;
@Value(value = "${jeecg.path.upload}")
private String uploadpath;
/**
* 本地local miniominio 阿里alioss
*/
@Value(value="${jeecg.uploadType}")
private String uploadType;
/**
* @Author 政辉
* @return
@ -51,48 +64,124 @@ public class CommonController {
public Result<?> noauth() {
return Result.error("没有权限,请联系管理员授权");
}
/**
* 文件上传统一方法
* @param request
* @param response
* @return
*/
@PostMapping(value = "/upload")
public Result<?> upload(HttpServletRequest request, HttpServletResponse response) {
Result<?> result = new Result<>();
try {
String ctxPath = uploadpath;
String fileName = null;
String bizPath = "files";
String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());
File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);
if (!file.exists()) {
file.mkdirs();// 创建文件根目录
String savePath = "";
String bizPath = request.getParameter("biz");
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
if(oConvertUtils.isEmpty(bizPath)){
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
result.setMessage("使用阿里云文件上传时,必须添加目录!");
result.setSuccess(false);
return result;
}else{
bizPath = "";
}
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile mf = multipartRequest.getFile("file");// 获取上传文件对象
String orgName = mf.getOriginalFilename();// 获取文件名
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(mf.getBytes(), savefile);
String dbpath = bizPath + File.separator + nowday + File.separator + fileName;
if (dbpath.contains("\\")) {
dbpath = dbpath.replace("\\", "/");
}
result.setMessage(dbpath);
}
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
savePath = this.uploadLocal(file,bizPath);
}else{
savePath = sysBaseAPI.upload(file,bizPath,uploadType);
}
if(oConvertUtils.isNotEmpty(savePath)){
result.setMessage(savePath);
result.setSuccess(true);
} catch (IOException e) {
}else {
result.setMessage("上传失败!");
result.setSuccess(false);
result.setMessage(e.getMessage());
log.error(e.getMessage(), e);
}
return result;
}
/**
* 预览图片
* 请求地址http://localhost:8080/common/view/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
*
* 本地文件上传
* @param mf 文件
* @param bizPath 自定义路径
* @return
*/
private String uploadLocal(MultipartFile mf,String bizPath){
try {
String ctxPath = uploadpath;
String fileName = null;
File file = new File(ctxPath + File.separator + bizPath + File.separator );
if (!file.exists()) {
file.mkdirs();// 创建文件根目录
}
String orgName = mf.getOriginalFilename();// 获取文件名
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(mf.getBytes(), savefile);
String dbpath = null;
if(oConvertUtils.isNotEmpty(bizPath)){
dbpath = bizPath + File.separator + fileName;
}else{
dbpath = fileName;
}
if (dbpath.contains("\\")) {
dbpath = dbpath.replace("\\", "/");
}
return dbpath;
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return "";
}
// @PostMapping(value = "/upload2")
// public Result<?> upload2(HttpServletRequest request, HttpServletResponse response) {
// Result<?> result = new Result<>();
// try {
// String ctxPath = uploadpath;
// String fileName = null;
// String bizPath = "files";
// String tempBizPath = request.getParameter("biz");
// if(oConvertUtils.isNotEmpty(tempBizPath)){
// bizPath = tempBizPath;
// }
// String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());
// File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);
// if (!file.exists()) {
// file.mkdirs();// 创建文件根目录
// }
// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
// MultipartFile mf = multipartRequest.getFile("file");// 获取上传文件对象
// String orgName = mf.getOriginalFilename();// 获取文件名
// fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
// String savePath = file.getPath() + File.separator + fileName;
// File savefile = new File(savePath);
// FileCopyUtils.copy(mf.getBytes(), savefile);
// String dbpath = bizPath + File.separator + nowday + File.separator + fileName;
// if (dbpath.contains("\\")) {
// dbpath = dbpath.replace("\\", "/");
// }
// result.setMessage(dbpath);
// result.setSuccess(true);
// } catch (IOException e) {
// result.setSuccess(false);
// result.setMessage(e.getMessage());
// log.error(e.getMessage(), e);
// }
// return result;
// }
/**
* 预览图片&下载文件
* 请求地址http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
*
* @param request
* @param response
*/
@GetMapping(value = "/view/**")
@GetMapping(value = "/static/**")
public void view(HttpServletRequest request, HttpServletResponse response) {
// ISO-8859-1 ==> UTF-8 进行编码转换
String imgPath = extractPathFromPattern(request);
@ -104,10 +193,12 @@ public class CommonController {
if (imgPath.endsWith(",")) {
imgPath = imgPath.substring(0, imgPath.length() - 1);
}
response.setContentType("image/jpeg;charset=utf-8");
String localPath = uploadpath;
String imgurl = localPath + File.separator + imgPath;
inputStream = new BufferedInputStream(new FileInputStream(imgurl));
String filePath = uploadpath + File.separator + imgPath;
String downloadFilePath = uploadpath + File.separator + filePath;
File file = new File(downloadFilePath);
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
inputStream = new BufferedInputStream(new FileInputStream(filePath));
outputStream = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
@ -116,7 +207,7 @@ public class CommonController {
}
response.flushBuffer();
} catch (IOException e) {
log.error("预览图片失败" + e.getMessage());
log.error("预览文件失败" + e.getMessage());
// e.printStackTrace();
} finally {
if (inputStream != null) {
@ -136,64 +227,65 @@ public class CommonController {
}
}
/**
* 下载文件
* 请求地址http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
*
* @param request
* @param response
* @throws Exception
*/
@GetMapping(value = "/download/**")
public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ISO-8859-1 ==> UTF-8 进行编码转换
String filePath = extractPathFromPattern(request);
// 其余处理略
InputStream inputStream = null;
OutputStream outputStream = null;
try {
filePath = filePath.replace("..", "");
if (filePath.endsWith(",")) {
filePath = filePath.substring(0, filePath.length() - 1);
}
String localPath = uploadpath;
String downloadFilePath = localPath + File.separator + filePath;
File file = new File(downloadFilePath);
if (file.exists()) {
response.setContentType("application/force-download");// 设置强制下载不打开            
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
inputStream = new BufferedInputStream(new FileInputStream(file));
outputStream = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
}
} catch (Exception e) {
log.info("文件下载失败" + e.getMessage());
// e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// /**
// * 下载文件
// * 请求地址http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
// *
// * @param request
// * @param response
// * @throws Exception
// */
// @GetMapping(value = "/download/**")
// public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
// // ISO-8859-1 ==> UTF-8 进行编码转换
// String filePath = extractPathFromPattern(request);
// // 其余处理略
// InputStream inputStream = null;
// OutputStream outputStream = null;
// try {
// filePath = filePath.replace("..", "");
// if (filePath.endsWith(",")) {
// filePath = filePath.substring(0, filePath.length() - 1);
// }
// String localPath = uploadpath;
// String downloadFilePath = localPath + File.separator + filePath;
// File file = new File(downloadFilePath);
// if (file.exists()) {
// response.setContentType("application/force-download");// 设置强制下载不打开            
// response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
// inputStream = new BufferedInputStream(new FileInputStream(file));
// outputStream = response.getOutputStream();
// byte[] buf = new byte[1024];
// int len;
// while ((len = inputStream.read(buf)) > 0) {
// outputStream.write(buf, 0, len);
// }
// response.flushBuffer();
// }
//
// } catch (Exception e) {
// log.info("文件下载失败" + e.getMessage());
// // e.printStackTrace();
// } finally {
// if (inputStream != null) {
// try {
// inputStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// if (outputStream != null) {
// try {
// outputStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
//
// }
/**
* @功能pdf预览Iframe
* @param modelAndView
@ -206,7 +298,7 @@ public class CommonController {
}
/**
* 把指定URL后的字符串全部截断当成参数
* 把指定URL后的字符串全部截断当成参数
* 这么做是为了防止URL中包含中文或者特殊字符/等)时,匹配不了的问题
* @param request
* @return
@ -216,5 +308,5 @@ public class CommonController {
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
}
}

View File

@ -443,7 +443,7 @@ public class QueryGenerator {
/**
*
* 获取请求对应的数据权限规则
* @return
*/
public static Map<String, SysPermissionDataRuleModel> getRuleMap() {

View File

@ -18,6 +18,10 @@ public class ComboModel implements Serializable {
private boolean checked;
/**文档管理 表单table 用户账号*/
private String username;
/**文档管理 表单table 用户邮箱*/
private String email;
/**文档管理 表单table 角色编码*/
private String roleCode;
public ComboModel(){

View File

@ -0,0 +1,52 @@
package org.jeecg.common.system.vo;
import lombok.Data;
import org.springframework.beans.BeanUtils;
@Data
public class DynamicDataSourceModel {
public DynamicDataSourceModel() {
}
public DynamicDataSourceModel(Object dbSource) {
if (dbSource != null) {
BeanUtils.copyProperties(dbSource, this);
}
}
/**
* id
*/
private java.lang.String id;
/**
* 数据源编码
*/
private java.lang.String code;
/**
* 数据库类型
*/
private java.lang.String dbType;
/**
* 驱动类
*/
private java.lang.String dbDriver;
/**
* 数据源地址
*/
private java.lang.String dbUrl;
/**
* 数据库名称
*/
private java.lang.String dbName;
/**
* 用户名
*/
private java.lang.String dbUsername;
/**
* 密码
*/
private java.lang.String dbPassword;
}

View File

@ -90,4 +90,14 @@ public class LoginUser {
*/
private Date createTime;
/**
* 身份1 普通员工 2 上级)
*/
private Integer identity;
/**
* 管理部门ids
*/
private String departIds;
}

View File

@ -0,0 +1,52 @@
package org.jeecg.common.system.vo;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
* @Author qinfeng
* @Date 2020/2/19 12:01
* @Description:
* @Version 1.0
*/
public class SysCategoryModel {
/**主键*/
private java.lang.String id;
/**父级节点*/
private java.lang.String pid;
/**类型名称*/
private java.lang.String name;
/**类型编码*/
private java.lang.String code;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}

View File

@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.handler.IFillRuleHandler;
@ -14,6 +15,7 @@ import org.jeecg.common.handler.IFillRuleHandler;
* @author qinfeng
* @举例: 自动生成订单号;自动生成当前日期
*/
@Slf4j
public class FillRuleUtil {
/**
@ -30,6 +32,10 @@ public class FillRuleUtil {
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("rule_code", ruleCode);
JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper)));
if (entity == null) {
log.warn("填值规则:" + ruleCode + " 不存在");
return null;
}
// 获取必要的参数
String ruleClass = entity.getString("ruleClass");
JSONObject params = entity.getJSONObject("ruleParams");

View File

@ -24,14 +24,14 @@ public class PmsUtil {
public static String saveErrorTxtByList(List<String> msg, String name) {
Date d = new Date();
String saveDir = "logs" + File.separator + DateUtils.yyyyMMdd.format(d) + File.separator;
String saveDir = "logs" + File.separator + DateUtils.yyyyMMdd.get().format(d) + File.separator;
String saveFullDir = uploadPath + File.separator + saveDir;
File saveFile = new File(saveFullDir);
if (!saveFile.exists()) {
saveFile.mkdirs();
}
name += DateUtils.yyyymmddhhmmss.format(d) + Math.round(Math.random() * 10000);
name += DateUtils.yyyymmddhhmmss.get().format(d) + Math.round(Math.random() * 10000);
String saveFilePath = saveFullDir + name + ".txt";
try {

View File

@ -0,0 +1,238 @@
package org.jeecg.common.util;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;
/**
* @author 张代浩
* @desc 通过反射来动态调用get 和 set 方法
*/
@Slf4j
public class ReflectHelper {
private Class cls;
/**
* 传过来的对象
*/
private Object obj;
/**
* 存放get方法
*/
private Hashtable<String, Method> getMethods = null;
/**
* 存放set方法
*/
private Hashtable<String, Method> setMethods = null;
/**
* 定义构造方法 -- 一般来说是个pojo
*
* @param o 目标对象
*/
public ReflectHelper(Object o) {
obj = o;
initMethods();
}
/**
* @desc 初始化
*/
public void initMethods() {
getMethods = new Hashtable<String, Method>();
setMethods = new Hashtable<String, Method>();
cls = obj.getClass();
Method[] methods = cls.getMethods();
// 定义正则表达式从方法中过滤出getter / setter 函数.
String gs = "get(\\w+)";
Pattern getM = Pattern.compile(gs);
String ss = "set(\\w+)";
Pattern setM = Pattern.compile(ss);
// 把方法中的"set" 或者 "get" 去掉
String rapl = "$1";
String param;
for (int i = 0; i < methods.length; ++i) {
Method m = methods[i];
String methodName = m.getName();
if (Pattern.matches(gs, methodName)) {
param = getM.matcher(methodName).replaceAll(rapl).toLowerCase();
getMethods.put(param, m);
} else if (Pattern.matches(ss, methodName)) {
param = setM.matcher(methodName).replaceAll(rapl).toLowerCase();
setMethods.put(param, m);
} else {
// logger.info(methodName + " 不是getter,setter方法");
}
}
}
/**
* @desc 调用set方法
*/
public boolean setMethodValue(String property, Object object) {
Method m = setMethods.get(property.toLowerCase());
if (m != null) {
try {
// 调用目标类的setter函数
m.invoke(obj, object);
return true;
} catch (Exception ex) {
log.info("invoke getter on " + property + " error: " + ex.toString());
return false;
}
}
return false;
}
/**
* @desc 调用set方法
*/
public Object getMethodValue(String property) {
Object value = null;
Method m = getMethods.get(property.toLowerCase());
if (m != null) {
try {
/*
* 调用obj类的setter函数
*/
value = m.invoke(obj, new Object[]{});
} catch (Exception ex) {
log.info("invoke getter on " + property + " error: " + ex.toString());
}
}
return value;
}
/**
* 把map中的内容全部注入到obj中
*
* @param data
* @return
*/
public Object setAll(Map<String, Object> data) {
if (data == null || data.keySet().size() <= 0) {
return null;
}
for (Entry<String, Object> entry : data.entrySet()) {
this.setMethodValue(entry.getKey(), entry.getValue());
}
return obj;
}
/**
* 把map中的内容全部注入到obj中
*
* @param o
* @param data
* @return
*/
public static Object setAll(Object o, Map<String, Object> data) {
ReflectHelper reflectHelper = new ReflectHelper(o);
reflectHelper.setAll(data);
return o;
}
/**
* 把map中的内容全部注入到新实例中
*
* @param clazz
* @param data
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T setAll(Class<T> clazz, Map<String, Object> data) {
T o = null;
try {
o = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
o = null;
return o;
}
return (T) setAll(o, data);
}
/**
* 根据传入的class将mapList转换为实体类list
*
* @param mapist
* @param clazz
* @return
*/
public static <T> List<T> transList2Entrys(List<Map<String, Object>> mapist, Class<T> clazz) {
List<T> list = new ArrayList<T>();
if (mapist != null && mapist.size() > 0) {
for (Map<String, Object> data : mapist) {
list.add(ReflectHelper.setAll(clazz, data));
}
}
return list;
}
/**
* 根据属性名获取属性值
*/
public static Object getFieldValueByName(String fieldName, Object o) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = o.getClass().getMethod(getter, new Class[]{});
Object value = method.invoke(o, new Object[]{});
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取属性名数组
*/
public static String[] getFiledName(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
//System.out.println(fields[i].getType());
fieldNames[i] = fields[i].getName();
}
return fieldNames;
}
/**
* 获取属性类型(type),属性名(name),属性值(value)的map组成的list
*/
public static List<Map> getFiledsInfo(Object o) {
Field[] fields = o.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
List<Map> list = new ArrayList<Map>();
Map<String, Object> infoMap = null;
for (int i = 0; i < fields.length; i++) {
infoMap = new HashMap<String, Object>();
infoMap.put("type", fields[i].getType().toString());
infoMap.put("name", fields[i].getName());
infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
list.add(infoMap);
}
return list;
}
/**
* 获取对象的所有属性值,返回一个对象数组
*/
public static Object[] getFiledValues(Object o) {
String[] fieldNames = getFiledName(o);
Object[] value = new Object[fieldNames.length];
for (int i = 0; i < fieldNames.length; i++) {
value[i] = getFieldValueByName(fieldNames[i], o);
}
return value;
}
}

View File

@ -15,6 +15,28 @@ import java.util.Map;
*/
public class RestUtil {
private static String domain = null;
public static String getDomain() {
if (domain == null) {
domain = SpringContextUtils.getDomain();
}
return domain;
}
public static String path = null;
public static String getPath() {
if (path == null) {
path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path");
}
return path;
}
public static String getBaseUrl() {
return getDomain() + getPath();
}
/**
* RestAPI 调用器
*/

View File

@ -21,10 +21,12 @@ public class SqlInjectionUtil {
if (value == null || "".equals(value)) {
return;
}
value = value.toLowerCase();// 统一转为小写
// 统一转为小写
value = value.toLowerCase();
String[] xssArr = xssStr.split("\\|");
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1) {
log.error("请注意存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意值可能存在SQL注入风险!--->" + value);
}
@ -35,7 +37,7 @@ public class SqlInjectionUtil {
/**
* sql注入过滤处理遇到注入关键字抛异常
*
* @param value
* @param values
* @return
*/
public static void filterContent(String[] values) {
@ -44,9 +46,11 @@ public class SqlInjectionUtil {
if (value == null || "".equals(value)) {
return;
}
value = value.toLowerCase();// 统一转为小写
// 统一转为小写
value = value.toLowerCase();
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1) {
log.error("请注意存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意值可能存在SQL注入风险!--->" + value);
}
@ -62,14 +66,16 @@ public class SqlInjectionUtil {
*/
@Deprecated
public static void specialFilterContent(String value) {
String specialXssStr = "exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|+|";
String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|";
String[] xssArr = specialXssStr.split("\\|");
if (value == null || "".equals(value)) {
return;
}
value = value.toLowerCase();// 统一转为小写
// 统一转为小写
value = value.toLowerCase();
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1) {
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
log.error("请注意存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意值可能存在SQL注入风险!--->" + value);
}
@ -85,14 +91,16 @@ public class SqlInjectionUtil {
*/
@Deprecated
public static void specialFilterContentForOnlineReport(String value) {
String specialXssStr = "exec |insert |delete |update |drop |chr |mid |master |truncate |char |declare |";
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |";
String[] xssArr = specialXssStr.split("\\|");
if (value == null || "".equals(value)) {
return;
}
value = value.toLowerCase();// 统一转为小写
// 统一转为小写
value = value.toLowerCase();
for (int i = 0; i < xssArr.length; i++) {
if (value.indexOf(xssArr[i]) > -1) {
if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) {
log.error("请注意存在SQL注入关键词---> {}", xssArr[i]);
log.error("请注意值可能存在SQL注入风险!---> {}", value);
throw new RuntimeException("请注意值可能存在SQL注入风险!--->" + value);
}

View File

@ -0,0 +1,70 @@
package org.jeecg.common.util;
/**
* 系统公告自定义跳转方式
*/
public enum SysAnnmentTypeEnum {
/**
* 邮件跳转组件
*/
EMAIL("email", "component", "modules/eoa/email/modals/EoaEmailInForm"),
/**
* 工作流跳转链接我的办公
*/
BPM("bpm", "url", "/bpm/task/MyTaskList");
/**
* 业务类型(email:邮件 bpm:流程)
*/
private String type;
/**
* 打开方式 组件component 路由url
*/
private String openType;
/**
* 组件/路由 地址
*/
private String openPage;
SysAnnmentTypeEnum(String type, String openType, String openPage) {
this.type = type;
this.openType = openType;
this.openPage = openPage;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getOpenType() {
return openType;
}
public void setOpenType(String openType) {
this.openType = openType;
}
public String getOpenPage() {
return openPage;
}
public void setOpenPage(String openPage) {
this.openPage = openPage;
}
public static SysAnnmentTypeEnum getByType(String type) {
if (oConvertUtils.isEmpty(type)) {
return null;
}
for (SysAnnmentTypeEnum val : values()) {
if (val.getType().equals(type)) {
return val;
}
}
return null;
}
}

View File

@ -1,6 +1,7 @@
package org.jeecg.common.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
@ -38,6 +39,10 @@ public class TokenUtils {
log.info(" -- url --" + request.getRequestURL());
String token = getTokenByRequest(request);
if (StringUtils.isBlank(token)) {
throw new AuthenticationException("token不能为空!");
}
// 解密获得username用于和数据库进行对比
String username = JwtUtil.getUsername(token);
if (username == null) {

View File

@ -0,0 +1,87 @@
package org.jeecg.common.util.dynamic.db;
import org.apache.commons.dbcp.BasicDataSource;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DynamicDataSourceModel;
import org.jeecg.common.util.SpringContextUtils;
import java.util.HashMap;
import java.util.Map;
/**
* 数据源缓存池
*/
public class DataSourceCachePool {
/**
* DynamicDataSourceModel的 code 和 id 的对应关系。key为idvalue为code
*/
private static Map<String, String> dynamicDbSourcesIdToCode = new HashMap<>();
/**
* DynamicDataSourceModel的缓存。key为codevalue为数据源
*/
private static Map<String, DynamicDataSourceModel> dynamicDbSourcesCache = new HashMap<>();
/**
* 动态数据源参数配置【缓存】
*/
public static Map<String, DynamicDataSourceModel> getCacheAllDynamicDataSourceModel() {
return dynamicDbSourcesCache;
}
/**
* 获取多数据源缓存
*
* @param dbKey
* @return
*/
public static DynamicDataSourceModel getCacheDynamicDataSourceModel(String dbKey) {
DynamicDataSourceModel dbSource = dynamicDbSourcesCache.get(dbKey);
if (dbSource == null) {
ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
dbSource = sysBaseAPI.getDynamicDbSourceByCode(dbKey);
dynamicDbSourcesCache.put(dbKey, dbSource);
dynamicDbSourcesIdToCode.put(dbSource.getId(), dbKey);
}
return dbSource;
}
/**
* 动态数据源连接池【本地class缓存 - 不支持分布式】
*/
private static Map<String, BasicDataSource> dbSources = new HashMap<>();
public static BasicDataSource getCacheBasicDataSource(String dbKey) {
return dbSources.get(dbKey);
}
/**
* put 数据源缓存
*
* @param dbKey
* @param db
*/
public static void putCacheBasicDataSource(String dbKey, BasicDataSource db) {
dbSources.put(dbKey, db);
}
/**
* 清空数据源缓存
*/
public static void cleanCacheBasicDataSource() {
dbSources.clear();
}
public static void removeCache(String dbKey) {
dbSources.remove(dbKey);
dynamicDbSourcesCache.remove(dbKey);
}
public static void removeCacheById(String dbId) {
String dbKey = dynamicDbSourcesIdToCode.get(dbId);
dbSources.remove(dbKey);
dynamicDbSourcesCache.remove(dbKey);
}
}

View File

@ -0,0 +1,283 @@
package org.jeecg.common.util.dynamic.db;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.lang.ArrayUtils;
import org.jeecg.common.system.vo.DynamicDataSourceModel;
import org.jeecg.common.util.ReflectHelper;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Spring JDBC 实时数据库访问
*
* @author chenguobin
* @version 1.0
* @date 2014-09-05
*/
@Slf4j
public class DynamicDBUtil {
/**
* 获取数据源【最底层方法,不要随便调用】
*
* @param dbSource
* @return
*/
@Deprecated
private static BasicDataSource getJdbcDataSource(final DynamicDataSourceModel dbSource) {
BasicDataSource dataSource = new BasicDataSource();
String driverClassName = dbSource.getDbDriver();
String url = dbSource.getDbUrl();
String dbUser = dbSource.getDbUsername();
String dbPassword = dbSource.getDbPassword();
//设置数据源的时候,要重新解密
// String dbPassword = PasswordUtil.decrypt(dbSource.getDbPassword(), dbSource.getDbUsername(), PasswordUtil.getStaticSalt());//解密字符串;
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(dbUser);
dataSource.setPassword(dbPassword);
return dataSource;
}
/**
* 通过 dbKey ,获取数据源
*
* @param dbKey
* @return
*/
public static BasicDataSource getDbSourceByDbKey(final String dbKey) {
//获取多数据源配置
DynamicDataSourceModel dbSource = DataSourceCachePool.getCacheDynamicDataSourceModel(dbKey);
//先判断缓存中是否存在数据库链接
BasicDataSource cacheDbSource = DataSourceCachePool.getCacheBasicDataSource(dbKey);
if (cacheDbSource != null && !cacheDbSource.isClosed()) {
log.debug("--------getDbSourceBydbKey------------------从缓存中获取DB连接-------------------");
return cacheDbSource;
} else {
BasicDataSource dataSource = getJdbcDataSource(dbSource);
DataSourceCachePool.putCacheBasicDataSource(dbKey, dataSource);
log.info("--------getDbSourceBydbKey------------------创建DB数据库连接-------------------");
return dataSource;
}
}
/**
* 关闭数据库连接池
*
* @param dbKey
* @return
*/
public static void closeDbKey(final String dbKey) {
BasicDataSource dataSource = getDbSourceByDbKey(dbKey);
try {
if (dataSource != null && !dataSource.isClosed()) {
dataSource.getConnection().commit();
dataSource.getConnection().close();
dataSource.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private static JdbcTemplate getJdbcTemplate(String dbKey) {
BasicDataSource dataSource = getDbSourceByDbKey(dbKey);
return new JdbcTemplate(dataSource);
}
/**
* Executes the SQL statement in this <code>PreparedStatement</code> object,
* which must be an SQL Data Manipulation Language (DML) statement, such as <code>INSERT</code>, <code>UPDATE</code> or
* <code>DELETE</code>; or an SQL statement that returns nothing,
* such as a DDL statement.
*/
public static int update(final String dbKey, String sql, Object... param) {
int effectCount;
JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey);
if (ArrayUtils.isEmpty(param)) {
effectCount = jdbcTemplate.update(sql);
} else {
effectCount = jdbcTemplate.update(sql, param);
}
return effectCount;
}
/**
* 支持miniDao语法操作的Update
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持minidao语法逻辑
* @param data sql语法中需要判断的数据及sql拼接注入中需要的数据
* @return
*/
public static int updateByHash(final String dbKey, String sql, HashMap<String, Object> data) {
int effectCount;
JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey);
//根据模板获取sql
sql = FreemarkerParseFactory.parseTemplateContent(sql, data);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
effectCount = namedParameterJdbcTemplate.update(sql, data);
return effectCount;
}
public static Object findOne(final String dbKey, String sql, Object... param) {
List<Map<String, Object>> list;
list = findList(dbKey, sql, param);
if (oConvertUtils.listIsEmpty(list)) {
log.error("Except one, but not find actually");
}
if (list.size() > 1) {
log.error("Except one, but more than one actually");
}
return list.get(0);
}
/**
* 支持miniDao语法操作的查询 返回HashMap
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持minidao语法逻辑
* @param data sql语法中需要判断的数据及sql拼接注入中需要的数据
* @return
*/
public static Object findOneByHash(final String dbKey, String sql, HashMap<String, Object> data) {
List<Map<String, Object>> list;
list = findListByHash(dbKey, sql, data);
if (oConvertUtils.listIsEmpty(list)) {
log.error("Except one, but not find actually");
}
if (list.size() > 1) {
log.error("Except one, but more than one actually");
}
return list.get(0);
}
/**
* 直接sql查询 根据clazz返回单个实例
*
* @param dbKey 数据源标识
* @param sql 执行sql语句
* @param clazz 返回实例的Class
* @param param
* @return
*/
@SuppressWarnings("unchecked")
public static <T> Object findOne(final String dbKey, String sql, Class<T> clazz, Object... param) {
Map<String, Object> map = (Map<String, Object>) findOne(dbKey, sql, param);
return ReflectHelper.setAll(clazz, map);
}
/**
* 支持miniDao语法操作的查询 返回单个实例
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持minidao语法逻辑
* @param clazz 返回实例的Class
* @param data sql语法中需要判断的数据及sql拼接注入中需要的数据
* @return
*/
@SuppressWarnings("unchecked")
public static <T> Object findOneByHash(final String dbKey, String sql, Class<T> clazz, HashMap<String, Object> data) {
Map<String, Object> map = (Map<String, Object>) findOneByHash(dbKey, sql, data);
return ReflectHelper.setAll(clazz, map);
}
public static List<Map<String, Object>> findList(final String dbKey, String sql, Object... param) {
List<Map<String, Object>> list;
JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey);
if (ArrayUtils.isEmpty(param)) {
list = jdbcTemplate.queryForList(sql);
} else {
list = jdbcTemplate.queryForList(sql, param);
}
return list;
}
/**
* 支持miniDao语法操作的查询
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持minidao语法逻辑
* @param data sql语法中需要判断的数据及sql拼接注入中需要的数据
* @return
*/
public static List<Map<String, Object>> findListByHash(final String dbKey, String sql, HashMap<String, Object> data) {
List<Map<String, Object>> list;
JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey);
//根据模板获取sql
sql = FreemarkerParseFactory.parseTemplateContent(sql, data);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
list = namedParameterJdbcTemplate.queryForList(sql, data);
return list;
}
//此方法只能返回单列,不能返回实体类
public static <T> List<T> findList(final String dbKey, String sql, Class<T> clazz, Object... param) {
List<T> list;
JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey);
if (ArrayUtils.isEmpty(param)) {
list = jdbcTemplate.queryForList(sql, clazz);
} else {
list = jdbcTemplate.queryForList(sql, clazz, param);
}
return list;
}
/**
* 支持miniDao语法操作的查询 返回单列数据list
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持minidao语法逻辑
* @param clazz 类型Long、String等
* @param data sql语法中需要判断的数据及sql拼接注入中需要的数据
* @return
*/
public static <T> List<T> findListByHash(final String dbKey, String sql, Class<T> clazz, HashMap<String, Object> data) {
List<T> list;
JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey);
//根据模板获取sql
sql = FreemarkerParseFactory.parseTemplateContent(sql, data);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
list = namedParameterJdbcTemplate.queryForList(sql, data, clazz);
return list;
}
/**
* 直接sql查询 返回实体类列表
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持 minidao 语法逻辑
* @param clazz 返回实体类列表的class
* @param param sql拼接注入中需要的数据
* @return
*/
public static <T> List<T> findListEntities(final String dbKey, String sql, Class<T> clazz, Object... param) {
List<Map<String, Object>> queryList = findList(dbKey, sql, param);
return ReflectHelper.transList2Entrys(queryList, clazz);
}
/**
* 支持miniDao语法操作的查询 返回实体类列表
*
* @param dbKey 数据源标识
* @param sql 执行sql语句sql支持minidao语法逻辑
* @param clazz 返回实体类列表的class
* @param data sql语法中需要判断的数据及sql拼接注入中需要的数据
* @return
*/
public static <T> List<T> findListEntitiesByHash(final String dbKey, String sql, Class<T> clazz, HashMap<String, Object> data) {
List<Map<String, Object>> queryList = findListByHash(dbKey, sql, data);
return ReflectHelper.transList2Entrys(queryList, clazz);
}
}

View File

@ -0,0 +1,173 @@
package org.jeecg.common.util.dynamic.db;
import freemarker.cache.StringTemplateLoader;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jeecgframework.codegenerate.generate.util.SimpleFormat;
import java.io.StringWriter;
import java.util.Map;
import java.util.regex.Pattern;
/**
* @author 赵俊夫
* @version V1.0
* @Title:FreemarkerHelper
* @description:Freemarker引擎协助类
* @date Jul 5, 2013 2:58:29 PM
*/
@Slf4j
public class FreemarkerParseFactory {
private static final String ENCODE = "utf-8";
/**
* 参数格式化工具类
*/
private static final String MINI_DAO_FORMAT = "DaoFormat";
/**
* 文件缓存
*/
private static final Configuration _tplConfig = new Configuration();
/**
* SQL 缓存
*/
private static final Configuration _sqlConfig = new Configuration();
private static StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
// 使用内嵌的(?ms)打开单行和多行模式
private final static Pattern p = Pattern
.compile("(?ms)/\\*.*?\\*/|^\\s*//.*?$");
static {
_tplConfig.setClassForTemplateLoading(
new FreemarkerParseFactory().getClass(), "/");
_tplConfig.setNumberFormat("0.#####################");
_sqlConfig.setTemplateLoader(stringTemplateLoader);
_sqlConfig.setNumberFormat("0.#####################");
//classic_compatible设置解决报空指针错误
_sqlConfig.setClassicCompatible(true);
}
/**
* 判断模板是否存在
*
* @throws Exception
*/
public static boolean isExistTemplate(String tplName) throws Exception {
try {
Template mytpl = _tplConfig.getTemplate(tplName, "UTF-8");
if (mytpl == null) {
return false;
}
} catch (Exception e) {
//update-begin--Author:scott Date:20180320 for解决问题 - 错误提示sql文件不存在实际问题是sql freemarker用法错误-----
if (e instanceof ParseException) {
log.error(e.getMessage(), e.fillInStackTrace());
throw new Exception(e);
}
log.debug("----isExistTemplate----" + e.toString());
//update-end--Author:scott Date:20180320 for解决问题 - 错误提示sql文件不存在实际问题是sql freemarker用法错误------
return false;
}
return true;
}
/**
* 解析ftl模板
*
* @param tplName 模板名
* @param paras 参数
* @return
*/
public static String parseTemplate(String tplName, Map<String, Object> paras) {
try {
log.debug(" minidao sql templdate : " + tplName);
StringWriter swriter = new StringWriter();
Template mytpl = _tplConfig.getTemplate(tplName, ENCODE);
if (paras.containsKey(MINI_DAO_FORMAT)) {
throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!");
}
paras.put(MINI_DAO_FORMAT, new SimpleFormat());
mytpl.process(paras, swriter);
String sql = getSqlText(swriter.toString());
paras.remove(MINI_DAO_FORMAT);
return sql;
} catch (Exception e) {
log.error(e.getMessage(), e.fillInStackTrace());
log.error("发送一次的模板key:{ " + tplName + " }");
//System.err.println(e.getMessage());
//System.err.println("模板名:{ "+ tplName +" }");
throw new RuntimeException("解析SQL模板异常");
}
}
/**
* 解析ftl
*
* @param tplContent 模板内容
* @param paras 参数
* @return String 模板解析后内容
*/
public static String parseTemplateContent(String tplContent,
Map<String, Object> paras) {
try {
StringWriter swriter = new StringWriter();
if (stringTemplateLoader.findTemplateSource("sql_" + tplContent.hashCode()) == null) {
stringTemplateLoader.putTemplate("sql_" + tplContent.hashCode(), tplContent);
}
Template mytpl = _sqlConfig.getTemplate("sql_" + tplContent.hashCode(), ENCODE);
if (paras.containsKey(MINI_DAO_FORMAT)) {
throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!");
}
paras.put(MINI_DAO_FORMAT, new SimpleFormat());
mytpl.process(paras, swriter);
String sql = getSqlText(swriter.toString());
paras.remove(MINI_DAO_FORMAT);
return sql;
} catch (Exception e) {
log.error(e.getMessage(), e.fillInStackTrace());
log.error("发送一次的模板key:{ " + tplContent + " }");
//System.err.println(e.getMessage());
//System.err.println("模板内容:{ "+ tplContent +" }");
throw new RuntimeException("解析SQL模板异常");
}
}
/**
* 除去无效字段,去掉注释 不然批量处理可能报错 去除无效的等于
*/
private static String getSqlText(String sql) {
// 将注释替换成""
sql = p.matcher(sql).replaceAll("");
sql = sql.replaceAll("\\n", " ").replaceAll("\\t", " ")
.replaceAll("\\s{1,}", " ").trim();
// 去掉 最后是 where这样的问题
if (sql.endsWith("where") || sql.endsWith("where ")) {
sql = sql.substring(0, sql.lastIndexOf("where"));
}
// 去掉where and 这样的问题
int index = 0;
while ((index = StringUtils.indexOfIgnoreCase(sql, "where and", index)) != -1) {
sql = sql.substring(0, index + 5)
+ sql.substring(index + 9, sql.length());
}
// 去掉 , where 这样的问题
index = 0;
while ((index = StringUtils.indexOfIgnoreCase(sql, ", where", index)) != -1) {
sql = sql.substring(0, index)
+ sql.substring(index + 1, sql.length());
}
// 去掉 最后是 ,这样的问题
if (sql.endsWith(",") || sql.endsWith(", ")) {
sql = sql.substring(0, sql.lastIndexOf(","));
}
return sql;
}
}

View File

@ -0,0 +1,212 @@
package org.jeecg.common.util.dynamic.db;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.system.vo.DynamicDataSourceModel;
import java.text.MessageFormat;
import java.util.Map;
/**
* 根据不同的数据库动态生成SQL例如分页
*/
public class SqlUtils {
public static final String DATABSE_TYPE_MYSQL = "mysql";
public static final String DATABSE_TYPE_POSTGRE = "postgresql";
public static final String DATABSE_TYPE_ORACLE = "oracle";
public static final String DATABSE_TYPE_SQLSERVER = "sqlserver";
/**
* 分页SQL
*/
public static final String MYSQL_SQL = "select * from ( {0}) sel_tab00 limit {1},{2}";
public static final String POSTGRE_SQL = "select * from ( {0}) sel_tab00 limit {2} offset {1}";
public static final String ORACLE_SQL = "select * from (select row_.*,rownum rownum_ from ({0}) row_ where rownum <= {1}) where rownum_>{2}";
public static final String SQLSERVER_SQL = "select * from ( select row_number() over(order by tempColumn) tempRowNumber, * from (select top {1} tempColumn = 0, {0}) t ) tt where tempRowNumber > {2}";
/**
* 获取所有表的SQL
*/
public static final String MYSQL_ALLTABLES_SQL = "select distinct table_name from information_schema.columns where table_schema = {0}";
public static final String POSTGRE__ALLTABLES_SQL = "SELECT distinct c.relname AS table_name FROM pg_class c";
public static final String ORACLE__ALLTABLES_SQL = "select distinct colstable.table_name as table_name from user_tab_cols colstable";
public static final String SQLSERVER__ALLTABLES_SQL = "select distinct c.name as table_name from sys.objects c";
/**
* 获取指定表的所有列名
*/
public static final String MYSQL_ALLCOLUMNS_SQL = "select column_name from information_schema.columns where table_name = {0} and table_schema = {1}";
public static final String POSTGRE_ALLCOLUMNS_SQL = "select table_name from information_schema.columns where table_name = {0}";
public static final String ORACLE_ALLCOLUMNS_SQL = "select column_name from all_tab_columns where table_name ={0}";
public static final String SQLSERVER_ALLCOLUMNS_SQL = "select name from syscolumns where id={0}";
/*
* 判断数据库类型
*/
public static boolean dbTypeIsMySQL(String dbType) {
return dbTypeIf(dbType, DATABSE_TYPE_MYSQL, DataBaseConstant.DB_TYPE_MYSQL_NUM);
}
public static boolean dbTypeIsOracle(String dbType) {
return dbTypeIf(dbType, DATABSE_TYPE_ORACLE, DataBaseConstant.DB_TYPE_ORACLE_NUM);
}
public static boolean dbTypeIsSQLServer(String dbType) {
return dbTypeIf(dbType, DATABSE_TYPE_SQLSERVER, DataBaseConstant.DB_TYPE_SQLSERVER_NUM);
}
public static boolean dbTypeIsPostgre(String dbType) {
return dbTypeIf(dbType, DATABSE_TYPE_POSTGRE, DataBaseConstant.DB_TYPE_POSTGRESQL_NUM);
}
/**
* 判断数据库类型
*/
public static boolean dbTypeIf(String dbType, String... correctTypes) {
for (String type : correctTypes) {
if (type.equalsIgnoreCase(dbType)) {
return true;
}
}
return false;
}
/**
* 获取全 SQL
* 拼接 where 条件
*
* @param sql
* @param params
* @return
*/
public static String getFullSql(String sql, Map params) {
return getFullSql(sql, params, null, null);
}
/**
* 获取全 SQL
* 拼接 where 条件
* 拼接 order 排序
*
* @param sql
* @param params
* @param orderColumn 排序字段
* @param orderBy 排序方式,只能是 DESC 或 ASC
* @return
*/
public static String getFullSql(String sql, Map params, String orderColumn, String orderBy) {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT t.* FROM ( ").append(sql).append(" ) t ");
if (params != null && params.size() >= 1) {
sqlBuilder.append("WHERE 1=1 ");
for (Object key : params.keySet()) {
String value = String.valueOf(params.get(key));
if (StringUtils.isNotBlank(value)) {
sqlBuilder.append(" AND (").append(key).append(" = N'").append(value).append("')");
}
}
if (StringUtils.isNotBlank(orderColumn) && StringUtils.isNotBlank(orderBy)) {
sqlBuilder.append("ORDER BY ").append(orderColumn).append(" ").append("DESC".equalsIgnoreCase(orderBy) ? "DESC" : "ASC");
}
}
return sqlBuilder.toString();
}
/**
* 获取求数量 SQL
*
* @param sql
* @return
*/
public static String getCountSql(String sql) {
return String.format("SELECT COUNT(1) \"total\" FROM ( %s ) temp_count", sql);
}
/**
* 生成分页查询 SQL
*
* @param dbType 数据库类型
* @param sql
* @param page
* @param rows
* @return
*/
public static String createPageSqlByDBType(String dbType, String sql, int page, int rows) {
int beginNum = (page - 1) * rows;
Object[] sqlParam = new Object[3];
sqlParam[0] = sql;
sqlParam[1] = String.valueOf(beginNum);
sqlParam[2] = String.valueOf(rows);
if (dbTypeIsMySQL(dbType)) {
sql = MessageFormat.format(MYSQL_SQL, sqlParam);
} else if (dbTypeIsPostgre(dbType)) {
sql = MessageFormat.format(POSTGRE_SQL, sqlParam);
} else {
int beginIndex = (page - 1) * rows;
int endIndex = beginIndex + rows;
sqlParam[2] = Integer.toString(beginIndex);
sqlParam[1] = Integer.toString(endIndex);
if (dbTypeIsOracle(dbType)) {
sql = MessageFormat.format(ORACLE_SQL, sqlParam);
} else if (dbTypeIsSQLServer(dbType)) {
sqlParam[0] = sql.substring(getAfterSelectInsertPoint(sql));
sql = MessageFormat.format(SQLSERVER_SQL, sqlParam);
}
}
return sql;
}
/**
* 生成分页查询 SQL
*
* @param sql
* @param page
* @param rows
* @return
*/
public static String createPageSqlByDBKey(String dbKey, String sql, int page, int rows) {
DynamicDataSourceModel dynamicSourceEntity = DataSourceCachePool.getCacheDynamicDataSourceModel(dbKey);
String dbType = dynamicSourceEntity.getDbType();
return createPageSqlByDBType(dbType, sql, page, rows);
}
private static int getAfterSelectInsertPoint(String sql) {
int selectIndex = sql.toLowerCase().indexOf("select");
int selectDistinctIndex = sql.toLowerCase().indexOf("select distinct");
return selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6);
}
public static String getAllTableSql(String dbType, Object... params) {
if (StringUtils.isNotEmpty(dbType)) {
if (dbTypeIsMySQL(dbType)) {
return MessageFormat.format(MYSQL_ALLTABLES_SQL, params);
} else if (dbTypeIsOracle(dbType)) {
return ORACLE__ALLTABLES_SQL;
} else if (dbTypeIsPostgre(dbType)) {
return POSTGRE__ALLTABLES_SQL;
} else if (dbTypeIsSQLServer(dbType)) {
return SQLSERVER__ALLTABLES_SQL;
}
}
return null;
}
public static String getAllColumnSQL(String dbType, Object... params) {
if (StringUtils.isNotEmpty(dbType)) {
if (dbTypeIsMySQL(dbType)) {
return MessageFormat.format(MYSQL_ALLCOLUMNS_SQL, params);
} else if (dbTypeIsOracle(dbType)) {
return MessageFormat.format(ORACLE_ALLCOLUMNS_SQL, params);
} else if (dbTypeIsPostgre(dbType)) {
return MessageFormat.format(POSTGRE_ALLCOLUMNS_SQL, params);
} else if (dbTypeIsSQLServer(dbType)) {
return MessageFormat.format(SQLSERVER_ALLCOLUMNS_SQL, params);
}
}
return null;
}
}

View File

@ -3,6 +3,7 @@ package org.jeecg.common.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
@ -12,20 +13,10 @@ import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
/**
*
* @Author 张代浩
@ -631,4 +622,28 @@ public class oConvertUtils {
return (T)model;
}
/**
* 判断 list 是否为空
*
* @param list
* @return true or false
* list == null : true
* list.size() == 0 : true
*/
public static boolean listIsEmpty(Collection list) {
return (list == null || list.size() == 0);
}
/**
* 判断 list 是否不为空
*
* @param list
* @return true or false
* list == null : false
* list.size() == 0 : false
*/
public static boolean listIsNotEmpty(Collection list) {
return !listIsEmpty(list);
}
}

View File

@ -6,6 +6,7 @@ import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.PutObjectResult;
import org.apache.tomcat.util.http.fileupload.FileItemStream;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@ -69,8 +70,11 @@ public class OssBootUtil {
}
fileUrl = fileUrl.append(fileDir + fileName);
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
//FILE_URL = staticDomain + "/" + fileUrl;
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
FILE_URL = staticDomain + "/" + fileUrl;
} else {
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
}
PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.getInputStream());
// 设置权限(公开读)
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
@ -105,8 +109,11 @@ public class OssBootUtil {
}
fileUrl = fileUrl.append(fileDir + fileName);
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
//FILE_URL = staticDomain + "/" + fileUrl;
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
FILE_URL = staticDomain + "/" + fileUrl;
} else {
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
}
PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.openStream());
// 设置权限(公开读)
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);