This commit is contained in:
tangw 2026-02-28 10:22:47 +08:00
parent 03fbbea28a
commit 7f91844201
2 changed files with 199 additions and 9 deletions

View File

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

View File

@ -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<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> column=LisUtil.mapToEntityList(list,"Column",ComStatsParameter.class);
if(column==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="";