From 7f91844201db638b62d1ab43cf434976cc60e77b Mon Sep 17 00:00:00 2001 From: tangw Date: Sat, 28 Feb 2026 10:22:47 +0800 Subject: [PATCH] =?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="";