JeecgBoot 2.4.2 积木报表版本发布,基于SpringBoot的低代码平台

This commit is contained in:
zhangdaiscott
2021-01-23 23:59:31 +08:00
parent e9255f6bcc
commit df75998aae
238 changed files with 4660 additions and 35961 deletions

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-base</artifactId>
<version>2.4.0</version>
<version>2.4.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -75,13 +75,6 @@
<artifactId>commons-lang</artifactId>
<version>${commons.version}</version>
</dependency>
<!-- 拼音库 -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>${pinyin4j.version}</version>
</dependency>
<!-- freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
@ -121,6 +114,7 @@
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>${sqljdbc4.version}</version>
<scope>runtime</scope>
</dependency>
<!-- oracle驱动 -->
<dependency>
@ -159,7 +153,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-re</artifactId>
<version>2.3.07</version>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
@ -226,17 +220,6 @@
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
<exclusions>
<exclusion>
<artifactId>okio</artifactId>
<groupId>com.squareup.okio</groupId>
</exclusion>
<exclusion>
<artifactId>okhttp</artifactId>
<groupId>com.squareup.okhttp3</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
@ -260,17 +243,6 @@
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
<version>${justauth-spring-boot-starter.version}</version>
<exclusions>
<exclusion>
<artifactId>hutool-core</artifactId>
<groupId>cn.hutool</groupId>
</exclusion>
<exclusion>
<artifactId>fastjson</artifactId>
<groupId>com.alibaba</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>

View File

@ -52,7 +52,7 @@ public interface CacheConstant {
/**
* gateway路由缓存
*/
public static final String GATEWAY_ROUTES = "geteway_routes";
public static final String GATEWAY_ROUTES = "gateway_routes";
/**

View File

@ -1,6 +1,7 @@
package org.jeecg.common.constant;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
@ -14,10 +15,6 @@ 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){
@ -57,8 +54,7 @@ public class ProvinceCityArea {
if(this.areaList==null || this.areaList.size()==0){
this.areaList = new ArrayList<Area>();
try {
File file = jsonData.getFile();
String jsonData = this.jsonRead(file);
String jsonData = oConvertUtils.readStatic("classpath:static/pca.json");
JSONObject baseJson = JSONObject.parseObject(jsonData);
//第一层 省
JSONObject provinceJson = baseJson.getJSONObject("86");
@ -83,7 +79,7 @@ public class ProvinceCityArea {
}
}
}
} catch (IOException e) {
} catch (Exception e) {
e.printStackTrace();
}
}

View File

@ -3,7 +3,7 @@ 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.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Value;

View File

@ -1,6 +1,5 @@
package org.jeecg.common.system.query;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.util.oConvertUtils;
/**

View File

@ -40,6 +40,10 @@ public class QueryGenerator {
private static final String MULTI = "_MultiString";
private static final String STAR = "*";
private static final String COMMA = ",";
/**
* 查询 逗号转义符 相当于一个逗号【作废】
*/
public static final String QUERY_COMMA_ESCAPE = "++";
private static final String NOT_EQUAL = "!";
/**页面带有规则值查询,空格作为分隔符*/
private static final String QUERY_SEPARATE_KEYWORD = " ";
@ -261,7 +265,16 @@ public class QueryGenerator {
&& oConvertUtils.isNotEmpty(rule.getVal())) {
log.debug("SuperQuery ==> " + rule.toString());
addEasyQuery(andWrapper, fieldColumnMap.get(rule.getField()), QueryRuleEnum.getByValue(rule.getRule()), rule.getVal());
//update-begin-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错
Object queryValue = rule.getVal();
if("date".equals(rule.getType())){
queryValue = DateUtils.str2Date(rule.getVal(),DateUtils.date_sdf.get());
}else if("datetime".equals(rule.getType())){
queryValue = DateUtils.str2Date(rule.getVal(), DateUtils.datetimeFormat.get());
}
addEasyQuery(andWrapper, fieldColumnMap.get(rule.getField()), QueryRuleEnum.getByValue(rule.getRule()), queryValue);
//update-end-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错
// 如果拼接方式是OR就拼接OR
if (MatchTypeEnum.OR == matchType && i < (conditions.size() - 1)) {
@ -324,6 +337,7 @@ public class QueryGenerator {
rule = QueryRuleEnum.RIGHT_LIKE;
}
}
// step 4 in
if (rule == null && val.contains(COMMA)) {
//TODO in 查询这里应该有个bug 如果一字段本身就是多选 此时用in查询 未必能查询出来
@ -333,6 +347,18 @@ public class QueryGenerator {
if(rule == null && val.startsWith(NOT_EQUAL)){
rule = QueryRuleEnum.NE;
}
// step 6 xx+xx+xx 这种情况适用于如果想要用逗号作精确查询 但是系统默认逗号走in 所以可以用++替换【此逻辑作废】
if(rule == null && val.indexOf(QUERY_COMMA_ESCAPE)>0){
rule = QueryRuleEnum.EQ_WITH_ADD;
}
//update-begin--Author:taoyan Date:20201229 forinitQueryWrapper组装sql查询条件错误 #284---------------------
//特殊处理Oracle的表达式to_date('xxx','yyyy-MM-dd')含有逗号会被识别为in查询转为等于查询
if(rule == QueryRuleEnum.IN && val.indexOf("yyyy-MM-dd")>=0 && val.indexOf("to_date")>=0){
rule = QueryRuleEnum.EQ;
}
//update-end--Author:taoyan Date:20201229 forinitQueryWrapper组装sql查询条件错误 #284---------------------
return rule != null ? rule : QueryRuleEnum.EQ;
}
@ -365,7 +391,9 @@ public class QueryGenerator {
value = specialStrConvert(value.toString());
} else if (rule == QueryRuleEnum.IN) {
value = val.split(",");
} else {
} else if (rule == QueryRuleEnum.EQ_WITH_ADD) {
value = val.replaceAll("\\+\\+", COMMA);
}else {
//update-begin--Author:scott Date:20190724 forinitQueryWrapper组装sql查询条件错误 #284-------------------
if(val.startsWith(rule.getValue())){
//TODO 此处逻辑应该注释掉-> 如果查询内容中带有查询匹配规则符号,就会被截取的(比如:>=您好)
@ -470,6 +498,7 @@ public class QueryGenerator {
queryWrapper.le(name, value);
break;
case EQ:
case EQ_WITH_ADD:
queryWrapper.eq(name, value);
break;
case NE:
@ -653,34 +682,59 @@ public class QueryGenerator {
* @return
*/
public static String getSingleQueryConditionSql(String field,String alias,Object value,boolean isString) {
return getSingleQueryConditionSql(field, alias, value, isString,null);
}
/**
* 报表获取查询条件 支持多数据源
* @param field
* @param alias
* @param value
* @param isString
* @param dataBaseType
* @return
*/
public static String getSingleQueryConditionSql(String field,String alias,Object value,boolean isString, String dataBaseType) {
if (value == null) {
return "";
}
field = alias+oConvertUtils.camelToUnderline(field);
QueryRuleEnum rule = QueryGenerator.convert2Rule(value);
return getSingleSqlByRule(rule, field, value, isString);
return getSingleSqlByRule(rule, field, value, isString, dataBaseType);
}
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) {
/**
* 获取单个查询条件的值
* @param rule
* @param field
* @param value
* @param isString
* @param dataBaseType
* @return
*/
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString, String dataBaseType) {
String res = "";
switch (rule) {
case GT:
res =field+rule.getValue()+getFieldConditionValue(value, isString);
res =field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
break;
case GE:
res = field+rule.getValue()+getFieldConditionValue(value, isString);
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
break;
case LT:
res = field+rule.getValue()+getFieldConditionValue(value, isString);
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
break;
case LE:
res = field+rule.getValue()+getFieldConditionValue(value, isString);
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
break;
case EQ:
res = field+rule.getValue()+getFieldConditionValue(value, isString);
res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType);
break;
case EQ_WITH_ADD:
res = field+" = "+getFieldConditionValue(value, isString, dataBaseType);
break;
case NE:
res = field+" <> "+getFieldConditionValue(value, isString);
res = field+" <> "+getFieldConditionValue(value, isString, dataBaseType);
break;
case IN:
res = field + " in "+getInConditionValue(value, isString);
@ -695,12 +749,33 @@ public class QueryGenerator {
res = field + " like "+getLikeConditionValue(value);
break;
default:
res = field+" = "+getFieldConditionValue(value, isString);
res = field+" = "+getFieldConditionValue(value, isString, dataBaseType);
break;
}
return res;
}
private static String getFieldConditionValue(Object value,boolean isString) {
/**
* 获取单个查询条件的值
* @param rule
* @param field
* @param value
* @param isString
* @return
*/
public static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) {
return getSingleSqlByRule(rule, field, value, isString, null);
}
/**
* 获取查询条件的值
* @param value
* @param isString
* @param dataBaseType
* @return
*/
private static String getFieldConditionValue(Object value,boolean isString, String dataBaseType) {
String str = value.toString().trim();
if(str.startsWith("!")) {
str = str.substring(1);
@ -712,22 +787,27 @@ public class QueryGenerator {
str = str.substring(1);
}else if(str.startsWith("<")) {
str = str.substring(1);
}else if(str.indexOf(QUERY_COMMA_ESCAPE)>0) {
str = str.replaceAll("\\+\\+", COMMA);
}
if(dataBaseType==null){
dataBaseType = getDbType();
}
if(isString) {
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType)){
return " N'"+str+"' ";
}else{
return " '"+str+"' ";
}
}else {
// 如果不是字符串 有一种特殊情况 popup调用都走这个逻辑 参数传递的可能是“admin”这种格式的
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType()) && str.endsWith("'") && str.startsWith("'")){
if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType) && str.endsWith("'") && str.startsWith("'")){
return " N"+str;
}
return value.toString();
}
}
private static String getInConditionValue(Object value,boolean isString) {
if(isString) {
String temp[] = value.toString().split(",");

View File

@ -19,6 +19,8 @@ public enum QueryRuleEnum {
LIKE("LIKE","like","全模糊"),
LEFT_LIKE("LEFT_LIKE","left_like","左模糊"),
RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"),
EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"),
LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配————暂时未用上"),
SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段");
private String value;

View File

@ -75,10 +75,6 @@ public class CommonUtils {
}
//替换上传文件名字的特殊字符
fileName = fileName.replace("=","").replace(",","").replace("&","").replace("#", "");
//替换上传文件名字中的中文
if(ifContainChinese(fileName)){
fileName= PinyinUtil.getPinyin(fileName, StrUtil.EMPTY);
}
//替换上传文件名字中的空格
fileName=fileName.replaceAll("\\s","");
return fileName;

View File

@ -1,6 +1,6 @@
package org.jeecg.common.util;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
public enum DySmsEnum {

View File

@ -1,436 +0,0 @@
package org.jeecg.common.util;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.dict.service.AutoPoiDictServiceI;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecgframework.poi.excel.annotation.ExcelCollection;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.jeecgframework.poi.excel.annotation.ExcelVerify;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelCollectionParams;
import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity;
import org.jeecgframework.poi.excel.entity.params.ExcelVerifyEntity;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelImportEnum;
import org.jeecgframework.poi.util.ExcelUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.util.*;
/**
* 验证excel标题是否存在当前默认有0.880%)即可通过验证
*/
public class FieldPresenceUtil {
/**当有标题到达多少可以通过验证*/
public static final Double NUM = 0.8;
public static Boolean fieldPresence(InputStream inputstream, Class<?> pojoClass, ImportParams params) {
Workbook book = null;
int errorNum = 0;
int successNum = 0;
if (!(inputstream.markSupported())) {
inputstream = new PushbackInputStream(inputstream, 8);
}
try {
if (POIFSFileSystem.hasPOIFSHeader(inputstream)) {
book = new HSSFWorkbook(inputstream);
} else if (POIXMLDocument.hasOOXMLHeader(inputstream)) {
book = new XSSFWorkbook(OPCPackage.open(inputstream));
}
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
e.printStackTrace();
}
for (int i = 0; i < params.getSheetNum(); i++) {
Row row = null;
//跳过表头和标题行
Iterator<Row> rows;
try{
rows= book.getSheetAt(i).rowIterator();
}catch (Exception e){
//为空说明读取不到故不是excel
throw new RuntimeException("请导入正确格式的excel文件");
}
for (int j = 0; j < params.getTitleRows() + params.getHeadRows(); j++) {
try{
row = rows.next();
}catch (NoSuchElementException e){
//为空说明标题不出在excel格式错误
throw new RuntimeException("请填写内容标题!");
}
}
Sheet sheet = book.getSheetAt(i);
Map<Integer, String> titlemap = null;
try {
titlemap = getTitleMap(sheet, params);
} catch (Exception e) {
e.printStackTrace();
}
Set<Integer> columnIndexSet = titlemap.keySet();
Integer maxColumnIndex = Collections.max(columnIndexSet);
Integer minColumnIndex = Collections.min(columnIndexSet);
while (rows.hasNext() && (row == null || sheet.getLastRowNum() - row.getRowNum() > params.getLastOfInvalidRow())) {
row = rows.next();
Map<String, ExcelImportEntity> excelParams = new HashMap<String, ExcelImportEntity>();
List<ExcelCollectionParams> excelCollection = new ArrayList<ExcelCollectionParams>();
String targetId = null;
if (!Map.class.equals(pojoClass)) {
Field fileds[] = PoiPublicUtil.getClassFields(pojoClass);
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
if (etarget != null) {
targetId = etarget.value();
}
try {
getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
int firstCellNum = row.getFirstCellNum();
if (firstCellNum > minColumnIndex) {
firstCellNum = minColumnIndex;
}
int lastCellNum = row.getLastCellNum();
if (lastCellNum < maxColumnIndex + 1) {
lastCellNum = maxColumnIndex + 1;
}
for (int j = firstCellNum, le = lastCellNum; j < le; j++) {
String titleString = (String) titlemap.get(j);
if (excelParams.containsKey(titleString) || Map.class.equals(pojoClass)) {
successNum+=1;
}else{
if(excelCollection.size()>0){
Iterator var33 = excelCollection.iterator();
ExcelCollectionParams param = (ExcelCollectionParams)var33.next();
if (param.getExcelParams().containsKey(titleString)) {
successNum+=1;
}else{
errorNum+=1;
}
}else{
errorNum+=1;
}
}
}
if(successNum<errorNum){
return false;
}else if(successNum>errorNum){
if(errorNum>0){
double newNumber = (double) successNum / (successNum + errorNum);
BigDecimal bg = new BigDecimal(newNumber);
double f1 = bg.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
if(f1<NUM){
return false;
}else{
return true;
}
}else{
return true;
}
}else if(successNum==errorNum){
return false;
}else{
return false;
}
} catch (ExcelImportException e) {
if (!e.getType().equals(ExcelImportEnum.VERIFY_ERROR)) {
throw new ExcelImportException(e.getType(), e);
}
}
}
}
return null;
}
/**
* 获取文件名称标题
* @Author JEECG
* @date 20201023
* @throws Exception
*/
private static Map<Integer, String> getTitleMap(Sheet sheet, ImportParams params) throws Exception {
Map<Integer, String> titlemap = new HashMap<Integer, String>();
Iterator<Cell> cellTitle = null;
String collectionName = null;
Row headRow = null;
int headBegin = params.getTitleRows();
int allRowNum = sheet.getPhysicalNumberOfRows();
while(headRow == null && headBegin < allRowNum){
headRow = sheet.getRow(headBegin++);
}
if(headRow==null){
throw new Exception("不识别该文件");
}
if (ExcelUtil.isMergedRegion(sheet, headRow.getRowNum(), 0)) {
params.setHeadRows(2);
}else{
params.setHeadRows(1);
}
cellTitle = headRow.cellIterator();
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = getKeyValue(cell);
if (StringUtils.isNotEmpty(value)) {
titlemap.put(cell.getColumnIndex(), value);//加入表头列表
}
}
//多行表头
for (int j = headBegin; j < headBegin + params.getHeadRows()-1; j++) {
headRow = sheet.getRow(j);
cellTitle = headRow.cellIterator();
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = getKeyValue(cell);
if (StringUtils.isNotEmpty(value)) {
int columnIndex = cell.getColumnIndex();
//当前cell的上一行是否为合并单元格
if(ExcelUtil.isMergedRegion(sheet, cell.getRowIndex()-1, columnIndex)){
collectionName = ExcelUtil.getMergedRegionValue(sheet, cell.getRowIndex()-1, columnIndex);
if(params.isIgnoreHeader(collectionName)){
titlemap.put(cell.getColumnIndex(), value);
}else{
titlemap.put(cell.getColumnIndex(), collectionName + "_" + value);
}
}else{
titlemap.put(cell.getColumnIndex(), value);
}
}
}
}
return titlemap;
}
/**
* 获取key的值,针对不同类型获取不同的值
*
* @Author JEECG
* @date 20201023
* @param cell
* @return
*/
private static String getKeyValue(Cell cell) {
if(cell==null){
return null;
}
Object obj = null;
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
obj = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_BOOLEAN:
obj = cell.getBooleanCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
obj = cell.getNumericCellValue();
break;
case Cell.CELL_TYPE_FORMULA:
obj = cell.getCellFormula();
break;
}
return obj == null ? null : obj.toString().trim();
}
/**
* 获取需要导出的全部字段
*
*
*
* @param targetId
* 目标ID
* @param fields
* @param excelCollection
* @throws Exception
*/
public static void getAllExcelField(String targetId, Field[] fields, Map<String, ExcelImportEntity> excelParams, List<ExcelCollectionParams> excelCollection, Class<?> pojoClass, List<Method> getMethods) throws Exception {
ExcelImportEntity excelEntity = null;
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (PoiPublicUtil.isNotUserExcelUserThis(null, field, targetId)) {
continue;
}
if (PoiPublicUtil.isCollection(field.getType())) {
// 集合对象设置属性
ExcelCollectionParams collection = new ExcelCollectionParams();
collection.setName(field.getName());
Map<String, ExcelImportEntity> temp = new HashMap();
ParameterizedType pt = (ParameterizedType)field.getGenericType();
Class<?> clz = (Class)pt.getActualTypeArguments()[0];
collection.setType(clz);
getExcelFieldList(targetId, PoiPublicUtil.getClassFields(clz), clz, temp, (List)null);
collection.setExcelParams(temp);
collection.setExcelName(((ExcelCollection)field.getAnnotation(ExcelCollection.class)).name());
additionalCollectionName(collection);
excelCollection.add(collection);
} else if (PoiPublicUtil.isJavaClass(field)) {
addEntityToMap(targetId, field, (ExcelImportEntity)excelEntity, pojoClass, getMethods, excelParams);
} else {
List<Method> newMethods = new ArrayList<Method>();
if (getMethods != null) {
newMethods.addAll(getMethods);
}
newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass));
getAllExcelField(targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, excelCollection, field.getType(), newMethods);
}
}
}
public static void getExcelFieldList(String targetId, Field[] fields, Class<?> pojoClass, Map<String, ExcelImportEntity> temp, List<Method> getMethods) throws Exception {
ExcelImportEntity excelEntity = null;
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (!PoiPublicUtil.isNotUserExcelUserThis((List)null, field, targetId)) {
if (PoiPublicUtil.isJavaClass(field)) {
addEntityToMap(targetId, field, (ExcelImportEntity)excelEntity, pojoClass, getMethods, temp);
} else {
List<Method> newMethods = new ArrayList();
if (getMethods != null) {
newMethods.addAll(getMethods);
}
newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass, field.getType()));
getExcelFieldList(targetId, PoiPublicUtil.getClassFields(field.getType()), field.getType(), temp, newMethods);
}
}
}
}
/**
* 追加集合名称到前面
*
* @param collection
*/
private static void additionalCollectionName(ExcelCollectionParams collection) {
Set<String> keys = new HashSet();
keys.addAll(collection.getExcelParams().keySet());
Iterator var3 = keys.iterator();
while(var3.hasNext()) {
String key = (String)var3.next();
collection.getExcelParams().put(collection.getExcelName() + "_" + key, collection.getExcelParams().get(key));
collection.getExcelParams().remove(key);
}
}
/**
* 把这个注解解析放到类型对象中
*
* @param targetId
* @param field
* @param excelEntity
* @param pojoClass
* @param getMethods
* @param temp
* @throws Exception
*/
public static void addEntityToMap(String targetId, Field field, ExcelImportEntity excelEntity, Class<?> pojoClass, List<Method> getMethods, Map<String, ExcelImportEntity> temp) throws Exception {
Excel excel = field.getAnnotation(Excel.class);
excelEntity = new ExcelImportEntity();
excelEntity.setType(excel.type());
excelEntity.setSaveUrl(excel.savePath());
excelEntity.setSaveType(excel.imageType());
excelEntity.setReplace(excel.replace());
excelEntity.setDatabaseFormat(excel.databaseFormat());
excelEntity.setVerify(getImportVerify(field));
excelEntity.setSuffix(excel.suffix());
excelEntity.setNumFormat(excel.numFormat());
excelEntity.setGroupName(excel.groupName());
//update-begin-author:taoYan date:20180202 for:TASK #2067 【bug excel 问题】excel导入字典文本翻译问题
excelEntity.setMultiReplace(excel.multiReplace());
if(StringUtils.isNotEmpty(excel.dicCode())){
AutoPoiDictServiceI jeecgDictService = null;
try {
jeecgDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class);
} catch (Exception e) {
}
if(jeecgDictService!=null){
String[] dictReplace = jeecgDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText());
if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){
excelEntity.setReplace(dictReplace);
}
}
}
//update-end-author:taoYan date:20180202 for:TASK #2067 【bug excel 问题】excel导入字典文本翻译问题
getExcelField(targetId, field, excelEntity, excel, pojoClass);
if (getMethods != null) {
List<Method> newMethods = new ArrayList<Method>();
newMethods.addAll(getMethods);
newMethods.add(excelEntity.getMethod());
excelEntity.setMethods(newMethods);
}
temp.put(excelEntity.getName(), excelEntity);
}
public static void getExcelField(String targetId, Field field, ExcelImportEntity excelEntity, Excel excel, Class<?> pojoClass) throws Exception {
excelEntity.setName(getExcelName(excel.name(), targetId));
String fieldname = field.getName();
//update-begin-author:taoyan for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, field.getType(),excel.importConvert()));
//update-end-author:taoyan for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
if (StringUtils.isNotEmpty(excel.importFormat())) {
excelEntity.setFormat(excel.importFormat());
} else {
excelEntity.setFormat(excel.format());
}
}
/**
* 判断在这个单元格显示的名称
*
* @param exportName
* @param targetId
* @return
*/
public static String getExcelName(String exportName, String targetId) {
if (exportName.indexOf("_") < 0) {
return exportName;
}
String[] arr = exportName.split(",");
for (String str : arr) {
if (str.indexOf(targetId) != -1) {
return str.split("_")[0];
}
}
return null;
}
/**
* 获取导入校验参数
*
* @param field
* @return
*/
public static ExcelVerifyEntity getImportVerify(Field field) {
ExcelVerify verify = field.getAnnotation(ExcelVerify.class);
if (verify != null) {
ExcelVerifyEntity entity = new ExcelVerifyEntity();
entity.setEmail(verify.isEmail());
entity.setInterHandler(verify.interHandler());
entity.setMaxLength(verify.maxLength());
entity.setMinLength(verify.minLength());
entity.setMobile(verify.isMobile());
entity.setNotNull(verify.notNull());
entity.setRegex(verify.regex());
entity.setRegexTip(verify.regexTip());
entity.setTel(verify.isTel());
return entity;
}
return null;
}
}

View File

@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.handler.IFillRuleHandler;

View File

@ -1,6 +1,6 @@
package org.jeecg.common.util;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.util.HtmlUtils;
/**

View File

@ -2,7 +2,7 @@ package org.jeecg.common.util;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -47,7 +47,7 @@ public class ImportExcelUtil {
throw new Exception(errorFlag);
}
} catch (Exception e) {
String message = e.getMessage();
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {
@ -75,7 +75,7 @@ public class ImportExcelUtil {
throw new Exception(errorFlag);
}
} catch (Exception e) {
String message = e.getMessage();
String message = e.getMessage().toLowerCase();
int lineNumber = i + 1;
// 通过索引名判断出错信息
if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) {

View File

@ -1,8 +1,6 @@
package org.jeecg.common.util;
import io.minio.MinioClient;
import io.minio.errors.InvalidEndpointException;
import io.minio.errors.InvalidPortException;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.filter.StrAttackFilter;
import org.springframework.web.multipart.MultipartFile;
@ -63,11 +61,11 @@ public class MinioUtil {
try {
initMinio(minioUrl, minioName,minioPass);
// 检查存储桶是否已经存在
if(minioClient.bucketExists(newBucket)) {
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(newBucket).build())) {
log.info("Bucket already exists.");
} else {
// 创建一个名为ota的存储桶
minioClient.makeBucket(newBucket);
minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build());
log.info("create a new bucket.");
}
InputStream stream = file.getInputStream();
@ -83,7 +81,11 @@ public class MinioUtil {
if(objectName.startsWith("/")){
objectName = objectName.substring(1);
}
minioClient.putObject(newBucket,objectName, stream,stream.available(),"application/octet-stream");
PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
.bucket(newBucket)
.contentType("application/octet-stream")
.stream(stream,stream.available(),-1).build();
minioClient.putObject(objectArgs);
stream.close();
file_url = minioUrl+newBucket+"/"+objectName;
}catch (Exception e){
@ -112,7 +114,9 @@ public class MinioUtil {
InputStream inputStream = null;
try {
initMinio(minioUrl, minioName, minioPass);
inputStream = minioClient.getObject(bucketName, objectName);
GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
inputStream = minioClient.getObject(objectArgs);
} catch (Exception e) {
log.info("文件获取失败" + e.getMessage());
}
@ -128,7 +132,9 @@ public class MinioUtil {
public static void removeObject(String bucketName, String objectName) {
try {
initMinio(minioUrl, minioName,minioPass);
minioClient.removeObject(bucketName, objectName);
RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(objectName)
.bucket(bucketName).build();
minioClient.removeObject(objectArgs);
}catch (Exception e){
log.info("文件删除失败" + e.getMessage());
}
@ -144,7 +150,10 @@ public class MinioUtil {
public static String getObjectURL(String bucketName, String objectName, Integer expires) {
initMinio(minioUrl, minioName,minioPass);
try{
String url = minioClient.presignedGetObject(bucketName, objectName, expires);
GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName)
.bucket(bucketName)
.expiry(expires).build();
String url = minioClient.getPresignedObjectUrl(objectArgs);
return URLDecoder.decode(url,"UTF-8");
}catch (Exception e){
log.info("文件路径获取失败" + e.getMessage());
@ -162,10 +171,11 @@ public class MinioUtil {
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) {
minioClient = MinioClient.builder()
.endpoint(minioUrl)
.credentials(minioName, minioPass)
.build();
} catch (Exception e) {
e.printStackTrace();
}
}
@ -180,14 +190,18 @@ public class MinioUtil {
*/
public static String upload(InputStream stream,String relativePath) throws Exception {
initMinio(minioUrl, minioName,minioPass);
if(minioClient.bucketExists(bucketName)) {
if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
log.info("Bucket already exists.");
} else {
// 创建一个名为ota的存储桶
minioClient.makeBucket(bucketName);
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
log.info("create a new bucket.");
}
minioClient.putObject(bucketName,relativePath, stream, stream.available(),"application/octet-stream");
PutObjectArgs objectArgs = PutObjectArgs.builder().object(relativePath)
.bucket(bucketName)
.contentType("application/octet-stream")
.stream(stream,stream.available(),-1).build();
minioClient.putObject(objectArgs);
stream.close();
return minioUrl+bucketName+"/"+relativePath;
}

View File

@ -1,5 +1,6 @@
package org.jeecg.common.util;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -7,8 +8,7 @@ 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;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@ -572,4 +572,44 @@ public class RedisUtil {
return 0;
}
}
/**
* 获取指定前缀的一系列key
* 使用scan命令代替keys, Redis是单线程处理keys命令在KEY数量较多时
* 操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求
* @param keyPrefix
* @return
*/
private Set<String> keys(String keyPrefix) {
String realKey = keyPrefix + "*";
try {
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> binaryKeys = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(realKey).count(Integer.MAX_VALUE).build());
while (cursor.hasNext()) {
binaryKeys.add(new String(cursor.next()));
}
return binaryKeys;
});
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* 删除指定前缀的一系列key
* @param keyPrefix
*/
public void removeAll(String keyPrefix) {
try {
Set<String> keys = keys(keyPrefix);
redisTemplate.delete(keys);
} catch (Throwable e) {
e.printStackTrace();
}
}
}

View File

@ -2,7 +2,7 @@ package org.jeecg.common.util;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;

View File

@ -1,7 +1,7 @@
package org.jeecg.common.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.constant.CommonConstant;

View File

@ -2,7 +2,7 @@ package org.jeecg.common.util.dynamic.db;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.DynamicDataSourceModel;

View File

@ -5,7 +5,7 @@ import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecgframework.codegenerate.generate.util.SimpleFormat;
import java.io.StringWriter;

View File

@ -1,6 +1,6 @@
package org.jeecg.common.util.dynamic.db;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.DataBaseConstant;
import org.jeecg.common.system.vo.DynamicDataSourceModel;

View File

@ -56,6 +56,8 @@ public abstract class CommonProperty implements Serializable{
protected String fieldExtendJson;//扩展参数
protected Integer dbPointLength;//小数点
public String getDefVal() {
return defVal;
}
@ -136,6 +138,14 @@ public abstract class CommonProperty implements Serializable{
this.fieldExtendJson = fieldExtendJson;
}
public Integer getDbPointLength() {
return dbPointLength;
}
public void setDbPointLength(Integer dbPointLength) {
this.dbPointLength = dbPointLength;
}
/**
* 返回一个map有两个key
* <P>key ---> Property JSON的key
@ -175,6 +185,9 @@ public abstract class CommonProperty implements Serializable{
if(fieldExtendJson != null){
json.put("fieldExtendJson", fieldExtendJson);
}
if(dbPointLength !=null ) {
json.put("dbPointLength", dbPointLength);
}
return json;
}

View File

@ -1,9 +1,12 @@
package org.jeecg.common.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
@ -646,4 +649,20 @@ public class oConvertUtils {
return !listIsEmpty(list);
}
/**
* 读取静态文本内容
* @param url
* @return
*/
public static String readStatic(String url) {
String json = "";
try {
//换个写法解决springboot读取jar包中文件的问题
InputStream stream = oConvertUtils.class.getClassLoader().getResourceAsStream(url.replace("classpath:", ""));
json = IOUtils.toString(stream,"UTF-8");
} catch (IOException e) {
log.error(e.getMessage(),e);
}
return json;
}
}

View File

@ -138,6 +138,19 @@ public class OssBootUtil {
return FILE_URL;
}
/**
* 获取原始URL
* @param url: 原始URL
* @Return: java.lang.String
*/
public static String getOriginalUrl(String url) {
String originalDomain = "https://" + bucketName + "." + endPoint;
if(url.indexOf(staticDomain)!=-1){
url = url.replace(staticDomain,originalDomain);
}
return url;
}
/**
* 文件上传
* @param file

View File

@ -1,167 +0,0 @@
//package org.jeecg.config;
//
//import com.fasterxml.jackson.core.JsonGenerator;
//import com.fasterxml.jackson.databind.*;
//import com.fasterxml.jackson.databind.module.SimpleModule;
//import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
//import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
//import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
//import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
//
//import java.io.IOException;
//import java.math.BigDecimal;
//import java.text.SimpleDateFormat;
//import java.util.Date;
//import java.util.List;
//import java.util.TimeZone;
//
//import static org.jeecg.config.JacksonAutoConfiguration.SerializerFeature.*;
//
//
///**
// * @author: zyf
// * @date: 2019/5/20 14:56
// * @description:
// */
//@Slf4j
//@Configuration
//public class JacksonAutoConfiguration {
//
// public enum SerializerFeature {
// WriteNullListAsEmpty,
// WriteNullStringAsEmpty,
// WriteNullNumberAsZero,
// WriteNullBooleanAsFalse,
// WriteNullMapAsEmpty;
//
// public final int mask;
//
// SerializerFeature() {
// mask = (1 << ordinal());
// }
// }
//
// public static class FastJsonSerializerFeatureCompatibleForJackson extends BeanSerializerModifier {
// final private JsonSerializer<Object> nullBooleanJsonSerializer;
// final private JsonSerializer<Object> nullNumberJsonSerializer;
// final private JsonSerializer<Object> nullListJsonSerializer;
// final private JsonSerializer<Object> nullStringJsonSerializer;
// final private JsonSerializer<Object> nullMapJsonSerializer;
//
// FastJsonSerializerFeatureCompatibleForJackson(SerializerFeature... features) {
// int config = 0;
// for (SerializerFeature feature : features) {
// config |= feature.mask;
// }
// nullBooleanJsonSerializer = (config & WriteNullBooleanAsFalse.mask) != 0 ? new NullBooleanSerializer() : null;
// nullNumberJsonSerializer = (config & WriteNullNumberAsZero.mask) != 0 ? new NullNumberSerializer() : null;
// nullListJsonSerializer = (config & WriteNullListAsEmpty.mask) != 0 ? new NullListJsonSerializer() : null;
// nullStringJsonSerializer = (config & WriteNullStringAsEmpty.mask) != 0 ? new NullStringSerializer() : null;
// nullMapJsonSerializer = (config & WriteNullMapAsEmpty.mask) != 0 ? new NullMapSerializer() : null;
// }
//
// @Override
// public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
// for (BeanPropertyWriter writer : beanProperties) {
// final JavaType javaType = writer.getType();
// final Class<?> rawClass = javaType.getRawClass();
// if (javaType.isArrayType() || javaType.isCollectionLikeType()) {
// writer.assignNullSerializer(nullListJsonSerializer);
// } else if (Number.class.isAssignableFrom(rawClass) && (rawClass.getName().startsWith("java.lang") || rawClass.getName().startsWith("java.match"))) {
// writer.assignNullSerializer(nullNumberJsonSerializer);
// } else if (BigDecimal.class.isAssignableFrom(rawClass)) {
// writer.assignNullSerializer(nullNumberJsonSerializer);
// } else if (Boolean.class.equals(rawClass)) {
// writer.assignNullSerializer(nullBooleanJsonSerializer);
// } else if (String.class.equals(rawClass) || Date.class.equals(rawClass)) {
// writer.assignNullSerializer(nullStringJsonSerializer);
// } else if (!Date.class.equals(rawClass)) {
// writer.assignNullSerializer(nullMapJsonSerializer);
// }
// }
// return beanProperties;
// }
//
// private static class NullListJsonSerializer extends JsonSerializer<Object> {
// @Override
// public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// jgen.writeStartArray();
// jgen.writeEndArray();
// }
// }
//
// private static class NullNumberSerializer extends JsonSerializer<Object> {
// @Override
// public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// jgen.writeNumber(0);
// }
// }
//
// private static class NullBooleanSerializer extends JsonSerializer<Object> {
// @Override
// public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// jgen.writeBoolean(false);
// }
// }
//
// private static class NullStringSerializer extends JsonSerializer<Object> {
// @Override
// public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// jgen.writeString("");
// }
// }
//
// private static class NullMapSerializer extends JsonSerializer<Object> {
// @Override
// public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// jgen.writeStartObject();
// jgen.writeEndObject();
// }
// }
// }
//
// @Bean
// @Primary
// @ConditionalOnMissingBean(ObjectMapper.class)
// public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
// ObjectMapper objectMapper = new ObjectMapper();
// objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// // 排序key
// objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
//
// objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// //忽略在json字符串中存在在java类中不存在字段防止错误。
// objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// objectMapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
// /**
// * 序列换成json时,将所有的long变成string
// * js中long过长精度丢失
// */
// SimpleModule simpleModule = new SimpleModule();
// simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
// simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
// //注册xss解析器
// //simpleModule.addSerializer(String.class, new XssStringJsonSerializer());
// //simpleModule.addDeserializer(String.class, new XssStringJsonDeserializer());
// objectMapper.registerModule(simpleModule);
// // 兼容fastJson 的一些空值处理
// SerializerFeature[] features = new SerializerFeature[]{
// WriteNullListAsEmpty,
// WriteNullStringAsEmpty,
// WriteNullNumberAsZero,
// WriteNullBooleanAsFalse,
// WriteNullMapAsEmpty
// };
// objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new FastJsonSerializerFeatureCompatibleForJackson(features)));
// log.info("ObjectMapper [{}]", objectMapper);
// return objectMapper;
// }
//
//}

View File

@ -0,0 +1,22 @@
package org.jeecg.config;
import org.jeecg.common.constant.CommonConstant;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* 微服务环境加载条件
*/
public class JeecgCloudCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Object object = context.getEnvironment().getProperty(CommonConstant.CLOUD_SERVER_KEY);
//如果没有服务注册发现的配置 说明是单体应用
if(object==null){
return false;
}
return true;
}
}

View File

@ -12,6 +12,7 @@ import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.schema.Column;
import org.apache.ibatis.reflection.MetaObject;
import org.jeecg.common.util.oConvertUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -72,7 +73,7 @@ public class MybatisPlusConfig {
@Override
public Expression getTenantId(boolean select) {
String tenant_id = TenantContext.getTenant();
String tenant_id = oConvertUtils.getString(TenantContext.getTenant(),"0");
return new LongValue(tenant_id);
}
@Override

View File

@ -14,6 +14,7 @@ import org.crazycake.shiro.RedisClusterManager;
import org.crazycake.shiro.RedisManager;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.shiro.filters.CustomShiroFilterFactoryBean;
import org.jeecg.config.shiro.filters.JwtFilter;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
@ -58,7 +59,7 @@ public class ShiroConfig {
*/
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
CustomShiroFilterFactoryBean shiroFilterFactoryBean = new CustomShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
@ -87,8 +88,6 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
//filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token
//filterChainDefinitionMap.put("/sys/common/download/**", "anon");//文件下载不限制token
filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/doc.html", "anon");
@ -101,11 +100,9 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/**/*.png", "anon");
filterChainDefinitionMap.put("/**/*.ico", "anon");
// update-begin--Author:sunjianlei Date:20190813 for排除字体格式的后缀
filterChainDefinitionMap.put("/**/*.ttf", "anon");
filterChainDefinitionMap.put("/**/*.woff", "anon");
filterChainDefinitionMap.put("/**/*.woff2", "anon");
// update-begin--Author:sunjianlei Date:20190813 for排除字体格式的后缀
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
@ -117,19 +114,23 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/jmreport/**", "anon");
filterChainDefinitionMap.put("/**/*.js.map", "anon");
filterChainDefinitionMap.put("/**/*.css.map", "anon");
//大屏设计器排除
filterChainDefinitionMap.put("/bigscreen/**", "anon");
//测试示例
filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试
filterChainDefinitionMap.put("/test/bigScreen/**", "anon"); //大屏模板例子
//filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试
//filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面
//filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试
//websocket排除
filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告
filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块
filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例
filterChainDefinitionMap.put("/eoaSocket/**","anon");//我的聊天
//性能监控 TODO 存在安全漏洞
//filterChainDefinitionMap.put("/actuator/**", "anon");
//性能监控 TODO 存在安全漏洞泄露TOEKNdurid连接池也有
filterChainDefinitionMap.put("/actuator/**", "anon");
// 添加自己的过滤器并且取名为jwt
Map<String, Filter> filterMap = new HashMap<String, Filter>(1);

View File

@ -152,7 +152,7 @@ public class ShiroRealm extends AuthorizingRealm {
// 设置超时时间
redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, newAuthorization);
redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME *2 / 1000);
log.info("——————————用户在线操作更新token保证不掉线—————————jwtTokenRefresh——————— "+ token);
log.debug("——————————用户在线操作更新token保证不掉线—————————jwtTokenRefresh——————— "+ token);
}
//update-begin--Author:scott Date:20191005 for解决每次请求都重写redis中 token缓存问题
// else {

View File

@ -0,0 +1,76 @@
package org.jeecg.config.shiro.filters;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.InvalidRequestFilter;
import org.apache.shiro.web.filter.mgt.DefaultFilter;
import org.apache.shiro.web.filter.mgt.FilterChainManager;
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.beans.factory.BeanInitializationException;
import javax.servlet.Filter;
import java.util.Map;
/**
* 自定义ShiroFilterFactoryBean解决资源中文路径问题
*/
@Slf4j
public class CustomShiroFilterFactoryBean extends ShiroFilterFactoryBean {
@Override
public Class getObjectType() {
return MySpringShiroFilter.class;
}
@Override
protected AbstractShiroFilter createInstance() throws Exception {
SecurityManager securityManager = getSecurityManager();
if (securityManager == null) {
String msg = "SecurityManager property must be set.";
throw new BeanInitializationException(msg);
}
if (!(securityManager instanceof WebSecurityManager)) {
String msg = "The security manager does not implement the WebSecurityManager interface.";
throw new BeanInitializationException(msg);
}
FilterChainManager manager = createFilterChainManager();
//Expose the constructed FilterChainManager by first wrapping it in a
// FilterChainResolver implementation. The AbstractShiroFilter implementations
// do not know about FilterChainManagers - only resolvers:
PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
chainResolver.setFilterChainManager(manager);
Map<String, Filter> filterMap = manager.getFilters();
Filter invalidRequestFilter = filterMap.get(DefaultFilter.invalidRequest.name());
if (invalidRequestFilter instanceof InvalidRequestFilter) {
//此处是关键,设置false跳过URL携带中文400servletPath中文校验bug
((InvalidRequestFilter) invalidRequestFilter).setBlockNonAscii(false);
}
//Now create a concrete ShiroFilter instance and apply the acquired SecurityManager and built
//FilterChainResolver. It doesn't matter that the instance is an anonymous inner class
//here - we're just using it because it is a concrete AbstractShiroFilter instance that accepts
//injection of the SecurityManager and FilterChainResolver:
return new MySpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
}
private static final class MySpringShiroFilter extends AbstractShiroFilter {
protected MySpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
if (webSecurityManager == null) {
throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
} else {
this.setSecurityManager(webSecurityManager);
if (resolver != null) {
this.setFilterChainResolver(resolver);
}
}
}
}
}

View File

@ -54,6 +54,11 @@ public class JwtFilter extends BasicHttpAuthenticationFilter {
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String token = httpServletRequest.getHeader(CommonConstant.X_ACCESS_TOKEN);
// update-begin--Author:lvdandan Date:20210105 forJT-355 OA聊天添加token验证获取token参数
if(token == null){
token = httpServletRequest.getParameter("token");
}
// update-end--Author:lvdandan Date:20210105 forJT-355 OA聊天添加token验证获取token参数
JwtToken jwtToken = new JwtToken(token);
// 提交给realm进行登入如果错误他会抛出异常并被捕获

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.base.service.impl;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.LogDTO;
import org.jeecg.common.constant.CacheConstant;
@ -22,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
import java.util.*;
@Service
@Slf4j
public class BaseCommonServiceImpl implements BaseCommonService {
@Resource
@ -32,7 +34,13 @@ public class BaseCommonServiceImpl implements BaseCommonService {
if(oConvertUtils.isEmpty(logDTO.getId())){
logDTO.setId(String.valueOf(IdWorker.getId()));
}
baseCommonMapper.saveLog(logDTO);
//保存日志异常捕获处理防止数据太大存储失败导致业务失败JT-238
try {
baseCommonMapper.saveLog(logDTO);
} catch (Exception e) {
log.warn(" LogContent length : "+logDTO.getLogContent().length());
log.warn(e.getMessage());
}
}
@Override
@ -64,8 +72,13 @@ public class BaseCommonServiceImpl implements BaseCommonService {
sysLog.setUsername(user.getRealname());
}
sysLog.setCreateTime(new Date());
//保存系统日志
baseCommonMapper.saveLog(sysLog);
//保存日志异常捕获处理防止数据太大存储失败导致业务失败JT-238
try {
baseCommonMapper.saveLog(sysLog);
} catch (Exception e) {
log.warn(" LogContent length : "+sysLog.getLogContent().length());
log.warn(e.getMessage());
}
}
@Override