Initial commit
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.linln.component</groupId>
|
||||
<artifactId>actionLog</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>组件:行为日志</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.linln</groupId>
|
||||
<artifactId>component</artifactId>
|
||||
<version>2.0.3</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.linln</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.linln.modules</groupId>
|
||||
<artifactId>system</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.linln.component</groupId>
|
||||
<artifactId>shiro</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.linln.component.actionLog.action;
|
||||
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
import com.linln.component.actionLog.action.base.ResetLog;
|
||||
import com.linln.component.actionLog.action.model.BusinessMethod;
|
||||
import com.linln.modules.system.domain.Role;
|
||||
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* 角色日志行为
|
||||
* @author gion
|
||||
* @date 2018/10/14
|
||||
*/
|
||||
public class RoleAction extends BaseActionMap {
|
||||
|
||||
public static final String ROLE_SAVE = "role_save";
|
||||
public static final String ROLE_AUTH = "role_auth";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// 保存日志行为
|
||||
putMethod(ROLE_SAVE, new BusinessMethod("日志管理","roleSave"));
|
||||
// 角色授权行为
|
||||
putMethod(ROLE_AUTH, new BusinessMethod("角色授权","roleAuth"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户行为方法
|
||||
*/
|
||||
public void roleSave(ResetLog resetLog){
|
||||
resetLog.getActionLog().setMessage("日志成功:${title}");
|
||||
SaveAction.defaultMethod(resetLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色授权行为方法
|
||||
*/
|
||||
public void roleAuth(ResetLog resetLog){
|
||||
Role role = (Role) resetLog.getParam("role");
|
||||
Table table = Role.class.getAnnotation(Table.class);
|
||||
resetLog.getActionLog().setModel(table.name());
|
||||
resetLog.getActionLog().setRecordId(role.getId());
|
||||
if (resetLog.isSuccess()){
|
||||
resetLog.getActionLog().setMessage("角色授权成功:"+role.getTitle());
|
||||
}else {
|
||||
resetLog.getActionLog().setMessage("角色授权失败:"+role.getTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.linln.component.actionLog.action;
|
||||
|
||||
import com.linln.common.utils.EntityBeanUtil;
|
||||
import com.linln.common.utils.HttpServletUtil;
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
import com.linln.component.actionLog.action.base.ResetLog;
|
||||
import com.linln.modules.system.domain.ActionLog;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* 通用:记录保存数据的行为
|
||||
*
|
||||
* @author gion
|
||||
* @date 2018/10/14
|
||||
*/
|
||||
@Slf4j
|
||||
public class SaveAction extends BaseActionMap {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// 记录数据保存日志
|
||||
putMethod("default", "defaultMethod");
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新包装保存的数据行为方法
|
||||
*
|
||||
* @param resetLog ResetLog对象数据
|
||||
*/
|
||||
public static void defaultMethod(ResetLog resetLog) {
|
||||
ActionLog actionLog = resetLog.getActionLog();
|
||||
Object entity = resetLog.getEntityParam();
|
||||
Assert.notNull(entity, "日志记录失败:未发现@EntityParam注解参数,将不做数据日志记录");
|
||||
|
||||
// 获取实体类的@Table表名
|
||||
Table table = entity.getClass().getAnnotation(Table.class);
|
||||
Assert.notNull(table, "该对象不存在" + Table.class.getName() + "注解!请检查!");
|
||||
actionLog.setModel(table.name());
|
||||
|
||||
// 获取实体对象数据ID
|
||||
Object[] idInfo = EntityBeanUtil.getId(entity);
|
||||
Assert.notNull(idInfo, "无法获取该实体对象的主键ID字段!");
|
||||
actionLog.setRecordId(Long.valueOf(String.valueOf(idInfo[1])));
|
||||
|
||||
// 日志消息
|
||||
String idParam = HttpServletUtil.getParameter(String.valueOf(idInfo[0]));
|
||||
String message = "数据成功";
|
||||
if (!actionLog.getMessage().isEmpty()) {
|
||||
message = resetLog.fillRule(entity, actionLog.getMessage());
|
||||
}
|
||||
|
||||
if (idParam == null) {
|
||||
actionLog.setMessage("添加" + message);
|
||||
} else {
|
||||
actionLog.setMessage("更新" + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.linln.component.actionLog.action;
|
||||
|
||||
import com.linln.common.utils.StatusUtil;
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
import com.linln.component.actionLog.action.base.ResetLog;
|
||||
import com.linln.common.enums.StatusEnum;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用:记录数据状态的行为
|
||||
*
|
||||
* @author gion
|
||||
* @date 2018/10/14
|
||||
*/
|
||||
public class StatusAction extends BaseActionMap {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// 记录数据状态改变日志
|
||||
putMethod("default", "defaultMethod");
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新包装保存的数据行为方法
|
||||
*
|
||||
* @param resetLog ResetLog对象数据
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void defaultMethod(ResetLog resetLog) {
|
||||
if(resetLog.isSuccessRecord()){
|
||||
String param = (String) resetLog.getParam("param");
|
||||
StatusEnum statusEnum = StatusUtil.getStatusEnum(param);
|
||||
List<Long> ids = (List<Long>) resetLog.getParam("ids");
|
||||
resetLog.getActionLog().setMessage(statusEnum.getMessage() + "ID:" + ids.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.linln.component.actionLog.action;
|
||||
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
import com.linln.component.actionLog.action.base.ResetLog;
|
||||
import com.linln.component.actionLog.action.model.SystemMethod;
|
||||
import com.linln.modules.system.domain.ActionLog;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/19
|
||||
*/
|
||||
public class SystemAction extends BaseActionMap {
|
||||
|
||||
public static final String RUNTIME_EXCEPTION = "runtime_exception";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// 系统异常行为
|
||||
putMethod(RUNTIME_EXCEPTION, new SystemMethod("系统异常","runtimeException"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统异常行为方法
|
||||
*/
|
||||
public void runtimeException(ResetLog resetLog){
|
||||
RuntimeException runtime = (RuntimeException) resetLog.getParam("e");
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append(runtime.toString());
|
||||
StackTraceElement[] stackTrace = runtime.getStackTrace();
|
||||
for (StackTraceElement stack : stackTrace) {
|
||||
message.append("\n\t").append(stack.toString());
|
||||
}
|
||||
ActionLog actionLog = resetLog.getActionLog();
|
||||
actionLog.setOperName("系统");
|
||||
actionLog.setMessage(String.valueOf(message));
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package com.linln.component.actionLog.action;
|
||||
|
||||
import com.linln.common.vo.ResultVo;
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
import com.linln.component.actionLog.action.base.ResetLog;
|
||||
import com.linln.component.actionLog.action.model.BusinessMethod;
|
||||
import com.linln.component.actionLog.action.model.LoginMethod;
|
||||
import com.linln.modules.system.domain.ActionLog;
|
||||
import com.linln.modules.system.domain.User;
|
||||
import com.linln.modules.system.service.ActionLogService;
|
||||
import com.linln.common.utils.SpringContextUtil;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import javax.persistence.Table;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户日志行为
|
||||
* @author gion
|
||||
* @date 2018/10/14
|
||||
*/
|
||||
public class UserAction extends BaseActionMap {
|
||||
|
||||
public static final String USER_LOGIN = "user_login";
|
||||
public static final String USER_SAVE = "user_save";
|
||||
public static final String EDIT_PWD = "edit_pwd";
|
||||
public static final String EDIT_ROLE = "edit_role";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// 用户登录行为
|
||||
putMethod(USER_LOGIN, new LoginMethod("用户登录","userLogin"));
|
||||
// 保存用户行为
|
||||
putMethod(USER_SAVE, new BusinessMethod("用户管理","userSave"));
|
||||
// 修改用户密码行为
|
||||
putMethod(EDIT_PWD, new BusinessMethod("用户密码","editPwd"));
|
||||
// 角色分配行为
|
||||
putMethod(EDIT_ROLE, new BusinessMethod("角色分配","editRole"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录行为方法
|
||||
*/
|
||||
public void userLogin(ResetLog resetLog){
|
||||
ActionLog actionLog = resetLog.getActionLog();
|
||||
if (resetLog.isSuccess()){
|
||||
actionLog.setMessage("后台登录成功");
|
||||
}else {
|
||||
String username = (String) resetLog.getParam("username");
|
||||
ResultVo resultVo = (ResultVo) resetLog.getRetValue();
|
||||
actionLog.setOperName(username);
|
||||
actionLog.setMessage(String.format("后台登录失败:[%s]%s", username, resultVo.getMsg()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户行为方法
|
||||
*/
|
||||
public void userSave(ResetLog resetLog){
|
||||
resetLog.getActionLog().setMessage("用户成功:${username}");
|
||||
SaveAction.defaultMethod(resetLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户密码行为方法
|
||||
*/
|
||||
public void editPwd(ResetLog resetLog){
|
||||
@SuppressWarnings("unchecked") List<User> users = (List<User>) resetLog.getParam("users");
|
||||
Table table = User.class.getAnnotation(Table.class);
|
||||
String message = "修改用户密码成功";
|
||||
if(!resetLog.isSuccess()){
|
||||
message = "修改用户密码失败";
|
||||
}
|
||||
ActionLogService actionLogService = SpringContextUtil.getBean(ActionLogService.class);
|
||||
|
||||
String finalMessage = message;
|
||||
users.forEach(user -> {
|
||||
ActionLog actionLog = new ActionLog();
|
||||
BeanUtils.copyProperties(resetLog.getActionLog(), actionLog);
|
||||
actionLog.setModel(table.name());
|
||||
actionLog.setRecordId(user.getId());
|
||||
actionLog.setMessage(finalMessage + user.getUsername());
|
||||
|
||||
// 保存日志
|
||||
actionLogService.save(actionLog);
|
||||
});
|
||||
resetLog.setRecord(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色分配行为方法
|
||||
*/
|
||||
public void editRole(ResetLog resetLog){
|
||||
User user = (User) resetLog.getParam("user");
|
||||
Table table = User.class.getAnnotation(Table.class);
|
||||
resetLog.getActionLog().setModel(table.name());
|
||||
resetLog.getActionLog().setRecordId(user.getId());
|
||||
if (resetLog.isSuccess()){
|
||||
resetLog.getActionLog().setMessage("角色分配成功:"+user.getUsername());
|
||||
}else {
|
||||
resetLog.getActionLog().setMessage("角色分配失败:"+user.getUsername());
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package com.linln.component.actionLog.action.base;
|
||||
|
||||
import com.linln.component.actionLog.action.model.BusinessMethod;
|
||||
import com.linln.component.actionLog.action.model.BusinessType;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/14
|
||||
*/
|
||||
public abstract class BaseActionMap {
|
||||
|
||||
protected HashMap<String, Object> dictory = new HashMap<>();
|
||||
|
||||
public BaseActionMap(){
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化行为列表
|
||||
*/
|
||||
public abstract void init();
|
||||
|
||||
/**
|
||||
* 获取指定的行为
|
||||
* @param key 行为key
|
||||
*/
|
||||
public Object get(String key) {
|
||||
return this.dictory.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行为
|
||||
* @param key 行为key
|
||||
* @param modelType 模型类型对象
|
||||
*/
|
||||
public void put(String key, Object modelType) {
|
||||
this.dictory.put(key, modelType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行为-默认类型(业务)
|
||||
* @param key 行为key
|
||||
* @param message 日志消息
|
||||
*/
|
||||
public void put(String key, String message) {
|
||||
this.dictory.put(key, new BusinessType(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行为-默认类型(业务)
|
||||
* @param key 行为key
|
||||
* @param name 日志名称
|
||||
* @param message 日志消息
|
||||
*/
|
||||
public void put(String key, String name, String message) {
|
||||
this.dictory.put(key, new BusinessType(name, message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行为方法名
|
||||
* @param key 行为key
|
||||
* @param modelMethod 模型方法名对象
|
||||
*/
|
||||
public void putMethod(String key, Object modelMethod) {
|
||||
this.dictory.put(key, modelMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行为方法名-默认类型(业务)
|
||||
* @param key 行为key
|
||||
* @param method 方法名
|
||||
*/
|
||||
public void putMethod(String key, String method) {
|
||||
this.dictory.put(key, new BusinessMethod(method));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加行为方法名-默认类型(业务)
|
||||
* @param key 行为key
|
||||
* @param name 日志名称
|
||||
* @param method 方法名
|
||||
*/
|
||||
public void putMethod(String key, String name, String method) {
|
||||
this.dictory.put(key, new BusinessMethod(name, method));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
package com.linln.component.actionLog.action.base;
|
||||
|
||||
import com.linln.common.enums.ResultEnum;
|
||||
import com.linln.common.utils.EntityBeanUtil;
|
||||
import com.linln.common.vo.ResultVo;
|
||||
import com.linln.component.actionLog.annotation.EntityParam;
|
||||
import com.linln.component.shiro.ShiroUtil;
|
||||
import com.linln.modules.system.domain.ActionLog;
|
||||
import lombok.Data;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 自定义日志数据
|
||||
* @author gion
|
||||
* @date 2018/10/14
|
||||
*/
|
||||
@Data
|
||||
public class ResetLog {
|
||||
|
||||
/* 封装操作对象 */
|
||||
/** 注解日志的方法返回值 */
|
||||
private Object retValue;
|
||||
/** 获取日志实体对象 */
|
||||
private ActionLog actionLog;
|
||||
/** Aop连接点信息对象 */
|
||||
private JoinPoint joinPoint;
|
||||
/** 是否记录日志(默认记录) */
|
||||
private Boolean record = true;
|
||||
|
||||
/* 辅助方法 */
|
||||
/**
|
||||
* 判断返回值是否为ResultVo对象
|
||||
*/
|
||||
public boolean isResultVo(){
|
||||
return retValue instanceof ResultVo;
|
||||
}
|
||||
/**
|
||||
* 判断ResultVo状态码是否为成功
|
||||
*/
|
||||
public boolean isSuccess(){
|
||||
return retValue instanceof ResultVo &&
|
||||
((ResultVo) retValue).getCode().equals(ResultEnum.SUCCESS.getCode());
|
||||
}
|
||||
/**
|
||||
* 判断ResultVo状态码是否为成功,且设置是否记录日志
|
||||
*/
|
||||
public boolean isSuccessRecord(){
|
||||
return record = retValue instanceof ResultVo &&
|
||||
((ResultVo) retValue).getCode().equals(ResultEnum.SUCCESS.getCode());
|
||||
}
|
||||
/**
|
||||
* 获取切入点方法指定名称的参数值
|
||||
*/
|
||||
public Object getParam(String name){
|
||||
Object[] args = joinPoint.getArgs();
|
||||
if(args.length > 0){
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
String[] parameterNames = methodSignature.getParameterNames();
|
||||
for (int i = 0; i < parameterNames.length; i++) {
|
||||
if(parameterNames[i].equals(name)){
|
||||
return args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 获取切入点参数注解@EntityParam的对象
|
||||
*/
|
||||
public Object getEntityParam(){
|
||||
Object[] args = joinPoint.getArgs();
|
||||
if(args.length > 0){
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
|
||||
for (int i = 0; i < parameterAnnotations.length; i++) {
|
||||
for (int j = 0; j < parameterAnnotations[i].length; j++) {
|
||||
if(parameterAnnotations[i][j] instanceof EntityParam){
|
||||
return args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static final Pattern FILL_PATTERN = Pattern.compile("\\$\\{[a-zA-Z0-9]+\\}");
|
||||
/**
|
||||
* 内容填充规则
|
||||
*/
|
||||
public String fillRule(Object beanObject, String content){
|
||||
Matcher matcher = FILL_PATTERN.matcher(content);
|
||||
while(matcher.find()){
|
||||
String matchWord = matcher.group(0);
|
||||
String property = matchWord.substring(2, matchWord.length()-1);
|
||||
String fill = null;
|
||||
try {
|
||||
fill = String.valueOf(EntityBeanUtil.getField(beanObject, property));
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
} finally {
|
||||
content = content.replace(matchWord, fill);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
/* 快捷数据 */
|
||||
/**
|
||||
* 获取用户名
|
||||
*/
|
||||
public String getUsername(){
|
||||
return ShiroUtil.getSubject().getUsername();
|
||||
}
|
||||
/**
|
||||
* 获取用户昵称
|
||||
*/
|
||||
public String getNickname(){
|
||||
return ShiroUtil.getSubject().getNickname();
|
||||
}
|
||||
/**
|
||||
* 获取当前时间
|
||||
*/
|
||||
public String getDatetime(){
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return df.format(new Date());
|
||||
}
|
||||
/**
|
||||
* 获取当前时间(自定义时间格式)
|
||||
*/
|
||||
public String getDatetime(String pattern){
|
||||
SimpleDateFormat df = new SimpleDateFormat(pattern);
|
||||
return df.format(new Date());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class ActionModel {
|
||||
/** 日志名称 */
|
||||
protected String name;
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type;
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import com.linln.modules.system.enums.ActionLogEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessMethod extends ActionModel{
|
||||
/** 日志名称 */
|
||||
protected String name;
|
||||
|
||||
/** 行为方法名 */
|
||||
protected String method;
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type = ActionLogEnum.BUSINESS.getCode();
|
||||
|
||||
/**
|
||||
* 只构建行为方法名,日志名称由日志注解name定义
|
||||
* @param method 行为方法名
|
||||
*/
|
||||
public BusinessMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建日志名称和行为方法名
|
||||
* @param name 日志名称
|
||||
* @param method 行为方法名
|
||||
*/
|
||||
public BusinessMethod(String name, String method) {
|
||||
this.name = name;
|
||||
this.method = method;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import com.linln.modules.system.enums.ActionLogEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessType extends ActionModel{
|
||||
|
||||
/** 日志名称 */
|
||||
protected String name;
|
||||
|
||||
/** 日志消息 */
|
||||
protected String message;
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type = ActionLogEnum.BUSINESS.getCode();
|
||||
|
||||
/**
|
||||
* 只构建日志消息,日志名称有日志注解name定义
|
||||
* @param message 日志消息
|
||||
*/
|
||||
public BusinessType(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建日志名称和日志消息
|
||||
* @param name 日志名称
|
||||
* @param message 日志消息
|
||||
*/
|
||||
public BusinessType(String name, String message) {
|
||||
this.name = name;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import com.linln.modules.system.enums.ActionLogEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class LoginMethod extends BusinessMethod{
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type = ActionLogEnum.LOGIN.getCode();
|
||||
|
||||
public LoginMethod(String method) {
|
||||
super(method);
|
||||
}
|
||||
|
||||
public LoginMethod(String name, String method) {
|
||||
super(name, method);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import com.linln.modules.system.enums.ActionLogEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class LoginType extends BusinessType{
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type = ActionLogEnum.LOGIN.getCode();
|
||||
|
||||
public LoginType(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public LoginType(String name, String message) {
|
||||
super(name, message);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import com.linln.modules.system.enums.ActionLogEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class SystemMethod extends BusinessMethod{
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type = ActionLogEnum.SYSTEM.getCode();
|
||||
|
||||
public SystemMethod(String method) {
|
||||
super(method);
|
||||
}
|
||||
|
||||
public SystemMethod(String name, String method) {
|
||||
super(name, method);
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.linln.component.actionLog.action.model;
|
||||
|
||||
import com.linln.modules.system.enums.ActionLogEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2018/10/15
|
||||
*/
|
||||
@Getter
|
||||
public class SystemType extends BusinessType{
|
||||
|
||||
/** 日志类型 */
|
||||
protected Byte type = ActionLogEnum.SYSTEM.getCode();
|
||||
|
||||
public SystemType(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public SystemType(String name, String message) {
|
||||
super(name, message);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.linln.component.actionLog.annotation;
|
||||
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 行为日志注解
|
||||
* @author gion
|
||||
* @date 2018/11/12
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
public @interface ActionLog {
|
||||
// 日志名称
|
||||
String name() default "";
|
||||
// 日志消息
|
||||
String message() default "";
|
||||
// 行为key
|
||||
String key() default "";
|
||||
// 行为类
|
||||
Class<? extends BaseActionMap> action() default BaseActionMap.class;
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package com.linln.component.actionLog.annotation;
|
||||
|
||||
import com.linln.common.utils.SpringContextUtil;
|
||||
import com.linln.component.actionLog.action.base.BaseActionMap;
|
||||
import com.linln.component.actionLog.action.base.ResetLog;
|
||||
import com.linln.component.actionLog.action.model.ActionModel;
|
||||
import com.linln.component.actionLog.action.model.BusinessMethod;
|
||||
import com.linln.component.actionLog.action.model.BusinessType;
|
||||
import com.linln.component.shiro.ShiroUtil;
|
||||
import com.linln.modules.system.domain.ActionLog;
|
||||
import com.linln.modules.system.service.ActionLogService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
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.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 行为日志注解AOP
|
||||
* @author gion
|
||||
* @date 2018/11/12
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ActionLogAop {
|
||||
private final static String DEFAULT_ACTION_NAME = "default";
|
||||
|
||||
@Pointcut("@annotation(com.linln.component.actionLog.annotation.ActionLog)")
|
||||
public void actionLog() {};
|
||||
|
||||
@Around("actionLog()")
|
||||
public Object recordLog(ProceedingJoinPoint point) throws Throwable {
|
||||
// 先执行切入点,获取返回值
|
||||
Object proceed = point.proceed();
|
||||
|
||||
|
||||
/* 读取ActionLog注解消息 */
|
||||
Method targetMethod = ((MethodSignature)(point.getSignature())).getMethod();
|
||||
com.linln.component.actionLog.annotation.ActionLog anno =
|
||||
targetMethod.getAnnotation(com.linln.component.actionLog.annotation.ActionLog.class);
|
||||
// 获取name值
|
||||
String name = anno.name();
|
||||
// 获取message值
|
||||
String message = anno.message();
|
||||
// 获取key值
|
||||
String key = anno.key();
|
||||
// 获取行为模型
|
||||
Class<? extends BaseActionMap> action = anno.action();
|
||||
BaseActionMap instance = action.newInstance();
|
||||
Object actionModel = instance.get(!key.isEmpty() ? key : DEFAULT_ACTION_NAME);
|
||||
Assert.notNull(actionModel, "无法获取日志的行为方法,请检查:"+point.getSignature());
|
||||
|
||||
|
||||
// 封装日志实例对象
|
||||
ActionLog actionLog = new ActionLog();
|
||||
actionLog.setIpaddr(ShiroUtil.getIp());
|
||||
actionLog.setClazz(point.getTarget().getClass().getName());
|
||||
actionLog.setMethod(targetMethod.getName());
|
||||
actionLog.setType(((ActionModel) actionModel).getType());
|
||||
actionLog.setName(!name.isEmpty() ? name : ((ActionModel) actionModel).getName());
|
||||
actionLog.setMessage(message);
|
||||
actionLog.setOperBy(ShiroUtil.getSubject());
|
||||
if(ShiroUtil.getSubject() != null){
|
||||
actionLog.setOperName(ShiroUtil.getSubject().getNickname());
|
||||
}
|
||||
|
||||
//判断是否为普通实例对象
|
||||
if(actionModel instanceof BusinessType){
|
||||
actionLog.setMessage(((BusinessType) actionModel).getMessage());
|
||||
}else {
|
||||
// 重置日志-自定义日志数据
|
||||
ResetLog resetLog = new ResetLog();
|
||||
resetLog.setActionLog(actionLog);
|
||||
resetLog.setRetValue(proceed);
|
||||
resetLog.setJoinPoint(point);
|
||||
try {
|
||||
Method method = action.getDeclaredMethod(((BusinessMethod)actionModel).getMethod(), ResetLog.class);
|
||||
method.invoke(instance, resetLog);
|
||||
if(!resetLog.getRecord()) {
|
||||
return proceed;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
log.error("获取行为对象方法错误!请检查方法名称是否正确!", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 保存日志
|
||||
ActionLogService actionLogService = SpringContextUtil.getBean(ActionLogService.class);
|
||||
actionLogService.save(actionLog);
|
||||
|
||||
return proceed;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.linln.component.actionLog.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 控制器实体参数注解
|
||||
* @author gion
|
||||
* @date 2019/2/25
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Documented
|
||||
public @interface EntityParam {
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.linln.component.actionLog.config;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* @author gion
|
||||
* @date 2021/3/19
|
||||
*/
|
||||
@ComponentScan(basePackages = "com.linln.component.actionLog")
|
||||
public class ActionLogAutoConfig {
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.linln.component.actionLog.exception;
|
||||
|
||||
import com.linln.common.exception.advice.ExceptionAdvice;
|
||||
import com.linln.component.actionLog.action.SystemAction;
|
||||
import com.linln.component.actionLog.annotation.ActionLog;
|
||||
|
||||
/**
|
||||
* 运行时抛出的异常进行日志记录
|
||||
* @author gion
|
||||
* @date 2019/4/6
|
||||
*/
|
||||
public class ActionLogProceedAdvice implements ExceptionAdvice {
|
||||
|
||||
@Override
|
||||
@ActionLog(key = SystemAction.RUNTIME_EXCEPTION, action = SystemAction.class)
|
||||
public void run(RuntimeException e) {}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.linln.component.actionLog.exception;
|
||||
|
||||
import com.linln.common.exception.advice.ResultExceptionAdvice;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 将异常切入程序添加到异常通知器中
|
||||
* @author gion
|
||||
* @date 2019/4/6
|
||||
*/
|
||||
@Configuration
|
||||
public class ActionLogProceedAdviceConfig {
|
||||
|
||||
@Bean
|
||||
public ActionLogProceedAdvice actionLogProceedAdvice(ResultExceptionAdvice advice) {
|
||||
ActionLogProceedAdvice authorization = new ActionLogProceedAdvice();
|
||||
advice.putProceed(authorization);
|
||||
return authorization;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.linln.component.actionLog.config.ActionLogAutoConfig
|
||||
Reference in New Issue
Block a user