diff --git a/.idea/compiler.xml b/.idea/compiler.xml index e67f790..9475cb2 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -9,6 +9,7 @@ + @@ -16,6 +17,7 @@ + diff --git a/.idea/encodings.xml b/.idea/encodings.xml index ad50fd9..6dbb144 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,6 +1,7 @@ + diff --git a/pom.xml b/pom.xml index c9816e8..23dceb1 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ spzx-common spzx-model spzx-manager + spzx-common/common-log diff --git a/spzx-common/common-log/pom.xml b/spzx-common/common-log/pom.xml new file mode 100644 index 0000000..ccfcd69 --- /dev/null +++ b/spzx-common/common-log/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + + com.atguigu + spzx-parent-v2 + 1.0-SNAPSHOT + ../../pom.xml + + + common-log + jar + + common-log + http://maven.apache.org + + + UTF-8 + + + + + com.atguigu + spzx-model + 1.0-SNAPSHOT + + + com.atguigu + common-util + 1.0-SNAPSHOT + + + com.atguigu + common-service + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-web + provided + + + diff --git a/spzx-common/common-log/src/main/java/com/atguigu/log/annotation/EnableLogAspect.java b/spzx-common/common-log/src/main/java/com/atguigu/log/annotation/EnableLogAspect.java new file mode 100644 index 0000000..f5b4ae7 --- /dev/null +++ b/spzx-common/common-log/src/main/java/com/atguigu/log/annotation/EnableLogAspect.java @@ -0,0 +1,18 @@ +package com.atguigu.log.annotation; + +import com.atguigu.log.aspect.LogAspect; +import org.springframework.context.annotation.Import; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +// 开启动类中开启包扫描也可以, +// 如果不想这样写可以按照下面定义一个切面类, +// 之后在SpringBoot中加入这个注解,让其扫描到 +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Import(value = LogAspect.class) +public @interface EnableLogAspect { +} \ No newline at end of file diff --git a/spzx-common/common-log/src/main/java/com/atguigu/log/annotation/Log.java b/spzx-common/common-log/src/main/java/com/atguigu/log/annotation/Log.java new file mode 100644 index 0000000..241dc80 --- /dev/null +++ b/spzx-common/common-log/src/main/java/com/atguigu/log/annotation/Log.java @@ -0,0 +1,24 @@ +package com.atguigu.log.annotation; + +import com.atguigu.log.enums.OperatorType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Log { // 自定义操作日志记录注解 + + String title(); // 模块名称 + + OperatorType operatorType() default OperatorType.MANAGE; // 操作人类别 + + int businessType(); // 业务类型(0其它 1新增 2修改 3删除) + + boolean isSaveRequestData() default true; // 是否保存请求的参数 + + boolean isSaveResponseData() default true; // 是否保存响应的参数 + +} \ No newline at end of file diff --git a/spzx-common/common-log/src/main/java/com/atguigu/log/aspect/LogAspect.java b/spzx-common/common-log/src/main/java/com/atguigu/log/aspect/LogAspect.java new file mode 100644 index 0000000..12d3013 --- /dev/null +++ b/spzx-common/common-log/src/main/java/com/atguigu/log/aspect/LogAspect.java @@ -0,0 +1,47 @@ +package com.atguigu.log.aspect; + +import com.atguigu.exception.BunnyException; +import com.atguigu.log.annotation.Log; +import com.atguigu.log.service.AsyncOperaLogService; +import com.atguigu.log.utils.LogUtil; +import com.atguigu.spzx.model.entity.system.SysOperLog; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Aspect +@Component +@Slf4j +public class LogAspect { + @Autowired + private AsyncOperaLogService asyncOperaLogService; + + @Around(value = "@annotation(sysLog)") + public Object doAroundAdvice(ProceedingJoinPoint joinPoint, Log sysLog) { + // 构建前置参数 + SysOperLog sysOperLog = new SysOperLog(); + + LogUtil.beforeHandleLog(sysLog, joinPoint, sysOperLog); + + Object proceed = null; + try { + proceed = joinPoint.proceed(); + // 执行业务方法 + LogUtil.afterHandleLog(sysLog, proceed, sysOperLog, 0, null); + // 构建响应结果参数 + } catch (Throwable e) { // 代码执行进入到catch中, + // 业务方法执行产生异常 + LogUtil.afterHandleLog(sysLog, proceed, sysOperLog, 1, e.getMessage()); + throw new BunnyException(e.getMessage()); + } + + // 保存日志数据 + asyncOperaLogService.saveSysOperaLog(sysOperLog); + + // 返回执行结果 + return proceed; + } +} \ No newline at end of file diff --git a/spzx-common/common-log/src/main/java/com/atguigu/log/enums/OperatorType.java b/spzx-common/common-log/src/main/java/com/atguigu/log/enums/OperatorType.java new file mode 100644 index 0000000..d9c454a --- /dev/null +++ b/spzx-common/common-log/src/main/java/com/atguigu/log/enums/OperatorType.java @@ -0,0 +1,8 @@ +package com.atguigu.log.enums; + +// 操作人类别 +public enum OperatorType { + OTHER,// 其他 + MANAGE,// 后台用户 + MOBILE// 手机端用户 +} \ No newline at end of file diff --git a/spzx-common/common-log/src/main/java/com/atguigu/log/service/AsyncOperaLogService.java b/spzx-common/common-log/src/main/java/com/atguigu/log/service/AsyncOperaLogService.java new file mode 100644 index 0000000..887e207 --- /dev/null +++ b/spzx-common/common-log/src/main/java/com/atguigu/log/service/AsyncOperaLogService.java @@ -0,0 +1,8 @@ +package com.atguigu.log.service; + +import com.atguigu.spzx.model.entity.system.SysOperLog; + +// 保存日志数据 +public interface AsyncOperaLogService { + void saveSysOperaLog(SysOperLog sysOperLog); +} diff --git a/spzx-common/common-log/src/main/java/com/atguigu/log/utils/LogUtil.java b/spzx-common/common-log/src/main/java/com/atguigu/log/utils/LogUtil.java new file mode 100644 index 0000000..89337b6 --- /dev/null +++ b/spzx-common/common-log/src/main/java/com/atguigu/log/utils/LogUtil.java @@ -0,0 +1,62 @@ +package com.atguigu.log.utils; + +import com.alibaba.fastjson.JSON; +import com.atguigu.context.BaseContext; +import com.atguigu.log.annotation.Log; +import com.atguigu.spzx.model.entity.system.SysOperLog; +import jakarta.servlet.http.HttpServletRequest; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.http.HttpMethod; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import java.lang.reflect.Method; +import java.util.Arrays; + +public class LogUtil { + + // 操作执行之后调用 + public static void afterHandleLog(Log sysLog, Object proceed, + SysOperLog sysOperLog, int status, + String errorMsg) { + if (sysLog.isSaveResponseData()) { + sysOperLog.setJsonResult(JSON.toJSONString(proceed)); + } + sysOperLog.setStatus(status); + sysOperLog.setErrorMsg(errorMsg); + } + + // 操作执行之前调用 + public static void beforeHandleLog(Log sysLog, + ProceedingJoinPoint joinPoint, + SysOperLog sysOperLog) { + + // 设置操作模块名称 + sysOperLog.setTitle(sysLog.title()); + sysOperLog.setOperatorType(sysLog.operatorType().name()); + + // 获取目标方法信息 + MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); + Method method = methodSignature.getMethod(); + sysOperLog.setMethod(method.getDeclaringClass().getName()); + + // 获取请求相关参数 + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) + RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = requestAttributes.getRequest(); + sysOperLog.setRequestMethod(request.getMethod()); + sysOperLog.setOperUrl(request.getRequestURI()); + sysOperLog.setOperIp(request.getRemoteAddr()); + + // 设置请求参数 + if (sysLog.isSaveRequestData()) { + String requestMethod = sysOperLog.getRequestMethod(); + if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) { + String params = Arrays.toString(joinPoint.getArgs()); + sysOperLog.setOperParam(params); + } + } + sysOperLog.setOperName(BaseContext.getSysUser().getName()); + } +} \ No newline at end of file diff --git a/spzx-common/common-service/src/main/java/com/atguigu/handler/GlobalExceptionHandler.java b/spzx-common/common-service/src/main/java/com/atguigu/handler/GlobalExceptionHandler.java index 3c4d76d..5d5b790 100644 --- a/spzx-common/common-service/src/main/java/com/atguigu/handler/GlobalExceptionHandler.java +++ b/spzx-common/common-service/src/main/java/com/atguigu/handler/GlobalExceptionHandler.java @@ -21,7 +21,8 @@ public class GlobalExceptionHandler { @ResponseBody public Result exceptionHandler(BunnyException exception) { log.error("GlobalExceptionHandler===>自定义异常信息:{}", exception.getMessage()); - return Result.error(exception.getCode(), exception.getMessage()); + Integer code = exception.getCode() != null ? exception.getCode() : 500; + return Result.error(null, code, exception.getMessage()); } // 运行时异常信息 @@ -29,7 +30,8 @@ public class GlobalExceptionHandler { @ResponseBody public Result exceptionHandler(RuntimeException exception) { log.error("GlobalExceptionHandler===>运行时异常信息:{}", exception.getMessage()); - return Result.error(500, "出错了啦"); + + return Result.error(null, 500, "出错了啦"); } // 捕获系统异常 @@ -37,7 +39,8 @@ public class GlobalExceptionHandler { @ResponseBody public Result error(Exception exception) { log.error("GlobalExceptionHandler===>系统异常信息:{}", exception.getMessage()); - return Result.error(exception.getMessage()); + + return Result.error(null, 500, exception.getMessage()); } // 特定异常处理 @@ -45,7 +48,7 @@ public class GlobalExceptionHandler { @ResponseBody public Result error(ArithmeticException exception) { log.error("GlobalExceptionHandler===>特定异常信息:{}", exception.getMessage()); - return Result.error(null, exception.getMessage()); + return Result.error(null, 500, exception.getMessage()); } // spring security异常 diff --git a/spzx-manager/pom.xml b/spzx-manager/pom.xml index 78a98e0..aaa2672 100644 --- a/spzx-manager/pom.xml +++ b/spzx-manager/pom.xml @@ -29,6 +29,11 @@ common-util 1.0-SNAPSHOT + + com.atguigu + common-log + 1.0-SNAPSHOT + org.springframework.boot diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/MangerApplication.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/MangerApplication.java index dfd7c12..6995570 100644 --- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/MangerApplication.java +++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/MangerApplication.java @@ -1,5 +1,6 @@ package com.atguigu.spzx.manger; +import com.atguigu.log.annotation.EnableLogAspect; import lombok.extern.slf4j.Slf4j; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; @@ -14,6 +15,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @EnableCaching// 开启缓存注解 @EnableScheduling @ComponentScan("com.atguigu") +@EnableLogAspect// 开启切面类 @MapperScan("com.atguigu.spzx.manger.mapper") @Slf4j public class MangerApplication { diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/CategoryController.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/CategoryController.java index e15347a..d54e3f8 100644 --- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/CategoryController.java +++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/CategoryController.java @@ -1,5 +1,7 @@ package com.atguigu.spzx.manger.controller; +import com.atguigu.log.annotation.Log; +import com.atguigu.log.enums.OperatorType; import com.atguigu.spzx.manger.service.CategoryService; import com.atguigu.spzx.model.entity.product.Category; import com.atguigu.spzx.model.vo.result.Result; @@ -19,6 +21,8 @@ public class CategoryController { @Autowired private CategoryService categoryService; + + @Log(title = "根据parentId获取下级节点", businessType = 0, operatorType = OperatorType.MANAGE) @Operation(summary = "根据parentId获取下级节点", description = "根据parentId获取下级节点") @GetMapping(value = "findCategoryList/{parentId}") public Result> findByParentId(@PathVariable Long parentId) { diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/ProductController.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/ProductController.java index 7ba45fb..28fc2a5 100644 --- a/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/ProductController.java +++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/controller/ProductController.java @@ -1,5 +1,7 @@ package com.atguigu.spzx.manger.controller; +import com.atguigu.log.annotation.Log; +import com.atguigu.log.enums.OperatorType; import com.atguigu.spzx.manger.service.CategoryBrandService; import com.atguigu.spzx.manger.service.ProductService; import com.atguigu.spzx.model.dto.product.ProductDto; @@ -46,6 +48,7 @@ public class ProductController { return Result.success(); } + @Log(title = "查询商品详情", businessType = 0, operatorType = OperatorType.MANAGE) @Operation(summary = "查询商品详情", description = "查询商品详情") @GetMapping("getById/{id}") public Result getById(@PathVariable Long id) { @@ -76,7 +79,7 @@ public class ProductController { @Operation(summary = "商品上下架", description = "商品上下架") @GetMapping("/updateStatus/{id}/{status}") - public Result updateStatus(@PathVariable Long id, @PathVariable Integer status) { + public Result updateStatus(@PathVariable Long id, @PathVariable Integer status) { productService.updateStatus(id, status); return Result.build(null, ResultCodeEnum.SUCCESS); } diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/mapper/SysOperaLogMapper.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/mapper/SysOperaLogMapper.java new file mode 100644 index 0000000..6b54990 --- /dev/null +++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/mapper/SysOperaLogMapper.java @@ -0,0 +1,14 @@ +package com.atguigu.spzx.manger.mapper; + +import com.atguigu.spzx.model.entity.system.SysOperLog; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SysOperaLogMapper { + /** + * 异步执行保存日志操作 + * + * @param sysOperaLog SysOperaLog + */ + void insert(SysOperLog sysOperaLog); +} diff --git a/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/AsyncOperaLogServiceImpl.java b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/AsyncOperaLogServiceImpl.java new file mode 100644 index 0000000..3619e76 --- /dev/null +++ b/spzx-manager/src/main/java/com/atguigu/spzx/manger/service/impl/AsyncOperaLogServiceImpl.java @@ -0,0 +1,25 @@ +package com.atguigu.spzx.manger.service.impl; + +import com.atguigu.log.service.AsyncOperaLogService; +import com.atguigu.spzx.manger.mapper.SysOperaLogMapper; +import com.atguigu.spzx.model.entity.system.SysOperLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +@Service +public class AsyncOperaLogServiceImpl implements AsyncOperaLogService { + @Autowired + private SysOperaLogMapper sysOperaLogMapper; + + /** + * 异步执行保存日志操作 + * + * @param sysOperaLog SysOperLog + */ + @Async + @Override + public void saveSysOperaLog(SysOperLog sysOperaLog) { + sysOperaLogMapper.insert(sysOperaLog); + } +} \ No newline at end of file diff --git a/spzx-manager/src/main/resources/mapper/OrderInfoMapper.xml b/spzx-manager/src/main/resources/mapper/OrderInfoMapper.xml index b25ad5b..e8667dd 100644 --- a/spzx-manager/src/main/resources/mapper/OrderInfoMapper.xml +++ b/spzx-manager/src/main/resources/mapper/OrderInfoMapper.xml @@ -2,7 +2,6 @@ - select DATE_FORMAT(oi.create_time, '%Y-%m-%d') orderDate, diff --git a/spzx-manager/src/main/resources/mapper/SysOperaLogMapper.xml b/spzx-manager/src/main/resources/mapper/SysOperaLogMapper.xml new file mode 100644 index 0000000..a2f49c6 --- /dev/null +++ b/spzx-manager/src/main/resources/mapper/SysOperaLogMapper.xml @@ -0,0 +1,12 @@ + + + + + + + insert into sys_oper_log (id, title, method, request_method, operator_type, oper_name, oper_url, oper_ip, + oper_param, json_result, status, error_msg) + values (#{id}, #{title}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{operUrl}, #{operIp}, + #{operParam}, #{jsonResult}, #{status}, #{errorMsg}) + + diff --git a/spzx-model/src/main/java/com/atguigu/spzx/model/entity/system/SysOperLog.java b/spzx-model/src/main/java/com/atguigu/spzx/model/entity/system/SysOperLog.java index 064ae31..186a4a3 100644 --- a/spzx-model/src/main/java/com/atguigu/spzx/model/entity/system/SysOperLog.java +++ b/spzx-model/src/main/java/com/atguigu/spzx/model/entity/system/SysOperLog.java @@ -7,42 +7,40 @@ import lombok.Data; @Data @Schema(description = "SysOperLog") public class SysOperLog extends BaseEntity { + private static final long serialVersionUID = 1L; - private static final long serialVersionUID = 1L; + @Schema(description = "模块标题") + private String title; - @Schema(description = "模块标题") - private String title; + @Schema(description = "方法名称") + private String method; - @Schema(description = "方法名称") - private String method; + @Schema(description = "请求方式") + private String requestMethod; - @Schema(description = "请求方式") - private String requestMethod; + private Integer businessType; // 业务类型(0其它 1新增 2修改 3删除) - private Integer businessType ; // 业务类型(0其它 1新增 2修改 3删除) + @Schema(description = "操作类别(0其它 1后台用户 2手机端用户)") + private String operatorType; - @Schema(description = "操作类别(0其它 1后台用户 2手机端用户)") - private String operatorType; + @Schema(description = "操作人员") + private String operName; - @Schema(description = "操作人员") - private String operName; + @Schema(description = "请求URL") + private String operUrl; - @Schema(description = "请求URL") - private String operUrl; + @Schema(description = "主机地址") + private String operIp; - @Schema(description = "主机地址") - private String operIp; + @Schema(description = "请求参数") + private String operParam; - @Schema(description = "请求参数") - private String operParam; + @Schema(description = "返回参数") + private String jsonResult; - @Schema(description = "返回参数") - private String jsonResult; - - @Schema(description = "操作状态(0正常 1异常)") - private Integer status; - - @Schema(description = "错误消息") - private String errorMsg; + @Schema(description = "操作状态(0正常 1异常)") + private Integer status; + @Schema(description = "错误消息") + private String errorMsg; } \ No newline at end of file