操作日志管理模块

This commit is contained in:
阿沐 2023-05-22 15:58:44 +08:00
parent 021c4a2407
commit f899fb9721
9 changed files with 392 additions and 0 deletions

View File

@ -0,0 +1,39 @@
package net.maku.system.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.common.utils.Result;
import net.maku.system.query.SysLogOperateQuery;
import net.maku.system.service.SysLogOperateService;
import net.maku.system.vo.SysLogOperateVO;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@RestController
@RequestMapping("sys/log/operate")
@Tag(name = "操作日志")
@AllArgsConstructor
public class SysLogOperateController {
private final SysLogOperateService sysLogOperateService;
@GetMapping("page")
@Operation(summary = "分页")
@PreAuthorize("hasAuthority('sys:operate:all')")
public Result<PageResult<SysLogOperateVO>> page(@ParameterObject @Valid SysLogOperateQuery query) {
PageResult<SysLogOperateVO> page = sysLogOperateService.page(query);
return Result.ok(page);
}
}

View File

@ -0,0 +1,26 @@
package net.maku.system.convert;
import net.maku.system.entity.SysLogOperateEntity;
import net.maku.system.vo.SysLogOperateVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@Mapper
public interface SysLogOperateConvert {
SysLogOperateConvert INSTANCE = Mappers.getMapper(SysLogOperateConvert.class);
SysLogOperateEntity convert(SysLogOperateVO vo);
SysLogOperateVO convert(SysLogOperateEntity entity);
List<SysLogOperateVO> convertList(List<SysLogOperateEntity> list);
}

View File

@ -0,0 +1,16 @@
package net.maku.system.dao;
import net.maku.framework.mybatis.dao.BaseDao;
import net.maku.system.entity.SysLogOperateEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@Mapper
public interface SysLogOperateDao extends BaseDao<SysLogOperateEntity> {
}

View File

@ -0,0 +1,103 @@
package net.maku.system.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@Data
@TableName("sys_log_operate")
public class SysLogOperateEntity {
/**
* id
*/
@TableId
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 操作人
*/
private String realName;
/**
* 模块名
*/
private String module;
/**
* 操作名
*/
private String name;
/**
* 请求URI
*/
private String reqUri;
/**
* 请求方法
*/
private String reqMethod;
/**
* 请求参数
*/
private String reqParams;
/**
* 操作IP
*/
private String ip;
/**
* 登录地点
*/
private String address;
/**
* User Agent
*/
private String userAgent;
/**
* 操作类型
*/
private Integer operateType;
/**
* 执行时长
*/
private Integer duration;
/**
* 操作状态
*/
private Integer status;
/**
* 返回消息
*/
private String resultMsg;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
}

View File

@ -0,0 +1,30 @@
package net.maku.system.query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import net.maku.framework.common.query.Query;
/**
* 操作日志查询
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(description = "操作日志查询")
public class SysLogOperateQuery extends Query {
@Schema(description = "用户")
private String realName;
@Schema(description = "模块名")
private String module;
@Schema(description = "请求URI")
private String reqUri;
@Schema(description = "操作状态")
private Integer status;
}

View File

@ -0,0 +1,18 @@
package net.maku.system.service;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.BaseService;
import net.maku.system.entity.SysLogOperateEntity;
import net.maku.system.query.SysLogOperateQuery;
import net.maku.system.vo.SysLogOperateVO;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
public interface SysLogOperateService extends BaseService<SysLogOperateEntity> {
PageResult<SysLogOperateVO> page(SysLogOperateQuery query);
}

View File

@ -0,0 +1,83 @@
package net.maku.system.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import net.maku.framework.common.cache.RedisCache;
import net.maku.framework.common.cache.RedisKeys;
import net.maku.framework.common.utils.ExceptionUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.framework.operatelog.dto.OperateLogDTO;
import net.maku.system.convert.SysLogOperateConvert;
import net.maku.system.dao.SysLogOperateDao;
import net.maku.system.entity.SysLogOperateEntity;
import net.maku.system.query.SysLogOperateQuery;
import net.maku.system.service.SysLogOperateService;
import net.maku.system.vo.SysLogOperateVO;
import org.springframework.stereotype.Service;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@Service
@AllArgsConstructor
public class SysLogOperateServiceImpl extends BaseServiceImpl<SysLogOperateDao, SysLogOperateEntity> implements SysLogOperateService {
private final RedisCache redisCache;
@Override
public PageResult<SysLogOperateVO> page(SysLogOperateQuery query) {
IPage<SysLogOperateEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
return new PageResult<>(SysLogOperateConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
}
private LambdaQueryWrapper<SysLogOperateEntity> getWrapper(SysLogOperateQuery query) {
LambdaQueryWrapper<SysLogOperateEntity> wrapper = Wrappers.lambdaQuery();
wrapper.eq(query.getStatus() != null, SysLogOperateEntity::getStatus, query.getStatus());
wrapper.like(StrUtil.isNotBlank(query.getRealName()), SysLogOperateEntity::getRealName, query.getRealName());
wrapper.like(StrUtil.isNotBlank(query.getModule()), SysLogOperateEntity::getModule, query.getModule());
wrapper.like(StrUtil.isNotBlank(query.getReqUri()), SysLogOperateEntity::getReqUri, query.getReqUri());
wrapper.orderByDesc(SysLogOperateEntity::getId);
return wrapper;
}
/**
* 启动项目时从Redis队列获取操作日志并保存
*/
@PostConstruct
public void saveLog() {
ScheduledExecutorService scheduledService = ThreadUtil.createScheduledExecutor(1);
// 每隔10秒钟执行一次
scheduledService.scheduleWithFixedDelay(() -> {
try {
String key = RedisKeys.getLogKey();
// 每次插入10条
int count = 10;
for (int i = 0; i < count; i++) {
OperateLogDTO log = (OperateLogDTO) redisCache.rightPop(key);
if (log == null) {
return;
}
SysLogOperateEntity entity = BeanUtil.copyProperties(log, SysLogOperateEntity.class);
baseMapper.insert(entity);
}
} catch (Exception e) {
log.error("SysLogOperateServiceImpl.saveLog Error" + ExceptionUtils.getExceptionMessage(e));
}
}, 1, 10, TimeUnit.SECONDS);
}
}

View File

@ -0,0 +1,71 @@
package net.maku.system.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.maku.framework.common.utils.DateUtils;
import java.io.Serializable;
import java.util.Date;
/**
* 操作日志
*
* @author 阿沐 babamu@126.com
* <a href="https://maku.net">MAKU</a>
*/
@Data
@Schema(description = "操作日志")
public class SysLogOperateVO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "id")
private Long id;
@Schema(description = "用户ID")
private Long userId;
@Schema(description = "操作人")
private String realName;
@Schema(description = "模块名")
private String module;
@Schema(description = "操作名")
private String name;
@Schema(description = "请求URI")
private String reqUri;
@Schema(description = "请求方法")
private String reqMethod;
@Schema(description = "请求参数")
private String reqParams;
@Schema(description = "操作IP")
private String ip;
@Schema(description = "登录地点")
private String address;
@Schema(description = "User Agent")
private String userAgent;
@Schema(description = "操作类型")
private Integer operateType;
@Schema(description = "执行时长")
private Integer duration;
@Schema(description = "操作状态")
private Integer status;
@Schema(description = "返回消息")
private String resultMsg;
@Schema(description = "创建时间")
@JsonFormat(pattern = DateUtils.DATE_TIME_PATTERN)
private Date createTime;
}

View File

@ -0,0 +1,6 @@
<?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="net.maku.system.dao.SysLogOperateDao">
</mapper>