mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-26 16:26:41 +08:00
Jeecg-Boot 2.1.4 版本发布 | 重构较大,较多新功能
This commit is contained in:
@ -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";
|
||||
|
||||
/**
|
||||
* 文件上传类型(本地:local,Minio:minio,阿里云: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;
|
||||
}
|
||||
|
||||
@ -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";
|
||||
//*********系统上下文变量****************************************
|
||||
/**
|
||||
* 数据-所属机构编码
|
||||
|
||||
@ -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;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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 minio:minio 阿里: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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -443,7 +443,7 @@ public class QueryGenerator {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 获取请求对应的数据权限规则
|
||||
* @return
|
||||
*/
|
||||
public static Map<String, SysPermissionDataRuleModel> getRuleMap() {
|
||||
|
||||
@ -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(){
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -90,4 +90,14 @@ public class LoginUser {
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 身份(1 普通员工 2 上级)
|
||||
*/
|
||||
private Integer identity;
|
||||
|
||||
/**
|
||||
* 管理部门ids
|
||||
*/
|
||||
private String departIds;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -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");
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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 调用器
|
||||
*/
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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为id,value为code
|
||||
*/
|
||||
private static Map<String, String> dynamicDbSourcesIdToCode = new HashMap<>();
|
||||
/**
|
||||
* DynamicDataSourceModel的缓存。key为code,value为数据源
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user