使用mybatis-flex重构“登录日志”模块代码

This commit is contained in:
dataprince 2023-10-19 21:03:40 +08:00
parent 6966236b61
commit a36301fecb
11 changed files with 225 additions and 243 deletions

View File

@ -15,7 +15,7 @@ import java.lang.annotation.*;
public @interface ExcelDictFormat {
/**
* 如果是字典类型请设置字典的type值 (: sys_user_sex)
* 如果是字典类型请设置字典的type值 (: sys_user_gender)
*/
String dictType() default "";

View File

@ -4,12 +4,16 @@ import java.util.List;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.ruoyi.common.core.constant.GlobalConstants;
import com.ruoyi.common.core.core.domain.R;
import com.ruoyi.common.excel.utils.ExcelUtil;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.system.domain.bo.SysLogininforBo;
import com.ruoyi.system.domain.vo.SysLogininforVo;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@ -19,9 +23,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.web.core.BaseController;
import com.ruoyi.common.core.core.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
//import com.ruoyi.framework.web.service.SysPasswordService;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService;
/**
@ -34,19 +35,14 @@ import com.ruoyi.system.service.ISysLogininforService;
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
@Autowired
@Resource
private ISysLogininforService logininforService;
// @Autowired
// private SysPasswordService passwordService;
@SaCheckPermission("monitor:logininfor:list")
@GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor)
public TableDataInfo<SysLogininforVo> list(SysLogininforBo logininforBo)
{
startPage();
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
return getDataTable(list);
return logininforService.selectPage(logininforBo);
}
/**
@ -55,11 +51,10 @@ public class SysLogininforController extends BaseController
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@SaCheckPermission("monitor:logininfor:export")
@PostMapping("/export")
public void export(HttpServletResponse response, SysLogininfor logininfor)
public void export(HttpServletResponse response, SysLogininforBo logininfor)
{
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<>(SysLogininfor.class);
util.exportExcel(response, list, "登录日志");
List<SysLogininforVo> list = logininforService.selectLogininforList(logininfor);
ExcelUtil.exportExcel(list, "登录日志", SysLogininforVo.class, response);
}
/**
@ -69,9 +64,13 @@ public class SysLogininforController extends BaseController
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public AjaxResult remove(@PathVariable Long[] infoIds)
public R<Void> remove(@PathVariable Long[] infoIds)
{
return toAjax(logininforService.deleteLogininforByIds(infoIds));
boolean deleted = logininforService.deleteLogininforByIds(infoIds);
if (!deleted) {
R.fail("删除登录日志记录失败!");
}
return R.ok();
}
/**
@ -80,10 +79,13 @@ public class SysLogininforController extends BaseController
@SaCheckPermission("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public AjaxResult clean()
public R<Void> clean()
{
logininforService.cleanLogininfor();
return success();
boolean cleaned = logininforService.cleanLogininfor();
if (!cleaned) {
R.fail("清除登录日志记录失败!");
}
return R.ok();
}
@SaCheckPermission("monitor:logininfor:unlock")
@ -91,8 +93,6 @@ public class SysLogininforController extends BaseController
@GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName)
{
// passwordService.clearLoginRecordCache(userName);
// return success();
String loginName = GlobalConstants.PWD_ERR_CNT_KEY + userName;
if (RedisUtils.hasKey(loginName)) {
RedisUtils.deleteObject(loginName);

View File

@ -2,145 +2,58 @@ package com.ruoyi.system.domain;
import java.io.Serial;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.annotation.Excel.ColumnType;
import com.ruoyi.common.orm.core.domain.BaseEntity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table;
import lombok.Data;
/**
* 系统访问记录表 sys_logininfor
*
* @author ruoyi
*/
public class SysLogininfor extends BaseEntity
@Data
@Table(value = "sys_logininfor")
public class SysLogininfor
{
@Serial
private static final long serialVersionUID = 1L;
/** ID */
@Excel(name = "序号", cellType = ColumnType.NUMERIC)
@Id
private Long infoId;
/** 用户账号 */
@Excel(name = "用户账号")
//@Excel(name = "用户账号")
private String userName;
/** 登录状态 0成功 1失败 */
@Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
private String status;
/** 登录IP地址 */
@Excel(name = "登录地址")
private String ipaddr;
/** 登录地点 */
@Excel(name = "登录地点")
private String loginLocation;
/** 浏览器类型 */
@Excel(name = "浏览器")
private String browser;
/** 操作系统 */
@Excel(name = "操作系统")
private String os;
/** 提示消息 */
@Excel(name = "提示消息")
private String msg;
/** 访问时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date loginTime;
public Long getInfoId()
{
return infoId;
}
public void setInfoId(Long infoId)
{
this.infoId = infoId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getIpaddr()
{
return ipaddr;
}
public void setIpaddr(String ipaddr)
{
this.ipaddr = ipaddr;
}
public String getLoginLocation()
{
return loginLocation;
}
public void setLoginLocation(String loginLocation)
{
this.loginLocation = loginLocation;
}
public String getBrowser()
{
return browser;
}
public void setBrowser(String browser)
{
this.browser = browser;
}
public String getOs()
{
return os;
}
public void setOs(String os)
{
this.os = os;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
public Date getLoginTime()
{
return loginTime;
}
public void setLoginTime(Date loginTime)
{
this.loginTime = loginTime;
}
/**
* 请求参数
*/
private Map<String, Object> params = new HashMap<>();
}

View File

@ -26,7 +26,7 @@ public class SysLogininforBo {
/**
* 租户编号
*/
private String tenantId;
private Long tenantId;
/**
* 用户账号

View File

@ -36,7 +36,7 @@ public class SysLogininforVo implements Serializable {
/**
* 租户编号
*/
private String tenantId;
private Long tenantId;
/**
* 用户账号

View File

@ -63,8 +63,8 @@ public class SysUserImportVo implements Serializable {
* 用户性别
*/
@ExcelProperty(value = "用户性别", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_user_sex")
private String sex;
@ExcelDictFormat(dictType = "sys_user_gender")
private String gender;
/**
* 帐号状态0正常 1停用

View File

@ -1,42 +1,18 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.mybatisflex.core.BaseMapper;
import com.ruoyi.system.domain.SysLogininfor;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统访问日志情况信息 数据层
*
*
* @author ruoyi
*/
public interface SysLogininforMapper
@Mapper
public interface SysLogininforMapper extends BaseMapper<SysLogininfor>
{
/**
* 新增系统登录日志
*
* @param logininfor 访问日志对象
*/
public void insertLogininfor(SysLogininfor logininfor);
/**
* 查询系统登录日志集合
*
* @param logininfor 访问日志对象
* @return 登录记录集合
*/
public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor);
/**
* 批量删除系统登录日志
*
* @param infoIds 需要删除的登录日志ID
* @return 结果
*/
public int deleteLogininforByIds(Long[] infoIds);
/**
* 清空系统登录日志
*
* @return 结果
*/
public int cleanLogininfor();
}

View File

@ -1,40 +1,54 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.orm.core.service.IBaseService;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.domain.bo.SysLogininforBo;
import com.ruoyi.system.domain.vo.SysLogininforVo;
/**
* 系统访问日志情况信息 服务层
*
*
* @author ruoyi
*/
public interface ISysLogininforService
public interface ISysLogininforService extends IBaseService<SysLogininfor>
{
/**
* 新增系统登录日志
*
*
* @param logininfor 访问日志对象
*/
public void insertLogininfor(SysLogininfor logininfor);
void insertLogininfor(SysLogininforBo logininfor);
/**
* 查询系统登录日志集合
*
*
* @param logininfor 访问日志对象
* @return 登录记录集合
*/
public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor);
List<SysLogininforVo> selectLogininforList(SysLogininforBo logininfor);
/**
* 分页查询登录日志列表
*
* @param logininforBo 登录日志
* @return 登录日志集合
*/
TableDataInfo<SysLogininforVo> selectPage(SysLogininforBo logininforBo);
/**
* 批量删除系统登录日志
*
*
* @param infoIds 需要删除的登录日志ID
* @return 结果
* @return 结果:true 删除成功false 删除失败
*/
public int deleteLogininforByIds(Long[] infoIds);
boolean deleteLogininforByIds(Long[] infoIds);
/**
* 清空系统登录日志
* 返回结果true 删除成功false 删除失败
*/
public void cleanLogininfor();
boolean cleanLogininfor();
}

View File

@ -1,65 +1,197 @@
package com.ruoyi.system.service.impl;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.utils.MapstructUtils;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ip.AddressUtils;
import com.ruoyi.common.log.event.LogininforEvent;
import com.ruoyi.common.orm.core.page.PageQuery;
import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl;
import com.ruoyi.system.domain.bo.SysLogininforBo;
import com.ruoyi.system.domain.vo.SysLogininforVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.mapper.SysLogininforMapper;
import com.ruoyi.system.service.ISysLogininforService;
import org.springframework.transaction.annotation.Transactional;
import static com.ruoyi.system.domain.table.SysLogininforTableDef.SYS_LOGININFOR;
/**
* 系统访问日志情况信息 服务层处理
*
*
* @author ruoyi
*/
@RequiredArgsConstructor
@Slf4j
@Service
public class SysLogininforServiceImpl implements ISysLogininforService
public class SysLogininforServiceImpl extends BaseServiceImpl<SysLogininforMapper, SysLogininfor> implements ISysLogininforService
{
@Autowired
private SysLogininforMapper logininforMapper;
@Override
public QueryWrapper query() {
return super.query().from(SYS_LOGININFOR);
}
/**
* 记录登录信息
*
* @param logininforEvent 登录事件
*/
@Async
@EventListener
public void recordLogininfor(LogininforEvent logininforEvent) {
HttpServletRequest request = logininforEvent.getRequest();
final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
final String ip = ServletUtils.getClientIP(request);
String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder();
s.append(getBlock(ip));
s.append(address);
s.append(getBlock(logininforEvent.getUsername()));
s.append(getBlock(logininforEvent.getStatus()));
s.append(getBlock(logininforEvent.getMessage()));
// 打印信息到日志
log.info(s.toString(), logininforEvent.getArgs());
// 获取客户端操作系统
String os = userAgent.getOs().getName();
// 获取客户端浏览器
String browser = userAgent.getBrowser().getName();
// 封装对象
SysLogininforBo logininfor = new SysLogininforBo();
logininfor.setTenantId(logininforEvent.getTenantId());
logininfor.setUserName(logininforEvent.getUsername());
logininfor.setIpaddr(ip);
logininfor.setLoginLocation(address);
logininfor.setBrowser(browser);
logininfor.setOs(os);
logininfor.setMsg(logininforEvent.getMessage());
// 日志状态
if (StringUtils.equalsAny(logininforEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
logininfor.setStatus(Constants.SUCCESS);
} else if (Constants.LOGIN_FAIL.equals(logininforEvent.getStatus())) {
logininfor.setStatus(Constants.FAIL);
}
// 插入数据
insertLogininfor(logininfor);
}
private String getBlock(Object msg) {
if (msg == null) {
msg = "";
}
return "[" + msg.toString() + "]";
}
/**
* 新增系统登录日志
*
* @param logininfor 访问日志对象
*
* @param logininforBo 访问日志对象
*/
@Override
public void insertLogininfor(SysLogininfor logininfor)
public void insertLogininfor(SysLogininforBo logininforBo)
{
logininforMapper.insertLogininfor(logininfor);
SysLogininfor logininfor = MapstructUtils.convert(logininforBo, SysLogininfor.class);
logininfor.setLoginTime(new Date());
this.save(logininfor);
}
/**
* 根据noticeBo构建QueryWrapper查询条件
*
* @param logininforBo
* @return 查询条件
*/
private QueryWrapper buildQueryWrapper(SysLogininforBo logininforBo) {
QueryWrapper queryWrapper = QueryWrapper.create()
.select(SYS_LOGININFOR.INFO_ID,SYS_LOGININFOR.USER_NAME,SYS_LOGININFOR.IPADDR,SYS_LOGININFOR.LOGIN_LOCATION,SYS_LOGININFOR.BROWSER,SYS_LOGININFOR.OS,SYS_LOGININFOR.STATUS,SYS_LOGININFOR.MSG,SYS_LOGININFOR.LOGIN_TIME)
.from(SYS_LOGININFOR);
if (StringUtils.isNotEmpty(logininforBo.getIpaddr())) {
queryWrapper.and(SYS_LOGININFOR.IPADDR.like(logininforBo.getIpaddr()));
}
if (StringUtils.isNotEmpty(logininforBo.getStatus())) {
queryWrapper.and(SYS_LOGININFOR.STATUS.eq(logininforBo.getStatus()));
}
if (ObjectUtil.isNotNull(logininforBo.getUserName())) {
queryWrapper.and(SYS_LOGININFOR.USER_NAME.like(logininforBo.getUserName()));
}
Map<String, Object> params = logininforBo.getParams();
if (params.get("beginTime") != null && params.get("endTime") != null) {
queryWrapper.and(SYS_LOGININFOR.LOGIN_TIME.between(params.get("beginTime"), params.get("endTime")));
}
queryWrapper.orderBy(SYS_LOGININFOR.INFO_ID.desc());
return queryWrapper;
}
/**
* 查询系统登录日志集合
*
* @param logininfor 访问日志对象
*
* @param logininforBo 访问日志对象
* @return 登录记录集合
*/
@Override
public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor)
public List<SysLogininforVo> selectLogininforList(SysLogininforBo logininforBo)
{
return logininforMapper.selectLogininforList(logininfor);
QueryWrapper queryWrapper = buildQueryWrapper(logininforBo);
return this.listAs(queryWrapper, SysLogininforVo.class);
}
/**
* 分页查询登录日志列表
*
* @param logininforBo 登录日志
* @return 登录日志集合
*/
@Override
public TableDataInfo<SysLogininforVo> selectPage(SysLogininforBo logininforBo) {
QueryWrapper queryWrapper = buildQueryWrapper(logininforBo);
Page<SysLogininforVo> page = this.pageAs(PageQuery.build(), queryWrapper, SysLogininforVo.class);
return TableDataInfo.build(page);
}
/**
* 批量删除系统登录日志
*
* delete from sys_logininfor where info_id in
* @param infoIds 需要删除的登录日志ID
* @return 结果
* @return 结果:true 删除成功false 删除失败
*/
@Override
public int deleteLogininforByIds(Long[] infoIds)
@Transactional
public boolean deleteLogininforByIds(Long[] infoIds)
{
return logininforMapper.deleteLogininforByIds(infoIds);
return this.removeByIds(Arrays.asList(infoIds));
}
/**
* 清空系统登录日志
* delete from sys_logininfor where info_id>0
* 返回结果true 删除成功false 删除失败
*/
@Override
public void cleanLogininfor()
public boolean cleanLogininfor()
{
logininforMapper.cleanLogininfor();
QueryWrapper queryWrapper = query().from(SYS_LOGININFOR).where(SYS_LOGININFOR.INFO_ID.gt(0));
return this.remove(queryWrapper);
}
}

View File

@ -32,9 +32,6 @@ import static com.ruoyi.system.domain.table.SysNoticeTableDef.SYS_NOTICE;
*/
@Service
public class SysNoticeServiceImpl extends BaseServiceImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {
@Resource
private SysNoticeMapper noticeMapper;
@Override
public QueryWrapper query() {
return super.query().from(SYS_NOTICE);

View File

@ -4,54 +4,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysLogininforMapper">
<resultMap type="SysLogininfor" id="SysLogininforResult">
<id property="infoId" column="info_id" />
<result property="userName" column="user_name" />
<result property="status" column="status" />
<result property="ipaddr" column="ipaddr" />
<result property="loginLocation" column="login_location" />
<result property="browser" column="browser" />
<result property="os" column="os" />
<result property="msg" column="msg" />
<result property="loginTime" column="login_time" />
</resultMap>
<insert id="insertLogininfor" parameterType="SysLogininfor">
insert into sys_logininfor (user_name, status, ipaddr, login_location, browser, os, msg, login_time)
values (#{userName}, #{status}, #{ipaddr}, #{loginLocation}, #{browser}, #{os}, #{msg}, sysdate())
</insert>
<select id="selectLogininforList" parameterType="SysLogininfor" resultMap="SysLogininforResult">
select info_id, user_name, ipaddr, login_location, browser, os, status, msg, login_time from sys_logininfor
<where>
<if test="ipaddr != null and ipaddr != ''">
AND ipaddr like concat('%', #{ipaddr}, '%')
</if>
<if test="status != null and status != ''">
AND status = #{status}
</if>
<if test="userName != null and userName != ''">
AND user_name like concat('%', #{userName}, '%')
</if>
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
AND login_time &gt;= #{params.beginTime}
</if>
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
AND login_time &lt;= #{params.endTime}
</if>
</where>
order by info_id desc
</select>
<delete id="deleteLogininforByIds" parameterType="Long">
delete from sys_logininfor where info_id in
<foreach collection="array" item="infoId" open="(" separator="," close=")">
#{infoId}
</foreach>
</delete>
<update id="cleanLogininfor">
truncate table sys_logininfor
</update>
</mapper>
</mapper>