mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-26 16:26:41 +08:00
JeecgBoot 2.1.1 代码生成器AI版本发布
This commit is contained in:
@ -52,13 +52,6 @@ public class Result<T> implements Serializable {
|
||||
|
||||
}
|
||||
|
||||
public Result<T> error500(String message) {
|
||||
this.message = message;
|
||||
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
|
||||
this.success = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Result<T> success(String message) {
|
||||
this.message = message;
|
||||
this.code = CommonConstant.SC_OK_200;
|
||||
@ -102,7 +95,13 @@ public class Result<T> implements Serializable {
|
||||
r.setSuccess(false);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
public Result<T> error500(String message) {
|
||||
this.message = message;
|
||||
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
|
||||
this.success = false;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 无权限访问返回结果
|
||||
*/
|
||||
|
||||
@ -10,27 +10,37 @@ public interface CacheConstant {
|
||||
/**
|
||||
* 字典信息缓存
|
||||
*/
|
||||
public static final String DICT_CACHE = "dictCache";
|
||||
public static final String SYS_DICT_CACHE = "sys:cache:dict";
|
||||
/**
|
||||
* 表字典信息缓存
|
||||
*/
|
||||
public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable";
|
||||
|
||||
/**
|
||||
* 权限信息缓存
|
||||
* 数据权限配置缓存
|
||||
*/
|
||||
public static final String PERMISSION_CACHE = "permission";
|
||||
public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules";
|
||||
|
||||
/**
|
||||
* 登录用户规则缓存
|
||||
* 缓存用户信息
|
||||
*/
|
||||
public static final String LOGIN_USER_RULES_CACHE = "loginUser_cacheRules";
|
||||
public static final String SYS_USERS_CACHE = "sys:cache:user";
|
||||
|
||||
/**
|
||||
* 部门信息缓存
|
||||
* 全部部门信息缓存
|
||||
*/
|
||||
public static final String DEPART_INFO_CACHE = "departCache_info";
|
||||
public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata";
|
||||
|
||||
|
||||
/**
|
||||
* 部门id信息缓存
|
||||
* 全部部门ids缓存
|
||||
*/
|
||||
public static final String DEPART_IDMODEL_CACHE = "departCache_idmodel";
|
||||
public static final String SYS_DEPART_IDS_CACHE = "sys:cache:depart:allids";
|
||||
|
||||
|
||||
/**
|
||||
* 测试缓存key
|
||||
*/
|
||||
public static final String TEST_DEMO_CACHE = "test:demo";
|
||||
|
||||
}
|
||||
|
||||
@ -71,15 +71,14 @@ public interface CommonConstant {
|
||||
/**访问权限认证未通过 510*/
|
||||
public static final Integer SC_JEECG_NO_AUTHZ=510;
|
||||
|
||||
/** 登录用户拥有角色缓存KEY前缀 */
|
||||
public static String LOGIN_USER_CACHERULES_ROLE = "loginUser_cacheRules::Roles_";
|
||||
/** 登录用户拥有权限缓存KEY前缀 */
|
||||
public static String LOGIN_USER_CACHERULES_PERMISSION = "loginUser_cacheRules::Permissions_";
|
||||
/** 登录用户令牌缓存KEY前缀 */
|
||||
public static final int TOKEN_EXPIRE_TIME = 3600; //3600秒即是一小时
|
||||
|
||||
public static final String PREFIX_USER_TOKEN = "PREFIX_USER_TOKEN_";
|
||||
/** 登录用户Shiro权限缓存KEY前缀 */
|
||||
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.modules.shiro.authc.ShiroRealm.authorizationCache:";
|
||||
/** 登录用户Token令牌缓存KEY前缀 */
|
||||
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
|
||||
/** Token缓存时间:3600秒即一小时 */
|
||||
public static final int TOKEN_EXPIRE_TIME = 3600;
|
||||
|
||||
|
||||
/**
|
||||
* 0:一级菜单
|
||||
*/
|
||||
@ -150,5 +149,42 @@ public interface CommonConstant {
|
||||
|
||||
/**字典翻译文本后缀*/
|
||||
public static final String DICT_TEXT_SUFFIX = "_dictText";
|
||||
|
||||
|
||||
/**
|
||||
* 表单设计器主表类型
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_TYPE_MAIN = 1;
|
||||
|
||||
/**
|
||||
* 表单设计器子表表类型
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_TYPE_SUB = 2;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权通过
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
|
||||
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
|
||||
/**
|
||||
* 表单设计器URL授权未通过
|
||||
*/
|
||||
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,11 @@ package org.jeecg.common.constant;
|
||||
* 数据库上下文常量
|
||||
*/
|
||||
public interface DataBaseConstant {
|
||||
//*********数据库类型****************************************
|
||||
public static final String DB_TYPE_MYSQL = "MYSQL";
|
||||
public static final String DB_TYPE_ORACLE = "ORACLE";
|
||||
public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL";
|
||||
public static final String DB_TYPE_SQLSERVER = "SQLSERVER";
|
||||
|
||||
//*********系统上下文变量****************************************
|
||||
/**
|
||||
|
||||
@ -0,0 +1,335 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等)
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JeecgElasticsearchTemplate {
|
||||
|
||||
@Value("${jeecg.elasticsearch.cluster-nodes}")
|
||||
private String baseUrl;
|
||||
|
||||
private final String FORMAT_JSON = "format=json";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建索引
|
||||
* <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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据,详见: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).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 中为空的值
|
||||
for (String key : data.keySet()) {
|
||||
String value = data.getString(key);
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
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) {
|
||||
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("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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
package org.jeecg.common.es;
|
||||
|
||||
/**
|
||||
* 用于创建 ElasticSearch 的 queryString
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
public class QueryStringBuilder {
|
||||
|
||||
StringBuilder builder;
|
||||
|
||||
public QueryStringBuilder(String field, String str) {
|
||||
builder = new StringBuilder(field).append(":(").append(str);
|
||||
}
|
||||
|
||||
public QueryStringBuilder and(String str) {
|
||||
builder.append(" AND ").append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryStringBuilder or(String str) {
|
||||
builder.append(" OR ").append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryStringBuilder not(String str) {
|
||||
builder.append(" NOT ").append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.append(")").toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,9 +1,12 @@
|
||||
package org.jeecg.common.exception;
|
||||
|
||||
import io.lettuce.core.RedisConnectionException;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.data.redis.connection.PoolException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
@ -52,7 +55,7 @@ public class JeecgBootExceptionHandler {
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result<?> handleException(Exception e){
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error(e.getMessage());
|
||||
return Result.error("操作失败,"+e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,4 +78,16 @@ public class JeecgBootExceptionHandler {
|
||||
return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
|
||||
}
|
||||
|
||||
@ExceptionHandler(DataIntegrityViolationException.class)
|
||||
public Result<?> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("字段太长,超出数据库字段的长度");
|
||||
}
|
||||
|
||||
@ExceptionHandler(PoolException.class)
|
||||
public Result<?> handlePoolException(PoolException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("Redis 连接异常!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.jeecg.common.system.api;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.common.system.vo.ComboModel;
|
||||
import org.jeecg.common.system.vo.DictModel;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
|
||||
@ -23,12 +24,19 @@ public interface ISysBaseAPI {
|
||||
void addLog(String LogContent, Integer logType, Integer operatetype);
|
||||
|
||||
/**
|
||||
* 根据用户账号查询登录用户信息
|
||||
* 根据用户账号查询用户信息
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public LoginUser getUserByName(String username);
|
||||
|
||||
/**
|
||||
* 根据用户id查询用户信息
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public LoginUser getUserById(String id);
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色集合
|
||||
* @param username
|
||||
@ -36,6 +44,20 @@ public interface ISysBaseAPI {
|
||||
*/
|
||||
public List<String> getRolesByUsername(String username);
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门集合
|
||||
* @param username
|
||||
* @return 部门 id
|
||||
*/
|
||||
List<String> getDepartIdsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 通过用户账号查询部门 name
|
||||
* @param username
|
||||
* @return 部门 name
|
||||
*/
|
||||
List<String> getDepartNamesByUsername(String username);
|
||||
|
||||
/**
|
||||
* 获取当前数据库类型
|
||||
* @return
|
||||
@ -77,4 +99,47 @@ public interface ISysBaseAPI {
|
||||
*/
|
||||
public void sendSysAnnouncement(String fromUser,String toUser,String title, String msgContent);
|
||||
|
||||
/**
|
||||
* 查询表字典 支持过滤数据
|
||||
* @param table
|
||||
* @param text
|
||||
* @param code
|
||||
* @param filterSql
|
||||
* @return
|
||||
*/
|
||||
public List<DictModel> queryFilterTableDictInfo(String table, String text, String code, String filterSql);
|
||||
|
||||
/**
|
||||
* 获取所有有效用户
|
||||
* @return
|
||||
*/
|
||||
public List<ComboModel> queryAllUser();
|
||||
|
||||
/**
|
||||
* 获取所有角色
|
||||
* @return
|
||||
*/
|
||||
public List<ComboModel> queryAllRole();
|
||||
|
||||
/**
|
||||
* 通过用户账号查询角色Id集合
|
||||
* @param username
|
||||
* @return
|
||||
*/
|
||||
public List<String> getRoleIdsByUsername(String username);
|
||||
|
||||
/**
|
||||
* 通过部门编号查询部门id
|
||||
* @param orgCode
|
||||
* @return
|
||||
*/
|
||||
public String getDepartIdsByOrgCode(String orgCode);
|
||||
|
||||
/**
|
||||
* 查询上一级部门
|
||||
* @param departId
|
||||
* @return
|
||||
*/
|
||||
public DictModel getParentDepartId(String departId);
|
||||
|
||||
}
|
||||
|
||||
@ -1,18 +1,24 @@
|
||||
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.extension.service.IService;
|
||||
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;
|
||||
import org.jeecgframework.poi.excel.ExcelImportUtil;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
@ -34,72 +40,94 @@ import lombok.extern.slf4j.Slf4j;
|
||||
* @Version: 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class JeecgController<T extends JeecgEntity, S extends JeecgService<T>> {
|
||||
@Autowired
|
||||
S service;
|
||||
public class JeecgController<T, S extends IService<T>> {
|
||||
@Autowired
|
||||
S service;
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
*/
|
||||
protected ModelAndView exportXls(HttpServletRequest request,T object,Class<T> clazz,String title) {
|
||||
//--------------------------------------------------------------------------------
|
||||
//获取当前用户
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
//--------------------------------------------------------------------------------
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
protected ModelAndView exportXls(HttpServletRequest request, T object, Class<T> clazz, String title) {
|
||||
// Step.1 组装查询条件
|
||||
QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
// Step.2 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
List<T> pageList = service.list(queryWrapper);
|
||||
// 导出文件名称
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
|
||||
mv.addObject(NormalExcelConstants.CLASS, clazz);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:"+sysUser.getRealname(), title + "表"));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
|
||||
return mv;
|
||||
}
|
||||
// Step.2 获取导出数据
|
||||
List<T> pageList = service.list(queryWrapper);
|
||||
List<T> exportList = null;
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
MultipartFile file = entity.getValue();// 获取上传文件对象
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);
|
||||
//update-begin-author:taoyan date:20190528 for:批量插入数据
|
||||
long start = System.currentTimeMillis();
|
||||
service.saveBatch(list);
|
||||
//400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒
|
||||
//1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
|
||||
log.info("消耗时间"+(System.currentTimeMillis()-start)+"毫秒");
|
||||
//update-end-author:taoyan date:20190528 for:批量插入数据
|
||||
return Result.ok("文件导入成功!数据行数:" + list.size());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("文件导入失败:" + e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
// 过滤选中数据
|
||||
String selections = request.getParameter("selections");
|
||||
if (oConvertUtils.isNotEmpty(selections)) {
|
||||
List<String> selectionList = Arrays.asList(selections.split(","));
|
||||
exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
|
||||
} else {
|
||||
exportList = pageList;
|
||||
}
|
||||
|
||||
// Step.3 AutoPoi 导出Excel
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
|
||||
mv.addObject(NormalExcelConstants.CLASS, clazz);
|
||||
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
|
||||
return mv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取对象ID
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getId(T item) {
|
||||
try {
|
||||
return PropertyUtils.getProperty(item, "id").toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
MultipartFile file = entity.getValue();// 获取上传文件对象
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
try {
|
||||
List<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);
|
||||
//update-begin-author:taoyan date:20190528 for:批量插入数据
|
||||
long start = System.currentTimeMillis();
|
||||
service.saveBatch(list);
|
||||
//400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒
|
||||
//1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
|
||||
log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
//update-end-author:taoyan date:20190528 for:批量插入数据
|
||||
return Result.ok("文件导入成功!数据行数:" + list.size());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return Result.error("文件导入失败:" + e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.error("文件导入失败!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
package org.jeecg.common.system.query;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
|
||||
/**
|
||||
* 查询链接规则
|
||||
*
|
||||
* @Author Sunjianlei
|
||||
*/
|
||||
public enum MatchTypeEnum {
|
||||
|
||||
AND("AND"),
|
||||
OR("OR");
|
||||
|
||||
private String value;
|
||||
|
||||
MatchTypeEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static MatchTypeEnum getByValue(String value) {
|
||||
if (oConvertUtils.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
for (MatchTypeEnum val : values()) {
|
||||
if (val.getValue().toLowerCase().equals(value.toLowerCase())) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
public class QueryGenerator {
|
||||
|
||||
public static final String SQL_RULES_COLUMN = "SQL_RULES_COLUMN";
|
||||
|
||||
|
||||
private static final String BEGIN = "_begin";
|
||||
private static final String END = "_end";
|
||||
private static final String STAR = "*";
|
||||
@ -534,6 +534,10 @@ public class QueryGenerator {
|
||||
}
|
||||
field = alias+oConvertUtils.camelToUnderline(field);
|
||||
QueryRuleEnum rule = QueryGenerator.convert2Rule(value);
|
||||
return getSingleSqlByRule(rule, field, value, isString);
|
||||
}
|
||||
|
||||
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) {
|
||||
String res = "";
|
||||
switch (rule) {
|
||||
case GT:
|
||||
@ -614,9 +618,82 @@ public class QueryGenerator {
|
||||
}else if(str.endsWith("*")) {
|
||||
return "'"+str.substring(0,str.length()-1)+"%'";
|
||||
}else {
|
||||
return str;
|
||||
if(str.indexOf("%")>=0) {
|
||||
return str;
|
||||
}else {
|
||||
return "'%"+str+"%'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据权限相关配置生成相关的SQL 语句
|
||||
* @param searchObj
|
||||
* @param parameterMap
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static String installAuthJdbc(Class<?> clazz) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
//权限查询
|
||||
Map<String,SysPermissionDataRule> ruleMap = getRuleMap();
|
||||
PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(clazz);
|
||||
String sql_and = " and ";
|
||||
for (String c : ruleMap.keySet()) {
|
||||
if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){
|
||||
sb.append(sql_and+getSqlRuleValue(ruleMap.get(c).getRuleValue()));
|
||||
}
|
||||
}
|
||||
String name;
|
||||
for (int i = 0; i < origDescriptors.length; i++) {
|
||||
name = origDescriptors[i].getName();
|
||||
if (judgedIsUselessField(name)) {
|
||||
continue;
|
||||
}
|
||||
if(ruleMap.containsKey(name)) {
|
||||
SysPermissionDataRule dataRule = ruleMap.get(name);
|
||||
QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
|
||||
Class propType = origDescriptors[i].getPropertyType();
|
||||
boolean isString = propType.equals(String.class);
|
||||
Object value;
|
||||
if(isString) {
|
||||
value = converRuleValue(dataRule.getRuleValue());
|
||||
}else {
|
||||
value = NumberUtils.parseNumber(dataRule.getRuleValue(),propType);
|
||||
}
|
||||
String filedSql = getSingleSqlByRule(rule, oConvertUtils.camelToUnderline(name), value,isString);
|
||||
sb.append(sql_and+filedSql);
|
||||
}
|
||||
}
|
||||
log.info("query auth sql is:"+sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据权限相关配置 组装mp需要的权限
|
||||
* @param searchObj
|
||||
* @param parameterMap
|
||||
* @return
|
||||
*/
|
||||
public static void installAuthMplus(QueryWrapper<?> queryWrapper,Class<?> clazz) {
|
||||
//权限查询
|
||||
Map<String,SysPermissionDataRule> ruleMap = getRuleMap();
|
||||
PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(clazz);
|
||||
for (String c : ruleMap.keySet()) {
|
||||
if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){
|
||||
queryWrapper.and(i ->i.apply(getSqlRuleValue(ruleMap.get(c).getRuleValue())));
|
||||
}
|
||||
}
|
||||
String name;
|
||||
for (int i = 0; i < origDescriptors.length; i++) {
|
||||
name = origDescriptors[i].getName();
|
||||
if (judgedIsUselessField(name)) {
|
||||
continue;
|
||||
}
|
||||
if(ruleMap.containsKey(name)) {
|
||||
addRuleToQueryWrapper(ruleMap.get(name), name, origDescriptors[i].getPropertyType(), queryWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ import org.jeecg.common.util.oConvertUtils;
|
||||
**/
|
||||
public class JwtUtil {
|
||||
|
||||
// 过期时间30分钟
|
||||
// Token过期时间30分钟(用户登录过期时间是此时间的两倍,以token在reids缓存时间为准)
|
||||
public static final long EXPIRE_TIME = 30 * 60 * 1000;
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package org.jeecg.common.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ComboModel implements Serializable {
|
||||
private String id;
|
||||
private String title;
|
||||
|
||||
public ComboModel(){
|
||||
|
||||
};
|
||||
|
||||
public ComboModel(String id,String title){
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
};
|
||||
}
|
||||
@ -85,4 +85,9 @@ public class LoginUser {
|
||||
*/
|
||||
private String activitiSync;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@ import org.apache.commons.lang.StringUtils;
|
||||
|
||||
public enum DySmsEnum {
|
||||
|
||||
LOGIN_TEMPLATE_CODE("SMS_167040816","JEECG","code"),
|
||||
FORGET_PASSWORD_TEMPLATE_CODE("SMS_167040816","JEECG","code"),
|
||||
REGISTER_TEMPLATE_CODE("SMS_144146309","JEECG","code");
|
||||
LOGIN_TEMPLATE_CODE("SMS_175435174","JEECG","code"),
|
||||
FORGET_PASSWORD_TEMPLATE_CODE("SMS_175435174","JEECG","code"),
|
||||
REGISTER_TEMPLATE_CODE("SMS_175430166","JEECG","code");
|
||||
|
||||
/**
|
||||
* 短信模板编码
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PmsUtil {
|
||||
|
||||
|
||||
private static String uploadPath;
|
||||
|
||||
@Value("${jeecg.path.upload}")
|
||||
public void setUploadPath(String uploadPath) {
|
||||
PmsUtil.uploadPath = uploadPath;
|
||||
}
|
||||
|
||||
public static String saveErrorTxtByList(List<String> msg, String name) {
|
||||
Date d = new Date();
|
||||
String saveDir = "logs" + File.separator + DateUtils.yyyyMMdd.format(d) + File.separator;
|
||||
String saveFullDir = uploadPath + File.separator + saveDir;
|
||||
|
||||
File saveFile = new File(saveFullDir);
|
||||
if (!saveFile.exists()) {
|
||||
saveFile.mkdirs();
|
||||
}
|
||||
name += DateUtils.yyyymmddhhmmss.format(d) + Math.round(Math.random() * 10000);
|
||||
String saveFilePath = saveFullDir + name + ".txt";
|
||||
|
||||
try {
|
||||
//封装目的地
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(saveFilePath));
|
||||
//遍历集合
|
||||
for (String s : msg) {
|
||||
//写数据
|
||||
if (s.indexOf("_") > 0) {
|
||||
String arr[] = s.split("_");
|
||||
bw.write("第" + arr[0] + "行:" + arr[1]);
|
||||
} else {
|
||||
bw.write(s);
|
||||
}
|
||||
//bw.newLine();
|
||||
bw.write("\r\n");
|
||||
}
|
||||
//释放资源
|
||||
bw.flush();
|
||||
bw.close();
|
||||
} catch (Exception e) {
|
||||
log.info("excel导入生成错误日志文件异常:" + e.getMessage());
|
||||
}
|
||||
return saveDir + name + ".txt";
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,6 +5,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
@ -0,0 +1,213 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 调用 Restful 接口 Util
|
||||
*
|
||||
* @author sunjianlei
|
||||
*/
|
||||
public class RestUtil {
|
||||
|
||||
/**
|
||||
* RestAPI 调用器
|
||||
*/
|
||||
private final static RestTemplate RT = new RestTemplate();
|
||||
|
||||
public static RestTemplate getRestTemplate() {
|
||||
return RT;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url) {
|
||||
return getNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url, JSONObject variables) {
|
||||
return getNative(url, variables, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求
|
||||
*/
|
||||
public static JSONObject get(String url, JSONObject variables, JSONObject params) {
|
||||
return getNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 get 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> getNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.GET, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url) {
|
||||
return postNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url, JSONObject params) {
|
||||
return postNative(url, null, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 Post 请求
|
||||
*/
|
||||
public static JSONObject post(String url, JSONObject variables, JSONObject params) {
|
||||
return postNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 POST 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> postNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.POST, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url) {
|
||||
return putNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url, JSONObject params) {
|
||||
return putNative(url, null, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求
|
||||
*/
|
||||
public static JSONObject put(String url, JSONObject variables, JSONObject params) {
|
||||
return putNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 put 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> putNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.PUT, variables, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求
|
||||
*/
|
||||
public static JSONObject delete(String url) {
|
||||
return deleteNative(url, null, null).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求
|
||||
*/
|
||||
public static JSONObject delete(String url, JSONObject variables, JSONObject params) {
|
||||
return deleteNative(url, variables, params).getBody();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送 delete 请求,返回原生 ResponseEntity 对象
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> deleteNative(String url, JSONObject variables, JSONObject params) {
|
||||
return request(url, HttpMethod.DELETE, null, variables, params, JSONObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*/
|
||||
public static ResponseEntity<JSONObject> request(String url, HttpMethod method, JSONObject variables, JSONObject params) {
|
||||
return request(url, method, getHeaderApplicationJson(), variables, params, JSONObject.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param method 请求方式
|
||||
* @param headers 请求头 可空
|
||||
* @param variables 请求url参数 可空
|
||||
* @param params 请求body参数 可空
|
||||
* @param responseType 返回类型
|
||||
* @return ResponseEntity<responseType>
|
||||
*/
|
||||
public static <T> ResponseEntity<T> request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, JSONObject params, Class<T> responseType) {
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
throw new RuntimeException("url 不能为空");
|
||||
}
|
||||
if (method == null) {
|
||||
throw new RuntimeException("method 不能为空");
|
||||
}
|
||||
if (headers == null) {
|
||||
headers = new HttpHeaders();
|
||||
}
|
||||
// 请求体
|
||||
String body = "";
|
||||
if (params != null) {
|
||||
body = params.toJSONString();
|
||||
}
|
||||
// 拼接 url 参数
|
||||
if (variables != null) {
|
||||
url += ("?" + asUrlVariables(variables));
|
||||
}
|
||||
// 发送请求
|
||||
HttpEntity<String> request = new HttpEntity<>(body, headers);
|
||||
return RT.exchange(url, method, request, responseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取JSON请求头
|
||||
*/
|
||||
private static HttpHeaders getHeaderApplicationJson() {
|
||||
return getHeader(MediaType.APPLICATION_JSON_UTF8_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头
|
||||
*/
|
||||
private static HttpHeaders getHeader(String mediaType) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.parseMediaType(mediaType));
|
||||
headers.add("Accept", mediaType);
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 JSONObject 转为 a=1&b=2&c=3...&n=n 的形式
|
||||
*/
|
||||
public static String asUrlVariables(JSONObject variables) {
|
||||
Map<String, Object> source = variables.getInnerMap();
|
||||
Iterator<String> it = source.keySet().iterator();
|
||||
StringBuilder urlVariables = new StringBuilder();
|
||||
while (it.hasNext()) {
|
||||
String key = it.next();
|
||||
String value = "";
|
||||
Object object = source.get(key);
|
||||
if (object != null) {
|
||||
if (!StringUtils.isEmpty(object.toString())) {
|
||||
value = object.toString();
|
||||
}
|
||||
}
|
||||
urlVariables.append("&").append(key).append("=").append(value);
|
||||
}
|
||||
// 去掉第一个&
|
||||
return urlVariables.substring(1);
|
||||
}
|
||||
|
||||
}
|
||||
@ -19,7 +19,7 @@ public class SpringContextUtils implements ApplicationContextAware {
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
SpringContextUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
package org.jeecg.common.util;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.util.JwtUtil;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @Author scott
|
||||
* @Date 2019/9/23 14:12
|
||||
* @Description: 编程校验token有效性
|
||||
*/
|
||||
public class TokenUtils {
|
||||
|
||||
/**
|
||||
* 验证Token
|
||||
*/
|
||||
public static boolean verifyToken(HttpServletRequest request, ISysBaseAPI sysBaseAPI, RedisUtil redisUtil) {
|
||||
String token = request.getParameter("token");
|
||||
|
||||
// 解密获得username,用于和数据库进行对比
|
||||
String username = JwtUtil.getUsername(token);
|
||||
if (username == null) {
|
||||
throw new AuthenticationException("token非法无效!");
|
||||
}
|
||||
|
||||
// 查询用户信息
|
||||
LoginUser user = sysBaseAPI.getUserByName(username);
|
||||
if (user == null) {
|
||||
throw new AuthenticationException("用户不存在!");
|
||||
}
|
||||
// 判断用户状态
|
||||
if (user.getStatus() != 1) {
|
||||
throw new AuthenticationException("账号已被锁定,请联系管理员!");
|
||||
}
|
||||
// 校验token是否超时失效 & 或者账号密码是否错误
|
||||
if (!jwtTokenRefresh(token, username, user.getPassword(), redisUtil)) {
|
||||
throw new AuthenticationException("Token失效,请重新登录!");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token(保证用户在线操作不掉线)
|
||||
* @param token
|
||||
* @param userName
|
||||
* @param passWord
|
||||
* @param redisUtil
|
||||
* @return
|
||||
*/
|
||||
private static boolean jwtTokenRefresh(String token, String userName, String passWord, RedisUtil redisUtil) {
|
||||
String cacheToken = String.valueOf(redisUtil.get(CommonConstant.PREFIX_USER_TOKEN + token));
|
||||
if (oConvertUtils.isNotEmpty(cacheToken)) {
|
||||
// 校验token有效性
|
||||
if (!JwtUtil.verify(cacheToken, userName, passWord)) {
|
||||
String newAuthorization = JwtUtil.sign(userName, passWord);
|
||||
// 设置Toekn缓存有效时间
|
||||
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, newAuthorization);
|
||||
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
|
||||
}
|
||||
//update-begin--Author:scott Date:20191005 for:解决每次请求,都重写redis中 token缓存问题
|
||||
// else {
|
||||
// redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, cacheToken);
|
||||
// // 设置超时时间
|
||||
// redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);
|
||||
// }
|
||||
//update-end--Author:scott Date:20191005 for:解决每次请求,都重写redis中 token缓存问题
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package org.jeecg.common.util.jsonschema.validate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jeecg.common.util.jsonschema.CommonProperty;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* 字典属性
|
||||
* @author 86729
|
||||
*
|
||||
*/
|
||||
public class HiddenProperty extends CommonProperty {
|
||||
|
||||
private static final long serialVersionUID = -8939298551502162479L;
|
||||
|
||||
public HiddenProperty() {}
|
||||
|
||||
public HiddenProperty(String key,String title) {
|
||||
this.type = "string";
|
||||
this.view = "hidden";
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getPropertyJson() {
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("key",getKey());
|
||||
JSONObject prop = getCommonJson();
|
||||
prop.put("hidden",true);
|
||||
map.put("prop",prop);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
@ -20,6 +20,7 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
private String pidField;//父级字段 默认pid
|
||||
private String pidValue;//父级节点的值 暂时没用到 默认为0
|
||||
private String hasChildField;
|
||||
private String textField;//树形下拉保存text值的字段名
|
||||
|
||||
public String getDict() {
|
||||
return dict;
|
||||
@ -54,9 +55,17 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
}
|
||||
|
||||
public TreeSelectProperty() {}
|
||||
|
||||
|
||||
public String getTextField() {
|
||||
return textField;
|
||||
}
|
||||
|
||||
public void setTextField(String textField) {
|
||||
this.textField = textField;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
* 构造器 构造普通树形下拉
|
||||
*/
|
||||
public TreeSelectProperty(String key,String title,String dict,String pidField,String pidValue) {
|
||||
this.type = "string";
|
||||
@ -67,6 +76,32 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
this.pidField= pidField;
|
||||
this.pidValue= pidValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分类字典下拉专用
|
||||
* @param key
|
||||
* @param title
|
||||
* @param pidValue
|
||||
*/
|
||||
public TreeSelectProperty(String key,String title,String pidValue) {
|
||||
this.type = "string";
|
||||
this.view = "cat_tree";
|
||||
this.key = key;
|
||||
this.title = title;
|
||||
this.pidValue = pidValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分类字典 支持存储text 下拉专用
|
||||
* @param key
|
||||
* @param title
|
||||
* @param pidValue
|
||||
* @param textField
|
||||
*/
|
||||
public TreeSelectProperty(String key,String title,String pidValue,String textField) {
|
||||
this(key,title,pidValue);
|
||||
this.textField = textField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getPropertyJson() {
|
||||
@ -82,6 +117,9 @@ public class TreeSelectProperty extends CommonProperty {
|
||||
if(pidValue!=null) {
|
||||
prop.put("pidValue",pidValue);
|
||||
}
|
||||
if(textField!=null) {
|
||||
prop.put("textField",textField);
|
||||
}
|
||||
if(hasChildField!=null) {
|
||||
prop.put("hasChildField",hasChildField);
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ public class SysPermissionDataRule implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.UUID)
|
||||
@TableId(type = IdType.ID_WORKER_STR)
|
||||
private String id;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user