Quellcode durchsuchen

新增系统操作日志切面

tsurumure vor 8 Monaten
Ursprung
Commit
b366fe0d5c

+ 19 - 0
db/sys_log.sql

@@ -0,0 +1,19 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2024/12/28 16:37:00
+*/
+
+DROP TABLE IF EXISTS `sys_log`;
+CREATE TABLE `sys_log` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT(10) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+    `username` VARCHAR(255) NOT NULL COMMENT '用户名',
+    `operation` VARCHAR(255) COMMENT '用户操作',
+    `classname` VARCHAR(255) COMMENT '请求类名',
+    `method` VARCHAR(255) COMMENT '请求方法',
+    `params` VARCHAR(5000) COMMENT '请求参数',
+    `time` INT COMMENT '执行时长(毫秒)',
+    `ip` VARCHAR(64) COMMENT 'IP',
+    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统日志';

+ 2 - 1
db/sys_user_role_module.sql

@@ -73,7 +73,8 @@ INSERT INTO sys_user_role_module(id, parent_id, module_name, sort) VALUES
             ('4.1.3', '4.1', '系统角色-编辑', null),
             ('4.1.4', '4.1', '系统角色-删除', null),
             ('4.1.5', '4.1', '系统角色-模块列表', null),
-
+    ('5', -1, '系统日志管理', 901),
+        ('5.1', '5', '系统日志-列表', null),
 
     -- ('10', -1, '资讯管理', null),
     --     ('10.1', '10', '幻灯片-列表', null),

+ 2 - 1
db/sys_user_role_module_relation.sql

@@ -56,7 +56,8 @@ INSERT INTO sys_user_role_module_relation(role_id, module_id) VALUES
     (1, '4'),
         (1, '4.1'),
             (1, '4.1.1'), (1, '4.1.2'), (1, '4.1.3'), (1, '4.1.4'), (1, '4.1.5'),
-
+    (1, '5'),
+        (1, '5.1'),
 #     (1, '10'),
 #         (1, '10.1'),
 #             (1, '10.1.1'), (1, '10.1.2'), (1, '10.1.3'), (1, '10.1.4'),

+ 13 - 0
src/main/java/com/backendsys/modules/common/aspect/SysLog.java

@@ -0,0 +1,13 @@
+package com.backendsys.modules.common.aspect;
+
+import java.lang.annotation.*;
+
+/**
+ * 系统日志注解
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface SysLog {
+	String value() default "";
+}

+ 73 - 0
src/main/java/com/backendsys/modules/common/aspect/SysLogAspect.java

@@ -0,0 +1,73 @@
+package com.backendsys.modules.common.aspect;
+
+import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
+import com.backendsys.modules.system.dao.SysLogDao;
+import com.backendsys.modules.system.entity.SysLogEntity;
+import com.google.gson.Gson;
+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.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+/**
+ * 系统日志,切面处理类
+ */
+@Aspect
+@Component
+public class SysLogAspect {
+
+	@Autowired
+	private HttpRequestUtil httpRequestUtil;
+
+	@Autowired
+	private SysLogDao sysLogDao;
+	
+	@Pointcut("@annotation(com.backendsys.modules.common.aspect.SysLog)")
+	public void logPointCut() {}
+
+	@Around("logPointCut()")
+	public Object around(ProceedingJoinPoint point) throws Throwable {
+		long beginTime = System.currentTimeMillis();
+		Object result = point.proceed();
+		// 执行时长(毫秒)
+		long time = System.currentTimeMillis() - beginTime;
+		// 保存日志
+		saveSysLog(point, time);
+		return result;
+	}
+
+	private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
+		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+		Method method = signature.getMethod();
+
+		SysLogEntity sysLogEntity = new SysLogEntity();
+
+		// 注解上的描述
+		SysLog syslog = method.getAnnotation(SysLog.class);
+		if(syslog != null){
+			sysLogEntity.setOperation(syslog.value());
+		}
+
+		// 请求方法名
+		String className = joinPoint.getTarget().getClass().getName();
+		String methodName = signature.getName();
+		sysLogEntity.setClassname(className);
+		sysLogEntity.setMethod(methodName);
+
+		// 请求参数
+		Object[] args = joinPoint.getArgs();
+		String params = new Gson().toJson(args);
+		sysLogEntity.setParams(params);
+
+		sysLogEntity.setIp(httpRequestUtil.getIpAddr());
+		sysLogEntity.setUsername(httpRequestUtil.getUserName());
+		sysLogEntity.setTime(time);
+		// 保存系统日志
+		sysLogDao.insert(sysLogEntity);
+	}
+}

+ 11 - 0
src/main/java/com/backendsys/modules/common/config/security/utils/HttpRequestUtil.java

@@ -42,6 +42,17 @@ public class HttpRequestUtil {
         }
         return null;
     }
+    public String getUserName() {
+        HttpServletRequest request = getRequest();
+        if (request != null) {
+            Claims tokenInfo = tokenUtil.getTokenInfo(request);
+            if (tokenInfo != null) {
+                Map<String, Object> userInfo = (Map<String, Object>) tokenInfo.get("userInfo");
+                return Convert.toStr(userInfo.get("username"));
+            }
+        }
+        return null;
+    }
 
     /**
      * 从 Token 中获得 member_id

+ 30 - 0
src/main/java/com/backendsys/modules/system/controller/SysLogController.java

@@ -0,0 +1,30 @@
+package com.backendsys.modules.system.controller;
+
+import com.backendsys.modules.common.utils.Result;
+import com.backendsys.modules.system.entity.SysLogEntity;
+import com.backendsys.modules.system.entity.SysUserDTO;
+import com.backendsys.modules.system.service.SysLogService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@Tag(name = "系统日志")
+public class SysLogController {
+
+    @Autowired
+    private SysLogService sysLogService;
+
+    @Operation(summary = "获取系统日志列表")
+    @PreAuthorize("@sr.hasPermission('5.1')")
+    @GetMapping("/api/system/log/getLogList")
+    public Result getLogList(SysLogEntity sysLogEntity) {
+        return Result.success().put("data", sysLogService.selectLogList(sysLogEntity));
+    }
+
+}

+ 3 - 1
src/main/java/com/backendsys/modules/system/controller/SysUserController.java

@@ -2,6 +2,7 @@ package com.backendsys.modules.system.controller;
 
 import cn.hutool.core.util.ObjectUtil;
 import com.backendsys.exception.CustException;
+import com.backendsys.modules.common.aspect.SysLog;
 import com.backendsys.modules.common.config.security.enums.SecurityEnum;
 import com.backendsys.modules.common.config.security.utils.SecurityUtil;
 import com.backendsys.modules.common.utils.Result;
@@ -22,11 +23,11 @@ import java.util.List;
 @Tag(name = "系统用户")
 public class SysUserController {
 
-
     /**
      * TODO 1.手机号码字段,需要经过验证码校验,不能用 updateUserInfo 改 (待修改)
      * TODO 2.审核用户,需要单独的表做审核记录,不能直接改字段
      */
+
     @Autowired
     private SysUserV2Service sysUserV2Service;
 
@@ -88,6 +89,7 @@ public class SysUserController {
         return Result.success().put("data", sysUserV2Service.selectUserModule(user_id));
     }
 
+    @SysLog("创建系统用户")
     @Operation(summary = "创建系统用户")
     @PreAuthorize("@ss.hasPermi('3.2.2')")
     @PostMapping("/api/system/user/createUser")

+ 14 - 0
src/main/java/com/backendsys/modules/system/dao/SysLogDao.java

@@ -0,0 +1,14 @@
+package com.backendsys.modules.system.dao;
+
+import com.backendsys.modules.system.entity.SysLogEntity;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+@Mapper
+public interface SysLogDao extends BaseMapper<SysLogEntity> {
+
+    List<SysLogEntity> selectLogList(SysLogEntity sysLogEntity);
+
+}

+ 27 - 0
src/main/java/com/backendsys/modules/system/entity/SysLogEntity.java

@@ -0,0 +1,27 @@
+package com.backendsys.modules.system.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName("sys_log")
+public class SysLogEntity {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private String username;
+    private String operation;
+    private String classname;
+    private String method;
+    private String params;
+    private Long time;
+    private String ip;
+    private String create_time;
+
+    @TableField(exist = false)
+    private String create_time_begin;
+    @TableField(exist = false)
+    private String create_time_end;
+}

+ 11 - 0
src/main/java/com/backendsys/modules/system/service/SysLogService.java

@@ -0,0 +1,11 @@
+package com.backendsys.modules.system.service;
+
+import com.backendsys.modules.system.entity.SysLogEntity;
+import com.backendsys.utils.response.PageEntity;
+
+public interface SysLogService {
+
+    // 获取系统日志列表
+    PageEntity selectLogList(SysLogEntity sysLogEntity);
+
+}

+ 35 - 0
src/main/java/com/backendsys/modules/system/service/impl/SysLogServiceImpl.java

@@ -0,0 +1,35 @@
+package com.backendsys.modules.system.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.backendsys.modules.system.dao.SysLogDao;
+import com.backendsys.modules.system.entity.SysLogEntity;
+import com.backendsys.modules.system.entity.SysUserInfo;
+import com.backendsys.modules.system.service.SysLogService;
+import com.backendsys.utils.response.PageEntity;
+import com.backendsys.utils.response.PageInfoResult;
+import com.backendsys.utils.v2.PageUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class SysLogServiceImpl implements SysLogService {
+
+    @Autowired
+    private SysLogDao sysLogDao;
+
+    /**
+     * 获取系统日志列表
+     */
+    @Override
+    public PageEntity selectLogList(SysLogEntity sysLogEntity) {
+        PageUtils.startPage();  // 分页
+        List<SysLogEntity> list = sysLogDao.selectLogList(sysLogEntity);
+        return new PageInfoResult(list).toEntity();
+    }
+
+
+}

+ 49 - 0
src/main/resources/mapper/system/SysLogDao.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.backendsys.modules.system.dao.SysLogDao">
+
+    <sql id="includeLog">
+        id,
+        username,
+        COALESCE(operation, '') operation,
+        COALESCE(classname, '') classname,
+        COALESCE(method, '') method,
+        COALESCE(params, '') params,
+        COALESCE(time, '') time,
+        COALESCE(ip, '') ip,
+        create_time
+    </sql>
+
+    <resultMap id="resultMapLogList" type="java.util.LinkedHashMap">
+        <id property="id" column="id" jdbcType="BIGINT" />
+        <result property="username" column="username" />
+        <result property="operation" column="operation" />
+        <result property="classname" column="classname" />
+        <result property="method" column="method" />
+        <result property="params" column="params" />
+        <result property="time" column="time" javaType="java.lang.Long" />
+        <result property="ip" column="ip" />
+        <result property="create_time" column="create_time" />
+    </resultMap>
+
+    <select id="selectLogList" resultMap="resultMapLogList">
+        SELECT <include refid="includeLog" />
+        FROM sys_log
+        <where>
+            <if test="username != null and username != ''">
+                AND username LIKE CONCAT('%', #{username}, '%')
+            </if>
+            <if test="operation != null and operation != ''">
+                AND operation LIKE CONCAT('%', #{operation}, '%')
+            </if>
+            <if test="ip != null and ip != ''">
+                AND ip = #{ip}
+            </if>
+            <if test="create_time_begin != null and create_time_begin != '' and create_time_end != null and create_time_end != ''">
+                AND create_time BETWEEN #{create_time_begin} AND #{create_time_end}
+            </if>
+        </where>
+        ORDER BY create_time DESC
+    </select>
+
+</mapper>