package com.eip.common.util;
import cn.hutool.core.util.ReflectUtil;
import com.beust.jcommander.internal.Lists;
import com.eip.common.annotation.FieldName;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.persistence.Column;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 反射工具类
*
*/
@Slf4j
public class ReflectionUtils extends ReflectUtil {
/**
* 获取Object对象,所有成员变量属性值
*/
public static HashMap<String, Object> getObjAttr(Object obj) {
return getObjAttr(null, obj);
}
/**
* 获取Object对象,所有成员变量属性值
*/
public static HashMap<String, Object> getObjAttr(String prefix, Object obj) {
if (obj == null) return Maps.newHashMap();
Field[] fields = obj.getClass().getDeclaredFields();
HashMap<String, Object> map = Maps.newHashMap();
int count = 0;
for (Field field : fields) {
// 对于每个属性,获取属性名
String varName = field.getName();
try {
boolean access = field.isAccessible();
if (!access) {
field.setAccessible(true);
}
//反射获取所有成员变量值
Object o = field.get(obj);
if (PublicUtil.isNotEmpty(o)) count++;
if (StringUtils.isNotBlank(prefix)) map.put(prefix + "_" + varName, o);
if (StringUtils.isBlank(prefix)) map.put(varName, o);
if (!access) {
field.setAccessible(false);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
return count > 0 ? map : null;
}
/**
* 判断该对象是否
* @param obj 返回ture表示所有属性为null返回false表示不是所有属性都是null
* @return
*/
public static boolean isAllFieldNull(Object obj) {
boolean flag = true;
try {
Class stuCla = (Class) obj.getClass();//得到类对象
Field[] fs = stuCla.getDeclaredFields();//得到属性集合
for (Field f : fs) {//遍历属性
f.setAccessible(true);//设置属性是可以访问的(私有的也可以)
Object val = f.get(obj);
if (val != null) {//只要有1个属性不为空,那么就不是所有的属性值都为空
flag = false;
break;
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return flag;
}
/**
* 比较两个类型一样的对象中的值变更返回字符串
*
* @param pre 变化前的对象
* @param last 变化后的对象
* @param fileIds 需要比对的字段 all为全部
* @param orgNum 查询需要机构号时传入
* @return
* @apiNote 配合@FieldName注解一起使用
*/
public static String compareObjectDifferentAttributes(Object pre, Object last, String fileIds, Integer orgNum) {
if (StringUtils.isBlank(fileIds)) fileIds = "all";
List<String> fileIdList = Arrays.asList(fileIds.split(","));
StringBuilder result = new StringBuilder();
Class<?> preClass = pre.getClass();
Class<?> lastClass = last.getClass();
if (!preClass.equals(lastClass)) throw new RuntimeException("两个对象类型不一致");
Field[] declaredFields = preClass.getDeclaredFields();
for (Field field : declaredFields) {
//获取方法名
String fieldName = field.getName();
if (!"all".equalsIgnoreCase(fileIds) && !fileIdList.contains(fieldName)) continue;
try {
//没有注解跳过比较
if (!field.isAnnotationPresent(FieldName.class)) continue;
FieldName fieldAnno = field.getAnnotation(FieldName.class);
boolean access = field.isAccessible();
String type = field.getType().getName();
if (!access) field.setAccessible(true);
Object preValue = field.get(pre);
Object lastValue = field.get(last);
if ("".equals(preValue)) preValue = null;
if ("".equals(lastValue)) lastValue = null;
//BigDecimal 类型的数据要去掉小数点后尾部的0不一致造成数据比对差异
if ("java.math.BigDecimal".equals(type) && preValue != null && lastValue != null) {
BigDecimal valOldBig = new BigDecimal(String.valueOf(preValue));
BigDecimal valNewBig = new BigDecimal(String.valueOf(lastValue));
//由于无法获取精度值,只能对所有带小数点的数据进行处理
if (String.valueOf(valOldBig).contains(".") || String.valueOf(valNewBig).contains(".")) {
DecimalFormat formatter1 = new DecimalFormat("0.00");
preValue = formatter1.format(valOldBig);
lastValue = formatter1.format(valNewBig);
}
}
//DATE 类型的数据要格式化
if ("java.util.Date".equals(type)) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (preValue != null) preValue = sdf.format(preValue);
if (lastValue != null) lastValue = sdf.format(lastValue);
}
//如果前后两个值都是空,那么无需比较
if (Objects.isNull(preValue) && Objects.isNull(lastValue)) {
continue;
} else if (Objects.isNull(preValue) && Objects.nonNull(lastValue)) { //前值为空,后值不为空
if (fieldAnno.isForeignKey()) {
lastValue = getForeignKeyName(fieldAnno.sql(), lastValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam());
}else if(fieldAnno.isSysKey()){
lastValue = getSysKeyValue(fieldAnno.sysKey() ,lastValue);
}
result.append("'").append(fieldAnno.name()).append("'").append("由'空'变为").append("'").append(lastValue).append("'").append("\r\n");
} else if (Objects.nonNull(preValue) && Objects.isNull(lastValue)) {//前值不为空,后值为空
if (fieldAnno.isForeignKey()) {
preValue = getForeignKeyName(fieldAnno.sql(), preValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam());
}else if(fieldAnno.isSysKey()){
preValue = getSysKeyValue(fieldAnno.sysKey() ,preValue);
}
result.append("'").append(fieldAnno.name()).append("'").append("由").append("'").append(preValue).append("'").append("变为'空'").append("\r\n");
} else if (Objects.nonNull(preValue) && Objects.nonNull(lastValue)) { //两个都不为空
if (preValue.equals(lastValue)) continue;
//是否外键
if (fieldAnno.isForeignKey()) {
preValue = getForeignKeyName(fieldAnno.sql(), preValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam());
lastValue = getForeignKeyName(fieldAnno.sql(), lastValue, fieldAnno.isOrgNum(), orgNum,fieldAnno.isStringParam());
}else if(fieldAnno.isSysKey()){
preValue = getSysKeyValue(fieldAnno.sysKey() ,preValue);
lastValue = getSysKeyValue(fieldAnno.sysKey() ,lastValue);
}
result.append("'").append(fieldAnno.name()).append("'").append("由").append("'")
.append(preValue).append("'").append("变为").append("'").append(lastValue).append("'").append("\r\n");
}
if (!access) field.setAccessible(false);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return result.toString();
}
/**
* 查询系统定义的值
* @param sysKey
* @param value
* @return
*/
@SuppressWarnings("unchecked")
public static String getSysKeyValue(String sysKey ,Object value) {
if(StringUtils.isBlank(sysKey))return value.toString();
try {
Map<String, String> map = Maps.newHashMap();
map = new Gson().fromJson(sysKey, map.getClass());
return map.get(value.toString())==null?value.toString():map.get(value.toString());
} catch (Exception e) {
return value.toString();
}
}
/**
* 查询外键所对应的名称
*
* @param sql
* @param value
* @param isOrgNum
* @return
*/
public static String getForeignKeyName(String sql, Object value, boolean isOrgNum, Integer orgNum,boolean isStringParam) {
// Preconditions.checkArgument(StringUtils.isNotBlank(sql), "sql不能为空!");
if (StringUtils.isBlank(sql)) return "";
try {
JdbcTemplate bean = ApplicationContextHolder.getBean(JdbcTemplate.class);
Object[] args ;
if(isStringParam){
args = new Object[]{value.toString()};
}else{
args = new Object[]{Integer.valueOf(value.toString())};
}
if (isOrgNum) {
sql += " and f_org_num = ?";
if(isStringParam){
args = new Object[]{value.toString(), orgNum};
}else{
args = new Object[]{Integer.valueOf(value.toString()), orgNum};
}
}
return bean.queryForObject(sql, args, String.class);
} catch (Exception e) {
return "空";
}
}
/**
* 解析方法注解
*
* @param clazz
*/
public static String getAnnotationAttribute(Class<?> clazz, String attributeField) {
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().equalsIgnoreCase(attributeField) && field.isAnnotationPresent(Column.class)) {
Column column = field.getAnnotation(Column.class);
// System.out.println(column.name());
return column.name();
}
}
return null;
}
/**
* 获取字段属性
*
* @param clazz
* @param attributeField
* @return
*/
public static String getFieldType(Class<?> clazz, String attributeField) {
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().equalsIgnoreCase(attributeField)) {
return field.getType().toString();
}
}
return null;
}
/**
* 获取字段名称
* @param clazz
* @param ignoreFields
* @return
*/
public static String[] getFieldName(Class<?> clazz, String ignoreFields) {
if(ignoreFields==null)ignoreFields="";
List<String> list = Lists.newArrayList();
for (Field field : clazz.getDeclaredFields()) {
if (!ignoreFields.contains(field.getName())) {
list.add(field.getName());
}
}
return list.stream().toArray(String[]::new);
}
/**
* 通过反射实现get方法
* @param o 要操作类的对象
* @param args 属性名
* @param <T>
* @return
* @throws NoSuchFieldException
*/
public static <T> T getMethod(T o,String args) throws NoSuchFieldException {
Class cls = o.getClass();
//判断该属性是否存在
Field field = cls.getDeclaredField(args);
if(field == null){
field = cls.getField(args);
}
if(field == null){
return (T)"";
}
String fieldName = "get"+args.substring(0,1).toUpperCase()+(args.length()>1?args.substring(1):"");
Method method;
try {
method = cls.getMethod(fieldName);
//Boolean返回 true是 false否
if(getFieldType(cls,args).equals("class java.lang.Boolean")){
Boolean invoke = (Boolean)method.invoke(o);
return invoke.equals(true) ?(T)"是" :(T)"否";
}
//Date返回 yyyy-MM-dd
else if (getFieldType(cls,args).equals("class java.util.Date")){
if(method.invoke(o)!=null){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(method.invoke(o));
return (T)date;
}
}
return (T)method.invoke(o);
} catch (NoSuchMethodException e) {
log.error(e.getMessage());
} catch (IllegalAccessException e) {
log.error(e.getMessage());
} catch (InvocationTargetException e) {
log.error(e.getMessage());
}
return (T)"";
}
}