提交 eedfa55f 编写于 作者: zhouweidong's avatar zhouweidong

审计

上级 4dff20d9
...@@ -89,6 +89,11 @@ public class ${item.getCodeName()} extends EntityMP implements Serializable { ...@@ -89,6 +89,11 @@ public class ${item.getCodeName()} extends EntityMP implements Serializable {
/** /**
* ${defield.getLogicName()} * ${defield.getLogicName()}
*/ */
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
<#assign auditExpression=getAuditExpression(defield)>
@${pub.getPKGCodeName()}.util.annotation.Audit(${auditExpression})
</#if>
<#comment>属性默认值</#comment> <#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true> <#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano}) @DEField(${defieldano})
...@@ -336,6 +341,11 @@ public class ${item.getCodeName()} extends EntityMongo implements Serializable { ...@@ -336,6 +341,11 @@ public class ${item.getCodeName()} extends EntityMongo implements Serializable {
*/ */
<#if defield.isKeyDEField()==true> <#if defield.isKeyDEField()==true>
@Id() @Id()
</#if>
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
<#assign auditExpression=getAuditExpression(defield)>
@${pub.getPKGCodeName()}.util.annotation.Audit(${auditExpression})
</#if> </#if>
<#comment>属性默认值</#comment> <#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true> <#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
...@@ -501,6 +511,11 @@ public class ${item.getCodeName()} extends EntityClient implements Serializable ...@@ -501,6 +511,11 @@ public class ${item.getCodeName()} extends EntityClient implements Serializable
/** /**
* ${defield.getLogicName()} * ${defield.getLogicName()}
*/ */
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
<#assign auditExpression=getAuditExpression(defield)>
@${pub.getPKGCodeName()}.util.annotation.Audit(${auditExpression})
</#if>
<#comment>属性默认值</#comment> <#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true> <#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano}) @DEField(${defieldano})
...@@ -677,6 +692,11 @@ public class ${item.getCodeName()} extends EntityBase implements Serializable { ...@@ -677,6 +692,11 @@ public class ${item.getCodeName()} extends EntityBase implements Serializable {
/** /**
* ${defield.getLogicName()} * ${defield.getLogicName()}
*/ */
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
<#assign auditExpression=getAuditExpression(defield)>
@${pub.getPKGCodeName()}.util.annotation.Audit(${auditExpression})
</#if>
<#comment>属性默认值</#comment> <#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true> <#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano}) @DEField(${defieldano})
...@@ -823,6 +843,28 @@ public class ${item.getCodeName()} extends EntityBase implements Serializable { ...@@ -823,6 +843,28 @@ public class ${item.getCodeName()} extends EntityBase implements Serializable {
<#return unionKeyResult> <#return unionKeyResult>
</#function> </#function>
<#comment>审计注解</#comment>
<#function getAuditExpression defield>
<#assign defDataType = (defield.getDataType())!"">
<#assign defStdType=srfjavatype(defield.stdDataType)>
<#assign expressionCond="fieldLogicName=\""+ defield.getLogicName()+"\""> //拼接字段逻辑名
<#if defield.getPSCodeList?? && defield.getPSCodeList()??>
<#if ((defield.getPredefinedType())!'')!='LOGICVALID'>
<#assign expressionCond=expressionCond+",dictName=\""+ sys.codeName+"_"+defield.getPSCodeList().codeName+"CodeList"+"\""> //拼接代码表
</#if>
</#if>
<#if defDataType == "DATETIME">//拼接时间
<#assign expressionCond=expressionCond+",fieldType=\"DATETIME\",format=\"yyyy-MM-dd HH:mm:ss\"">//日期时间型
<#elseif defDataType == "DATE">
<#assign expressionCond=expressionCond+",fieldType=\"DATE\",format=\"yyyy-MM-dd\"">//日期型
<#elseif defDataType == "TIME">
<#assign expressionCond=expressionCond+",fieldType=\"TIME\",format=\"HH:mm\"">//时间型
<#elseif defDataType=='PICKUPDATA'&& defStdType=='Timestamp'><#comment>外键值附加数据,数据类型为时间</#comment>
<#assign expressionCond=expressionCond+",fieldType=\"DATETIME\",format=\"yyyy-MM-dd HH:mm:ss\"">//日期时间型
</#if>
<#return expressionCond/>
</#function>
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="Think (generated)" id="1566027230162-1">
<preConditions onFail="MARK_RAN" >
<not>
<tableExists tableName="IBZDATAAUDIT" />
</not>
</preConditions>
<createTable remarks="数据审计" tableName="IBZDATAAUDIT">
<column name="DATAAUDITID" remarks="数据审计标识" type="VARCHAR2(100 BYTE)">
<constraints primaryKey="true" primaryKeyName="SYS_C00115093"/>
</column>
<column name="OPPERSONID" remarks="操作人标识" type="VARCHAR2(100 BYTE)"/>
<column name="OPPERSONNAME" remarks="操作人名称" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITTYPE" remarks="审计行为类型" type="VARCHAR2(60 BYTE)"/>
<column name="OPTIME" remarks="操作时间" type="date"/>
<column name="IPADDRESS" remarks="访问地址" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITOBJECTDATA" remarks="审计对象(表数据)" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITOBJECT" remarks="审计对象(表)" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITINFO" remarks="审计明细" type="CLOB"/>
<column name="ISDATACHANGED" remarks="审计数据是否发生变化" type="INTEGER"/>
</createTable>
</changeSet>
</databaseChangeLog>
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD})
public @interface Audit
{
String fieldLogicName() default "";//字段逻辑名称
String dictName() default "";//代码表名称
String fieldType() default"";//字段类型
String format() default "";//格式化
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.aspect;
import lombok.SneakyThrows;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import ${pub.getPKGCodeName()}.util.helper.DEFieldCacheMap;
import ${pub.getPKGCodeName()}.util.service.IBZDataAuditService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 实体数据审计切面类
*/
@Aspect
@Component
public class AuditAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
@Autowired
IBZDataAuditService dataAuditService;
/**
* 实体数据建立切面,在成功创建数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* @param point
*/
@AfterReturning(value = "execution(* ${pub.getPKGCodeName()}.core.*.service.*.create(..))")
@SneakyThrows
public void create(JoinPoint point){
HttpServletRequest request=null;
RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object [] args = point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0)
return;
Object serviceParam =args[0];
EntityBase entity=(EntityBase)serviceParam;//创建数据
Map<String, Audit> auditFields= DEFieldCacheMap.getAuditFields(entity.getClass());
if(auditFields.size()==0)//是否有审计属性
return;
String idField=DEFieldCacheMap.getDEKeyField(entity.getClass());
Object idValue="";
if(!StringUtils.isEmpty(idField)){
idValue=entity.get(idField);
}
//记录审计日志
dataAuditService.createAudit(request,entity,idValue,auditFields);
return;
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取到更新前后的实体数据并进行差异比较,并将差异内容记入审计日志内
* @param point
*/
@Around("execution(* ${pub.getPKGCodeName()}.core.*.service.*.update(..))")
public Object update(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request=null;
RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object serviceObj=point.getTarget();
Object args[]=point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0)
return point.proceed();
Object arg=args[0];
EntityBase entity= (EntityBase) arg;
Map<String, Audit> auditFields= DEFieldCacheMap.getAuditFields(entity.getClass());
//是否有审计属性
if(auditFields.size()==0)
return point.proceed();
String idField=DEFieldCacheMap.getDEKeyField(entity.getClass());
Object idValue="";
if(!StringUtils.isEmpty(idField)){
idValue=entity.get(idField);
}
if(ObjectUtils.isEmpty(idValue))
return point.proceed();
//获取更新前实体
EntityBase beforeEntity=getEntity(serviceObj,idValue);
//执行更新操作
point.proceed();
//记录审计日志
dataAuditService.updateAudit(request,beforeEntity,serviceObj,idValue,auditFields);
return true;
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取要删除的完整数据,并将审计属性相关信息记录到审计日志中
* @param point
* @return
* @throws Throwable
*/
@Around("execution(* ${pub.getPKGCodeName()}.core.*.service.*.remove(..))")
public Object remove(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request=null;
RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object serviceObj=point.getTarget();
Object args[]=point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0)
return point.proceed();
Object idValue=args[0];
EntityBase entity=getEntity(serviceObj,idValue);
Map<String, Audit> auditFields= DEFieldCacheMap.getAuditFields(entity.getClass());
if(auditFields.size()==0){
return point.proceed();
}
else{
//执行删除操作
point.proceed();
//记录审计日志
dataAuditService.removeAudit(request,entity,idValue,auditFields);
return true;
}
}
/**
* 获取实体
* @param service
* @param id
* @return
*/
@SneakyThrows
private EntityBase getEntity(Object service, Object id){
EntityBase entity=null;
if(!ObjectUtils.isEmpty(service)){
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service",service);
oldContext.setVariable("id",id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
return oldExp.getValue(oldContext, EntityBase.class);
}
return entity;
}
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Objects;
/**
* 实体[DataAudit] 数据对象
*/
@TableName(value = "IBZDATAAUDIT")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class IBZDataAudit implements Serializable{
@TableId(value= "dataauditid",type=IdType.UUID)//指定主键生成策略
private String dataauditid;
private String dataauditname;
private String oppersonid;
private String oppersonname;
private String audittype;
private Timestamp optime;
private String ipaddress;
private String auditinfo;
private Object auditobjectdata;
private String auditobject;
private int isdatachanged;
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ TARGET=PSSYSTEM ...@@ -4,6 +4,7 @@ TARGET=PSSYSTEM
package ${pub.getPKGCodeName()}.util.helper; package ${pub.getPKGCodeName()}.util.helper;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.annotation.DEField; import ${pub.getPKGCodeName()}.util.annotation.DEField;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
...@@ -25,6 +26,8 @@ public class DEFieldCacheMap { ...@@ -25,6 +26,8 @@ public class DEFieldCacheMap {
private static Hashtable<String, Hashtable<String,DEField>> cacheDEField = new Hashtable<>(); private static Hashtable<String, Hashtable<String,DEField>> cacheDEField = new Hashtable<>();
private static Hashtable<String, Hashtable<String,Audit>> cacheAuditField = new Hashtable<>();
private static Hashtable<String, String> cacheDEKeyField = new Hashtable<>(); private static Hashtable<String, String> cacheDEKeyField = new Hashtable<>();
private static Object objLock1=new Object(); private static Object objLock1=new Object();
...@@ -47,6 +50,7 @@ public class DEFieldCacheMap { ...@@ -47,6 +50,7 @@ public class DEFieldCacheMap {
List<Field> list=new ArrayList<Field>(); List<Field> list=new ArrayList<Field>();
Hashtable<String,String> keys=new Hashtable<String,String>(); Hashtable<String,String> keys=new Hashtable<String,String>();
Hashtable<String,DEField> defields=new Hashtable<>(); Hashtable<String,DEField> defields=new Hashtable<>();
Hashtable<String, Audit> auditfields=new Hashtable<>();
Hashtable<String,String> dekeyfields=new Hashtable<>(); Hashtable<String,String> dekeyfields=new Hashtable<>();
Field[] fields=clazz.getDeclaredFields(); Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){ for(Field field:fields){
...@@ -54,16 +58,21 @@ public class DEFieldCacheMap { ...@@ -54,16 +58,21 @@ public class DEFieldCacheMap {
list.add(field); list.add(field);
keys.put(field.getName().toLowerCase(),field.getName()); keys.put(field.getName().toLowerCase(),field.getName());
DEField deField=field.getAnnotation(DEField.class); DEField deField=field.getAnnotation(DEField.class);
Audit auditField=field.getAnnotation(Audit.class);
if(!ObjectUtils.isEmpty(deField)) { if(!ObjectUtils.isEmpty(deField)) {
defields.put(field.getName(),deField); defields.put(field.getName(),deField);
if(deField.isKeyField()) if(deField.isKeyField())
cacheDEKeyField.put(className,field.getName()); cacheDEKeyField.put(className,field.getName());
} }
if(!ObjectUtils.isEmpty(auditField)) {
auditfields.put(field.getName(),auditField);
}
} }
cacheMap.put(className, result); cacheMap.put(className, result);
cacheList.put(className,list); cacheList.put(className,list);
cacheKey.put(className,keys); cacheKey.put(className,keys);
cacheDEField.put(className,defields); cacheDEField.put(className,defields);
cacheAuditField.put(className,auditfields);
return result; return result;
} }
} }
...@@ -100,6 +109,23 @@ public class DEFieldCacheMap { ...@@ -100,6 +109,23 @@ public class DEFieldCacheMap {
} }
} }
/**
* 从缓存中查询审计属性集合
* @param
* @return
*/
public static <T> Hashtable<String,Audit> getAuditFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheAuditField.containsKey(className))
return cacheAuditField.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheAuditField.get(className);
}
}
/** /**
* 从缓存中查询实体对象主键 * 从缓存中查询实体对象主键
* @param * @param
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${pub.getPKGCodeName()}.util.domain.IBZDataAudit;
public interface IBZDataAuditMapper extends BaseMapper<IBZDataAudit> {
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.service;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import org.springframework.scheduling.annotation.Async;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 实体[DataAudit] 服务对象接口
*/
public interface IBZDataAuditService {
@Async
void createAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields);
@Async
void updateAudit(HttpServletRequest request, EntityBase beforeEntity, Object serviceObj, Object idValue, Map<String, Audit> auditFields);
@Async
void removeAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields);
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import ${pub.getPKGCodeName()}.util.domain.IBZDataAudit;
import ${pub.getPKGCodeName()}.util.mapper.IBZDataAuditMapper;
import ${pub.getPKGCodeName()}.util.security.AuthenticationUser;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 实体[DataAudit] 服务对象接口实现
*/
@Service
@Slf4j
public class SimpleAuditService extends ServiceImpl<IBZDataAuditMapper, IBZDataAudit> implements IBZDataAuditService {
private final ExpressionParser parser = new SpelExpressionParser();
private static List cacheMap = Collections.synchronizedList(new ArrayList());
@Override
public boolean save(IBZDataAudit entity) {
cacheMap.add(entity);
log.info(String.format("当前待保存审计集合数量为[%S]",cacheMap.size()));
return false;
}
@Scheduled(fixedRate = 10000)
public void saveAudit() {
if(cacheMap.size()>0){
log.info(String.format("正在保存审计数据,当前审计集合数量为[%S]",cacheMap.size()));
List temp=new ArrayList();
if(cacheMap.size()<2)
temp.addAll(cacheMap);
else
temp.addAll(cacheMap.subList(0,2));
this.saveBatch(temp);
cacheMap.removeAll(temp);
log.info(String.format("保存完成,当前审计集合数量为[%S]",cacheMap.size()));
}
}
/**
* 新建审计日志
* @param request
* @param entity
* @param idValue
* @param auditFields
*/
@Override
public void createAudit(HttpServletRequest request, EntityBase entity, Object idValue, Map<String, Audit> auditFields) {
IBZDataAudit dataAudit =new IBZDataAudit();
dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
dataAudit.setOppersonname(String.format("%s[%s]",AuthenticationUser.getAuthenticationUser().getPersonname(),AuthenticationUser.getAuthenticationUser().getOrgname()));
dataAudit.setAudittype("CREATE");
dataAudit.setAuditobject(entity.getClass().getSimpleName());
dataAudit.setAuditobjectdata(idValue);
dataAudit.setOptime(new Timestamp(new Date().getTime()));
if(request!=null)
dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
dataAudit.setAuditinfo(getCreateAuditInfo(entity,auditFields));
dataAudit.setIsdatachanged(1);
save(dataAudit);
}
/**
* 更新审计日志
* @param request
* @param beforeEntity
* @param serviceObj
* @param idValue
* @param auditFields
*/
@SneakyThrows
public void updateAudit(HttpServletRequest request, EntityBase beforeEntity, Object serviceObj, Object idValue, Map<String, Audit> auditFields){
System.out.println("updateAudit--开始休眠");
Thread.sleep(10000);
//获取更新后的实体
EntityBase afterEntity=getEntity(serviceObj,idValue);
//获取更新后的审计内容
String auditInfo=getUpdateAuditInfo(beforeEntity,afterEntity,auditFields);//比较更新前后差异内容
int isDataChanged=1;
if(StringUtils.isEmpty(auditInfo))//审计内容是否发生变化
isDataChanged=0;
IBZDataAudit dataAudit =new IBZDataAudit();
dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
dataAudit.setOppersonname(String.format("%s[%s]",AuthenticationUser.getAuthenticationUser().getPersonname(),AuthenticationUser.getAuthenticationUser().getOrgname()));
dataAudit.setAudittype("UPDATE");
dataAudit.setAuditobject(afterEntity.getClass().getSimpleName());
dataAudit.setAuditobjectdata(idValue);
dataAudit.setOptime(new Timestamp(new Date().getTime()));
if(request!=null)
dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
dataAudit.setAuditinfo(auditInfo);
dataAudit.setIsdatachanged(isDataChanged);
save(dataAudit);
System.out.println("updateAudit--结束休眠");
}
/**
* 删除审计日志
* @param request
* @param entity
* @param idValue
* @param auditFields
*/
public void removeAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields){
IBZDataAudit dataAudit =new IBZDataAudit();
dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
dataAudit.setOppersonname(String.format("%s[%s]",AuthenticationUser.getAuthenticationUser().getPersonname(),AuthenticationUser.getAuthenticationUser().getOrgname()));
dataAudit.setAudittype("REMOVE");
dataAudit.setAuditobject(entity.getClass().getSimpleName());
dataAudit.setAuditobjectdata(idValue);
dataAudit.setOptime(new Timestamp(new Date().getTime()));
if(request!=null)
dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
dataAudit.setAuditinfo(getRemoveAuditInfo(entity,auditFields));
dataAudit.setIsdatachanged(1);
save(dataAudit);
}
/**
* 获取新建审计内容
* @param entity
* @param auditFields
* @return
*/
private String getCreateAuditInfo(EntityBase entity, Map<String, Audit> auditFields){
JSONArray auditFieldArray=new JSONArray();
String auditResult="";
if(auditFields.size()==0)
return "";
for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
Object objFieldName=auditField.getKey();//获取注解字段
Audit auditAnnotation=auditField.getValue();//拿到注解
String fieldLogicName=auditAnnotation.fieldLogicName();
String fieldName=String.valueOf(objFieldName); //属性名称
Object value=entity.get(fieldName);//老属性值
value=dataTransfer(value,auditAnnotation.fieldType(),auditAnnotation.format());//属性值转换
if(!StringUtils.isEmpty(value)){
JSONObject auditFieldObj=new JSONObject();
auditFieldObj.put("field",fieldLogicName);
auditFieldObj.put("value",value);
if(!StringUtils.isEmpty(auditAnnotation.dictName())){
auditFieldObj.put("dictName",auditAnnotation.dictName());
}
auditFieldArray.add(auditFieldObj);
}
}
if(auditFieldArray.size()>0){
auditResult=auditFieldArray.toString();
}
return auditResult;
}
/**
* 获取更新审计内容
* @param oldData
* @param newData
* @param auditFields
* @return
*/
private String getUpdateAuditInfo(EntityBase oldData, EntityBase newData, Map<String, Audit> auditFields){
String auditResult="";
JSONArray auditFieldArray=new JSONArray();
if(auditFields.size()==0)
return auditResult;
for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
Object objFieldName=auditField.getKey();//获取注解字段
String fieldName=String.valueOf(objFieldName); //属性名称
Audit auditAnnotation=auditField.getValue();//拿到注解
String fieldLogicName=auditAnnotation.fieldLogicName();//获取字段逻辑名称
Object oldValue=oldData.get(fieldName);//老属性值
Object newValue=newData.get(fieldName);//新属性值
if(!compare(oldValue,newValue)){
oldValue=dataTransfer(oldValue,auditAnnotation.fieldType(),auditAnnotation.format());//属性值转换
newValue=dataTransfer(newValue,auditAnnotation.fieldType(),auditAnnotation.format());//属性值转换
JSONObject auditFieldObj=new JSONObject();
auditFieldObj.put("field",fieldLogicName);
auditFieldObj.put("source",oldValue);
auditFieldObj.put("target",newValue);
if(!StringUtils.isEmpty(auditAnnotation.dictName())){
auditFieldObj.put("dictName",auditAnnotation.dictName());
}
auditFieldArray.add(auditFieldObj);
}
}
if(auditFieldArray.size()>0){
auditResult=auditFieldArray.toString();
}
return auditResult;
}
/**
* 获取删除审计内容
* @param entity
* @param auditFields
* @return
*/
private String getRemoveAuditInfo(EntityBase entity, Map<String, Audit> auditFields){
String auditResult="";
JSONArray auditFieldArray=new JSONArray();
if(auditFields.size()==0)
return auditResult;
for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
Object objFieldName=auditField.getKey();//获取注解字段
Audit auditAnnotation=auditField.getValue();//拿到注解
String fieldLogicName=auditAnnotation.fieldLogicName();
String fieldName=String.valueOf(objFieldName); //属性名称
Object value=entity.get(fieldName);//老属性值
value=dataTransfer(value,auditAnnotation.fieldType(),auditAnnotation.format());//属性值转换
if(!StringUtils.isEmpty(value)){
JSONObject auditFieldObj=new JSONObject();
auditFieldObj.put("field",fieldLogicName);
auditFieldObj.put("value",value);
if(!StringUtils.isEmpty(auditAnnotation.dictName())){
auditFieldObj.put("dictName",auditAnnotation.dictName());
}
auditFieldArray.add(auditFieldObj);
}
}
if(auditFieldArray.size()>0){
auditResult=auditFieldArray.toString();
}
return auditResult;
}
/**
* 数据转换
* @param value 转换值
* @param dataType 转换字段类型
* @param strFormat 转换字段格式化文本
* @return
*/
private String dataTransfer(Object value,String dataType, String strFormat){
if(value==null)
return "";
String transResult=value.toString();
if((dataType.equals("DATE") || dataType.equals("DATETIME") || dataType.equals("TIME")) && (!StringUtils.isEmpty(strFormat))){ //时间类型转换
Timestamp timestamp =(Timestamp)value;
Date date =timestamp;
SimpleDateFormat format =new SimpleDateFormat(strFormat);
transResult=format.format(date);
}
return transResult;
}
/**
* 对象比较
* @param sourceObj 比较源对象
* @param targetObj 比较目标对象
* @return
*/
private boolean compare(Object sourceObj,Object targetObj){
if(sourceObj==null && targetObj==null)
return true;
if(sourceObj==null && targetObj!=null)
return false;
return sourceObj.equals(targetObj);
}
/**
* 获取实体
* @param service
* @param id
* @return
*/
@SneakyThrows
private EntityBase getEntity(Object service, Object id){
EntityBase entity=null;
if(!ObjectUtils.isEmpty(service)){
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service",service);
oldContext.setVariable("id",id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
return oldExp.getValue(oldContext, EntityBase.class);
}
return entity;
}
/**
* 获取Ip地址
* @param request
* @return
*/
public String getIpAddress(HttpServletRequest request, AuthenticationUser authenticationUser) {
//客户端有提交ip,以提交的ip为准
if(authenticationUser != null && !StringUtils.isEmpty(authenticationUser.getAddr())){
return authenticationUser.getAddr();
}
if(request == null)
return "";
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
if(!StringUtils.isEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = XFor.indexOf(",");
if(index != -1){
return XFor.substring(0,index);
}else{
return XFor;
}
}
XFor = Xip;
if(!StringUtils.isEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
return XFor;
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getRemoteAddr();
}
return XFor;
}
}
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册