From 7f91844201db638b62d1ab43cf434976cc60e77b Mon Sep 17 00:00:00 2001 From: tangw Date: Sat, 28 Feb 2026 10:22:47 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czlis/interfaceCommon/utils/LisUtil.java | 192 ++++++++++++++++++ .../service/impl/stats/StatsServiceImpl.java | 16 +- 2 files changed, 199 insertions(+), 9 deletions(-) diff --git a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/LisUtil.java b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/LisUtil.java index 5f3964d..1682ced 100644 --- a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/LisUtil.java +++ b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/LisUtil.java @@ -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>类型) + * @param clazz 目标实体类Class(如Table1.class) + * @return 转换后的List,失败返回空List(避免NPE) + * @param 目标实体类型 + */ + public static List mapToEntityList(Map dataMap, String key, Class clazz) { + // 初始化返回空List,避免调用方判空 + List 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,复用单实体转换方法 + Map tempMap = new HashMap<>(); + tempMap.put("tempKey", item); + // 调用单实体转换方法 + T entity = mapToEntity(tempMap, "tempKey", clazz); + if (entity != null) { + resultList.add(entity); + } + } + + return resultList; + } + /** + * 通用方法:从Map中提取指定key的Object,转换为任意实体类 + * @param dataMap 数据源Map + * @param key 要提取的key(对应的值需是Map类型) + * @param clazz 目标实体类的Class对象(比如Table1.class、User.class) + * @return 转换后的实体对象,失败返回null + * @param 泛型:目标实体类类型 + */ + public static T mapToEntity(Map dataMap, String key, Class 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 entityMap = (Map) 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 mapToEntity(Map entityMap, Class 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; + } } diff --git a/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java b/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java index 9e83aa3..78f466e 100644 --- a/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java +++ b/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java @@ -11,6 +11,7 @@ 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; @@ -88,15 +89,12 @@ public class StatsServiceImpl implements StatsService { @Override public Result query(Map 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 column=(List)c; - List parameterlist=(List)p; + ComStatsTemplate template =LisUtil.mapToEntity(list,"Template",ComStatsTemplate.class); + if(template==null )return new Result("-1","模板为空"); + List column=LisUtil.mapToEntityList(list,"Column",ComStatsParameter.class); + if(column==null )return new Result("-1","字段为空"); + List 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=""; From 533aada39228802af881e57e2e9839d1d04ee0c3 Mon Sep 17 00:00:00 2001 From: tangw Date: Sat, 28 Feb 2026 15:48:44 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interfaceCommon/utils/CalcUtils.java | 2 + .../liswork/mapper/stats/StatsMapper.java | 4 + .../service/impl/stats/StatsServiceImpl.java | 82 ++++++++++++++++--- .../src/main/resources/mapper/StatsMapper.xml | 4 +- 4 files changed, 81 insertions(+), 11 deletions(-) diff --git a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java index 3db6d36..9aa9258 100644 --- a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java +++ b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java @@ -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"); diff --git a/liswork/src/main/java/com/czlis/liswork/mapper/stats/StatsMapper.java b/liswork/src/main/java/com/czlis/liswork/mapper/stats/StatsMapper.java index f2db45e..66cc159 100644 --- a/liswork/src/main/java/com/czlis/liswork/mapper/stats/StatsMapper.java +++ b/liswork/src/main/java/com/czlis/liswork/mapper/stats/StatsMapper.java @@ -1,4 +1,8 @@ package com.czlis.liswork.mapper.stats; +import java.util.List; +import java.util.Map; + public interface StatsMapper { + List> getsqldata(String wheresql); } diff --git a/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java b/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java index 78f466e..23dc4c2 100644 --- a/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java +++ b/liswork/src/main/java/com/czlis/liswork/service/impl/stats/StatsServiceImpl.java @@ -7,6 +7,7 @@ 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; @@ -25,6 +26,8 @@ public class StatsServiceImpl implements StatsService { @Autowired ComStatsTemplateMapper comStatsTemplateMapper; @Autowired + StatsMapper statsMapper; + @Autowired LisWorkUtils lisWorkUtils; @Override public Result getTemplate(String statsCode){ @@ -91,24 +94,83 @@ public class StatsServiceImpl implements StatsService { if(list==null||list.isEmpty())return new Result("-1","入参为空"); ComStatsTemplate template =LisUtil.mapToEntity(list,"Template",ComStatsTemplate.class); if(template==null )return new Result("-1","模板为空"); - List column=LisUtil.mapToEntityList(list,"Column",ComStatsParameter.class); - if(column==null )return new Result("-1","字段为空"); + List columnlist=LisUtil.mapToEntityList(list,"Column",ComStatsParameter.class); + if(columnlist==null )return new Result("-1","字段为空"); List 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 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> datalist=statsMapper.getsqldata(statsSql); + return new Result("0","成功",datalist); + } + private String inputParameter(String sql,List parameterlist) { + String[] parameters = CalcUtils.getParameters(sql); + for (String itemcode : parameters){ + Optional 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 parameterlist) { Map variables = new HashMap<>(); diff --git a/liswork/src/main/resources/mapper/StatsMapper.xml b/liswork/src/main/resources/mapper/StatsMapper.xml index 25bf78e..986f2ae 100644 --- a/liswork/src/main/resources/mapper/StatsMapper.xml +++ b/liswork/src/main/resources/mapper/StatsMapper.xml @@ -2,5 +2,7 @@ - + \ No newline at end of file