mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-01-03 20:35:29 +08:00
Jeecg-Boot 2.2.0 版本发布 | 重磅升级
This commit is contained in:
@ -0,0 +1,18 @@
|
||||
package org.jeecg.common.aspect.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* online请求拦截专用注解
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE,ElementType.METHOD})
|
||||
@Documented
|
||||
public @interface OnlineAuth {
|
||||
|
||||
/**
|
||||
* 请求关键字,在xxx/code之前的字符串
|
||||
* @return
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
@ -43,4 +43,9 @@ public interface CacheConstant {
|
||||
*/
|
||||
public static final String TEST_DEMO_CACHE = "test:demo";
|
||||
|
||||
/**
|
||||
* 字典信息缓存
|
||||
*/
|
||||
public static final String SYS_DYNAMICDB_CACHE = "sys:cache:dbconnect:dynamic:";
|
||||
|
||||
}
|
||||
|
||||
@ -126,9 +126,9 @@ public interface CommonConstant {
|
||||
/**
|
||||
* 同步工作流引擎1同步0不同步
|
||||
*/
|
||||
public static final String ACT_SYNC_0 = "0";
|
||||
public static final String ACT_SYNC_1 = "1";
|
||||
|
||||
public static final Integer ACT_SYNC_1 = 1;
|
||||
public static final Integer ACT_SYNC_0 = 0;
|
||||
|
||||
/**
|
||||
* 消息类型1:通知公告2:系统消息
|
||||
*/
|
||||
@ -142,7 +142,7 @@ public interface CommonConstant {
|
||||
public static final Integer RULE_FLAG_1 = 1;
|
||||
|
||||
/**
|
||||
* 是否用户已被冻结 1(解冻)正常 2冻结
|
||||
* 是否用户已被冻结 1正常(解冻) 2冻结
|
||||
*/
|
||||
public static final Integer USER_UNFREEZE = 1;
|
||||
public static final Integer USER_FREEZE = 2;
|
||||
@ -204,9 +204,62 @@ public interface CommonConstant {
|
||||
public static final String UPLOAD_TYPE_MINIO = "minio";
|
||||
public static final String UPLOAD_TYPE_OSS = "alioss";
|
||||
|
||||
/**
|
||||
* 文档上传自定义桶名称
|
||||
*/
|
||||
public static final String UPLOAD_CUSTOM_BUCKET = "eoafile";
|
||||
/**
|
||||
* 文档上传自定义路径
|
||||
*/
|
||||
public static final String UPLOAD_CUSTOM_PATH = "eoafile";
|
||||
/**
|
||||
* 文件外链接有效天数
|
||||
*/
|
||||
public static final Integer UPLOAD_EFFECTIVE_DAYS = 1;
|
||||
|
||||
/**
|
||||
* 员工身份 (1:普通员工 2:上级)
|
||||
*/
|
||||
public static final Integer USER_IDENTITY_1 = 1;
|
||||
public static final Integer USER_IDENTITY_2 = 2;
|
||||
|
||||
/** sys_user 表 username 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
|
||||
/** sys_user 表 work_no 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
|
||||
/** sys_user 表 phone 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
|
||||
/** sys_user 表 email 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
|
||||
/** sys_quartz_job 表 job_class_name 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
|
||||
/** sys_position 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_CODE = "uniq_code";
|
||||
/** sys_role 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
|
||||
/** sys_depart 表 code 唯一键索引 */
|
||||
public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
|
||||
/**
|
||||
* 在线聊天 是否为默认分组
|
||||
*/
|
||||
public static final String IM_DEFAULT_GROUP = "1";
|
||||
/**
|
||||
* 在线聊天 图片文件保存路径
|
||||
*/
|
||||
public static final String IM_UPLOAD_CUSTOM_PATH = "imfile";
|
||||
/**
|
||||
* 在线聊天 用户状态
|
||||
*/
|
||||
public static final String IM_STATUS_ONLINE = "online";
|
||||
|
||||
/**
|
||||
* 在线聊天 SOCKET消息类型
|
||||
*/
|
||||
public static final String IM_SOCKET_TYPE = "chatMessage";
|
||||
|
||||
/**
|
||||
* 考勤补卡业务状态 (1:同意 2:不同意)
|
||||
*/
|
||||
public static final String SIGN_PATCH_BIZ_STATUS_1 = "1";
|
||||
public static final String SIGN_PATCH_BIZ_STATUS_2 = "2";
|
||||
}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* 规则值生成 编码常量类
|
||||
* @author: taoyan
|
||||
* @date: 2020年04月02日
|
||||
*/
|
||||
public class FillRuleConstant {
|
||||
|
||||
/**
|
||||
* 公文发文编码
|
||||
*/
|
||||
public static final String DOC_SEND = "doc_send_code";
|
||||
|
||||
/**
|
||||
* 部门编码
|
||||
*/
|
||||
public static final String DEPART = "org_num_role";
|
||||
|
||||
/**
|
||||
* 分类字典编码
|
||||
*/
|
||||
public static final String CATEGORY = "category_code_rule";
|
||||
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
|
||||
@Component("pca")
|
||||
public class ProvinceCityArea {
|
||||
|
||||
@Value("classpath:static/pca.json")
|
||||
private Resource jsonData;
|
||||
|
||||
List<Area> areaList;
|
||||
|
||||
public String getText(String code){
|
||||
this.initAreaList();
|
||||
if(this.areaList!=null || this.areaList.size()>0){
|
||||
List<String> ls = new ArrayList<String>();
|
||||
getAreaByCode(code,ls);
|
||||
return String.join("/",ls);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getCode(String text){
|
||||
this.initAreaList();
|
||||
if(areaList!=null || areaList.size()>0){
|
||||
for(int i=areaList.size()-1;i>=0;i--){
|
||||
if(text.indexOf(areaList.get(i).getText())>=0){
|
||||
return areaList.get(i).getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void getAreaByCode(String code,List<String> ls){
|
||||
for(Area area: areaList){
|
||||
if(area.getId().equals(code)){
|
||||
String pid = area.getPid();
|
||||
ls.add(0,area.getText());
|
||||
getAreaByCode(pid,ls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initAreaList(){
|
||||
//System.out.println("=====================");
|
||||
if(this.areaList==null || this.areaList.size()==0){
|
||||
this.areaList = new ArrayList<Area>();
|
||||
try {
|
||||
File file = jsonData.getFile();
|
||||
String jsonData = this.jsonRead(file);
|
||||
JSONObject baseJson = JSONObject.parseObject(jsonData);
|
||||
//第一层 省
|
||||
JSONObject provinceJson = baseJson.getJSONObject("86");
|
||||
for(String provinceKey: provinceJson.keySet()){
|
||||
//System.out.println("===="+provinceKey);
|
||||
Area province = new Area(provinceKey,provinceJson.getString(provinceKey),"86");
|
||||
this.areaList.add(province);
|
||||
//第二层 市
|
||||
JSONObject cityJson = baseJson.getJSONObject(provinceKey);
|
||||
for(String cityKey:cityJson.keySet()){
|
||||
//System.out.println("-----"+cityKey);
|
||||
Area city = new Area(cityKey,cityJson.getString(cityKey),provinceKey);
|
||||
this.areaList.add(city);
|
||||
//第三层 区
|
||||
JSONObject areaJson = baseJson.getJSONObject(cityKey);
|
||||
if(areaJson!=null){
|
||||
for(String areaKey:areaJson.keySet()){
|
||||
//System.out.println("········"+areaKey);
|
||||
Area area = new Area(areaKey,areaJson.getString(areaKey),cityKey);
|
||||
this.areaList.add(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String jsonRead(File file){
|
||||
Scanner scanner = null;
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
try {
|
||||
scanner = new Scanner(file, "utf-8");
|
||||
while (scanner.hasNextLine()) {
|
||||
buffer.append(scanner.nextLine());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
class Area{
|
||||
String id;
|
||||
String text;
|
||||
String pid;
|
||||
|
||||
public Area(String id,String text,String pid){
|
||||
this.id = id;
|
||||
this.text = text;
|
||||
this.pid = pid;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getPid() {
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package org.jeecg.common.constant;
|
||||
|
||||
/**
|
||||
* @Description: Websocket常量类
|
||||
* @author: taoyan
|
||||
* @date: 2020年03月23日
|
||||
*/
|
||||
public class WebsocketConst {
|
||||
|
||||
|
||||
/**
|
||||
* 消息json key:cmd
|
||||
*/
|
||||
public static final String MSG_CMD = "cmd";
|
||||
|
||||
/**
|
||||
* 消息json key:msgId
|
||||
*/
|
||||
public static final String MSG_ID = "msgId";
|
||||
|
||||
/**
|
||||
* 消息json key:msgTxt
|
||||
*/
|
||||
public static final String MSG_TXT = "msgTxt";
|
||||
|
||||
/**
|
||||
* 消息json key:userId
|
||||
*/
|
||||
public static final String MSG_USER_ID = "userId";
|
||||
|
||||
/**
|
||||
* 消息类型 heartcheck
|
||||
*/
|
||||
public static final String CMD_CHECK = "heartcheck";
|
||||
|
||||
/**
|
||||
* 消息类型 user 用户消息
|
||||
*/
|
||||
public static final String CMD_USER = "user";
|
||||
|
||||
/**
|
||||
* 消息类型 topic 系统通知
|
||||
*/
|
||||
public static final String CMD_TOPIC = "topic";
|
||||
|
||||
/**
|
||||
* 消息类型 email
|
||||
*/
|
||||
public static final String CMD_EMAIL = "email";
|
||||
|
||||
/**
|
||||
* 消息类型 meetingsign 会议签到
|
||||
*/
|
||||
public static final String CMD_SIGN = "sign";
|
||||
|
||||
}
|
||||
@ -1,398 +1,481 @@
|
||||
//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.jeecg.common.util.oConvertUtils;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等)
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JeecgElasticsearchTemplate {
|
||||
/** es服务地址 */
|
||||
private String baseUrl;
|
||||
private final String FORMAT_JSON = "format=json";
|
||||
|
||||
// ElasticSearch 最大可返回条目数
|
||||
public static final int ES_MAX_SIZE = 10000;
|
||||
|
||||
public JeecgElasticsearchTemplate(@Value("${jeecg.elasticsearch.cluster-nodes}") String baseUrl, @Value("${jeecg.elasticsearch.check-enabled}") boolean checkEnabled) {
|
||||
log.debug("JeecgElasticsearchTemplate BaseURL:" + baseUrl);
|
||||
if (StringUtils.isNotEmpty(baseUrl)) {
|
||||
this.baseUrl = baseUrl;
|
||||
// 验证配置的ES地址是否有效
|
||||
if (checkEnabled) {
|
||||
try {
|
||||
RestUtil.get(this.getBaseUrl().toString());
|
||||
log.info("ElasticSearch 服务连接成功");
|
||||
} catch (Exception e) {
|
||||
log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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() {
|
||||
return getIndices(null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询单个索引
|
||||
* <p>
|
||||
* 查询地址:GET http://{baseUrl}/_cat/indices/{indexName}
|
||||
*/
|
||||
public JSONArray getIndices(String indexName) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID获取索引数据,未查询到返回null
|
||||
* <p>
|
||||
* 查询地址:GET http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
||||
*
|
||||
* @param indexName 索引名称
|
||||
* @param typeName type,一个任意字符串,用于分类
|
||||
* @param dataId 数据id
|
||||
* @return
|
||||
*/
|
||||
public JSONObject getDataById(String indexName, String typeName, String dataId) {
|
||||
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString();
|
||||
log.info("url:" + url);
|
||||
JSONObject result = RestUtil.get(url);
|
||||
boolean found = result.getBoolean("found");
|
||||
if (found) {
|
||||
return result.getJSONObject("_source");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建索引
|
||||
* <p>
|
||||
* 查询地址:PUT http://{baseUrl}/{indexName}
|
||||
*/
|
||||
public boolean createIndex(String indexName) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取索引字段映射(可获取字段类型)
|
||||
* <p>
|
||||
*
|
||||
* @param indexName 索引名称
|
||||
* @param typeName 分类名称
|
||||
* @return
|
||||
*/
|
||||
public JSONObject getIndexMapping(String indexName, String typeName) {
|
||||
String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString();
|
||||
log.info("getIndexMapping-url:" + url);
|
||||
/*
|
||||
* 参考返回JSON结构:
|
||||
*
|
||||
*{
|
||||
* // 索引名称
|
||||
* "[indexName]": {
|
||||
* "mappings": {
|
||||
* // 分类名称
|
||||
* "[typeName]": {
|
||||
* "properties": {
|
||||
* // 字段名
|
||||
* "input_number": {
|
||||
* // 字段类型
|
||||
* "type": "long"
|
||||
* },
|
||||
* "input_string": {
|
||||
* "type": "text",
|
||||
* "fields": {
|
||||
* "keyword": {
|
||||
* "type": "keyword",
|
||||
* "ignore_above": 256
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
try {
|
||||
return RestUtil.get(url);
|
||||
} catch (org.springframework.web.client.HttpClientErrorException e) {
|
||||
String message = e.getMessage();
|
||||
if (message != null && message.contains("404 Not Found")) {
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取索引字段映射,返回Java实体类
|
||||
*
|
||||
* @param indexName
|
||||
* @param typeName
|
||||
* @return
|
||||
*/
|
||||
public <T> Map<String, T> getIndexMappingFormat(String indexName, String typeName, Class<T> clazz) {
|
||||
JSONObject mapping = this.getIndexMapping(indexName, typeName);
|
||||
Map<String, T> map = new HashMap<>();
|
||||
if (mapping == null) {
|
||||
return map;
|
||||
}
|
||||
// 获取字段属性
|
||||
JSONObject properties = mapping.getJSONObject(indexName)
|
||||
.getJSONObject("mappings")
|
||||
.getJSONObject(typeName)
|
||||
.getJSONObject("properties");
|
||||
// 封装成 java类型
|
||||
for (String key : properties.keySet()) {
|
||||
T entity = properties.getJSONObject(key).toJavaObject(clazz);
|
||||
map.put(key, entity);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据,详见:saveOrUpdate
|
||||
*/
|
||||
public boolean save(String indexName, String typeName, String dataId, JSONObject data) {
|
||||
return this.saveOrUpdate(indexName, typeName, dataId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据,详见:saveOrUpdate
|
||||
*/
|
||||
public boolean update(String indexName, String typeName, String dataId, JSONObject data) {
|
||||
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) {
|
||||
String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).append("?refresh=wait_for").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);
|
||||
//1、剔除空值
|
||||
if (oConvertUtils.isEmpty(value) || "[]".equals(value)) {
|
||||
emptyKeys.add(key);
|
||||
}
|
||||
//2、剔除上传控件值(会导致ES同步失败,报异常failed to parse field [ge_pic] of type [text] )
|
||||
if (oConvertUtils.isNotEmpty(value) && value.indexOf("[{")!=-1) {
|
||||
emptyKeys.add(key);
|
||||
log.info("-------剔除上传控件字段------------key: "+ key);
|
||||
}
|
||||
}
|
||||
for (String key : emptyKeys) {
|
||||
data.remove(key);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
String result = RestUtil.put(url, data).getString("result");
|
||||
return "created".equals(result) || "updated".equals(result);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage() + "\n-- url: " + url + "\n-- data: " + data.toJSONString());
|
||||
//TODO 打印接口返回异常json
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除索引数据
|
||||
* <p>
|
||||
* 请求地址:DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId}
|
||||
*/
|
||||
public boolean delete(String indexName, String typeName, String dataId) {
|
||||
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) {
|
||||
String url = this.getBaseUrl(indexName, typeName).append("/_search").toString();
|
||||
|
||||
log.info("url:" + url + " ,search: " + queryObject.toJSONString());
|
||||
JSONObject res = RestUtil.post(url, queryObject);
|
||||
log.info("url:" + url + " ,return res: \n" + res.toJSONString());
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param _source (源滤波器)指定返回的字段,传null返回所有字段
|
||||
* @param query
|
||||
* @param from 从第几条数据开始
|
||||
* @param size 返回条目数
|
||||
* @return { "query": query }
|
||||
*/
|
||||
public JSONObject buildQuery(List<String> _source, JSONObject query, int from, int size) {
|
||||
JSONObject json = new JSONObject();
|
||||
if (_source != null) {
|
||||
json.put("_source", _source);
|
||||
}
|
||||
json.put("query", query);
|
||||
json.put("from", from);
|
||||
json.put("size", size);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -9,22 +9,84 @@ public class QueryStringBuilder {
|
||||
|
||||
StringBuilder builder;
|
||||
|
||||
public QueryStringBuilder(String field, String str) {
|
||||
builder = new StringBuilder(field).append(":(").append(str);
|
||||
public QueryStringBuilder(String field, String str, boolean not, boolean addQuot) {
|
||||
builder = this.createBuilder(field, str, not, addQuot);
|
||||
}
|
||||
|
||||
public QueryStringBuilder(String field, String str, boolean not) {
|
||||
builder = this.createBuilder(field, str, not, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 StringBuilder
|
||||
*
|
||||
* @param field
|
||||
* @param str
|
||||
* @param not 是否是不匹配
|
||||
* @param addQuot 是否添加双引号
|
||||
* @return
|
||||
*/
|
||||
public StringBuilder createBuilder(String field, String str, boolean not, boolean addQuot) {
|
||||
StringBuilder sb = new StringBuilder(field).append(":(");
|
||||
if (not) {
|
||||
sb.append(" NOT ");
|
||||
}
|
||||
this.addQuotEffect(sb, str, addQuot);
|
||||
return sb;
|
||||
}
|
||||
|
||||
public QueryStringBuilder and(String str) {
|
||||
builder.append(" AND ").append(str);
|
||||
return this.and(str, true);
|
||||
}
|
||||
|
||||
public QueryStringBuilder and(String str, boolean addQuot) {
|
||||
builder.append(" AND ");
|
||||
this.addQuot(str, addQuot);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryStringBuilder or(String str) {
|
||||
builder.append(" OR ").append(str);
|
||||
return this.or(str, true);
|
||||
}
|
||||
|
||||
public QueryStringBuilder or(String str, boolean addQuot) {
|
||||
builder.append(" OR ");
|
||||
this.addQuot(str, addQuot);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryStringBuilder not(String str) {
|
||||
builder.append(" NOT ").append(str);
|
||||
return this.not(str, true);
|
||||
}
|
||||
|
||||
public QueryStringBuilder not(String str, boolean addQuot) {
|
||||
builder.append(" NOT ");
|
||||
this.addQuot(str, addQuot);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加双引号(模糊查询,不能加双引号)
|
||||
*/
|
||||
private QueryStringBuilder addQuot(String str, boolean addQuot) {
|
||||
return this.addQuotEffect(this.builder, str, addQuot);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否在两边加上双引号
|
||||
* @param builder
|
||||
* @param str
|
||||
* @param addQuot
|
||||
* @return
|
||||
*/
|
||||
private QueryStringBuilder addQuotEffect(StringBuilder builder, String str, boolean addQuot) {
|
||||
if (addQuot) {
|
||||
builder.append('"');
|
||||
}
|
||||
builder.append(str);
|
||||
if (addQuot) {
|
||||
builder.append('"');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@ -5,9 +5,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import org.jeecg.common.system.vo.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @Description: 底层共通业务API,提供其他独立模块调用
|
||||
* @Author: scott
|
||||
@ -96,7 +99,13 @@ public interface ISysBaseAPI {
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryAllDepartBackDictModel();
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有部门,拼接查询条件
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryAllDepart(Wrapper wrapper);
|
||||
|
||||
/**
|
||||
* 发送系统消息
|
||||
* @param fromUser 发送人(用户登录账户)
|
||||
@ -184,6 +193,7 @@ public interface ISysBaseAPI {
|
||||
* @param keyArray
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray);
|
||||
|
||||
/**
|
||||
@ -199,6 +209,13 @@ public interface ISysBaseAPI {
|
||||
*/
|
||||
public JSONObject queryAllUser(String[] userIds, int pageNo, int pageSize);
|
||||
|
||||
/**
|
||||
* 获取所有有效用户 拼接查询条件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<JSONObject> queryAllUser(Wrapper wrapper);
|
||||
|
||||
/**
|
||||
* 获取所有角色
|
||||
* @return
|
||||
@ -271,4 +288,49 @@ public interface ISysBaseAPI {
|
||||
*/
|
||||
public String upload(MultipartFile file,String bizPath,String uploadType);
|
||||
|
||||
/**
|
||||
* 文件上传 自定义桶
|
||||
* @param file
|
||||
* @param bizPath
|
||||
* @param uploadType
|
||||
* @param customBucket
|
||||
* @return
|
||||
*/
|
||||
public String upload(MultipartFile file,String bizPath,String uploadType,String customBucket);
|
||||
|
||||
/**
|
||||
* 文档管理文件下载预览
|
||||
* @param filePath
|
||||
* @param uploadpath
|
||||
* @param response
|
||||
*/
|
||||
public void viewAndDownload(String filePath, String uploadpath, String uploadType,HttpServletResponse response);
|
||||
|
||||
|
||||
/**
|
||||
* 给指定用户发消息
|
||||
* @param userIds
|
||||
* @param cmd
|
||||
*/
|
||||
public void sendWebSocketMsg(String[] userIds, String cmd);
|
||||
|
||||
/**
|
||||
* 根据id获取所有参与用户
|
||||
* userIds
|
||||
* @return
|
||||
*/
|
||||
public List<LoginUser> queryAllUserByIds(String[] userIds);
|
||||
/**
|
||||
* 将会议签到信息推动到预览
|
||||
* userIds
|
||||
* @return
|
||||
* @param userId
|
||||
*/
|
||||
void meetingSignWebsocket(String userId);
|
||||
/**
|
||||
* 根据name获取所有参与用户
|
||||
* userNames
|
||||
* @return
|
||||
*/
|
||||
List<LoginUser> queryUserByNames(String[] userNames);
|
||||
}
|
||||
|
||||
@ -1,21 +1,11 @@
|
||||
package org.jeecg.common.system.base.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.base.entity.JeecgEntity;
|
||||
import org.jeecg.common.system.base.service.JeecgService;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
@ -29,9 +19,13 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Description: Controller基类
|
||||
|
||||
@ -1,35 +1,34 @@
|
||||
package org.jeecg.common.system.controller;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.RestUtil;
|
||||
import org.jeecg.common.util.TokenUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -80,15 +79,25 @@ public class CommonController {
|
||||
MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
|
||||
if(oConvertUtils.isEmpty(bizPath)){
|
||||
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
||||
result.setMessage("使用阿里云文件上传时,必须添加目录!");
|
||||
result.setSuccess(false);
|
||||
return result;
|
||||
//未指定目录,则用阿里云默认目录 upload
|
||||
bizPath = "upload";
|
||||
//result.setMessage("使用阿里云文件上传时,必须添加目录!");
|
||||
//result.setSuccess(false);
|
||||
//return result;
|
||||
}else{
|
||||
bizPath = "";
|
||||
}
|
||||
}
|
||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||
savePath = this.uploadLocal(file,bizPath);
|
||||
//针对jeditor编辑器如何使 lcaol模式,采用 base64格式存储
|
||||
String jeditor = request.getParameter("jeditor");
|
||||
if(oConvertUtils.isNotEmpty(jeditor)){
|
||||
result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL);
|
||||
result.setSuccess(true);
|
||||
return result;
|
||||
}else{
|
||||
savePath = this.uploadLocal(file,bizPath);
|
||||
}
|
||||
}else{
|
||||
savePath = sysBaseAPI.upload(file,bizPath,uploadType);
|
||||
}
|
||||
@ -117,7 +126,12 @@ public class CommonController {
|
||||
file.mkdirs();// 创建文件根目录
|
||||
}
|
||||
String orgName = mf.getOriginalFilename();// 获取文件名
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
if(orgName.indexOf(".")!=-1){
|
||||
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
}else{
|
||||
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(mf.getBytes(), savefile);
|
||||
@ -185,6 +199,9 @@ public class CommonController {
|
||||
public void view(HttpServletRequest request, HttpServletResponse response) {
|
||||
// ISO-8859-1 ==> UTF-8 进行编码转换
|
||||
String imgPath = extractPathFromPattern(request);
|
||||
if(oConvertUtils.isEmpty(imgPath) || imgPath=="null"){
|
||||
return;
|
||||
}
|
||||
// 其余处理略
|
||||
InputStream inputStream = null;
|
||||
OutputStream outputStream = null;
|
||||
@ -194,8 +211,11 @@ public class CommonController {
|
||||
imgPath = imgPath.substring(0, imgPath.length() - 1);
|
||||
}
|
||||
String filePath = uploadpath + File.separator + imgPath;
|
||||
String downloadFilePath = uploadpath + File.separator + filePath;
|
||||
File file = new File(downloadFilePath);
|
||||
File file = new File(filePath);
|
||||
if(!file.exists()){
|
||||
response.setStatus(404);
|
||||
throw new RuntimeException("文件不存在..");
|
||||
}
|
||||
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));
|
||||
@ -208,7 +228,8 @@ public class CommonController {
|
||||
response.flushBuffer();
|
||||
} catch (IOException e) {
|
||||
log.error("预览文件失败" + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
response.setStatus(404);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
@ -309,4 +330,53 @@ public class CommonController {
|
||||
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 中转HTTP请求,解决跨域问题
|
||||
*
|
||||
* @param url 必填:请求地址
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/transitRESTful")
|
||||
public Result transitRESTful(@RequestParam("url") String url, HttpServletRequest request) {
|
||||
try {
|
||||
ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
|
||||
// 中转请求method、body
|
||||
HttpMethod method = httpRequest.getMethod();
|
||||
JSONObject params;
|
||||
try {
|
||||
params = JSON.parseObject(JSON.toJSONString(httpRequest.getBody()));
|
||||
} catch (Exception e) {
|
||||
params = new JSONObject();
|
||||
}
|
||||
// 中转请求问号参数
|
||||
JSONObject variables = JSON.parseObject(JSON.toJSONString(request.getParameterMap()));
|
||||
variables.remove("url");
|
||||
// 在 headers 里传递Token
|
||||
String token = TokenUtils.getTokenByRequest(request);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("X-Access-Token", token);
|
||||
// 发送请求
|
||||
String httpURL = URLDecoder.decode(url, "UTF-8");
|
||||
ResponseEntity<String> response = RestUtil.request(httpURL, method, headers , variables, params, String.class);
|
||||
// 封装返回结果
|
||||
Result<Object> result = new Result<>();
|
||||
int statusCode = response.getStatusCodeValue();
|
||||
result.setCode(statusCode);
|
||||
result.setSuccess(statusCode == 200);
|
||||
String responseBody = response.getBody();
|
||||
try {
|
||||
// 尝试将返回结果转为JSON
|
||||
Object json = JSON.parse(responseBody);
|
||||
result.setResult(json);
|
||||
} catch (Exception e) {
|
||||
// 转成JSON失败,直接返回原始数据
|
||||
result.setResult(responseBody);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.debug("中转HTTP请求失败", e);
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,20 +1,8 @@
|
||||
package org.jeecg.common.system.query;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLDecoder;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.DataBaseConstant;
|
||||
@ -22,15 +10,21 @@ import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.util.JeecgDataAutorUtils;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.SysPermissionDataRuleModel;
|
||||
import org.jeecg.common.util.DateUtils;
|
||||
import org.jeecg.common.util.SqlInjectionUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecgframework.core.util.ApplicationContextUtil;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLDecoder;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Slf4j
|
||||
public class QueryGenerator {
|
||||
@ -38,6 +32,10 @@ public class QueryGenerator {
|
||||
|
||||
private static final String BEGIN = "_begin";
|
||||
private static final String END = "_end";
|
||||
/**
|
||||
* 数字类型字段,拼接此后缀 接受多值参数
|
||||
*/
|
||||
private static final String MULTI = "_MultiString";
|
||||
private static final String STAR = "*";
|
||||
private static final String COMMA = ",";
|
||||
private static final String NOT_EQUAL = "!";
|
||||
@ -45,7 +43,10 @@ public class QueryGenerator {
|
||||
private static final String QUERY_SEPARATE_KEYWORD = " ";
|
||||
/**高级查询前端传来的参数名*/
|
||||
private static final String SUPER_QUERY_PARAMS = "superQueryParams";
|
||||
|
||||
/** 高级查询前端传来的拼接方式参数名 */
|
||||
private static final String SUPER_QUERY_MATCH_TYPE = "superQueryMatchType";
|
||||
/** 单引号 */
|
||||
public static final String SQL_SQ = "'";
|
||||
/**排序列*/
|
||||
private static final String ORDER_COLUMN = "column";
|
||||
/**排序方式*/
|
||||
@ -131,7 +132,12 @@ public class QueryGenerator {
|
||||
endValue = parameterMap.get(name + END)[0].trim();
|
||||
addQueryByRule(queryWrapper, name, type, endValue, QueryRuleEnum.LE);
|
||||
}
|
||||
|
||||
//多值查询
|
||||
if (parameterMap != null && parameterMap.containsKey(name + MULTI)) {
|
||||
endValue = parameterMap.get(name + MULTI)[0].trim();
|
||||
addQueryByRule(queryWrapper, name.replace(MULTI,""), type, endValue, QueryRuleEnum.IN);
|
||||
}
|
||||
|
||||
//判断单值 参数带不同标识字符串 走不同的查询
|
||||
//TODO 这种前后带逗号的支持分割后模糊查询需要否 使多选字段的查询生效
|
||||
Object value = PropertyUtils.getSimpleProperty(searchObj, name);
|
||||
@ -209,21 +215,43 @@ public class QueryGenerator {
|
||||
public static void doSuperQuery(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap) {
|
||||
if(parameterMap!=null&& parameterMap.containsKey(SUPER_QUERY_PARAMS)){
|
||||
String superQueryParams = parameterMap.get(SUPER_QUERY_PARAMS)[0];
|
||||
// 解码
|
||||
try {
|
||||
superQueryParams = URLDecoder.decode(superQueryParams, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("--高级查询参数转码失败!", e);
|
||||
}
|
||||
List<QueryCondition> conditions = JSON.parseArray(superQueryParams, QueryCondition.class);
|
||||
log.info("---高级查询参数-->"+conditions.toString());
|
||||
|
||||
for (QueryCondition rule : conditions) {
|
||||
if(oConvertUtils.isNotEmpty(rule.getField()) && oConvertUtils.isNotEmpty(rule.getRule()) && oConvertUtils.isNotEmpty(rule.getVal())){
|
||||
addEasyQuery(queryWrapper, rule.getField(), QueryRuleEnum.getByValue(rule.getRule()), rule.getVal());
|
||||
}
|
||||
}
|
||||
String superQueryMatchType = parameterMap.get(SUPER_QUERY_MATCH_TYPE) != null ? parameterMap.get(SUPER_QUERY_MATCH_TYPE)[0] : MatchTypeEnum.AND.getValue();
|
||||
MatchTypeEnum matchType = MatchTypeEnum.getByValue(superQueryMatchType);
|
||||
// update-begin--Author:sunjianlei Date:20200325 for:高级查询的条件要用括号括起来,防止和用户的其他条件冲突 -------
|
||||
try {
|
||||
superQueryParams = URLDecoder.decode(superQueryParams, "UTF-8");
|
||||
List<QueryCondition> conditions = JSON.parseArray(superQueryParams, QueryCondition.class);
|
||||
if (conditions == null || conditions.size() == 0) {
|
||||
return;
|
||||
}
|
||||
log.info("---高级查询参数-->" + conditions.toString());
|
||||
queryWrapper.and(andWrapper -> {
|
||||
for (int i = 0; i < conditions.size(); i++) {
|
||||
QueryCondition rule = conditions.get(i);
|
||||
if (oConvertUtils.isNotEmpty(rule.getField())
|
||||
&& oConvertUtils.isNotEmpty(rule.getRule())
|
||||
&& oConvertUtils.isNotEmpty(rule.getVal())) {
|
||||
|
||||
log.debug("SuperQuery ==> " + rule.toString());
|
||||
addEasyQuery(andWrapper, rule.getField(), QueryRuleEnum.getByValue(rule.getRule()), rule.getVal());
|
||||
|
||||
// 如果拼接方式是OR,就拼接OR
|
||||
if (MatchTypeEnum.OR == matchType && i < (conditions.size() - 1)) {
|
||||
andWrapper.or();
|
||||
}
|
||||
}
|
||||
}
|
||||
return andWrapper;
|
||||
});
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("--高级查询参数转码失败:" + superQueryParams, e);
|
||||
} catch (Exception e) {
|
||||
log.error("--高级查询拼接失败:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
// update-end--Author:sunjianlei Date:20200325 for:高级查询的条件要用括号括起来,防止和用户的其他条件冲突 -------
|
||||
}
|
||||
//log.info(" superQuery getCustomSqlSegment: "+ queryWrapper.getCustomSqlSegment());
|
||||
}
|
||||
/**
|
||||
* 根据所传的值 转化成对应的比较方式
|
||||
@ -319,6 +347,13 @@ public class QueryGenerator {
|
||||
private static void addQueryByRule(QueryWrapper<?> queryWrapper,String name,String type,String value,QueryRuleEnum rule) throws ParseException {
|
||||
if(oConvertUtils.isNotEmpty(value)) {
|
||||
Object temp;
|
||||
// 针对数字类型字段,多值查询
|
||||
if(value.indexOf(COMMA)!=-1){
|
||||
temp = value;
|
||||
addEasyQuery(queryWrapper, name, rule, temp);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case "class java.lang.Integer":
|
||||
temp = Integer.parseInt(value);
|
||||
@ -476,7 +511,14 @@ public class QueryGenerator {
|
||||
}else {
|
||||
if (propertyType.equals(String.class)) {
|
||||
addEasyQuery(queryWrapper, name, rule, converRuleValue(dataRule.getRuleValue()));
|
||||
} else {
|
||||
}else if (propertyType.equals(Date.class)) {
|
||||
String dateStr =converRuleValue(dataRule.getRuleValue());
|
||||
if(dateStr.length()==10){
|
||||
addEasyQuery(queryWrapper, name, rule, DateUtils.str2Date(dateStr,DateUtils.date_sdf.get()));
|
||||
}else{
|
||||
addEasyQuery(queryWrapper, name, rule, DateUtils.str2Date(dateStr,DateUtils.datetimeFormat.get()));
|
||||
}
|
||||
}else {
|
||||
addEasyQuery(queryWrapper, name, rule, NumberUtils.parseNumber(dataRule.getRuleValue(), propertyType));
|
||||
}
|
||||
}
|
||||
@ -489,6 +531,26 @@ public class QueryGenerator {
|
||||
}
|
||||
return value!= null ? value : ruleValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author: scott
|
||||
* @Description: 去掉值前后单引号
|
||||
* @date: 2020/3/19 21:26
|
||||
* @param ruleValue:
|
||||
* @Return: java.lang.String
|
||||
*/
|
||||
public static String trimSingleQuote(String ruleValue) {
|
||||
if (oConvertUtils.isEmpty(ruleValue)) {
|
||||
return "";
|
||||
}
|
||||
if (ruleValue.startsWith(QueryGenerator.SQL_SQ)) {
|
||||
ruleValue = ruleValue.substring(1);
|
||||
}
|
||||
if (ruleValue.endsWith(QueryGenerator.SQL_SQ)) {
|
||||
ruleValue = ruleValue.substring(0, ruleValue.length() - 1);
|
||||
}
|
||||
return ruleValue;
|
||||
}
|
||||
|
||||
public static String getSqlRuleValue(String sqlRule){
|
||||
try {
|
||||
@ -642,9 +704,17 @@ public class QueryGenerator {
|
||||
}else {
|
||||
if(str.indexOf("%")>=0) {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
return "N"+str;
|
||||
if(str.startsWith("'") && str.endsWith("'")){
|
||||
return "N"+str;
|
||||
}else{
|
||||
return "N"+"'"+str+"'";
|
||||
}
|
||||
}else{
|
||||
return str;
|
||||
if(str.startsWith("'") && str.endsWith("'")){
|
||||
return str;
|
||||
}else{
|
||||
return "'"+str+"'";
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
|
||||
@ -726,6 +796,50 @@ public class QueryGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换sql中的系统变量
|
||||
* @param sql
|
||||
* @return
|
||||
*/
|
||||
public static String convertSystemVariables(String sql){
|
||||
return getSqlRuleValue(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有配置的权限 返回sql字符串 不受字段限制 配置什么就拿到什么
|
||||
* @return
|
||||
*/
|
||||
public static String getAllConfigAuth() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
//权限查询
|
||||
Map<String,SysPermissionDataRuleModel> ruleMap = getRuleMap();
|
||||
String sql_and = " and ";
|
||||
for (String c : ruleMap.keySet()) {
|
||||
SysPermissionDataRuleModel dataRule = ruleMap.get(c);
|
||||
String ruleValue = dataRule.getRuleValue();
|
||||
if(oConvertUtils.isEmpty(ruleValue)){
|
||||
continue;
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){
|
||||
sb.append(sql_and+getSqlRuleValue(ruleValue));
|
||||
}else{
|
||||
boolean isString = false;
|
||||
ruleValue = ruleValue.trim();
|
||||
if(ruleValue.startsWith("'") && ruleValue.endsWith("'")){
|
||||
isString = true;
|
||||
ruleValue = ruleValue.substring(1,ruleValue.length()-1);
|
||||
}
|
||||
QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
|
||||
String value = converRuleValue(ruleValue);
|
||||
String filedSql = getSingleSqlByRule(rule, c, value,isString);
|
||||
sb.append(sql_and+filedSql);
|
||||
}
|
||||
}
|
||||
log.info("query auth sql is = "+sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** 当前系统数据库类型 */
|
||||
private static String DB_TYPE;
|
||||
|
||||
@ -147,7 +147,7 @@ public class JwtUtil {
|
||||
key = key;
|
||||
}
|
||||
//替换为系统登录用户帐号
|
||||
if (key.equals(DataBaseConstant.SYS_USER_CODE)|| key.equals(DataBaseConstant.SYS_USER_CODE_TABLE)) {
|
||||
if (key.equals(DataBaseConstant.SYS_USER_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_USER_CODE_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getUsername();
|
||||
}else {
|
||||
@ -155,7 +155,7 @@ public class JwtUtil {
|
||||
}
|
||||
}
|
||||
//替换为系统登录用户真实名字
|
||||
else if (key.equals(DataBaseConstant.SYS_USER_NAME)|| key.equals(DataBaseConstant.SYS_USER_NAME_TABLE)) {
|
||||
else if (key.equals(DataBaseConstant.SYS_USER_NAME)|| key.toLowerCase().equals(DataBaseConstant.SYS_USER_NAME_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getRealname();
|
||||
}else {
|
||||
@ -164,7 +164,7 @@ public class JwtUtil {
|
||||
}
|
||||
|
||||
//替换为系统用户登录所使用的机构编码
|
||||
else if (key.equals(DataBaseConstant.SYS_ORG_CODE)|| key.equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) {
|
||||
else if (key.equals(DataBaseConstant.SYS_ORG_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) {
|
||||
if(user==null) {
|
||||
returnValue = sysUser.getOrgCode();
|
||||
}else {
|
||||
@ -172,7 +172,7 @@ public class JwtUtil {
|
||||
}
|
||||
}
|
||||
//替换为系统用户所拥有的所有机构编码
|
||||
else if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE)|| key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) {
|
||||
else if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE)|| key.toLowerCase().equals(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) {
|
||||
if(user.isOneDepart()) {
|
||||
returnValue = user.getSysMultiOrgCode().get(0);
|
||||
}else {
|
||||
@ -180,15 +180,15 @@ public class JwtUtil {
|
||||
}
|
||||
}
|
||||
//替换为当前系统时间(年月日)
|
||||
else if (key.equals(DataBaseConstant.SYS_DATE)|| key.equals(DataBaseConstant.SYS_DATE_TABLE)) {
|
||||
else if (key.equals(DataBaseConstant.SYS_DATE)|| key.toLowerCase().equals(DataBaseConstant.SYS_DATE_TABLE)) {
|
||||
returnValue = user.getSysDate();
|
||||
}
|
||||
//替换为当前系统时间(年月日时分秒)
|
||||
else if (key.equals(DataBaseConstant.SYS_TIME)|| key.equals(DataBaseConstant.SYS_TIME_TABLE)) {
|
||||
else if (key.equals(DataBaseConstant.SYS_TIME)|| key.toLowerCase().equals(DataBaseConstant.SYS_TIME_TABLE)) {
|
||||
returnValue = user.getSysTime();
|
||||
}
|
||||
//流程状态默认值(默认未发起)
|
||||
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.equals(DataBaseConstant.BPM_STATUS_TABLE)) {
|
||||
else if (key.equals(DataBaseConstant.BPM_STATUS)|| key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) {
|
||||
returnValue = "1";
|
||||
}
|
||||
if(returnValue!=null){returnValue = returnValue + moshi;}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 字典查询参数实体
|
||||
*/
|
||||
@Data
|
||||
public class DictQuery {
|
||||
/**
|
||||
* 表名
|
||||
*/
|
||||
private String table;
|
||||
/**
|
||||
* 存储列
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 显示列
|
||||
*/
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* 关键字查询
|
||||
*/
|
||||
private String keyword;
|
||||
|
||||
/**
|
||||
* 存储列的值 用于回显查询
|
||||
*/
|
||||
private String codeValue;
|
||||
|
||||
}
|
||||
@ -79,11 +79,11 @@ public class LoginUser {
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
private String delFlag;
|
||||
private Integer delFlag;
|
||||
/**
|
||||
* 同步工作流引擎1同步0不同步
|
||||
*/
|
||||
private String activitiSync;
|
||||
private Integer activitiSync;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
@ -93,11 +93,21 @@ public class LoginUser {
|
||||
/**
|
||||
* 身份(1 普通员工 2 上级)
|
||||
*/
|
||||
private Integer identity;
|
||||
private Integer userIdentity;
|
||||
|
||||
/**
|
||||
* 管理部门ids
|
||||
*/
|
||||
private String departIds;
|
||||
|
||||
/**
|
||||
* 职务,关联职务表
|
||||
*/
|
||||
private String post;
|
||||
|
||||
/**
|
||||
* 座机号
|
||||
*/
|
||||
private String telephone;
|
||||
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ public class SysDepartModel {
|
||||
/**排序*/
|
||||
private Integer departOrder;
|
||||
/**描述*/
|
||||
private Object description;
|
||||
private String description;
|
||||
/**机构类别 1组织机构,2岗位*/
|
||||
private String orgCategory;
|
||||
/**机构类型*/
|
||||
@ -81,11 +81,11 @@ public class SysDepartModel {
|
||||
this.departOrder = departOrder;
|
||||
}
|
||||
|
||||
public Object getDescription() {
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(Object description) {
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
@ -191,4 +191,16 @@ public class BrowserUtils {
|
||||
return browserLangCode;
|
||||
}
|
||||
|
||||
/** 判断请求是否来自电脑端 */
|
||||
public static boolean isDesktop(HttpServletRequest request) {
|
||||
return !isMobile(request);
|
||||
}
|
||||
|
||||
/** 判断请求是否来自移动端 */
|
||||
public static boolean isMobile(HttpServletRequest request) {
|
||||
String ua = request.getHeader("User-Agent").toLowerCase();
|
||||
Pattern pattern = Pattern.compile("(phone|pad|pod|iphone|ipod|ios|ipad|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|webos|symbian|windows phone)");
|
||||
return pattern.matcher(ua).find();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.oss.OssBootUtil;
|
||||
import org.jeecgframework.poi.util.PoiPublicUtil;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class CommonUtils {
|
||||
|
||||
public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){
|
||||
String dbPath = null;
|
||||
String fileName = "image" + Math.round(Math.random() * 100000000000L);
|
||||
fileName += "." + PoiPublicUtil.getFileExtendName(data);
|
||||
try {
|
||||
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
|
||||
File file = new File(basePath + File.separator + bizPath + File.separator );
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();// 创建文件根目录
|
||||
}
|
||||
String savePath = file.getPath() + File.separator + fileName;
|
||||
File savefile = new File(savePath);
|
||||
FileCopyUtils.copy(data, savefile);
|
||||
dbPath = bizPath + File.separator + fileName;
|
||||
}else {
|
||||
InputStream in = new ByteArrayInputStream(data);
|
||||
String relativePath = bizPath+"/"+fileName;
|
||||
if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){
|
||||
dbPath = MinioUtil.upload(in,relativePath);
|
||||
}else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
|
||||
dbPath = OssBootUtil.upload(in,relativePath);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return dbPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件名是否带盘符,重新处理
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static String getFileName(String fileName){
|
||||
//判断是否带有盘符信息
|
||||
// Check for Unix-style path
|
||||
int unixSep = fileName.lastIndexOf('/');
|
||||
// Check for Windows-style path
|
||||
int winSep = fileName.lastIndexOf('\\');
|
||||
// Cut off at latest possible point
|
||||
int pos = (winSep > unixSep ? winSep : unixSep);
|
||||
if (pos != -1) {
|
||||
// Any sort of path separator found...
|
||||
fileName = fileName.substring(pos + 1);
|
||||
}
|
||||
//替换上传文件名字的特殊字符
|
||||
fileName = fileName.replace("=","").replace(",","").replace("&","");
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 导出返回信息
|
||||
*/
|
||||
@Slf4j
|
||||
public class ImportExcelUtil {
|
||||
|
||||
public static Result<?> imporReturnRes(int errorLines,int successLines,List<String> errorMessage) throws IOException {
|
||||
if (errorLines == 0) {
|
||||
return Result.ok("共" + successLines + "行数据全部导入成功!");
|
||||
} else {
|
||||
JSONObject result = new JSONObject(5);
|
||||
int totalCount = successLines + errorLines;
|
||||
result.put("totalCount", totalCount);
|
||||
result.put("errorCount", errorLines);
|
||||
result.put("successCount", successLines);
|
||||
result.put("msg", "总上传行数:" + totalCount + ",已导入行数:" + successLines + ",错误行数:" + errorLines);
|
||||
String fileUrl = PmsUtil.saveErrorTxtByList(errorMessage, "userImportExcelErrorLog");
|
||||
int lastIndex = fileUrl.lastIndexOf(File.separator);
|
||||
String fileName = fileUrl.substring(lastIndex + 1);
|
||||
result.put("fileUrl", "/sys/common/static/" + fileUrl);
|
||||
result.put("fileName", fileName);
|
||||
Result res = Result.ok(result);
|
||||
res.setCode(201);
|
||||
res.setMessage("文件导入成功,但有错误。");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> importDateSave(List<Object> list, Class serviceClass,List<String> errorMessage,String errorFlag) {
|
||||
IService bean =(IService) SpringContextUtils.getBean(serviceClass);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
try {
|
||||
boolean save = bean.save(list.get(i));
|
||||
if(!save){
|
||||
throw new Exception(errorFlag);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String message = e.getMessage();
|
||||
int lineNumber = i + 1;
|
||||
// 通过索引名判断出错信息
|
||||
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:角色编码已经存在,忽略导入。");
|
||||
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:任务类名已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:职务编码已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:部门编码已经存在,忽略导入。");
|
||||
}else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public static List<String> importDateSaveOne(Object obj, Class serviceClass,List<String> errorMessage,int i,String errorFlag) {
|
||||
IService bean =(IService) SpringContextUtils.getBean(serviceClass);
|
||||
try {
|
||||
boolean save = bean.save(obj);
|
||||
if(!save){
|
||||
throw new Exception(errorFlag);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String message = e.getMessage();
|
||||
int lineNumber = i + 1;
|
||||
// 通过索引名判断出错信息
|
||||
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:角色编码已经存在,忽略导入。");
|
||||
} else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:任务类名已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:职务编码已经存在,忽略导入。");
|
||||
}else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) {
|
||||
errorMessage.add("第 " + lineNumber + " 行:部门编码已经存在,忽略导入。");
|
||||
}else {
|
||||
errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入");
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,208 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.errors.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* minio文件上传工具类
|
||||
*/
|
||||
@Slf4j
|
||||
public class MinioUtil {
|
||||
private static String minioUrl;
|
||||
private static String minioName;
|
||||
private static String minioPass;
|
||||
private static String bucketName;
|
||||
|
||||
public static void setMinioUrl(String minioUrl) {
|
||||
MinioUtil.minioUrl = minioUrl;
|
||||
}
|
||||
|
||||
public static void setMinioName(String minioName) {
|
||||
MinioUtil.minioName = minioName;
|
||||
}
|
||||
|
||||
public static void setMinioPass(String minioPass) {
|
||||
MinioUtil.minioPass = minioPass;
|
||||
}
|
||||
|
||||
public static void setBucketName(String bucketName) {
|
||||
MinioUtil.bucketName = bucketName;
|
||||
}
|
||||
|
||||
public static String getMinioUrl() {
|
||||
return minioUrl;
|
||||
}
|
||||
|
||||
public static String getBucketName() {
|
||||
return bucketName;
|
||||
}
|
||||
|
||||
private static MinioClient minioClient = null;
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static String upload(MultipartFile file, String bizPath, String customBucket) {
|
||||
String file_url = "";
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
initMinio(minioUrl, minioName,minioPass);
|
||||
// 检查存储桶是否已经存在
|
||||
if(minioClient.bucketExists(newBucket)) {
|
||||
log.info("Bucket already exists.");
|
||||
} else {
|
||||
// 创建一个名为ota的存储桶
|
||||
minioClient.makeBucket(newBucket);
|
||||
log.info("create a new bucket.");
|
||||
}
|
||||
InputStream stream = file.getInputStream();
|
||||
// 获取文件名
|
||||
String orgName = file.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String objectName = bizPath+"/"+orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
|
||||
// 使用putObject上传一个本地文件到存储桶中。
|
||||
minioClient.putObject(newBucket,objectName, stream,stream.available(),"application/octet-stream");
|
||||
stream.close();
|
||||
file_url = minioUrl+newBucket+"/"+objectName;
|
||||
}catch (IOException e){
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (InvalidKeyException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (NoResponseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (XmlPullParserException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (InvalidArgumentException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (RegionConflictException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (InvalidBucketNameException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (ErrorResponseException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (InternalException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (InsufficientDataException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return file_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param file
|
||||
* @param bizPath
|
||||
* @return
|
||||
*/
|
||||
public static String upload(MultipartFile file, String bizPath) {
|
||||
return upload(file,bizPath,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件流
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public static InputStream getMinioFile(String bucketName,String objectName){
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
initMinio(minioUrl, minioName, minioPass);
|
||||
inputStream = minioClient.getObject(bucketName, objectName);
|
||||
} catch (Exception e) {
|
||||
log.info("文件获取失败" + e.getMessage());
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void removeObject(String bucketName, String objectName) {
|
||||
try {
|
||||
initMinio(minioUrl, minioName,minioPass);
|
||||
minioClient.removeObject(bucketName, objectName);
|
||||
}catch (Exception e){
|
||||
log.info("文件删除失败" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件外链
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @param expires
|
||||
* @return
|
||||
*/
|
||||
public static String getObjectURL(String bucketName, String objectName, Integer expires) {
|
||||
initMinio(minioUrl, minioName,minioPass);
|
||||
try{
|
||||
String url = minioClient.presignedGetObject(bucketName, objectName, expires);
|
||||
return URLDecoder.decode(url,"UTF-8");
|
||||
}catch (Exception e){
|
||||
log.info("文件路径获取失败" + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化客户端
|
||||
* @param minioUrl
|
||||
* @param minioName
|
||||
* @param minioPass
|
||||
* @return
|
||||
*/
|
||||
private static MinioClient initMinio(String minioUrl, String minioName,String minioPass) {
|
||||
if (minioClient == null) {
|
||||
try {
|
||||
minioClient = new MinioClient(minioUrl, minioName,minioPass);
|
||||
} catch (InvalidEndpointException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidPortException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return minioClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件到minio
|
||||
* @param stream
|
||||
* @param relativePath
|
||||
* @return
|
||||
*/
|
||||
public static String upload(InputStream stream,String relativePath) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InternalException, NoResponseException, InvalidBucketNameException, XmlPullParserException, ErrorResponseException, RegionConflictException, InvalidArgumentException {
|
||||
initMinio(minioUrl, minioName,minioPass);
|
||||
if(minioClient.bucketExists(bucketName)) {
|
||||
log.info("Bucket already exists.");
|
||||
} else {
|
||||
// 创建一个名为ota的存储桶
|
||||
minioClient.makeBucket(bucketName);
|
||||
log.info("create a new bucket.");
|
||||
}
|
||||
minioClient.putObject(bucketName,relativePath, stream, stream.available(),"application/octet-stream");
|
||||
stream.close();
|
||||
return minioUrl+bucketName+"/"+relativePath;
|
||||
}
|
||||
|
||||
}
|
||||
@ -199,7 +199,7 @@ public class ReflectHelper {
|
||||
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());
|
||||
//log.info(fields[i].getType());
|
||||
fieldNames[i] = fields[i].getName();
|
||||
}
|
||||
return fieldNames;
|
||||
|
||||
@ -3,8 +3,11 @@ package org.jeecg.common.util;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
@ -40,7 +43,16 @@ public class RestUtil {
|
||||
/**
|
||||
* RestAPI 调用器
|
||||
*/
|
||||
private final static RestTemplate RT = new RestTemplate();
|
||||
private final static RestTemplate RT;
|
||||
|
||||
static {
|
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
requestFactory.setConnectTimeout(3000);
|
||||
requestFactory.setReadTimeout(3000);
|
||||
RT = new RestTemplate(requestFactory);
|
||||
// 解决乱码问题
|
||||
RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static RestTemplate getRestTemplate() {
|
||||
return RT;
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* sql注入处理工具类
|
||||
@ -9,7 +12,32 @@ import lombok.extern.slf4j.Slf4j;
|
||||
*/
|
||||
@Slf4j
|
||||
public class SqlInjectionUtil {
|
||||
final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|,";
|
||||
/**
|
||||
* sign 用于表字典加签的盐值【SQL漏洞】
|
||||
* (上线修改值 20200501,同步修改前端的盐值)
|
||||
*/
|
||||
private final static String TABLE_DICT_SIGN_SALT = "20200501";
|
||||
private final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|,";
|
||||
|
||||
/*
|
||||
* 针对表字典进行额外的sign签名校验(增加安全机制)
|
||||
* @param dictCode:
|
||||
* @param sign:
|
||||
* @param request:
|
||||
* @Return: void
|
||||
*/
|
||||
public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) {
|
||||
//表字典SQL注入漏洞,签名校验
|
||||
String accessToken = request.getHeader("X-Access-Token");
|
||||
String signStr = dictCode + SqlInjectionUtil.TABLE_DICT_SIGN_SALT + accessToken;
|
||||
String javaSign = SecureUtil.md5(signStr);
|
||||
if (!javaSign.equals(sign)) {
|
||||
log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode);
|
||||
throw new JeecgBootException("无权限访问!");
|
||||
}
|
||||
log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sql注入过滤处理,遇到注入关键字抛异常
|
||||
@ -82,13 +110,13 @@ public class SqlInjectionUtil {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @特殊方法(不通用) 仅用于Online报表SQL解析,注入过滤
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @特殊方法(不通用) 仅用于Online报表SQL解析,注入过滤
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public static void specialFilterContentForOnlineReport(String value) {
|
||||
String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |";
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
package org.jeecg.common.util.dynamic.db;
|
||||
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.vo.DynamicDataSourceModel;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -13,21 +15,15 @@ import java.util.Map;
|
||||
* 数据源缓存池
|
||||
*/
|
||||
public class DataSourceCachePool {
|
||||
/** 数据源连接池缓存【本地 class缓存 - 不支持分布式】 */
|
||||
private static Map<String, DruidDataSource> dbSources = new HashMap<>();
|
||||
private static RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
private static RedisTemplate<String, Object> getRedisTemplate() {
|
||||
if (redisTemplate == null) {
|
||||
redisTemplate = (RedisTemplate<String, Object>) SpringContextUtils.getBean("redisTemplate");
|
||||
}
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,22 +33,19 @@ public class DataSourceCachePool {
|
||||
* @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);
|
||||
String redisCacheKey = CacheConstant.SYS_DYNAMICDB_CACHE + dbKey;
|
||||
if (getRedisTemplate().hasKey(redisCacheKey)) {
|
||||
return (DynamicDataSourceModel) getRedisTemplate().opsForValue().get(redisCacheKey);
|
||||
}
|
||||
ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
|
||||
DynamicDataSourceModel dbSource = sysBaseAPI.getDynamicDbSourceByCode(dbKey);
|
||||
if (dbSource != null) {
|
||||
getRedisTemplate().opsForValue().set(redisCacheKey, dbSource);
|
||||
}
|
||||
return dbSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态数据源连接池【本地class缓存 - 不支持分布式】
|
||||
*/
|
||||
private static Map<String, BasicDataSource> dbSources = new HashMap<>();
|
||||
|
||||
public static BasicDataSource getCacheBasicDataSource(String dbKey) {
|
||||
public static DruidDataSource getCacheBasicDataSource(String dbKey) {
|
||||
return dbSources.get(dbKey);
|
||||
}
|
||||
|
||||
@ -62,26 +55,38 @@ public class DataSourceCachePool {
|
||||
* @param dbKey
|
||||
* @param db
|
||||
*/
|
||||
public static void putCacheBasicDataSource(String dbKey, BasicDataSource db) {
|
||||
public static void putCacheBasicDataSource(String dbKey, DruidDataSource db) {
|
||||
dbSources.put(dbKey, db);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据源缓存
|
||||
*/
|
||||
public static void cleanCacheBasicDataSource() {
|
||||
public static void cleanAllCache() {
|
||||
//关闭数据源连接
|
||||
for(Map.Entry<String, DruidDataSource> entry : dbSources.entrySet()){
|
||||
String dbkey = entry.getKey();
|
||||
DruidDataSource druidDataSource = entry.getValue();
|
||||
if(druidDataSource!=null && druidDataSource.isEnable()){
|
||||
druidDataSource.close();
|
||||
}
|
||||
//清空redis缓存
|
||||
getRedisTemplate().delete(CacheConstant.SYS_DYNAMICDB_CACHE + dbkey);
|
||||
}
|
||||
//清空缓存
|
||||
dbSources.clear();
|
||||
}
|
||||
|
||||
public static void removeCache(String dbKey) {
|
||||
//关闭数据源连接
|
||||
DruidDataSource druidDataSource = dbSources.get(dbKey);
|
||||
if(druidDataSource!=null && druidDataSource.isEnable()){
|
||||
druidDataSource.close();
|
||||
}
|
||||
//清空redis缓存
|
||||
getRedisTemplate().delete(CacheConstant.SYS_DYNAMICDB_CACHE + 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,31 @@
|
||||
package org.jeecg.common.util.dynamic.db;
|
||||
|
||||
public enum DbValidationQueryEnum {
|
||||
ORACLE("oracle", "SELECT 1 FROM DUAL"),
|
||||
MYSQL("mysql", "select 1"),
|
||||
SQLSERVER("sqlserver", "SELECT 1 FROM DUAL"),;
|
||||
|
||||
DbValidationQueryEnum(String dbType, String validationQuerySql) {
|
||||
this.dbType = dbType;
|
||||
this.validationQuerySql = validationQuerySql;
|
||||
}
|
||||
|
||||
private String dbType;
|
||||
private String validationQuerySql;
|
||||
|
||||
public String getDbType() {
|
||||
return dbType;
|
||||
}
|
||||
|
||||
public void setDbType(String dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public String getValidationQuerySql() {
|
||||
return validationQuerySql;
|
||||
}
|
||||
|
||||
public void setValidationQuerySql(String validationQuerySql) {
|
||||
this.validationQuerySql = validationQuerySql;
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,17 @@
|
||||
package org.jeecg.common.util.dynamic.db;
|
||||
|
||||
import com.alibaba.druid.pool.DruidDataSource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.dbcp.BasicDataSource;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
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 javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -30,20 +33,30 @@ public class DynamicDBUtil {
|
||||
* @param dbSource
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
private static BasicDataSource getJdbcDataSource(final DynamicDataSourceModel dbSource) {
|
||||
BasicDataSource dataSource = new BasicDataSource();
|
||||
private static DruidDataSource getJdbcDataSource(final DynamicDataSourceModel dbSource) {
|
||||
DruidDataSource dataSource = new DruidDataSource();
|
||||
|
||||
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.setValidationQuery("SELECT 1 FROM DUAL");
|
||||
dataSource.setTestWhileIdle(true);
|
||||
dataSource.setTestOnBorrow(false);
|
||||
dataSource.setTestOnReturn(false);
|
||||
dataSource.setBreakAfterAcquireFailure(true);
|
||||
dataSource.setConnectionErrorRetryAttempts(0);
|
||||
dataSource.setUsername(dbUser);
|
||||
dataSource.setMaxWait(60000);
|
||||
dataSource.setPassword(dbPassword);
|
||||
|
||||
log.info("******************************************");
|
||||
log.info("* *");
|
||||
log.info("*====【"+dbSource.getCode()+"】=====Druid连接池已启用 ====*");
|
||||
log.info("* *");
|
||||
log.info("******************************************");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
@ -53,17 +66,21 @@ public class DynamicDBUtil {
|
||||
* @param dbKey
|
||||
* @return
|
||||
*/
|
||||
public static BasicDataSource getDbSourceByDbKey(final String dbKey) {
|
||||
public static DruidDataSource getDbSourceByDbKey(final String dbKey) {
|
||||
//获取多数据源配置
|
||||
DynamicDataSourceModel dbSource = DataSourceCachePool.getCacheDynamicDataSourceModel(dbKey);
|
||||
//先判断缓存中是否存在数据库链接
|
||||
BasicDataSource cacheDbSource = DataSourceCachePool.getCacheBasicDataSource(dbKey);
|
||||
DruidDataSource cacheDbSource = DataSourceCachePool.getCacheBasicDataSource(dbKey);
|
||||
if (cacheDbSource != null && !cacheDbSource.isClosed()) {
|
||||
log.debug("--------getDbSourceBydbKey------------------从缓存中获取DB连接-------------------");
|
||||
return cacheDbSource;
|
||||
} else {
|
||||
BasicDataSource dataSource = getJdbcDataSource(dbSource);
|
||||
DataSourceCachePool.putCacheBasicDataSource(dbKey, dataSource);
|
||||
DruidDataSource dataSource = getJdbcDataSource(dbSource);
|
||||
if(dataSource!=null && dataSource.isEnable()){
|
||||
DataSourceCachePool.putCacheBasicDataSource(dbKey, dataSource);
|
||||
}else{
|
||||
throw new JeecgBootException("动态数据源连接失败,dbKey:"+dbKey);
|
||||
}
|
||||
log.info("--------getDbSourceBydbKey------------------创建DB数据库连接-------------------");
|
||||
return dataSource;
|
||||
}
|
||||
@ -76,7 +93,7 @@ public class DynamicDBUtil {
|
||||
* @return
|
||||
*/
|
||||
public static void closeDbKey(final String dbKey) {
|
||||
BasicDataSource dataSource = getDbSourceByDbKey(dbKey);
|
||||
DruidDataSource dataSource = getDbSourceByDbKey(dbKey);
|
||||
try {
|
||||
if (dataSource != null && !dataSource.isClosed()) {
|
||||
dataSource.getConnection().commit();
|
||||
@ -90,7 +107,7 @@ public class DynamicDBUtil {
|
||||
|
||||
|
||||
private static JdbcTemplate getJdbcTemplate(String dbKey) {
|
||||
BasicDataSource dataSource = getDbSourceByDbKey(dbKey);
|
||||
DruidDataSource dataSource = getDbSourceByDbKey(dbKey);
|
||||
return new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package org.jeecg.common.util.jsonschema;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 列 配置基本信息
|
||||
*/
|
||||
@Data
|
||||
public class BaseColumn {
|
||||
|
||||
/**
|
||||
* 列配置 描述 -对应数据库字段描述
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 列配置 名称 -对应数据库字段名
|
||||
*/
|
||||
private String field;
|
||||
|
||||
public BaseColumn(){}
|
||||
|
||||
public BaseColumn(String title,String field){
|
||||
this.title = title;
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
@ -52,7 +53,17 @@ public abstract class CommonProperty implements Serializable{
|
||||
protected Integer order;//字段显示排序
|
||||
|
||||
protected boolean disabled;//是否禁用
|
||||
|
||||
|
||||
protected String defVal; // 字段默认值
|
||||
|
||||
public String getDefVal() {
|
||||
return defVal;
|
||||
}
|
||||
|
||||
public void setDefVal(String defVal) {
|
||||
this.defVal = defVal;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
@ -150,6 +161,9 @@ public abstract class CommonProperty implements Serializable{
|
||||
JSONObject ui = JSONObject.parseObject(str);
|
||||
json.put("ui", ui);
|
||||
}
|
||||
if (StringUtils.isNotBlank(defVal)) {
|
||||
json.put("defVal", defVal);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
package org.jeecg.common.util.jsonschema.validate;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.util.jsonschema.BaseColumn;
|
||||
import org.jeecg.common.util.jsonschema.CommonProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 级联下拉
|
||||
*/
|
||||
public class LinkDownProperty extends CommonProperty {
|
||||
|
||||
/**
|
||||
* 配置信息
|
||||
*/
|
||||
String dictTable;
|
||||
|
||||
/**
|
||||
* 级联下拉组件 的其他级联列
|
||||
*/
|
||||
List<BaseColumn> otherColumns;
|
||||
|
||||
public String getDictTable(){
|
||||
return this.dictTable;
|
||||
}
|
||||
|
||||
public void setDictTable(String dictTable){
|
||||
this.dictTable = dictTable;
|
||||
}
|
||||
|
||||
public List<BaseColumn> getOtherColumns(){
|
||||
return this.otherColumns;
|
||||
}
|
||||
|
||||
public void setOtherColumns(List<BaseColumn> otherColumns){
|
||||
this.otherColumns = otherColumns;
|
||||
}
|
||||
|
||||
public LinkDownProperty() {}
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*/
|
||||
public LinkDownProperty(String key,String title,String dictTable) {
|
||||
this.type = "string";
|
||||
this.view = "link_down";
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
this.dictTable= dictTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getPropertyJson() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("key", getKey());
|
||||
JSONObject prop = getCommonJson();
|
||||
JSONObject temp = JSONObject.parseObject(this.dictTable);
|
||||
prop.put("config", temp);
|
||||
prop.put("others", otherColumns);
|
||||
map.put("prop", prop);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package org.jeecg.common.util.jsonschema.validate;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.jeecg.common.util.jsonschema.CommonProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 开关 属性
|
||||
*/
|
||||
public class SwitchProperty extends CommonProperty {
|
||||
|
||||
//扩展参数配置信息
|
||||
private String extendStr;
|
||||
|
||||
public SwitchProperty() {}
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*/
|
||||
public SwitchProperty(String key, String title, String extendStr) {
|
||||
this.type = "string";
|
||||
this.view = "switch";
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
this.extendStr = extendStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getPropertyJson() {
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("key",getKey());
|
||||
JSONObject prop = getCommonJson();
|
||||
JSONArray array = new JSONArray();
|
||||
if(extendStr!=null) {
|
||||
array = JSONArray.parseArray(extendStr);
|
||||
prop.put("extendOption",array);
|
||||
}
|
||||
map.put("prop",prop);
|
||||
return map;
|
||||
}
|
||||
|
||||
//TODO 重构问题:数据字典 只是字符串类的还是有存储的数值类型?只有字符串请跳过这个 只改前端
|
||||
}
|
||||
@ -21,6 +21,11 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
private String pidValue;//父级节点的值 暂时没用到 默认为0
|
||||
private String hasChildField;
|
||||
private String textField;//树形下拉保存text值的字段名
|
||||
|
||||
/**
|
||||
* 是不是pid 组件 1是 0否
|
||||
*/
|
||||
private Integer pidComponent = 0;
|
||||
|
||||
public String getDict() {
|
||||
return dict;
|
||||
@ -64,6 +69,14 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
this.textField = textField;
|
||||
}
|
||||
|
||||
public Integer getPidComponent() {
|
||||
return pidComponent;
|
||||
}
|
||||
|
||||
public void setPidComponent(Integer pidComponent) {
|
||||
this.pidComponent = pidComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器 构造普通树形下拉
|
||||
*/
|
||||
@ -123,6 +136,9 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
if(hasChildField!=null) {
|
||||
prop.put("hasChildField",hasChildField);
|
||||
}
|
||||
if(pidComponent!=null) {
|
||||
prop.put("pidComponent",pidComponent);
|
||||
}
|
||||
map.put("prop",prop);
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -4,18 +4,27 @@ import com.aliyun.oss.ClientConfiguration;
|
||||
import com.aliyun.oss.OSSClient;
|
||||
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
|
||||
import com.aliyun.oss.model.CannedAccessControlList;
|
||||
import com.aliyun.oss.model.OSSObject;
|
||||
import com.aliyun.oss.model.PutObjectResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.util.http.fileupload.FileItemStream;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @Description: 阿里云 oss 上传工具类(高依赖版)
|
||||
* @Date: 2019/5/10
|
||||
*/
|
||||
@Slf4j
|
||||
public class OssBootUtil {
|
||||
|
||||
private static String endPoint;
|
||||
@ -44,11 +53,14 @@ public class OssBootUtil {
|
||||
OssBootUtil.staticDomain = staticDomain;
|
||||
}
|
||||
|
||||
public static String getStaticDomain() {
|
||||
return staticDomain;
|
||||
}
|
||||
|
||||
/**
|
||||
* oss 工具客户端
|
||||
*/
|
||||
private static OSSClient ossClient = null;
|
||||
private static String FILE_URL;
|
||||
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
@ -59,12 +71,23 @@ public class OssBootUtil {
|
||||
* @param fileDir 文件保存目录
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String upload(MultipartFile file, String fileDir) {
|
||||
public static String upload(MultipartFile file, String fileDir,String customBucket) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(customBucket)){
|
||||
newBucket = customBucket;
|
||||
}
|
||||
try {
|
||||
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
|
||||
String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;
|
||||
//判断桶是否存在,不存在则创建桶
|
||||
if(!ossClient.doesBucketExist(newBucket)){
|
||||
ossClient.createBucket(newBucket);
|
||||
}
|
||||
// 获取文件名
|
||||
String orgName = file.getOriginalFilename();
|
||||
orgName = CommonUtils.getFileName(orgName);
|
||||
String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
|
||||
if (!fileDir.endsWith("/")) {
|
||||
fileDir = fileDir.concat("/");
|
||||
}
|
||||
@ -73,13 +96,13 @@ public class OssBootUtil {
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + fileUrl;
|
||||
} else {
|
||||
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
|
||||
FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.getInputStream());
|
||||
PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
|
||||
// 设置权限(公开读)
|
||||
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
|
||||
// ossClient.setBucketAcl(newBucket, CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
System.out.println("------OSS文件上传成功------" + fileUrl);
|
||||
log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -88,6 +111,15 @@ public class OssBootUtil {
|
||||
return FILE_URL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param file
|
||||
* @param fileDir
|
||||
* @return
|
||||
*/
|
||||
public static String upload(MultipartFile file, String fileDir) {
|
||||
return upload(file, fileDir,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件至阿里云 OSS
|
||||
@ -99,6 +131,7 @@ public class OssBootUtil {
|
||||
* @return oss 中的相对文件路径
|
||||
*/
|
||||
public static String upload(FileItemStream file, String fileDir) {
|
||||
String FILE_URL = null;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
StringBuilder fileUrl = new StringBuilder();
|
||||
try {
|
||||
@ -118,7 +151,7 @@ public class OssBootUtil {
|
||||
// 设置权限(公开读)
|
||||
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
System.out.println("------OSS文件上传成功------" + fileUrl);
|
||||
log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -132,10 +165,26 @@ public class OssBootUtil {
|
||||
* @param url
|
||||
*/
|
||||
public static void deleteUrl(String url) {
|
||||
String bucketUrl = "https://" + bucketName + "." + endPoint + "/";
|
||||
//String bucketUrl = staticDomain + "/";
|
||||
deleteUrl(url,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param url
|
||||
*/
|
||||
public static void deleteUrl(String url,String bucket) {
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(bucket)){
|
||||
newBucket = bucket;
|
||||
}
|
||||
String bucketUrl = "";
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
bucketUrl = staticDomain + "/" ;
|
||||
} else {
|
||||
bucketUrl = "https://" + newBucket + "." + endPoint + "/";
|
||||
}
|
||||
url = url.replace(bucketUrl,"");
|
||||
ossClient.deleteObject(bucketName, url);
|
||||
ossClient.deleteObject(newBucket, url);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,6 +195,57 @@ public class OssBootUtil {
|
||||
ossClient.deleteObject(bucketName, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件流
|
||||
* @param objectName
|
||||
* @param bucket
|
||||
* @return
|
||||
*/
|
||||
public static InputStream getOssFile(String objectName,String bucket){
|
||||
InputStream inputStream = null;
|
||||
try{
|
||||
String newBucket = bucketName;
|
||||
if(oConvertUtils.isNotEmpty(bucket)){
|
||||
newBucket = bucket;
|
||||
}
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
OSSObject ossObject = ossClient.getObject(newBucket,objectName);
|
||||
inputStream = new BufferedInputStream(ossObject.getObjectContent());
|
||||
}catch (Exception e){
|
||||
log.info("文件获取失败" + e.getMessage());
|
||||
}
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件流
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public static InputStream getOssFile(String objectName){
|
||||
return getOssFile(objectName,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件外链
|
||||
* @param bucketName
|
||||
* @param objectName
|
||||
* @param expires
|
||||
* @return
|
||||
*/
|
||||
public static String getObjectURL(String bucketName, String objectName, Date expires) {
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
try{
|
||||
if(ossClient.doesObjectExist(bucketName,objectName)){
|
||||
URL url = ossClient.generatePresignedUrl(bucketName,objectName,expires);
|
||||
return URLDecoder.decode(url.toString(),"UTF-8");
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.info("文件路径获取失败" + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 oss 客户端
|
||||
*
|
||||
@ -160,4 +260,30 @@ public class OssBootUtil {
|
||||
return ossClient;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件到oss
|
||||
* @param stream
|
||||
* @param relativePath
|
||||
* @return
|
||||
*/
|
||||
public static String upload(InputStream stream, String relativePath) {
|
||||
String FILE_URL = null;
|
||||
String fileUrl = relativePath;
|
||||
initOSS(endPoint, accessKeyId, accessKeySecret);
|
||||
if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
|
||||
FILE_URL = staticDomain + "/" + relativePath;
|
||||
} else {
|
||||
FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
|
||||
}
|
||||
PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(),stream);
|
||||
// 设置权限(公开读)
|
||||
ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
|
||||
if (result != null) {
|
||||
log.info("------OSS文件上传成功------" + fileUrl);
|
||||
}
|
||||
return FILE_URL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user