JeecgBoot 2.1.1 代码生成器AI版本发布

This commit is contained in:
zhangdaihao
2019-10-18 18:37:41 +08:00
parent 5b67b76b98
commit 6dbc37c410
267 changed files with 16761 additions and 26860 deletions

View File

@ -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;
}
/**
* 无权限访问返回结果
*/

View File

@ -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";
}

View File

@ -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";
}

View File

@ -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";
//*********系统上下文变量****************************************
/**

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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 连接异常!");
}
}

View File

@ -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);
}

View File

@ -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("文件导入失败!");
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;
/**

View File

@ -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;
};
}

View File

@ -85,4 +85,9 @@ public class LoginUser {
*/
private String activitiSync;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -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");
/**
* 短信模板编码

View File

@ -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";
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -19,7 +19,7 @@ public class SpringContextUtils implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
SpringContextUtils.applicationContext = applicationContext;
}
/**

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -28,7 +28,7 @@ public class SysPermissionDataRule implements Serializable {
/**
* id
*/
@TableId(type = IdType.UUID)
@TableId(type = IdType.ID_WORKER_STR)
private String id;
/**