文章目录
- 操作日志管理
- 操作日志管理界面 /monitor/operlog
- pojo - sys_oper_log 操作日志表
- SysOperlogController控制管理操作日志
- 查询操作日志列表 /monitor/operlog/list
- 新增操作日志由日志AOP切面类负责
- 删除操作日志 /monitor/operlog/remove
- 查看详细日志 /monitor/operlog/detail/{operId}
- 导出日志 /monitor/operlog/export
- 登录日志管理
- 登录日志管理界面 /monitor/logininfor
- pojo - sys_logininfo 登录日志表
- SysLogininforController控制管理登录日志
- 查询登录日志列表 /monitor/logininfo/list
- 删除登录日志 /monitor/logininfo/remove
- 清空登录日志 /monitor/logininfo/clean
- 导出登录日志 /monitor/logininfo/export
- 账户解锁 /monitor/logininfo/unlock
操作日志管理
操作日志管理界面 /monitor/operlog
pojo - sys_oper_log 操作日志表
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity;
public class SysOperLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
@Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
private Long operId;
@Excel(name = "操作模块")
private String title;
@Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
private Integer businessType;
private Integer[] businessTypes;
@Excel(name = "请求方法")
private String method;
@Excel(name = "请求方式")
private String requestMethod;
@Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
private Integer operatorType;
@Excel(name = "操作人员")
private String operName;
@Excel(name = "部门名称")
private String deptName;
@Excel(name = "请求地址")
private String operUrl;
@Excel(name = "操作地址")
private String operIp;
@Excel(name = "操作地点")
private String operLocation;
@Excel(name = "请求参数")
private String operParam;
@Excel(name = "返回参数")
private String jsonResult;
@Excel(name = "状态", readConverterExp = "0=正常,1=异常")
private Integer status;
@Excel(name = "错误消息")
private String errorMsg;
@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operTime;
public Long getOperId()
{
return operId;
}
public void setOperId(Long operId)
{
this.operId = operId;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public Integer getBusinessType()
{
return businessType;
}
public void setBusinessType(Integer businessType)
{
this.businessType = businessType;
}
public Integer[] getBusinessTypes()
{
return businessTypes;
}
public void setBusinessTypes(Integer[] businessTypes)
{
this.businessTypes = businessTypes;
}
public String getMethod()
{
return method;
}
public void setMethod(String method)
{
this.method = method;
}
public String getRequestMethod()
{
return requestMethod;
}
public void setRequestMethod(String requestMethod)
{
this.requestMethod = requestMethod;
}
public Integer getOperatorType()
{
return operatorType;
}
public void setOperatorType(Integer operatorType)
{
this.operatorType = operatorType;
}
public String getOperName()
{
return operName;
}
public void setOperName(String operName)
{
this.operName = operName;
}
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public String getOperUrl()
{
return operUrl;
}
public void setOperUrl(String operUrl)
{
this.operUrl = operUrl;
}
public String getOperIp()
{
return operIp;
}
public void setOperIp(String operIp)
{
this.operIp = operIp;
}
public String getOperLocation()
{
return operLocation;
}
public void setOperLocation(String operLocation)
{
this.operLocation = operLocation;
}
public String getOperParam()
{
return operParam;
}
public void setOperParam(String operParam)
{
this.operParam = operParam;
}
public String getJsonResult()
{
return jsonResult;
}
public void setJsonResult(String jsonResult)
{
this.jsonResult = jsonResult;
}
public Integer getStatus()
{
return status;
}
public void setStatus(Integer status)
{
this.status = status;
}
public String getErrorMsg()
{
return errorMsg;
}
public void setErrorMsg(String errorMsg)
{
this.errorMsg = errorMsg;
}
public Date getOperTime()
{
return operTime;
}
public void setOperTime(Date operTime)
{
this.operTime = operTime;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("operId", getOperId())
.append("title", getTitle())
.append("businessType", getBusinessType())
.append("businessTypes", getBusinessTypes())
.append("method", getMethod())
.append("requestMethod", getRequestMethod())
.append("operatorType", getOperatorType())
.append("operName", getOperName())
.append("deptName", getDeptName())
.append("operUrl", getOperUrl())
.append("operIp", getOperIp())
.append("operLocation", getOperLocation())
.append("operParam", getOperParam())
.append("status", getStatus())
.append("errorMsg", getErrorMsg())
.append("operTime", getOperTime())
.toString();
}
}
SysOperlogController控制管理操作日志
package com.ruoyi.web.controller.monitor;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService;
@Controller
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
private String prefix = "monitor/operlog";
@Autowired
private ISysOperLogService operLogService;
@RequiresPermissions("monitor:operlog:view")
@GetMapping()
public String operlog()
{
return prefix + "/operlog";
}
查询操作日志列表 /monitor/operlog/list
@RequiresPermissions("monitor:operlog:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysOperLog operLog)
{
startPage();
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
return getDataTable(list);
}
新增操作日志由日志AOP切面类负责
删除操作日志 /monitor/operlog/remove
@RequiresPermissions("monitor:operlog:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(operLogService.deleteOperLogByIds(ids));
}
查看详细日志 /monitor/operlog/detail/{operId}
@RequiresPermissions("monitor:operlog:detail")
@GetMapping("/detail/{operId}")
public String detail(@PathVariable("operId") Long operId, ModelMap mmap)
{
mmap.put("operLog", operLogService.selectOperLogById(operId));
return prefix + "/detail";
}
导出日志 /monitor/operlog/export
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:operlog:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysOperLog operLog)
{
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
return util.exportExcel(list, "操作日志");
}
登录日志管理
登录日志管理界面 /monitor/logininfor
pojo - sys_logininfo 登录日志表
SysLogininforController控制管理登录日志
package com.ruoyi.web.controller.monitor;
import java.util.List;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService;
@Controller
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
private String prefix = "monitor/logininfor";
@Autowired
private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("monitor:logininfor:view")
@GetMapping()
public String logininfor()
{
return prefix + "/logininfor";
}
查询登录日志列表 /monitor/logininfo/list
删除登录日志 /monitor/logininfo/remove
清空登录日志 /monitor/logininfo/clean
导出登录日志 /monitor/logininfo/export
账户解锁 /monitor/logininfo/unlock
@RequiresPermissions("monitor:logininfor:unlock")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@PostMapping("/unlock")
@ResponseBody
public AjaxResult unlock(String loginName)
{
passwordService.unlock(loginName);
return success();
}
service层
package com.ruoyi.framework.shiro.service;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.domain.SysUser;
@Component
public class SysPasswordService
{
@Autowired
private CacheManager cacheManager;
private Cache<String, AtomicInteger> loginRecordCache;
@Value(value = "${user.password.maxRetryCount}")
private String maxRetryCount;
@PostConstruct
public void init()
{
loginRecordCache = cacheManager.getCache(ShiroConstants.LOGINRECORDCACHE);
}
public void validate(SysUser user, String password)
{
String loginName = user.getLoginName();
AtomicInteger retryCount = loginRecordCache.get(loginName);
if (retryCount == null)
{
retryCount = new AtomicInteger(0);
loginRecordCache.put(loginName, retryCount);
}
if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue())
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount)));
throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
}
if (!matches(user, password))
{
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", retryCount)));
loginRecordCache.put(loginName, retryCount);
throw new UserPasswordNotMatchException();
}
else
{
clearLoginRecordCache(loginName);
}
}
public boolean matches(SysUser user, String newPassword)
{
return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
}
public void clearLoginRecordCache(String username)
{
loginRecordCache.remove(username);
}
public String encryptPassword(String username, String password, String salt)
{
return new Md5Hash(username + password + salt).toHex();
}
public void unlock(String loginName){
loginRecordCache.remove(loginName);
}
}