Commit c05885bf authored by liuyang's avatar liuyang

增加系统操作日志

parent bcc3ecad
package com.qkdata.biz.sys.controller;
import com.qkdata.biz.sys.entity.SysLogPO;
import com.qkdata.biz.sys.model.QueryLogModel;
import com.qkdata.biz.sys.service.SysLogService;
import com.qkdata.common.base.model.PageDTO;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api
@RestController
@RequestMapping("/api/sys/log")
public class SysLogController {
@Autowired
private SysLogService sysLogService;
@GetMapping("/list")
public PageDTO<SysLogPO> list(QueryLogModel queryLogModel){
return sysLogService.queryPageList(queryLogModel);
}
}
......@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.qkdata.biz.sys.model.LoginModel;
import com.qkdata.biz.sys.model.LoginUserInfo;
import com.qkdata.biz.sys.service.ShiroService;
import com.qkdata.common.annotation.SysLog;
import io.swagger.annotations.Api;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -20,6 +21,7 @@ public class SysLoginController {
private ShiroService shiroService;
@SysLog("登陆")
@PostMapping("/login")
public LoginUserInfo login(@RequestBody @Valid LoginModel loginModel) throws JsonProcessingException {
return shiroService.login(loginModel.getUsername(),loginModel.getPassword());
......
......@@ -6,6 +6,7 @@ import com.qkdata.biz.sys.model.QueryUserModel;
import com.qkdata.biz.sys.model.SysUserDTO;
import com.qkdata.biz.sys.model.SysUserModel;
import com.qkdata.biz.sys.service.SysUserService;
import com.qkdata.common.annotation.SysLog;
import com.qkdata.common.base.exception.BusinessException;
import com.qkdata.common.base.model.PageDTO;
import com.qkdata.common.constants.AddGroup;
......@@ -29,6 +30,7 @@ public class SysUserController {
@Autowired
private SysUserService sysUserService;
@SysLog("查询用户列表")
@GetMapping("/list")
@RequiresPermissions("sys:user:list")
public PageDTO<SysUserDTO> list(QueryUserModel queryUserModel){
......
package com.qkdata.biz.sys.entity;
import com.qkdata.common.base.entity.BasePO;
import lombok.Data;
import javax.persistence.Table;
import java.time.LocalDateTime;
@Data
@Table(name = "sys_log")
public class SysLogPO extends BasePO {
private String username;
private String operation;
private String method;
private String params;
private Long time;
private String ip;
private LocalDateTime createDate;
}
package com.qkdata.biz.sys.model;
import com.qkdata.biz.base.constants.Constants;
import lombok.Data;
@Data
public class QueryLogModel {
private Integer pageIndex = 1;
private Integer pageSize = Constants.DEFAULT_PAGE_SIZE;
private String condition;
}
package com.qkdata.biz.sys.repository;
import com.qkdata.biz.sys.entity.SysLogPO;
import com.qkdata.biz.sys.model.QueryLogModel;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
public interface SysLogMapper extends Mapper<SysLogPO> {
List<SysLogPO> selectByCondition(QueryLogModel queryLogModel);
}
package com.qkdata.biz.sys.service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qkdata.biz.sys.entity.SysLogPO;
import com.qkdata.biz.sys.model.QueryLogModel;
import com.qkdata.biz.sys.repository.SysLogMapper;
import com.qkdata.common.base.model.PageDTO;
import com.qkdata.common.base.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
@Service
public class SysLogService extends BaseServiceImpl<SysLogPO, Long> {
@Autowired
private SysLogMapper sysLogMapper;
@Override
protected Mapper<SysLogPO> getMapper() {
return sysLogMapper;
}
public PageDTO<SysLogPO> queryPageList(QueryLogModel queryLogModel) {
PageHelper.startPage(queryLogModel.getPageIndex(),queryLogModel.getPageSize());
List<SysLogPO> list = sysLogMapper.selectByCondition(queryLogModel);
return new PageDTO<>(new PageInfo<>(list));
}
}
package com.qkdata.common.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default "";
}
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
*
* 版权所有,侵权必究!
*/
package com.qkdata.common.aspect;
import com.qkdata.biz.sys.entity.SysLogPO;
import com.qkdata.biz.sys.entity.SysUserPO;
import com.qkdata.biz.sys.service.SysLogService;
import com.qkdata.biz.wx.utils.JsonUtils;
import com.qkdata.common.annotation.SysLog;
import com.qkdata.common.util.HttpContextUtils;
import com.qkdata.common.util.IPUtils;
import com.qkdata.common.util.UserContext;
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 javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
@Aspect
@Component
public class SysLogAspect {
@Autowired
private SysLogService sysLogService;
@Pointcut("@annotation(com.qkdata.common.annotation.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();
SysLogPO sysLog = new SysLogPO();
SysLog syslog = method.getAnnotation(SysLog.class);
if(syslog != null){
//注解上的描述
sysLog.setOperation(syslog.value());
}
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
//请求的参数
Object[] args = joinPoint.getArgs();
try{
String params = JsonUtils.toJson(args);
sysLog.setParams(params);
}catch (Exception e){
}
//获取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//设置IP地址
sysLog.setIp(IPUtils.getIpAddr(request));
//用户名
SysUserPO user = UserContext.getUser();
if (user != null){
String username = UserContext.getUser().getUsername();
sysLog.setUsername(username);
}
sysLog.setTime(time);
sysLog.setCreateDate(LocalDateTime.now());
//保存系统日志
sysLogService.save(sysLog);
}
}
/**
* Copyright (c) 2016-2019 人人开源 All rights reserved.
*
*
* 版权所有,侵权必究!
*/
package com.qkdata.common.util;
import com.alibaba.druid.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
public class IPUtils {
private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
*
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr(HttpServletRequest request) {
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
logger.error("IPUtils ERROR ", e);
}
// //使用代理,则获取第一个IP地址
// if(StringUtils.isEmpty(ip) && ip.length() > 15) {
// if(ip.indexOf(",") > 0) {
// ip = ip.substring(0, ip.indexOf(","));
// }
// }
return ip;
}
}
......@@ -125,3 +125,15 @@ CREATE TABLE `sys_user_role` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 COMMENT = '用户与角色对应关系' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NULL DEFAULT NULL COMMENT '用户名',
`operation` varchar(50) NULL DEFAULT NULL COMMENT '用户操作',
`method` varchar(200) NULL DEFAULT NULL COMMENT '请求方法',
`params` varchar(5000) NULL DEFAULT NULL COMMENT '请求参数',
`time` bigint(20) NULL DEFAULT NULL COMMENT '执行时长(毫秒)',
`ip` varchar(64) NULL DEFAULT NULL COMMENT 'IP地址',
`create_date` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 COMMENT = '系统日志' ROW_FORMAT = Dynamic;
\ No newline at end of file
<?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.qkdata.biz.sys.repository.SysLogMapper">
<select id="selectByCondition" resultType="com.qkdata.biz.sys.entity.SysLogPO" parameterType="com.qkdata.biz.sys.model.QueryLogModel">
select * from sys_log where 1=1
<if test="condition != null and condition != ''">
and username like concat('%',#{condition},'%') or operation like concat('%',#{condition},'%')
</if>
order by create_date desc
</select>
</mapper>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment