Merge remote-tracking branch 'lis8.0/master'
This commit is contained in:
commit
37b20d3f19
@ -119,6 +119,8 @@ public class CalcUtils {
|
||||
CalcExpression = CalcExpression.replaceAll("isnull\\s*\\(\\s*(.*?)\\s*\\)", "($1 == null)");
|
||||
// 1. 替换逻辑运算符:and→&&,or→||
|
||||
String processed = CalcExpression.replaceAll("\\band|AND\\b", "&&").replaceAll("\\bor|OR\\b", "||");
|
||||
// ========== 新增:将<>替换为!=(兼容空格) ==========
|
||||
processed = processed.replaceAll("\\s*<>\\s*", "!=");
|
||||
// 2. 替换变量格式:[a] → #a
|
||||
processed = processed.replaceAll("\\[(\\w+)/(\\w+)\\]", "[$1_$2]");
|
||||
processed = processed.replaceAll("\\[([^]]+)\\]", "#$1");
|
||||
|
||||
@ -6,6 +6,8 @@ import com.lowagie.text.Document;
|
||||
import com.lowagie.text.pdf.PdfCopy;
|
||||
import com.lowagie.text.pdf.PdfReader;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
@ -570,4 +572,194 @@ public class LisUtil {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
// ========== List实体转换(核心:遍历调用单实体转换) ==========
|
||||
/**
|
||||
* 从Map中提取指定key的Object,转换为List<实体类>
|
||||
* @param dataMap 数据源Map
|
||||
* @param key 要提取的key(对应的值需是List<Map<String, Object>>类型)
|
||||
* @param clazz 目标实体类Class(如Table1.class)
|
||||
* @return 转换后的List,失败返回空List(避免NPE)
|
||||
* @param <T> 目标实体类型
|
||||
*/
|
||||
public static <T> List<T> mapToEntityList(Map<String, Object> dataMap, String key, Class<T> clazz) {
|
||||
// 初始化返回空List,避免调用方判空
|
||||
List<T> resultList = new ArrayList<>();
|
||||
|
||||
// 步骤1:基础空值/类型校验
|
||||
if (dataMap == null || !dataMap.containsKey(key) || dataMap.get(key) == null) {
|
||||
return resultList;
|
||||
}
|
||||
Object value = dataMap.get(key);
|
||||
// 校验value是List类型
|
||||
if (!(value instanceof List)) {
|
||||
System.out.println("错误:key=" + key + " 的值不是List类型,实际类型:" + (value != null ? value.getClass().getName() : "null"));
|
||||
return resultList;
|
||||
}
|
||||
List<?> rawList = (List<?>) value;
|
||||
|
||||
// 步骤2:遍历List中的每个元素,转换为实体
|
||||
for (Object item : rawList) {
|
||||
// 每个元素必须是Map类型(才能转为实体)
|
||||
if (!(item instanceof Map)) {
|
||||
System.out.println("警告:List中存在非Map类型的元素,跳过:" + item);
|
||||
continue;
|
||||
}
|
||||
// 临时封装成Map<String, Object>,复用单实体转换方法
|
||||
Map<String, Object> tempMap = new HashMap<>();
|
||||
tempMap.put("tempKey", item);
|
||||
// 调用单实体转换方法
|
||||
T entity = mapToEntity(tempMap, "tempKey", clazz);
|
||||
if (entity != null) {
|
||||
resultList.add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
/**
|
||||
* 通用方法:从Map<String, Object>中提取指定key的Object,转换为任意实体类
|
||||
* @param dataMap 数据源Map
|
||||
* @param key 要提取的key(对应的值需是Map类型)
|
||||
* @param clazz 目标实体类的Class对象(比如Table1.class、User.class)
|
||||
* @return 转换后的实体对象,失败返回null
|
||||
* @param <T> 泛型:目标实体类类型
|
||||
*/
|
||||
public static <T> T mapToEntity(Map<String, Object> dataMap, String key, Class<T> clazz) {
|
||||
// 步骤1:安全校验Map和key对应值
|
||||
if (dataMap == null || !dataMap.containsKey(key) || dataMap.get(key) == null) {
|
||||
return null;
|
||||
}
|
||||
Object value = dataMap.get(key);
|
||||
|
||||
// 步骤2:校验value是Map类型(只有Map才能转为实体)
|
||||
if (!(value instanceof Map)) {
|
||||
System.out.println("错误:key=" + key + " 的值不是Map类型,实际类型:" + (value != null ? value.getClass().getName() : "null"));
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> entityMap = (Map<String, Object>) value;
|
||||
|
||||
try {
|
||||
// 步骤3:通过反射创建目标实体对象(核心:泛型类实例化)
|
||||
T targetEntity = clazz.getDeclaredConstructor().newInstance(); // 要求实体类有无参构造
|
||||
|
||||
// 步骤4:Spring BeanWrapper拷贝Map属性到实体
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(targetEntity);
|
||||
// 3. 遍历Map属性,自定义类型转换(核心:处理String→Date)
|
||||
entityMap.forEach((fieldName, fieldValue) -> {
|
||||
// 跳过空值
|
||||
if (fieldValue == null) {
|
||||
return;
|
||||
}
|
||||
// 校验属性是否存在且可写
|
||||
if (!beanWrapper.isWritableProperty(fieldName)) {
|
||||
System.out.println("警告:实体类" + clazz.getSimpleName() + "不存在可写属性:" + fieldName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取实体属性的目标类型
|
||||
Class<?> targetType = beanWrapper.getPropertyType(fieldName);
|
||||
Object convertValue = fieldValue;
|
||||
|
||||
// 4. 核心:String→Date 自定义转换
|
||||
if (targetType == Date.class && fieldValue instanceof String) {
|
||||
convertValue = convertStringToDate((String) fieldValue);
|
||||
if (convertValue == null) {
|
||||
System.out.println("警告:属性" + fieldName + "的日期格式错误,值:" + fieldValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 赋值到实体(基础类型BeanUtils会自动转换)
|
||||
beanWrapper.setPropertyValue(fieldName, convertValue);
|
||||
} catch (Exception e) {
|
||||
System.out.println("错误:属性" + fieldName + "赋值失败,原因:" + e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
return targetEntity;
|
||||
} catch (Exception e) {
|
||||
// 捕获反射/拷贝异常(无参构造不存在、类型不匹配等)
|
||||
System.out.println("转换实体失败:" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static <T> T mapToEntity(Map<String, Object> entityMap, Class<T> clazz) {
|
||||
// 步骤1:安全校验Map和key对应值
|
||||
if (entityMap == null ) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// 步骤3:通过反射创建目标实体对象(核心:泛型类实例化)
|
||||
T targetEntity = clazz.getDeclaredConstructor().newInstance(); // 要求实体类有无参构造
|
||||
|
||||
// 步骤4:Spring BeanWrapper拷贝Map属性到实体
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(targetEntity);
|
||||
// 3. 遍历Map属性,自定义类型转换(核心:处理String→Date)
|
||||
entityMap.forEach((fieldName, fieldValue) -> {
|
||||
// 跳过空值
|
||||
if (fieldValue == null) {
|
||||
return;
|
||||
}
|
||||
// 校验属性是否存在且可写
|
||||
if (!beanWrapper.isWritableProperty(fieldName)) {
|
||||
System.out.println("警告:实体类" + clazz.getSimpleName() + "不存在可写属性:" + fieldName);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取实体属性的目标类型
|
||||
Class<?> targetType = beanWrapper.getPropertyType(fieldName);
|
||||
Object convertValue = fieldValue;
|
||||
|
||||
// 4. 核心:String→Date 自定义转换
|
||||
if (targetType == Date.class && fieldValue instanceof String) {
|
||||
convertValue = convertStringToDate((String) fieldValue);
|
||||
if (convertValue == null) {
|
||||
System.out.println("警告:属性" + fieldName + "的日期格式错误,值:" + fieldValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 赋值到实体(基础类型BeanUtils会自动转换)
|
||||
beanWrapper.setPropertyValue(fieldName, convertValue);
|
||||
} catch (Exception e) {
|
||||
System.out.println("错误:属性" + fieldName + "赋值失败,原因:" + e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
return targetEntity;
|
||||
} catch (Exception e) {
|
||||
// 捕获反射/拷贝异常(无参构造不存在、类型不匹配等)
|
||||
System.out.println("转换实体失败:" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 辅助方法:String转Date,支持常见日期格式
|
||||
* @param dateStr 日期字符串(如 "2026-02-20"、"2026-02-20 12:00:00")
|
||||
* @return Date对象,格式错误返回null
|
||||
*/
|
||||
private static Date convertStringToDate(String dateStr) {
|
||||
// 定义支持的日期格式(按优先级排序)
|
||||
String[] patterns = {
|
||||
"yyyy-MM-dd HH:mm:ss",
|
||||
"yyyy-MM-dd",
|
||||
"yyyy/MM/dd HH:mm:ss",
|
||||
"yyyy/MM/dd",
|
||||
"yyyyMMdd"
|
||||
};
|
||||
|
||||
// 遍历格式尝试转换
|
||||
for (String pattern : patterns) {
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
|
||||
sdf.setLenient(false); // 严格校验日期(避免"2026-02-30"这种无效日期)
|
||||
return sdf.parse(dateStr);
|
||||
} catch (Exception e) {
|
||||
// 格式不匹配,继续尝试下一个
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
package com.czlis.liswork.mapper.stats;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface StatsMapper {
|
||||
List<Map<String,Object>> getsqldata(String wheresql);
|
||||
}
|
||||
|
||||
@ -7,10 +7,12 @@ import com.czlis.common.utils.StringUtils;
|
||||
import com.czlis.interfaceCommon.utils.CalcUtils;
|
||||
import com.czlis.interfaceCommon.utils.LisUtil;
|
||||
import com.czlis.interfaceCommon.utils.LisWorkUtils;
|
||||
import com.czlis.liswork.mapper.stats.StatsMapper;
|
||||
import com.czlis.liswork.mapper.xtwh.ComStatsParameterMapper;
|
||||
import com.czlis.liswork.mapper.xtwh.ComStatsTemplateMapper;
|
||||
import com.czlis.liswork.service.StatsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -24,6 +26,8 @@ public class StatsServiceImpl implements StatsService {
|
||||
@Autowired
|
||||
ComStatsTemplateMapper comStatsTemplateMapper;
|
||||
@Autowired
|
||||
StatsMapper statsMapper;
|
||||
@Autowired
|
||||
LisWorkUtils lisWorkUtils;
|
||||
@Override
|
||||
public Result getTemplate(String statsCode){
|
||||
@ -88,29 +92,85 @@ public class StatsServiceImpl implements StatsService {
|
||||
@Override
|
||||
public Result query(Map<String,Object> list){
|
||||
if(list==null||list.isEmpty())return new Result("-1","入参为空");
|
||||
Object t=list.get("Template");
|
||||
if(t==null )return new Result("-1","模板为空");
|
||||
Object c=list.get("Column");
|
||||
if(c==null )return new Result("-1","字段为空");
|
||||
Object p=list.get("Parameter");
|
||||
if(p==null )return new Result("-1","筛选条件为空");
|
||||
ComStatsTemplate template=(ComStatsTemplate)t;
|
||||
List<ComStatsParameter> column=(List<ComStatsParameter>)c;
|
||||
List<ComStatsParameter> parameterlist=(List<ComStatsParameter>)p;
|
||||
ComStatsTemplate template =LisUtil.mapToEntity(list,"Template",ComStatsTemplate.class);
|
||||
if(template==null )return new Result("-1","模板为空");
|
||||
List<ComStatsParameter> columnlist=LisUtil.mapToEntityList(list,"Column",ComStatsParameter.class);
|
||||
if(columnlist==null )return new Result("-1","字段为空");
|
||||
List<ComStatsParameter> parameterlist=LisUtil.mapToEntityList(list,"Parameter",ComStatsParameter.class);
|
||||
if(parameterlist==null )return new Result("-1","筛选条件为空");
|
||||
String statsSql=template.getStatsSql();
|
||||
if(statsSql==null)return new Result("-1","sql语句为空");
|
||||
String where="";
|
||||
for(ComStatsParameter parameter :parameterlist){
|
||||
String value=parameter.getParamDefvalue();
|
||||
if(value==null)continue;
|
||||
if("".equals(value.trim()))continue;
|
||||
String precondition=parameter.getPrecondition();
|
||||
Result result=checkprecondition(precondition,parameterlist);
|
||||
if(!"0".equals(result.getCode()))return result;
|
||||
boolean flag=(boolean)result.getData();
|
||||
if(flag){
|
||||
where=where+" "+parameter.getParamSql();
|
||||
}
|
||||
if(precondition!=null&&!"".equals(precondition)) {
|
||||
Result result = checkprecondition(precondition, parameterlist);
|
||||
if (!"0".equals(result.getCode())) return result;
|
||||
boolean flag = (boolean) result.getData();
|
||||
if (flag) {
|
||||
where = where + " " + parameter.getParamSql();
|
||||
}
|
||||
}else{
|
||||
where = where + " " + parameter.getParamSql();
|
||||
}
|
||||
}
|
||||
Map<String,Object> map=new HashMap<>();
|
||||
return new Result("0","成功",statsSql+where);
|
||||
String columns="";
|
||||
String column="";
|
||||
for(ComStatsParameter parameter :columnlist){
|
||||
Long Sequence = parameter.getParamSequence();
|
||||
if(Sequence==null||Sequence==0)continue;
|
||||
String value=parameter.getParamCode();
|
||||
if(value==null)continue;
|
||||
if("".equals(value.trim()))continue;
|
||||
String paramsql=parameter.getParamSql();
|
||||
if(paramsql!=null&&!"".equals(paramsql)) {
|
||||
value = paramsql + " as " + value;
|
||||
}else{
|
||||
paramsql=value;
|
||||
}
|
||||
String type=parameter.getParamType();
|
||||
String precondition=parameter.getPrecondition();
|
||||
if(precondition!=null&&!"".equals(precondition)) {
|
||||
Result result = checkprecondition(precondition, parameterlist);
|
||||
if (!"0".equals(result.getCode())) return result;
|
||||
boolean flag = (boolean) result.getData();
|
||||
if (flag) {
|
||||
if(!"".equals(columns))columns=columns+",";
|
||||
columns = columns + value;
|
||||
if(!"6".equals(type)) {
|
||||
if(!"".equals(column))column=column+",";
|
||||
column = column + paramsql;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(!"".equals(columns))columns=columns+",";
|
||||
columns = columns + value;
|
||||
if(!"6".equals(type)) {
|
||||
if(!"".equals(column))column=column+",";
|
||||
column = column + paramsql;
|
||||
}
|
||||
}
|
||||
}
|
||||
statsSql=statsSql.replace("[where]",where);
|
||||
statsSql=statsSql.replace("[columns]",columns);
|
||||
statsSql=statsSql.replace("[column]",column);
|
||||
if("".equals(column)||column==null)statsSql=statsSql.replace("group by","");
|
||||
statsSql=inputParameter(statsSql,parameterlist);
|
||||
List<Map<String,Object>> datalist=statsMapper.getsqldata(statsSql);
|
||||
return new Result("0","成功",datalist);
|
||||
}
|
||||
private String inputParameter(String sql,List<ComStatsParameter> parameterlist) {
|
||||
String[] parameters = CalcUtils.getParameters(sql);
|
||||
for (String itemcode : parameters){
|
||||
Optional<ComStatsParameter> temp=parameterlist.stream().filter(ss->itemcode.equals(ss.getParamCode())).findAny();
|
||||
if(temp.isPresent()) {
|
||||
sql=sql.replace("["+itemcode+"]","'"+temp.get().getParamDefvalue()+"'");
|
||||
}
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
private Result checkprecondition(String precondition,List<ComStatsParameter> parameterlist) {
|
||||
Map<String, String> variables = new HashMap<>();
|
||||
|
||||
@ -2,5 +2,7 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="com.czlis.liswork.mapper.stats.StatsMapper">
|
||||
|
||||
<select id="getsqldata" resultType="map">
|
||||
${wheresql}
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
x
Reference in New Issue
Block a user