后台操作日志
一、自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TitleName {
String value() default "";
int order() default 0;
boolean primaryKey() default false;
}
二、日志解析工具类
public class WebOperatorLogUtil {
public static final String ADD_OPERATOR_LOG_TEMPLATE = "{}<br/>[<br/>{}<br/>]";
public static final String UPDATE_OPERATOR_LOG_TEMPLATE = "{}<br/>[<br/>{}<br/>]";
public static final String DELETE_OPERATOR_LOG_TEMPLATE = "{}<br/>{}<br/>[<br/>{}<br/>]";
public static final String DEFAULT_OPERATOR_LOG_TEMPLATE = "{}<br/>[<br/>{}<br/>]";
public static String getAddContent(String desc, Object obj) {
Map<Integer, String> tempResultMap = new LinkedHashMap<>();
String eleTemplate = " {}: {}";
Field[] fields = ReflectUtil.getFields(obj.getClass());
for (Field field : fields) {
TitleName titleName = AnnotationUtil.getAnnotation(field, TitleName.class);
if (titleName == null) {
continue;
}
tempResultMap.put(titleName.order(), field.getName() + StrUtil.COLON + titleName.value());
}
TreeMap<Integer, String> resultMap = CollUtil.sort(tempResultMap, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
String titleName = "";
String value = "";
List<String> result = new ArrayList<>();
for (Map.Entry<Integer, String> ele : resultMap.entrySet()) {
String[] dataArray = StrUtil.split(ele.getValue(), StrUtil.COLON);
titleName = dataArray[1];
Object fieldValue = ReflectUtil.getFieldValue(obj, dataArray[0]);
value = fieldValue + "";
if (fieldValue instanceof Date) {
value = DateUtil.format(((Date) fieldValue), DatePattern.NORM_DATETIME_PATTERN);
}
String eleResult = StrUtil.format(eleTemplate, titleName, value);
result.add(eleResult);
}
return StrUtil.format(ADD_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(result, "<br/>"));
}
public static String getUpdateContent(String desc, Object srcObj, Object targetObj) {
Map<Integer, String> tempResultMap = new LinkedHashMap<>();
String eleTemplate = " {}: {} ==> {}";
Field[] fields = ReflectUtil.getFields(srcObj.getClass());
for (Field field : fields) {
TitleName titleName = AnnotationUtil.getAnnotation(field, TitleName.class);
if (titleName == null) {
continue;
}
tempResultMap.put(titleName.order(), field.getName() + StrUtil.COLON + titleName.value() + StrUtil.COLON + titleName.primaryKey());
}
TreeMap<Integer, String> resultMap = CollUtil.sort(tempResultMap, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
String titleName = "";
String srcValue = "";
String targetValue = "";
String primaryKey = "false";
List<String> result = new ArrayList<>();
for (Map.Entry<Integer, String> ele : resultMap.entrySet()) {
String[] dataArray = StrUtil.split(ele.getValue(), StrUtil.COLON);
titleName = dataArray[1];
primaryKey = dataArray[2];
Object srcFieldValue = ReflectUtil.getFieldValue(srcObj, dataArray[0]);
Object targetFieldValue = ReflectUtil.getFieldValue(targetObj, dataArray[0]);
srcValue = srcFieldValue + "";
targetValue = targetFieldValue + "";
if (srcFieldValue instanceof Date) {
srcValue = DateUtil.format(((Date) srcFieldValue), DatePattern.NORM_DATETIME_PATTERN);
targetValue = DateUtil.format(((Date) targetFieldValue), DatePattern.NORM_DATETIME_PATTERN);
}
if (StrUtil.equals(primaryKey, "true")) {
String eleResult = StrUtil.format(eleTemplate, titleName, srcValue, targetValue);
result.add(eleResult);
}
if (!StrUtil.equals(srcValue, targetValue)) {
targetValue = "<font color=\"red\">" + targetValue + "</font>";
String eleResult = StrUtil.format(eleTemplate, titleName, srcValue, targetValue);
result.add(eleResult);
}
}
return StrUtil.format(UPDATE_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(result, "<br/>"));
}
public static String getDeleteContent(String desc, Class clazz, int[] ids) {
ArrayList<String> tempResult = new ArrayList<>();
String eleTemplate = " {}";
for (int id : ids) {
tempResult.add(StrUtil.format(eleTemplate, id + ""));
}
List<String> primaryKeyTitles = new ArrayList<>();
Field[] fields = ReflectUtil.getFields(clazz);
for (Field field : fields) {
TitleName titleName = AnnotationUtil.getAnnotation(field, TitleName.class);
if (titleName == null) {
continue;
}
if (titleName.primaryKey() == true) {
primaryKeyTitles.add(titleName.value());
}
}
return StrUtil.format(DELETE_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(primaryKeyTitles, StrUtil.COMMA), CollUtil.join(tempResult, "<br/>"));
}
public static String getDeleteContent(String desc, Class clazz, String[] sids) {
ArrayList<String> tempResult = new ArrayList<>();
String eleTemplate = " {}";
for (String id : sids) {
tempResult.add(StrUtil.format(eleTemplate, id + ""));
}
List<String> primaryKeyTitles = new ArrayList<>();
Field[] fields = ReflectUtil.getFields(clazz);
for (Field field : fields) {
TitleName titleName = AnnotationUtil.getAnnotation(field, TitleName.class);
if (titleName == null) {
continue;
}
if (titleName.primaryKey() == true) {
primaryKeyTitles.add(titleName.value());
}
}
return StrUtil.format(DELETE_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(primaryKeyTitles, StrUtil.COMMA), CollUtil.join(tempResult, "<br/>"));
}
public static String getDeleteContent2(String desc, Class clazz, String[] sids,String splitBit) {
ArrayList<String> tempResult = new ArrayList<>();
String eleTemplate = " {}";
for (String sid : sids) {
StringBuilder ids = new StringBuilder();
String[] arr = sid.split(splitBit);
for (String value : arr) {
String s = value + StrUtil.COMMA;
ids.append(s);
}
String scoreResult = ids.substring(0, ids.length() - 1);
tempResult.add(StrUtil.format(eleTemplate, scoreResult + ""));
}
List<String> primaryKeyTitles = new ArrayList<>();
Field[] fields = ReflectUtil.getFields(clazz);
for (Field field : fields) {
TitleName titleName = AnnotationUtil.getAnnotation(field, TitleName.class);
if (titleName == null) {
continue;
}
if (titleName.primaryKey()) {
primaryKeyTitles.add(titleName.value());
}
}
return StrUtil.format(DELETE_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(primaryKeyTitles, StrUtil.COMMA), CollUtil.join(tempResult, "<br/>"));
}
public static String getDeleteContent(String desc, Class clazz, long[] lids) {
ArrayList<String> tempResult = new ArrayList<>();
String eleTemplate = " {}";
for (long id : lids) {
tempResult.add(StrUtil.format(eleTemplate, id + ""));
}
List<String> primaryKeyTitles = new ArrayList<>();
Field[] fields = ReflectUtil.getFields(clazz);
for (Field field : fields) {
TitleName titleName = AnnotationUtil.getAnnotation(field, TitleName.class);
if (titleName == null) {
continue;
}
if (titleName.primaryKey()) {
primaryKeyTitles.add(titleName.value());
}
}
return StrUtil.format(DELETE_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(primaryKeyTitles, StrUtil.COMMA), CollUtil.join(tempResult, "<br/>"));
}
public static String getDefaultContent(String desc, Object... params) {
ArrayList<String> content = new ArrayList<>();
String eleTemplate = " {}";
for (Object param : params) {
content.add(StrUtil.format(eleTemplate, param));
}
return StrUtil.format(DEFAULT_OPERATOR_LOG_TEMPLATE, desc, CollUtil.join(content, "<br/>"));
}
}
三、定义切面
@Aspect
@Component
public class OperatorLogAspect {
@Resource
private WebOperatorLogsMapper webOperatorLogsMapper;
@Autowired
private HttpServletRequest request;
@Pointcut("@annotation(higgs.ball.manage.annotation.WebOperationTag)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Object result = point.proceed();
try {
insertLog(point);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private void insertLog(ProceedingJoinPoint point) throws UnsupportedEncodingException {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
BaseController target = (BaseController) point.getTarget();
WebOperationTag annotation = method.getAnnotation(WebOperationTag.class);
String operationType = annotation.value().getName();
String operationLog = Arrays.toString(target.getOperationLogArgs());
String content = operationLog.substring(1, operationLog.length() - 1);
if (StringUtils.isBlank(content)) {
return;
}
if (content.getBytes("GBK").length > 800) {
content = this.subStringByByte(content, 800);
}
String module = method.getDeclaringClass().getName();
module = module.substring(module.lastIndexOf(".") + 1, module.lastIndexOf("Controller"));
WebOperatorLogs log = new WebOperatorLogs();
log.setLogTime(new Date());
log.setOperatorType(operationType);
log.setOperatorModule(module);
Identity identity = CookieUtil.getIdentityInfo(request);
log.setOperatorName(identity.getTrueName());
log.setOperatorId(identity.getUserId());
log.setContent(content);
log.setUserName(identity.getUserName());
webOperatorLogsMapper.add(log);
}
private String subStringByByte(String str, int splitByteNum) throws UnsupportedEncodingException {
if (StringUtils.isEmpty(str) || splitByteNum <= 0) {
return "";
}
String subStr = str.substring(0, splitByteNum > str.length() ? str.length() : splitByteNum);
int subStrByteNum = subStr.getBytes("GBK").length;
int len = splitByteNum;
while (subStrByteNum > len) {
int subStrLength = --splitByteNum;
subStr = str.substring(0, subStrLength > str.length() ? str.length() : subStrLength);
subStrByteNum = subStr.getBytes("GBK").length;
}
return subStr;
}
}
四、实体类添加注解
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dict extends ToStringBase {
private static final long serialVersionUID = -72567329833900420L;
@TitleName(value = "主键ID",primaryKey = true)
private long id;
@TitleName(value = "字典KEY",order = 1)
private String paramName;
@TitleName(value = "注释",order = 2)
private String remark;
@TitleName(value = "字典值",order = 3)
private String paramVal;
}
五、示例
I、新增
II、修改
III、删除