This commit is contained in:
parent
e8223a832b
commit
b20a3ef103
|
|
@ -0,0 +1,23 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface Elog {
|
||||
|
||||
String module();
|
||||
|
||||
String function();
|
||||
|
||||
String operateType();
|
||||
|
||||
String operateTypeName();
|
||||
|
||||
String sql() default "";
|
||||
|
||||
boolean isLocal() default true;
|
||||
|
||||
String infoMethod() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface ElogDetailField {
|
||||
|
||||
String fieldType() default "varchar";
|
||||
String length() default "50";
|
||||
String fieldName();
|
||||
String desc() default "自定义字段";
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface ElogDetailTable {
|
||||
|
||||
String module();
|
||||
|
||||
String function() default "common";
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import com.engine.salary.elog.dto.DateTypeEnum;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface ElogField {
|
||||
|
||||
DateTypeEnum dataType() default DateTypeEnum.VARCHAR;
|
||||
|
||||
int length() default 50;
|
||||
|
||||
String comment() default "自定义字段";
|
||||
|
||||
String defaultValue() default "";
|
||||
|
||||
boolean isNull() default true;
|
||||
|
||||
boolean isKey() default false;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
public @interface ElogPrimaryKey {
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
@Component
|
||||
public @interface ElogTable {
|
||||
|
||||
String module();
|
||||
|
||||
String function() default "common";
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.engine.salary.elog.annotation;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @ClassName: LoggerTarget
|
||||
* @Description 日志构造器-自定义注解
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface LoggerTarget {
|
||||
@AliasFor("module")
|
||||
String value() default "";
|
||||
|
||||
@AliasFor("value")
|
||||
String module() default "";
|
||||
|
||||
String function() default "common";
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
package com.engine.salary.elog.annotation.handle;
|
||||
|
||||
import com.weaver.common.async.producer.client.AsyncClient;
|
||||
import com.weaver.common.distribution.genid.IdGenerator;
|
||||
import com.weaver.common.elog.annotation.Elog;
|
||||
import com.weaver.common.elog.annotation.ElogPrimaryKey;
|
||||
import com.weaver.common.elog.dao.QueryCurretValusMapper;
|
||||
import com.weaver.common.elog.dto.LoggerContext;
|
||||
import com.weaver.common.elog.util.LoggerTemplate;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName: LoggerTargetHandler
|
||||
* @Description 从Spring扫描到的类中获取到Elog自定义注解类设置function属性
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class ElogHandler {
|
||||
|
||||
@Autowired
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
protected AsyncClient asyncClient;
|
||||
|
||||
@Autowired
|
||||
QueryCurretValusMapper queryCurretValusMapper;
|
||||
|
||||
/**
|
||||
* 切面写入日志
|
||||
*/
|
||||
@Pointcut("@annotation(com.weaver.common.elog.annotation.Elog)" )
|
||||
public void writeLog(){}
|
||||
@Around("writeLog()")
|
||||
public Object writeLog(ProceedingJoinPoint pjp){
|
||||
Object[] args = pjp.getArgs();
|
||||
Signature signature = pjp.getSignature();
|
||||
MethodSignature methodSignature = (MethodSignature) signature;
|
||||
Method method = methodSignature.getMethod();
|
||||
|
||||
Elog elog = method.getAnnotation(Elog.class);
|
||||
String moduleName = elog.module();
|
||||
String funtionName = elog.function();
|
||||
String operateType = elog.operateType();
|
||||
String operateTypeName = elog.operateTypeName();
|
||||
boolean isLocal = elog.isLocal();
|
||||
Annotation[][] annos = method.getParameterAnnotations();
|
||||
|
||||
Object id = null;
|
||||
int keyPosition = -1;
|
||||
int index = 0;
|
||||
|
||||
Class idClass = null;
|
||||
// 获取主键id注解
|
||||
for(Annotation[] anno : annos) {
|
||||
if(anno.length > 0) {
|
||||
for(Annotation annotation : anno) {
|
||||
if(annotation instanceof ElogPrimaryKey) {
|
||||
idClass = method.getParameters()[index].getType();
|
||||
id = args[index];
|
||||
if(StringUtils.isEmpty(id+"")) {
|
||||
id = idClass.cast(IdGenerator.generate() + "");
|
||||
}
|
||||
keyPosition = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
index ++;
|
||||
}
|
||||
|
||||
LoggerContext loggerContext = null;
|
||||
// 获取日志实体类
|
||||
for(Object arg: args) {
|
||||
if(arg instanceof LoggerContext) {
|
||||
loggerContext = (LoggerContext) arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(loggerContext == null) {
|
||||
loggerContext = new LoggerContext();
|
||||
}
|
||||
|
||||
// 日志实体类的初始化
|
||||
// loggerContext.setOperateType("UPDATE");
|
||||
loggerContext.setFunctionName(funtionName);
|
||||
loggerContext.setModuleName(moduleName);
|
||||
loggerContext.setOperateType(operateType);
|
||||
loggerContext.setOperateTypeName(operateTypeName);
|
||||
loggerContext.setDate(new Date());
|
||||
loggerContext.setDevice("IOS");
|
||||
|
||||
String sql = elog.sql();
|
||||
String infoMethod = elog.infoMethod();
|
||||
|
||||
boolean isSql = false;
|
||||
boolean isMethod = false;
|
||||
Object currentClass = null;
|
||||
Method infoMtd = null;
|
||||
if(StringUtils.isNotEmpty(id+"")) {
|
||||
if(StringUtils.isNotEmpty(sql)) {
|
||||
isSql = true;
|
||||
Map oldValue = queryCurretValusMapper.queryValues(String.format(sql, id));
|
||||
loggerContext.setOldValues(oldValue);
|
||||
} else if(StringUtils.isNotEmpty(infoMethod)){
|
||||
isMethod = true;
|
||||
currentClass = applicationContext.getBean(pjp.getTarget().getClass());
|
||||
// 获取方法
|
||||
infoMtd = ReflectionUtils.findMethod(pjp.getTarget().getClass(),infoMethod, idClass);
|
||||
|
||||
// todo 为空的情况加异常提醒
|
||||
// 反射执行方法
|
||||
Object res= ReflectionUtils.invokeMethod(infoMtd,currentClass, id);
|
||||
if(res != null) {
|
||||
if(res instanceof List) {
|
||||
loggerContext.setOldValueList((List) res);
|
||||
} else {
|
||||
loggerContext.setOldValues(res);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoggerTemplate loggerTemplate = new LoggerTemplate();
|
||||
loggerTemplate.setFunction(funtionName);
|
||||
loggerTemplate.setModule(moduleName);
|
||||
loggerTemplate.setAsyncClient(asyncClient);
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
args[keyPosition] = id;
|
||||
result = pjp.proceed(args);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
if(isSql) {
|
||||
Map oldValue = queryCurretValusMapper.queryValues(String.format(sql, id));
|
||||
loggerContext.setNewValues(oldValue);
|
||||
} else if(isMethod) {
|
||||
Object res= ReflectionUtils.invokeMethod(infoMtd,currentClass, id);
|
||||
if(res != null) {
|
||||
if(res instanceof List) {
|
||||
loggerContext.setNewValueList((List) res);
|
||||
} else {
|
||||
loggerContext.setNewValues(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isLocal)
|
||||
loggerTemplate.write(loggerContext);
|
||||
else
|
||||
loggerTemplate.write(loggerContext,false);
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
package com.engine.salary.elog.annotation.handle;
|
||||
|
||||
import com.engine.salary.elog.annotation.ElogField;
|
||||
import com.engine.salary.elog.annotation.ElogTable;
|
||||
import com.engine.salary.elog.dto.TableColumnBean;
|
||||
import com.engine.salary.elog.util.ElogUtils;
|
||||
import com.weaver.common.elog.dao.TableCheckerMapper;
|
||||
import com.weaver.common.elog.dto.DateTypeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @ClassName: ElogTableScanner
|
||||
* @Description 日志操作表扫描
|
||||
* @Author tanghj
|
||||
* @Date 2021/3/12 13:31
|
||||
*/
|
||||
@Slf4j
|
||||
public class ElogTableScanner {
|
||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Resource
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private TableCheckerMapper tableCheckerMapper;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
|
||||
// todo 需要考虑集群下,控制一台机器来跑
|
||||
scanElogTable();
|
||||
|
||||
}
|
||||
|
||||
private void scanElogTable() {
|
||||
// todo 是否还需要扫描Elog(因为可能不需要本地存储) ELogDetailTable,
|
||||
Map<String, Object> tableBeans = this.applicationContext.getBeansWithAnnotation(ElogTable.class);
|
||||
Reflections reflections = new Reflections("com.example.controller");
|
||||
Set<Class<?>> restController = reflections.getTypesAnnotatedWith(RestController.class);
|
||||
|
||||
List<TableColumnBean> baseColumns = new ArrayList<>();
|
||||
|
||||
Map<String, List<TableColumnBean>> tableColumns = elogTableHandle(tableBeans,baseColumns);
|
||||
|
||||
for(String tableName : tableColumns.keySet()) {
|
||||
|
||||
// todo 需要处理明细表,如果没有直接初始化原始明细表,如果有加上自定义的
|
||||
List<TableColumnBean> columns = tableColumns.get(tableName);
|
||||
if(columns == null) {
|
||||
columns = baseColumns;
|
||||
} else {
|
||||
columns.addAll(baseColumns);
|
||||
}
|
||||
tableCheck(tableName, columns);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<String, List<TableColumnBean>> elogTableHandle(Map<String, Object> tableBeans, List<TableColumnBean> baseColumns) {
|
||||
|
||||
|
||||
Map<String, List<TableColumnBean>> tableMap = new HashMap<>();
|
||||
|
||||
|
||||
for (Map.Entry<String, Object> entry : tableBeans.entrySet()) {//遍历每个controller层
|
||||
|
||||
List<TableColumnBean> list = new ArrayList<>();
|
||||
System.out.println(entry.getKey());//demo1Controller
|
||||
Object value = entry.getValue();
|
||||
Class<?> aClass = AopUtils.getTargetClass(value);//获取class
|
||||
|
||||
ElogTable elogTable = aClass.getAnnotation(ElogTable.class);
|
||||
|
||||
List<Field> fields = Arrays.asList(aClass.getDeclaredFields());//获取方法
|
||||
for (Field f : fields) {
|
||||
|
||||
ElogField field = f.getAnnotation(ElogField.class);
|
||||
if(field == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TableColumnBean tableColumnBean = new TableColumnBean();
|
||||
|
||||
tableColumnBean.setColumnName(f.getName());
|
||||
tableColumnBean.setColumnComment(field.comment());
|
||||
tableColumnBean.setColumnDefault(field.defaultValue());
|
||||
tableColumnBean.setFieldLength(field.length());
|
||||
tableColumnBean.setDataType(field.dataType());
|
||||
tableColumnBean.setNullable(field.isNull());
|
||||
list.add(tableColumnBean);
|
||||
}
|
||||
if(!ElogUtils.BASE_TABLE.equals(elogTable.module())) {
|
||||
|
||||
tableMap.put(ElogUtils.getTableName(elogTable.module(), elogTable.function()), list);
|
||||
} else {
|
||||
baseColumns.addAll(list);
|
||||
}
|
||||
}
|
||||
|
||||
return tableMap;
|
||||
}
|
||||
|
||||
private void tableCheck(String tableName, List<TableColumnBean> columns) {
|
||||
|
||||
List<TableColumnBean> oldColumns = tableCheckerMapper.getTableStructure(tableName);
|
||||
|
||||
// 表不存在
|
||||
if(oldColumns == null || oldColumns.size() == 0) {
|
||||
createTable(tableName,columns );
|
||||
} else {
|
||||
Map<String, TableColumnBean> newcolMap = new HashMap<>();
|
||||
Map<String, TableColumnBean> oldcolMap = new HashMap<>();
|
||||
|
||||
columns.stream().forEach(tableColumnBean -> newcolMap.put(tableColumnBean.getColumnName().toLowerCase(), tableColumnBean));
|
||||
oldColumns.stream().forEach(tableColumnBean -> {
|
||||
tableColumnBean.setDataType(ElogUtils.getEnumFromString(DateTypeEnum.class, tableColumnBean.getDataTypeStr()));
|
||||
tableColumnBean.setNullable("YES".equalsIgnoreCase(tableColumnBean.getIsNullableStr()));
|
||||
oldcolMap.put(tableColumnBean.getColumnName().toLowerCase(), tableColumnBean);
|
||||
});
|
||||
// 只增加或者修改,不删除字段
|
||||
for(String key : newcolMap.keySet()) {
|
||||
if(oldcolMap.containsKey(key)) {
|
||||
// 字段变动则修改
|
||||
if(!(newcolMap.get(key).toSql()).equals(oldcolMap.get(key).toSql()))
|
||||
this.modifyColumn(tableName, newcolMap.get(key));
|
||||
} else {
|
||||
this.addColumn(tableName, newcolMap.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createTable(String tableName, List<TableColumnBean> columns) {
|
||||
StringBuilder sb = new StringBuilder("create table ").append(tableName).append(" ( ");
|
||||
sb.append(columns.stream().map( bean -> bean.toSql()).collect(Collectors.joining(",")));
|
||||
sb.append(")");
|
||||
logger.info("创建sql:{}",sb.toString());
|
||||
tableCheckerMapper.createElogTable(sb.toString());
|
||||
}
|
||||
|
||||
private void addColumn(String tableName, TableColumnBean tableColumnBean) {
|
||||
StringBuilder sb = new StringBuilder("alter table ")
|
||||
.append(tableName).append(" ")
|
||||
.append(" add ")
|
||||
.append(" column ")
|
||||
.append(tableColumnBean.toSql());
|
||||
logger.info("新增字段sql:{}",sb.toString());
|
||||
tableCheckerMapper.createElogTable(sb.toString());
|
||||
}
|
||||
|
||||
private void modifyColumn(String tableName, TableColumnBean tableColumnBean) {
|
||||
StringBuilder sb = new StringBuilder("alter table ")
|
||||
.append(tableName).append(" ")
|
||||
.append(" modify ")
|
||||
.append(" column ")
|
||||
.append(tableColumnBean.toSql());
|
||||
logger.info("修改字段sql:{}",sb.toString());
|
||||
tableCheckerMapper.createElogTable(sb.toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.engine.salary.elog.annotation.handle;
|
||||
|
||||
import com.weaver.common.elog.annotation.LoggerTarget;
|
||||
import com.weaver.common.elog.util.LoggerTemplate;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName: LoggerTargetHandler
|
||||
* @Description 从Spring扫描到的类中获取到LoggerTarget自定义注解类设置function属性
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class LoggerTargetHandler implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
Map<String, Object> loggtemplateMap = applicationContext.getBeansWithAnnotation(LoggerTarget.class);
|
||||
|
||||
for(Object obj : loggtemplateMap.values()) {
|
||||
if(obj instanceof LoggerTemplate) {
|
||||
LoggerTarget loggerTarget = obj.getClass().getAnnotation(LoggerTarget.class);
|
||||
((LoggerTemplate) obj).setFunction(loggerTarget.function());
|
||||
((LoggerTemplate) obj).setModule(StringUtils.isNotEmpty(loggerTarget.value()) ? loggerTarget.value() : loggerTarget.module());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: CancelContext
|
||||
* @Description 撤销实体类
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
@ApiModel("撤销实体类")
|
||||
public class CancelContext<T> {
|
||||
|
||||
@ApiModelProperty("撤销参数")
|
||||
private T cancleParams;
|
||||
|
||||
public T getCancleParams() {
|
||||
return cancleParams;
|
||||
}
|
||||
|
||||
public void setCancleParams(T cancleParams) {
|
||||
this.cancleParams = cancleParams;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
public enum DateTypeEnum {
|
||||
VARCHAR,
|
||||
BIGINT,
|
||||
INT,
|
||||
DATETIME,
|
||||
TEXT,
|
||||
LONGTEXT,
|
||||
DOUBLE,
|
||||
DECIMAL,
|
||||
TINYINT,
|
||||
FLOAT;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
import com.engine.salary.elog.annotation.ElogField;
|
||||
import com.engine.salary.elog.annotation.ElogTable;
|
||||
import com.engine.salary.elog.util.ElogUtils;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName: LoggerContext
|
||||
* @Description 日志实体类。支持通过泛型扩展日志字段
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
@ElogTable(module = ElogUtils.BASE_TABLE)
|
||||
@ApiModel("日志实体类")
|
||||
public class LoggerContext<T> {
|
||||
@ElogField(comment = "ID", dataType = DateTypeEnum.VARCHAR, isKey = true, isNull = false)
|
||||
@ApiModelProperty("日志ID")
|
||||
private long id;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 36,comment = "日志UUID")
|
||||
@ApiModelProperty("日志UUID")
|
||||
private String uuid;
|
||||
|
||||
@ApiModelProperty("自定义日志字段信息")
|
||||
private T customInfo;
|
||||
@ElogField(dataType = DateTypeEnum.DATETIME,comment = "操作时间")
|
||||
@ApiModelProperty("操作时间")
|
||||
private Date date;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR,length = 50,comment = "终端信息")
|
||||
@ApiModelProperty("终端信息")
|
||||
private String device;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR,length = 50,comment = "操作人")
|
||||
@ApiModelProperty("操作人")
|
||||
private String operator;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR,length = 100,comment = "操作人姓名")
|
||||
@ApiModelProperty("操作人姓名")
|
||||
private String operatorName;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR,length = 10,comment = "租户id")
|
||||
@ApiModelProperty("租户id")
|
||||
private String tenant_key;
|
||||
|
||||
/**
|
||||
* 要操作的对象在表中的主键值
|
||||
*/
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR,length = 50,comment = "操作目标id")
|
||||
@ApiModelProperty("操作目标id")
|
||||
private String targetId;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.TEXT ,comment = "操作目标名称")
|
||||
@ApiModelProperty("操作目标名称(用于显示)")
|
||||
private String targetName;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 100,comment = "模块")
|
||||
@ApiModelProperty("目标对象类型(大分类,模块,服务)")
|
||||
private String moduleName;// 模块
|
||||
|
||||
/**
|
||||
* 目标对象类型(小分类,模块/服务下的子功能。子项目)
|
||||
* 数据存储是以模块名_子项目名作为最基本的存储单元
|
||||
* 如果是子项目下的子项目 命名为:子项目名_子项目名_子项目名(全部小写)
|
||||
*/
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 100,comment = "服务(方法)")
|
||||
@ApiModelProperty("目标对象类型(小分类,模块/服务下的子功能。子项目)")
|
||||
private String functionName;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 100,comment = "访问接口名")
|
||||
@ApiModelProperty("访问接口名")
|
||||
private String interfaceName;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 50,comment = "操作类型")
|
||||
@ApiModelProperty("操作类型(增删改查等)")
|
||||
private String operateType;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.TEXT,comment = "操作类型")
|
||||
@ApiModelProperty("操作类型名称")
|
||||
private String operateTypeName;
|
||||
|
||||
/**
|
||||
* 每个TableChangeBean 为一张表,支持记录多张表的前后值
|
||||
*/
|
||||
@ApiModelProperty("修改前、后的值")
|
||||
private List<TableChangeBean> changeValues;// 操作表名,[字段名,值]
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.TEXT,comment = "操作类型")
|
||||
@ApiModelProperty("操作详细说明")
|
||||
private String operatedesc;
|
||||
|
||||
@ApiModelProperty("涉及的相关参数")
|
||||
private Map<String, Object> params;
|
||||
|
||||
/*@ApiModelProperty("主日志")
|
||||
private String mainId;//当作为主表,belongMainId不赋值
|
||||
|
||||
@ApiModelProperty("从表日志")
|
||||
private String belongMainId;*/
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 50,comment = "操作IP")
|
||||
@ApiModelProperty("操作IP")
|
||||
private String clientIp;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 50,comment = "分组")
|
||||
@ApiModelProperty("分组")
|
||||
private String groupId;
|
||||
|
||||
/*@ApiModelProperty("是否明显表")
|
||||
private boolean isDetail;*/
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.TEXT, comment = "分组标题")
|
||||
@ApiModelProperty("分组标题")
|
||||
private int groupNameLabel;
|
||||
|
||||
@ApiModelProperty("重做业务接口")
|
||||
private String redoService;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.LONGTEXT, comment = "重做参数")
|
||||
@ApiModelProperty("重做参数")
|
||||
private RedoContext redoContext;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.VARCHAR, length = 200, comment = "撤销业务接口")
|
||||
@ApiModelProperty("撤销业务接口")
|
||||
private String cancelService;
|
||||
|
||||
@ElogField(dataType = DateTypeEnum.LONGTEXT, comment = "撤销参数")
|
||||
@ApiModelProperty("撤销参数")
|
||||
private CancelContext cancelContext;
|
||||
|
||||
@ApiModelProperty("日志明细列表(值变化列表-自动赋值、或者自定义字段)")
|
||||
private List<LoggerDetailContext> detailContexts;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public T getCustomInfo() {
|
||||
return customInfo;
|
||||
}
|
||||
|
||||
public void setCustomInfo(T customInfo) {
|
||||
this.customInfo = customInfo;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
public void setDevice(String device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public String getTenant_key() {
|
||||
return tenant_key;
|
||||
}
|
||||
|
||||
public void setTenant_key(String tenant_key) {
|
||||
this.tenant_key = tenant_key;
|
||||
}
|
||||
|
||||
public String getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
public void setTargetId(String targetId) {
|
||||
this.targetId = targetId;
|
||||
}
|
||||
|
||||
public String getTargetName() {
|
||||
return targetName;
|
||||
}
|
||||
|
||||
public void setTargetName(String targetName) {
|
||||
this.targetName = targetName;
|
||||
}
|
||||
|
||||
public String getModuleName() {
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
public void setModuleName(String moduleName) {
|
||||
this.moduleName = moduleName;
|
||||
}
|
||||
|
||||
public String getFunctionName() {
|
||||
return functionName;
|
||||
}
|
||||
|
||||
public void setFunctionName(String functionName) {
|
||||
this.functionName = functionName;
|
||||
}
|
||||
|
||||
public String getInterfaceName() {
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
public void setInterfaceName(String interfaceName) {
|
||||
this.interfaceName = interfaceName;
|
||||
}
|
||||
|
||||
public String getOperateType() {
|
||||
return operateType;
|
||||
}
|
||||
|
||||
public void setOperateType(String operateType) {
|
||||
this.operateType = operateType;
|
||||
}
|
||||
|
||||
public List<TableChangeBean> getChangeValues() {
|
||||
return changeValues;
|
||||
}
|
||||
|
||||
public void setChangeValues(List<TableChangeBean> changeValues) {
|
||||
this.changeValues = changeValues;
|
||||
}
|
||||
|
||||
public String getOperatedesc() {
|
||||
return operatedesc;
|
||||
}
|
||||
|
||||
public void setOperatedesc(String operatedesc) {
|
||||
this.operatedesc = operatedesc;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
/*public String getMainId() {
|
||||
return mainId;
|
||||
}
|
||||
|
||||
public void setMainId(String mainId) {
|
||||
this.mainId = mainId;
|
||||
}
|
||||
|
||||
public String getBelongMainId() {
|
||||
return belongMainId;
|
||||
}
|
||||
|
||||
public void setBelongMainId(String belongMainId) {
|
||||
this.belongMainId = belongMainId;
|
||||
}*/
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
public void setClientIp(String clientIp) {
|
||||
this.clientIp = clientIp;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
/* public boolean isDetail() {
|
||||
return isDetail;
|
||||
}
|
||||
|
||||
public void setDetail(boolean detail) {
|
||||
isDetail = detail;
|
||||
}*/
|
||||
|
||||
public int getGroupNameLabel() {
|
||||
return groupNameLabel;
|
||||
}
|
||||
|
||||
public void setGroupNameLabel(int groupNameLabel) {
|
||||
this.groupNameLabel = groupNameLabel;
|
||||
}
|
||||
|
||||
public String getRedoService() {
|
||||
return redoService;
|
||||
}
|
||||
|
||||
public void setRedoService(String redoService) {
|
||||
this.redoService = redoService;
|
||||
}
|
||||
|
||||
public RedoContext getRedoContext() {
|
||||
return redoContext;
|
||||
}
|
||||
|
||||
public void setRedoContext(RedoContext redoContext) {
|
||||
this.redoContext = redoContext;
|
||||
}
|
||||
|
||||
public CancelContext getCancelContext() {
|
||||
return cancelContext;
|
||||
}
|
||||
|
||||
public void setCancelContext(CancelContext cancelContext) {
|
||||
this.cancelContext = cancelContext;
|
||||
}
|
||||
|
||||
public String getCancelService() {
|
||||
return cancelService;
|
||||
}
|
||||
public void setCancelService(String cancelService) {
|
||||
this.cancelService = cancelService;
|
||||
}
|
||||
|
||||
public List<LoggerDetailContext> getDetailContexts() {
|
||||
return detailContexts;
|
||||
}
|
||||
|
||||
public void setDetailContexts(List<LoggerDetailContext> detailContexts) {
|
||||
this.detailContexts = detailContexts;
|
||||
}
|
||||
|
||||
public String getOperatorName() {
|
||||
return operatorName;
|
||||
}
|
||||
|
||||
public void setOperatorName(String operatorName) {
|
||||
this.operatorName = operatorName;
|
||||
}
|
||||
|
||||
public void setOldValues(Object object) {
|
||||
TableChangeBean bean = new TableChangeBean();
|
||||
bean.setOldValue(object);
|
||||
getChangeList().add(bean);
|
||||
}
|
||||
|
||||
public void setOldValueList(List<Object> list) {
|
||||
if(list != null)
|
||||
list.stream().forEach(obj -> setOldValues(obj));
|
||||
}
|
||||
|
||||
public void setNewValueList(List<Object> list) {
|
||||
if(list != null)
|
||||
list.stream().forEach(obj -> setNewValues(obj));
|
||||
}
|
||||
|
||||
public void setNewValues(Object object) {
|
||||
List<TableChangeBean> list = getChangeList();
|
||||
|
||||
boolean handled = false;
|
||||
for(TableChangeBean bean : list) {
|
||||
if(bean.getNewValue() == null) {
|
||||
bean.setNewValue(object);
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!handled) {
|
||||
TableChangeBean bean = new TableChangeBean();
|
||||
bean.setOldValue(object);
|
||||
list.add(bean);
|
||||
}
|
||||
}
|
||||
|
||||
public List<TableChangeBean> getChangeList() {
|
||||
|
||||
if(this.changeValues == null) {
|
||||
this.changeValues = new ArrayList<>();
|
||||
}
|
||||
|
||||
return this.changeValues;
|
||||
|
||||
}
|
||||
|
||||
public String getOperateTypeName() {
|
||||
return operateTypeName;
|
||||
}
|
||||
|
||||
public void setOperateTypeName(String operateTypeName) {
|
||||
this.operateTypeName = operateTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: ValueChangeBean
|
||||
* @Description 值变化实体类(自动将表字段值变更类转换为该类)
|
||||
* @Author tanghj
|
||||
* @Date 2021/3/9 11:06
|
||||
*/
|
||||
@ApiModel("值变化实体类")
|
||||
public class LoggerDetailContext<T> {
|
||||
|
||||
@ApiModelProperty("同一个bean转换的数据,uuid相同,作为区分标识")
|
||||
private String uuid;
|
||||
|
||||
@ApiModelProperty("表名")
|
||||
private String tableName;
|
||||
|
||||
@ApiModelProperty("字段名")
|
||||
private String fieldName;
|
||||
|
||||
@ApiModelProperty("更新后的值")
|
||||
private String newValue;
|
||||
|
||||
@ApiModelProperty("更新前的值")
|
||||
private String oldValue;
|
||||
|
||||
@ApiModelProperty("字段描述")
|
||||
private String fieldDesc;
|
||||
|
||||
@ApiModelProperty("字段展示顺序")
|
||||
private int showorder;
|
||||
|
||||
@ApiModelProperty("自定义字段")
|
||||
private T customDetailInfo;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public String getNewValue() {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
public void setNewValue(String newValue) {
|
||||
this.newValue = newValue;
|
||||
}
|
||||
|
||||
public String getOldValue() {
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public void setOldValue(String oldValue) {
|
||||
this.oldValue = oldValue;
|
||||
}
|
||||
|
||||
public String getFieldDesc() {
|
||||
return fieldDesc;
|
||||
}
|
||||
|
||||
public void setFieldDesc(String fieldDesc) {
|
||||
this.fieldDesc = fieldDesc;
|
||||
}
|
||||
|
||||
public int getShoworder() {
|
||||
return showorder;
|
||||
}
|
||||
|
||||
public void setShoworder(int showorder) {
|
||||
this.showorder = showorder;
|
||||
}
|
||||
|
||||
public T getCustomDetailInfo() {
|
||||
return customDetailInfo;
|
||||
}
|
||||
|
||||
public void setCustomDetailInfo(T customDetailInfo) {
|
||||
this.customDetailInfo = customDetailInfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: RedoContext
|
||||
* @Description 重做实体类
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
@ApiModel("重做实体类")
|
||||
public class RedoContext<T> {
|
||||
@ApiModelProperty("重做参数")
|
||||
private T redoParams;
|
||||
|
||||
public T getRedoParams() {
|
||||
return redoParams;
|
||||
}
|
||||
|
||||
public void setRedoParams(T redoParams) {
|
||||
this.redoParams = redoParams;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: TableChangeBean
|
||||
* @Description 表更新前后值类
|
||||
* @Author tanghj
|
||||
* @Date 2021/3/8 15:58
|
||||
*/
|
||||
@ApiModel("表更新前后值类")
|
||||
public class TableChangeBean<T> {
|
||||
|
||||
@ApiModelProperty("表名")
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 泛型必须是具体的实体类
|
||||
*/
|
||||
@ApiModelProperty("更新前的值")
|
||||
private T oldValue;
|
||||
|
||||
/**
|
||||
* 泛型必须是具体的实体类
|
||||
*/
|
||||
@ApiModelProperty("更新后的值")
|
||||
private T newValue;
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public T getOldValue() {
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public void setOldValue(T oldValue) {
|
||||
this.oldValue = oldValue;
|
||||
}
|
||||
|
||||
public T getNewValue() {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
public void setNewValue(T newValue) {
|
||||
this.newValue = newValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
package com.engine.salary.elog.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @ClassName: TableColumnBean
|
||||
* @Description 表字段类
|
||||
* @Author tanghj
|
||||
* @Date 2021/3/12 11:44
|
||||
*/
|
||||
@ApiModel("表字段类")
|
||||
public class TableColumnBean {
|
||||
|
||||
@ApiModelProperty("列名")
|
||||
private String columnName;
|
||||
|
||||
/**
|
||||
* varchar(20)
|
||||
*/
|
||||
@ApiModelProperty("数据类型")
|
||||
private String columnType;
|
||||
|
||||
@ApiModelProperty("字段类型-字符串")
|
||||
private String dataTypeStr;
|
||||
|
||||
@ApiModelProperty("字段类型")
|
||||
private DateTypeEnum dataType;
|
||||
|
||||
@ApiModelProperty("长度")
|
||||
private long fieldLength;
|
||||
|
||||
@ApiModelProperty("是否为空")
|
||||
private boolean isNullable;
|
||||
|
||||
@ApiModelProperty("是否为空-字符串")
|
||||
private String isNullableStr;
|
||||
|
||||
@ApiModelProperty("默认值")
|
||||
private Object columnDefault;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String columnComment;
|
||||
|
||||
public String getColumnName() {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
public void setColumnName(String columnName) {
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
public String getColumnType() {
|
||||
return columnType;
|
||||
}
|
||||
|
||||
public void setColumnType(String columnType) {
|
||||
this.columnType = columnType;
|
||||
}
|
||||
|
||||
public DateTypeEnum getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public void setDataType(DateTypeEnum dataType) {
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
public long getFieldLength() {
|
||||
return fieldLength;
|
||||
}
|
||||
|
||||
public void setFieldLength(long fieldLength) {
|
||||
this.fieldLength = fieldLength;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return isNullable;
|
||||
}
|
||||
|
||||
public void setNullable(boolean nullable) {
|
||||
isNullable = nullable;
|
||||
}
|
||||
|
||||
public Object getColumnDefault() {
|
||||
return columnDefault;
|
||||
}
|
||||
|
||||
public void setColumnDefault(Object columnDefault) {
|
||||
this.columnDefault = columnDefault;
|
||||
}
|
||||
|
||||
public String getColumnComment() {
|
||||
return columnComment;
|
||||
}
|
||||
|
||||
public void setColumnComment(String columnComment) {
|
||||
this.columnComment = columnComment;
|
||||
}
|
||||
|
||||
public String getDataTypeStr() {
|
||||
return dataTypeStr;
|
||||
}
|
||||
|
||||
public void setDataTypeStr(String dataTypeStr) {
|
||||
this.dataTypeStr = dataTypeStr;
|
||||
}
|
||||
|
||||
public String getIsNullableStr() {
|
||||
return isNullableStr;
|
||||
}
|
||||
|
||||
public void setIsNullableStr(String isNullableStr) {
|
||||
this.isNullableStr = isNullableStr;
|
||||
}
|
||||
|
||||
public boolean equals(TableColumnBean tableColumnBean) {
|
||||
|
||||
return this.toSql().equals(tableColumnBean.toSql());
|
||||
}
|
||||
|
||||
public String toSql() {
|
||||
|
||||
StringBuilder sb = new StringBuilder(this.columnName.toLowerCase()).append(" ");
|
||||
|
||||
if (this.dataType == null) {
|
||||
return "类型为空";
|
||||
}
|
||||
switch (this.dataType) {
|
||||
case BIGINT:
|
||||
case INT:
|
||||
case TEXT:
|
||||
case LONGTEXT:
|
||||
case DATETIME:
|
||||
case FLOAT:
|
||||
case TINYINT:
|
||||
case DOUBLE:
|
||||
sb.append(this.dataType.name().toLowerCase()).append(" ");
|
||||
break;
|
||||
case VARCHAR:
|
||||
sb.append(this.dataType.name().toLowerCase()).append("(").append(this.fieldLength).append(") ");
|
||||
break;
|
||||
case DECIMAL:
|
||||
long length = (this.fieldLength < 0 || this.fieldLength > 38) ? 0 : this.fieldLength;
|
||||
sb.append(this.dataType.name().toLowerCase()).append("(").append(38 - length).append(",").append(length).append(") ");
|
||||
break;
|
||||
default:
|
||||
sb.append("varchar").append("(").append(10).append(") ");
|
||||
}
|
||||
|
||||
sb.append("comment ").append("'").append(this.columnComment).append("' ");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.engine.salary.elog.util;
|
||||
|
||||
import com.engine.salary.elog.dto.DateTypeEnum;
|
||||
|
||||
/**
|
||||
* @ClassName: ElogUtils
|
||||
* @Description TODO
|
||||
* @Author tanghj
|
||||
* @Date 2021/3/12 14:17
|
||||
*/
|
||||
public class ElogUtils {
|
||||
|
||||
private static final String TABLE_SPACER = "_";
|
||||
private static final String TABLE_SUFFIX = "logs";
|
||||
private static final String DETAIL_TABLE_SUFFIX = "detail";
|
||||
public static final String BASE_TABLE = "BASE_ELOG_TABLE";
|
||||
|
||||
|
||||
public static String getTableName(String module, String function) {
|
||||
return getTableName(module, function, false);
|
||||
}
|
||||
|
||||
public static String getTableName(String module, String function, boolean isDetail){
|
||||
|
||||
return module + TABLE_SPACER + function + TABLE_SUFFIX + (isDetail ? DETAIL_TABLE_SUFFIX : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* String 转枚举
|
||||
* @param c
|
||||
* @param string
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T extends Enum<T>> T getEnumFromString(Class<T> c, String string) {
|
||||
if (c != null && string != null) {
|
||||
try {
|
||||
return Enum.valueOf(c, string.trim().toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(DateTypeEnum.BIGINT.name());
|
||||
DateTypeEnum columnTypeEnum = getEnumFromString(DateTypeEnum.class, "varchar");
|
||||
System.out.println(columnTypeEnum.equals(DateTypeEnum.VARCHAR));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
package com.engine.salary.elog.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.weaver.common.async.bean.AsyncBean;
|
||||
import com.weaver.common.async.producer.client.AsyncClient;
|
||||
import com.weaver.common.elog.dto.LoggerContext;
|
||||
import com.weaver.common.elog.dto.LoggerDetailContext;
|
||||
import com.weaver.common.elog.dto.TableChangeBean;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @ClassName: LoggerTemplate
|
||||
* @Description 日志基本功能类
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
public class LoggerTemplate {
|
||||
protected String function = "common";
|
||||
|
||||
protected String module;
|
||||
|
||||
protected String logCenterQueue = "Elog_cneterlogQueue";
|
||||
|
||||
protected String localQueue;
|
||||
|
||||
@Autowired
|
||||
protected AsyncClient asyncClient;
|
||||
/**
|
||||
* 写入日志消息队列
|
||||
* @param context 日志实体
|
||||
*/
|
||||
public void write(LoggerContext context){
|
||||
this.write(context, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入日志消息队列
|
||||
* @param context 日志实体
|
||||
* @param isLocal true 存储本地, false不存储本地
|
||||
*/
|
||||
public void write(LoggerContext context, boolean isLocal){
|
||||
AsyncBean<LoggerContext> asyncBean = new AsyncBean<>();
|
||||
handleContext(context);
|
||||
asyncBean.setMessage(context);
|
||||
asyncBean.setQueue(logCenterQueue);
|
||||
asyncClient.send(asyncBean);
|
||||
if(isLocal) {
|
||||
asyncBean.setQueue(localQueue);
|
||||
asyncClient.send(asyncBean);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleContext(LoggerContext context) {
|
||||
context.setModuleName(module);
|
||||
context.setFunctionName(function);
|
||||
|
||||
List<TableChangeBean> changeBeans = context.getChangeValues();
|
||||
|
||||
List<LoggerDetailContext> valueChangeList = new ArrayList<>();
|
||||
int showOrder = 0;
|
||||
if(changeBeans != null)
|
||||
for(TableChangeBean changeBean : changeBeans) {
|
||||
if(changeBean != null && (changeBean.getNewValue() != null || changeBean.getOldValue() != null)) {
|
||||
ApiModel apiModel = null;
|
||||
JSONObject newJo = new JSONObject();
|
||||
JSONObject oldJo = new JSONObject();
|
||||
JSONObject valueChange = JSONObject.parseObject(JSONObject.toJSONString(changeBean));
|
||||
if(changeBean.getNewValue() != null) {
|
||||
apiModel = changeBean.getNewValue().getClass().getAnnotation(ApiModel.class);
|
||||
newJo = valueChange.getJSONObject("newValue");
|
||||
} else {
|
||||
apiModel = changeBean.getOldValue().getClass().getAnnotation(ApiModel.class);
|
||||
}
|
||||
if(changeBean.getOldValue() != null) {
|
||||
oldJo = valueChange.getJSONObject("oldValue");
|
||||
}
|
||||
if(apiModel != null) {
|
||||
Field[] fields = changeBean.getNewValue().getClass().getDeclaredFields();
|
||||
for(Field field : fields) {
|
||||
ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
|
||||
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
|
||||
valueChangeBean.setTableName(changeBean.getTableName());
|
||||
valueChangeBean.setFieldName(field.getName());
|
||||
valueChangeBean.setFieldDesc(apiModelProperty.value());
|
||||
valueChangeBean.setNewValue(newJo.getString(field.getName()));
|
||||
valueChangeBean.setOldValue(oldJo.getString(field.getName()));
|
||||
valueChangeBean.setShoworder(showOrder++);
|
||||
valueChangeList.add(valueChangeBean);
|
||||
}
|
||||
} else {
|
||||
Set<String> keys = new HashSet<>();
|
||||
for(String key : newJo.keySet()) {
|
||||
keys.add(key);
|
||||
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
|
||||
valueChangeBean.setTableName(changeBean.getTableName());
|
||||
valueChangeBean.setFieldName(key);
|
||||
valueChangeBean.setFieldDesc(key);
|
||||
valueChangeBean.setNewValue(newJo.getString(key));
|
||||
valueChangeBean.setOldValue(oldJo.getString(key));
|
||||
valueChangeBean.setShoworder(showOrder++);
|
||||
valueChangeList.add(valueChangeBean);
|
||||
}
|
||||
for(String key : oldJo.keySet()) {
|
||||
if(keys.contains(key))
|
||||
continue;
|
||||
keys.add(key);
|
||||
LoggerDetailContext valueChangeBean = new LoggerDetailContext();
|
||||
valueChangeBean.setTableName(changeBean.getTableName());
|
||||
valueChangeBean.setFieldName(key);
|
||||
valueChangeBean.setFieldDesc(key);
|
||||
valueChangeBean.setNewValue(newJo.getString(key));
|
||||
valueChangeBean.setOldValue(oldJo.getString(key));
|
||||
valueChangeBean.setShoworder(showOrder++);
|
||||
valueChangeList.add(valueChangeBean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(valueChangeList.size() > 0)
|
||||
context.setDetailContexts(valueChangeList);
|
||||
}
|
||||
|
||||
public String getFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
public void setFunction(String function) {
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志实体类
|
||||
* @return
|
||||
*/
|
||||
public LoggerContext getContext() {
|
||||
|
||||
LoggerContext loggerContext = new LoggerContext();
|
||||
loggerContext.setUuid(UUID.randomUUID().toString().replace("-",""));
|
||||
loggerContext.setModuleName(this.module);
|
||||
loggerContext.setFunctionName(this.function);
|
||||
|
||||
return loggerContext;
|
||||
|
||||
}
|
||||
|
||||
public void setModule(String module) {
|
||||
this.localQueue = module + "LocalQueue";
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public void setAsyncClient(AsyncClient asyncClient) {
|
||||
this.asyncClient = asyncClient;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.engine.salary.elog.util;
|
||||
|
||||
/**
|
||||
* @ClassName: LoggerTemplateBuilder
|
||||
* @Description 日志基本类构造器
|
||||
* @Author tanghj
|
||||
* @Date 2021/2/10 14:18
|
||||
*/
|
||||
public class LoggerTemplateBuilder {
|
||||
|
||||
public static LoggerTemplate build(String module){
|
||||
return build(module, "common");
|
||||
}
|
||||
public static LoggerTemplate build(String module, String function){
|
||||
LoggerTemplate loggerTemplate = new LoggerTemplate();
|
||||
loggerTemplate.setFunction(function);
|
||||
loggerTemplate.setModule(module);
|
||||
|
||||
return loggerTemplate;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue