Initial commit

This commit is contained in:
易焱
2019-07-30 18:14:32 +08:00
commit daa60cf523
1624 changed files with 90832 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="Spring" name="Spring">
<configuration />
</facet>
<facet type="web" name="Web">
<configuration>
<webroots />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="common" />
<orderEntry type="module" module-name="system" />
<orderEntry type="module" module-name="excel" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:4.0.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.0.0" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:4.0.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:3.0.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.18" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="module" module-name="shiro" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.4.0" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-ehcache:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.4.0" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache-core:2.6.11" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.26" level="project" />
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.8" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.17" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.16.Final" level="project" />
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-jpa:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.2.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.transaction:javax.transaction-api:1.3" level="project" />
<orderEntry type="library" name="Maven: javax.xml.bind:jaxb-api:2.3.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:javax.activation-api:1.2.0" level="project" />
<orderEntry type="library" name="Maven: org.hibernate:hibernate-core:5.3.9.Final" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:javax.persistence-api:2.2" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.23.1-GA" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.12" level="project" />
<orderEntry type="library" name="Maven: antlr:antlr:2.7.7" level="project" />
<orderEntry type="library" name="Maven: org.jboss:jandex:2.0.5.Final" level="project" />
<orderEntry type="library" name="Maven: org.dom4j:dom4j:2.1.1" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.common:hibernate-commons-annotations:5.0.4.Final" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-jpa:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-orm:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-aspects:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-cache:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.springframework.boot:spring-boot-devtools:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.4.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.6.RELEASE" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.46" level="project" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.2" level="project" />
<orderEntry type="library" name="Maven: net.sf.ehcache:ehcache:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.26" level="project" />
<orderEntry type="library" name="Maven: org.jsoup:jsoup:1.11.3" level="project" />
</component>
</module>
+35
View File
@@ -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.cwhelp.component</groupId>
<artifactId>actionLog</artifactId>
<packaging>jar</packaging>
<name>组件:行为日志</name>
<parent>
<groupId>com.cwhelp</groupId>
<artifactId>component</artifactId>
<version>2.0.1</version>
</parent>
<dependencies>
<dependency>
<groupId>com.cwhelp</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.cwhelp.modules</groupId>
<artifactId>system</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.cwhelp.component</groupId>
<artifactId>shiro</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,45 @@
package com.cwhelp.component.actionLog.action;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import com.cwhelp.component.actionLog.action.base.ResetLog;
import com.cwhelp.component.actionLog.action.model.BusinessMethod;
import com.cwhelp.modules.system.domain.Role;
import javax.persistence.Table;
/**
* 角色日志行为
* @author yan.y
*/
public class RoleAction extends ActionMap {
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());
}
}
}
@@ -0,0 +1,60 @@
package com.cwhelp.component.actionLog.action;
import com.cwhelp.common.utils.EntityBeanUtil;
import com.cwhelp.common.utils.HttpServletUtil;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import com.cwhelp.component.actionLog.action.base.ResetLog;
import com.cwhelp.modules.system.domain.ActionLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import javax.persistence.Table;
/**
* 通用:记录保存数据的行为
*
* @author yan.y
*/
@Slf4j
public class SaveAction extends ActionMap {
@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);
}
}
}
@@ -0,0 +1,37 @@
package com.cwhelp.component.actionLog.action;
import com.cwhelp.common.utils.StatusUtil;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import com.cwhelp.component.actionLog.action.base.ResetLog;
import com.cwhelp.common.enums.StatusEnum;
import java.util.List;
/**
* 通用:记录数据状态的行为
*
* @author yan.y
*/
public class StatusAction extends ActionMap {
@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());
}
}
}
@@ -0,0 +1,34 @@
package com.cwhelp.component.actionLog.action;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import com.cwhelp.component.actionLog.action.base.ResetLog;
import com.cwhelp.component.actionLog.action.model.SystemMethod;
import com.cwhelp.modules.system.domain.ActionLog;
/**
* @author yan.y
*/
public class SystemAction extends ActionMap {
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));
}
}
@@ -0,0 +1,95 @@
package com.cwhelp.component.actionLog.action;
import com.cwhelp.common.vo.ResultVo;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import com.cwhelp.component.actionLog.action.base.ResetLog;
import com.cwhelp.component.actionLog.action.model.BusinessMethod;
import com.cwhelp.component.actionLog.action.model.LoginMethod;
import com.cwhelp.modules.system.domain.ActionLog;
import com.cwhelp.modules.system.domain.User;
import com.cwhelp.modules.system.service.ActionLogService;
import com.cwhelp.common.utils.SpringContextUtil;
import org.springframework.beans.BeanUtils;
import javax.persistence.Table;
import java.util.List;
/**
* 用户日志行为
* @author yan.y
*/
public class UserAction extends ActionMap {
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){
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());
}
}
}
@@ -0,0 +1,89 @@
package com.cwhelp.component.actionLog.action.base;
import com.cwhelp.component.actionLog.action.model.BusinessMethod;
import com.cwhelp.component.actionLog.action.model.BusinessType;
import java.util.HashMap;
/**
* @author yan.y
*/
public abstract class ActionMap {
protected HashMap<String, Object> dictory = new HashMap<>();
public ActionMap(){
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));
}
}
@@ -0,0 +1,121 @@
package com.cwhelp.component.actionLog.action.base;
import com.cwhelp.common.enums.ResultEnum;
import com.cwhelp.common.utils.EntityBeanUtil;
import com.cwhelp.common.vo.ResultVo;
import com.cwhelp.component.actionLog.annotation.EntityParam;
import com.cwhelp.component.shiro.ShiroUtil;
import com.cwhelp.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 yan.y
*/
@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;
}
// 内容填充规则
public String fillRule(Object beanObject, String content){
Pattern pattern = Pattern.compile("\\$\\{[a-zA-Z0-9]+\\}");
Matcher matcher = 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());
}
}
@@ -0,0 +1,14 @@
package com.cwhelp.component.actionLog.action.model;
import lombok.Getter;
/**
* @author yan.y
*/
@Getter
public class ActionModel {
// 日志名称
protected String name;
// 日志类型
protected Byte type;
}
@@ -0,0 +1,35 @@
package com.cwhelp.component.actionLog.action.model;
import com.cwhelp.modules.system.enums.ActionLogEnum;
import lombok.Getter;
/**
* @author yan.y
*/
@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;
}
}
@@ -0,0 +1,35 @@
package com.cwhelp.component.actionLog.action.model;
import com.cwhelp.modules.system.enums.ActionLogEnum;
import lombok.Getter;
/**
* @author yan.y
*/
@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;
}
}
@@ -0,0 +1,21 @@
package com.cwhelp.component.actionLog.action.model;
import com.cwhelp.modules.system.enums.ActionLogEnum;
import lombok.Getter;
/**
* @author yan.y
*/
@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);
}
}
@@ -0,0 +1,21 @@
package com.cwhelp.component.actionLog.action.model;
import com.cwhelp.modules.system.enums.ActionLogEnum;
import lombok.Getter;
/**
* @author yan.y
*/
@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);
}
}
@@ -0,0 +1,21 @@
package com.cwhelp.component.actionLog.action.model;
import com.cwhelp.modules.system.enums.ActionLogEnum;
import lombok.Getter;
/**
* @author yan.y
*/
@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);
}
}
@@ -0,0 +1,21 @@
package com.cwhelp.component.actionLog.action.model;
import com.cwhelp.modules.system.enums.ActionLogEnum;
import lombok.Getter;
/**
* @author yan.y
*/
@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);
}
}
@@ -0,0 +1,25 @@
package com.cwhelp.component.actionLog.annotation;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 行为日志注解
* @author yan.y
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ActionLog {
// 日志名称
String name() default "";
// 日志消息
String message() default "";
// 行为key
String key() default "";
// 行为类
Class<? extends ActionMap> action() default ActionMap.class;
}
@@ -0,0 +1,98 @@
package com.cwhelp.component.actionLog.annotation;
import com.cwhelp.common.utils.SpringContextUtil;
import com.cwhelp.component.actionLog.action.base.ActionMap;
import com.cwhelp.component.actionLog.action.base.ResetLog;
import com.cwhelp.component.actionLog.action.model.ActionModel;
import com.cwhelp.component.actionLog.action.model.BusinessMethod;
import com.cwhelp.component.actionLog.action.model.BusinessType;
import com.cwhelp.component.shiro.ShiroUtil;
import com.cwhelp.modules.system.domain.ActionLog;
import com.cwhelp.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 yan.y
*/
@Aspect
@Component
@Slf4j
public class ActionLogAop {
private final static String defaultActionName = "default";
@Pointcut("@annotation(com.cwhelp.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.cwhelp.component.actionLog.annotation.ActionLog anno =
targetMethod.getAnnotation(com.cwhelp.component.actionLog.annotation.ActionLog.class);
// 获取name值
String name = anno.name();
// 获取message值
String message = anno.message();
// 获取key值
String key = anno.key();
// 获取行为模型
Class<? extends ActionMap> action = anno.action();
ActionMap instance = action.newInstance();
Object actionModel = instance.get(!key.isEmpty() ? key : defaultActionName);
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;
}
}
@@ -0,0 +1,13 @@
package com.cwhelp.component.actionLog.annotation;
import java.lang.annotation.*;
/**
* 控制器实体参数注解
* @author yan.y
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Documented
public @interface EntityParam {
}
@@ -0,0 +1,16 @@
package com.cwhelp.component.actionLog.exception;
import com.cwhelp.common.exception.advice.ExceptionAdvice;
import com.cwhelp.component.actionLog.action.SystemAction;
import com.cwhelp.component.actionLog.annotation.ActionLog;
/**
* 运行时抛出的异常进行日志记录
* @author yan.y
*/
public class ActionLogProceedAdvice implements ExceptionAdvice {
@Override
@ActionLog(key = SystemAction.RUNTIME_EXCEPTION, action = SystemAction.class)
public void run(RuntimeException e) {}
}
@@ -0,0 +1,20 @@
package com.cwhelp.component.actionLog.exception;
import com.cwhelp.common.exception.advice.ResultExceptionAdvice;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 将异常切入程序添加到异常通知器中
* @author yan.y
*/
@Configuration
public class ActionLogProceedAdviceConfig {
@Bean
public ActionLogProceedAdvice actionLogProceedAdvice(ResultExceptionAdvice advice) {
ActionLogProceedAdvice authorization = new ActionLogProceedAdvice();
advice.putProceed(authorization);
return authorization;
}
}