refactor: 加入用户登录时或退出时类型

This commit is contained in:
Bunny 2024-10-19 00:05:01 +08:00
parent 6fcf473df8
commit 3e34dea4f5
16 changed files with 119 additions and 143 deletions

View File

@ -3,11 +3,7 @@ package cn.bunny.common.generator.generator;
import cn.bunny.common.generator.entity.BaseField; import cn.bunny.common.generator.entity.BaseField;
import cn.bunny.common.generator.entity.BaseResultMap; import cn.bunny.common.generator.entity.BaseResultMap;
import cn.bunny.common.generator.utils.GeneratorCodeUtils; import cn.bunny.common.generator.utils.GeneratorCodeUtils;
import cn.bunny.dao.dto.log.UserLoginLogAddDto;
import cn.bunny.dao.dto.log.UserLoginLogDto;
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
import cn.bunny.dao.entity.log.UserLoginLog; import cn.bunny.dao.entity.log.UserLoginLog;
import cn.bunny.dao.vo.log.UserLoginLogVo;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.google.common.base.CaseFormat; import com.google.common.base.CaseFormat;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -52,10 +48,10 @@ public class WebGeneratorCode {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Class<?> originalClass = UserLoginLog.class; Class<?> originalClass = UserLoginLog.class;
Class<?> dtoClass = UserLoginLogDto.class; Class<?> dtoClass = UserLoginLog.class;
Class<?> addDtoClass = UserLoginLogAddDto.class; Class<?> addDtoClass = UserLoginLog.class;
Class<?> updateDtoClass = UserLoginLogUpdateDto.class; Class<?> updateDtoClass = UserLoginLog.class;
Class<?> voClass = UserLoginLogVo.class; Class<?> voClass = UserLoginLog.class;
// 设置velocity资源加载器 // 设置velocity资源加载器
Properties prop = new Properties(); Properties prop = new Properties();

View File

@ -62,6 +62,8 @@ onMounted(() => {
<div class="main"> <div class="main">
<el-form ref="formRef" :inline="true" :model="${lowercaseName}Store.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"> <el-form ref="formRef" :inline="true" :model="${lowercaseName}Store.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
#foreach($item in $formList) #foreach($item in $formList)
<!-- $item.annotation -->
<el-form-item :label="$t('${lowercaseName}_${item.name}')" prop="${item.name}"> <el-form-item :label="$t('${lowercaseName}_${item.name}')" prop="${item.name}">
<el-input v-model="${lowercaseName}Store.form.${item.name}" :placeholder="`$leftBrace$t('input')}$leftBrace$t('${lowercaseName}_${item.name}')}`" class="!w-[180px]" clearable /> <el-input v-model="${lowercaseName}Store.form.${item.name}" :placeholder="`$leftBrace$t('input')}$leftBrace$t('${lowercaseName}_${item.name}')}`" class="!w-[180px]" clearable />
</el-form-item> </el-form-item>

View File

@ -14,7 +14,7 @@ import lombok.NoArgsConstructor;
@ApiModel(value = "IpEntity对象", description = "用户IP相关信息") @ApiModel(value = "IpEntity对象", description = "用户IP相关信息")
public class IpEntity { public class IpEntity {
@ApiModelProperty("原始地址") @ApiModelProperty("原始地址")
private String remoteAddr; private String ipAddr;
@ApiModelProperty("IP归属地") @ApiModelProperty("IP归属地")
private String ipRegion; private String ipRegion;

View File

@ -92,7 +92,7 @@ public class IpUtil {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String remoteAddr = requestAttributes != null ? getIpAddr(requestAttributes.getRequest()) : "0:0:0:0:0:0:0:1"; String remoteAddr = requestAttributes != null ? getIpAddr(requestAttributes.getRequest()) : "0:0:0:0:0:0:0:1";
String ipRegion = IpUtil.getIpRegion(remoteAddr); String ipRegion = IpUtil.getIpRegion(remoteAddr);
return IpEntity.builder().remoteAddr(remoteAddr).ipRegion(ipRegion).build(); return IpEntity.builder().ipAddr(remoteAddr).ipRegion(ipRegion).build();
} }
/** /**

View File

@ -1,34 +0,0 @@
package cn.bunny.dao.dto.log;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(name = "UserLoginLogDto对象", title = "用户登录日志分页查询", description = "用户登录日志分页查询")
public class UserLoginLogAddDto {
@Schema(name = "userId", title = "用户Id")
private Long userId;
@Schema(name = "username", title = "用户名")
private String username;
@Schema(name = "token", title = "登录token")
private String token;
@Schema(name = "ip", title = "登录Ip")
private String ip;
@Schema(name = "ipAddress", title = "登录Ip地点")
private String ipAddress;
@Schema(name = "userAgent", title = "登录时代理")
private String userAgent;
}

View File

@ -22,14 +22,17 @@ public class UserLoginLogDto {
@Schema(name = "token", title = "登录token") @Schema(name = "token", title = "登录token")
private String token; private String token;
@Schema(name = "ip", title = "登录Ip")
private String ip;
@Schema(name = "ipAddress", title = "登录Ip地点") @Schema(name = "ipAddress", title = "登录Ip地点")
private String ipAddress; private String ipAddress;
@Schema(name = "ipRegion", title = "登录Ip")
private String ipRegion;
@Schema(name = "userAgent", title = "登录时代理") @Schema(name = "userAgent", title = "登录时代理")
private String userAgent; private String userAgent;
@Schema(name = "type", title = "操作类型")
private String type;
} }

View File

@ -22,13 +22,16 @@ public class UserLoginLogUpdateDto {
@Schema(name = "token", title = "登录token") @Schema(name = "token", title = "登录token")
private String token; private String token;
@Schema(name = "ip", title = "登录Ip")
private String ip;
@Schema(name = "ipAddress", title = "登录Ip地点") @Schema(name = "ipAddress", title = "登录Ip地点")
private String ipAddress; private String ipAddress;
@Schema(name = "ipRegion", title = "登录Ip")
private String ipRegion;
@Schema(name = "userAgent", title = "登录时代理") @Schema(name = "userAgent", title = "登录时代理")
private String userAgent; private String userAgent;
@Schema(name = "type", title = "操作类型")
private String type;
} }

View File

@ -31,13 +31,16 @@ public class UserLoginLog extends BaseEntity {
@Schema(name = "token", title = "登录token") @Schema(name = "token", title = "登录token")
private String token; private String token;
@Schema(name = "ip", title = "登录Ip") @Schema(name = "ipAddress", title = "登录Ip")
private String ip;
@Schema(name = "ipAddress", title = "登录Ip地点")
private String ipAddress; private String ipAddress;
@Schema(name = "ipRegion", title = "登录Ip归属地")
private String ipRegion;
@Schema(name = "userAgent", title = "登录时代理") @Schema(name = "userAgent", title = "登录时代理")
private String userAgent; private String userAgent;
@Schema(name = "type", title = "操作类型")
private String type;
} }

View File

@ -21,13 +21,16 @@ public class UserLoginLogVo extends BaseVo {
@Schema(name = "token", title = "登录token") @Schema(name = "token", title = "登录token")
private String token; private String token;
@Schema(name = "ip", title = "登录Ip")
private String ip;
@Schema(name = "ipAddress", title = "登录Ip地点") @Schema(name = "ipAddress", title = "登录Ip地点")
private String ipAddress; private String ipAddress;
@Schema(name = "ipRegion", title = "登录Ip")
private String ipRegion;
@Schema(name = "userAgent", title = "登录时代理") @Schema(name = "userAgent", title = "登录时代理")
private String userAgent; private String userAgent;
@Schema(name = "type", title = "操作类型")
private String type;
} }

View File

@ -1,20 +0,0 @@
package cn.bunny.services.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 部门用户关系 前端控制器
* </p>
*
* @author Bunny
* @since 2024-10-04
*/
@Tag(name = "用户和部门", description = "用户和部门相关接口")
@RestController
@RequestMapping("admin/userDept")
public class UserDeptController {
}

View File

@ -1,6 +1,5 @@
package cn.bunny.services.controller; package cn.bunny.services.controller;
import cn.bunny.dao.dto.log.UserLoginLogAddDto;
import cn.bunny.dao.dto.log.UserLoginLogDto; import cn.bunny.dao.dto.log.UserLoginLogDto;
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto; import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
import cn.bunny.dao.entity.log.UserLoginLog; import cn.bunny.dao.entity.log.UserLoginLog;
@ -49,13 +48,6 @@ public class UserLoginLogController {
return Mono.just(Result.success(pageResult)); return Mono.just(Result.success(pageResult));
} }
@Operation(summary = "添加用户登录日志", description = "添加用户登录日志")
@PostMapping("addUserLoginLog")
public Mono<Result<String>> addUserLoginLog(@Valid @RequestBody UserLoginLogAddDto dto) {
userLoginLogService.addUserLoginLog(dto);
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
}
@Operation(summary = "更新用户登录日志", description = "更新用户登录日志") @Operation(summary = "更新用户登录日志", description = "更新用户登录日志")
@PutMapping("updateUserLoginLog") @PutMapping("updateUserLoginLog")
public Mono<Result<String>> updateUserLoginLog(@Valid @RequestBody UserLoginLogUpdateDto dto) { public Mono<Result<String>> updateUserLoginLog(@Valid @RequestBody UserLoginLogUpdateDto dto) {

View File

@ -3,6 +3,7 @@ package cn.bunny.services.factory;
import cn.bunny.common.service.utils.JwtHelper; import cn.bunny.common.service.utils.JwtHelper;
import cn.bunny.common.service.utils.ip.IpUtil; import cn.bunny.common.service.utils.ip.IpUtil;
import cn.bunny.common.service.utils.minio.MinioUtil; import cn.bunny.common.service.utils.minio.MinioUtil;
import cn.bunny.dao.entity.log.UserLoginLog;
import cn.bunny.dao.entity.system.AdminUser; import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.entity.system.Power; import cn.bunny.dao.entity.system.Power;
import cn.bunny.dao.entity.system.Role; import cn.bunny.dao.entity.system.Role;
@ -12,14 +13,18 @@ import cn.bunny.dao.pojo.constant.UserConstant;
import cn.bunny.dao.vo.system.user.LoginVo; import cn.bunny.dao.vo.system.user.LoginVo;
import cn.bunny.services.mapper.PowerMapper; import cn.bunny.services.mapper.PowerMapper;
import cn.bunny.services.mapper.RoleMapper; import cn.bunny.services.mapper.RoleMapper;
import cn.bunny.services.mapper.UserLoginLogMapper;
import cn.bunny.services.mapper.UserMapper; import cn.bunny.services.mapper.UserMapper;
import cn.bunny.services.security.custom.CustomCheckIsAdmin; import cn.bunny.services.security.custom.CustomCheckIsAdmin;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@ -36,13 +41,18 @@ public class UserFactory {
@Autowired @Autowired
private RoleMapper roleMapper; private RoleMapper roleMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private UserLoginLogMapper userLoginLogMapper;
@Autowired @Autowired
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, Object> redisTemplate;
@Autowired @Autowired
private MinioUtil minioUtil; private MinioUtil minioUtil;
@Autowired
private UserMapper userMapper;
public LoginVo buildUserVo(AdminUser user, long readMeDay) { public LoginVo buildUserVo(AdminUser user, long readMeDay) {
// 创建token // 创建token
@ -50,16 +60,21 @@ public class UserFactory {
String email = user.getEmail(); String email = user.getEmail();
String token = JwtHelper.createToken(userId, email, (int) readMeDay); String token = JwtHelper.createToken(userId, email, (int) readMeDay);
String avatar = user.getAvatar(); String avatar = user.getAvatar();
String remoteAddr = IpUtil.getCurrentUserIpAddress().getRemoteAddr();
// 获取IP地址
String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr();
String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion(); String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion();
// 当前请求request
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 判断用户是否有头像如果没有头像设置默认头像 // 判断用户是否有头像如果没有头像设置默认头像
avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR; avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR;
// 设置用户IP地址并更新用户信息 // 设置用户IP地址并更新用户信息
AdminUser updateUser = new AdminUser(); AdminUser updateUser = new AdminUser();
updateUser.setId(userId); updateUser.setId(userId);
updateUser.setLastLoginIp(remoteAddr); updateUser.setLastLoginIp(ipAddr);
updateUser.setLastLoginIpAddress(ipRegion); updateUser.setLastLoginIpAddress(ipRegion);
userMapper.updateById(updateUser); userMapper.updateById(updateUser);
@ -86,13 +101,28 @@ public class UserFactory {
loginVo.setAvatar(avatar); loginVo.setAvatar(avatar);
loginVo.setToken(token); loginVo.setToken(token);
loginVo.setRefreshToken(token); loginVo.setRefreshToken(token);
loginVo.setLastLoginIp(remoteAddr); loginVo.setLastLoginIp(ipAddr);
loginVo.setLastLoginIpAddress(ipRegion); loginVo.setLastLoginIpAddress(ipRegion);
loginVo.setRoles(roles); loginVo.setRoles(roles);
loginVo.setPermissions(permissions); loginVo.setPermissions(permissions);
loginVo.setUpdateUser(userId); loginVo.setUpdateUser(userId);
loginVo.setExpires(expires); loginVo.setExpires(expires);
// 将用户登录保存在用户登录日志表中
UserLoginLog userLoginLog = new UserLoginLog();
BeanUtils.copyProperties(user, userLoginLog);
userLoginLog.setUserId(userId);
userLoginLog.setIpAddress(ipAddr);
userLoginLog.setIpRegion(ipRegion);
userLoginLog.setToken(token);
userLoginLog.setType("login");
if (requestAttributes != null) {
HttpServletRequest request = requestAttributes.getRequest();
String userAgent = request.getHeader("User-Agent");
userLoginLog.setUserAgent(userAgent);
}
userLoginLogMapper.insert(userLoginLog);
// 将信息保存在Redis中 // 将信息保存在Redis中
redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS); redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS);

View File

@ -1,6 +1,5 @@
package cn.bunny.services.service; package cn.bunny.services.service;
import cn.bunny.dao.dto.log.UserLoginLogAddDto;
import cn.bunny.dao.dto.log.UserLoginLogDto; import cn.bunny.dao.dto.log.UserLoginLogDto;
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto; import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
import cn.bunny.dao.entity.log.UserLoginLog; import cn.bunny.dao.entity.log.UserLoginLog;
@ -29,13 +28,6 @@ public interface UserLoginLogService extends IService<UserLoginLog> {
*/ */
PageResult<UserLoginLogVo> getUserLoginLogList(Page<UserLoginLog> pageParams, UserLoginLogDto dto); PageResult<UserLoginLogVo> getUserLoginLogList(Page<UserLoginLog> pageParams, UserLoginLogDto dto);
/**
* * 添加用户登录日志
*
* @param dto 添加表单
*/
void addUserLoginLog(@Valid UserLoginLogAddDto dto);
/** /**
* * 更新用户登录日志 * * 更新用户登录日志
* *

View File

@ -1,6 +1,5 @@
package cn.bunny.services.service.impl; package cn.bunny.services.service.impl;
import cn.bunny.dao.dto.log.UserLoginLogAddDto;
import cn.bunny.dao.dto.log.UserLoginLogDto; import cn.bunny.dao.dto.log.UserLoginLogDto;
import cn.bunny.dao.dto.log.UserLoginLogUpdateDto; import cn.bunny.dao.dto.log.UserLoginLogUpdateDto;
import cn.bunny.dao.entity.log.UserLoginLog; import cn.bunny.dao.entity.log.UserLoginLog;
@ -54,19 +53,6 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
.build(); .build();
} }
/**
* 添加用户登录日志
*
* @param dto 用户登录日志添加
*/
@Override
public void addUserLoginLog(@Valid UserLoginLogAddDto dto) {
// 保存数据
UserLoginLog userLoginLog = new UserLoginLog();
BeanUtils.copyProperties(dto, userLoginLog);
save(userLoginLog);
}
/** /**
* 更新用户登录日志 * 更新用户登录日志
* *

View File

@ -6,6 +6,7 @@ import cn.bunny.common.service.utils.JwtHelper;
import cn.bunny.common.service.utils.minio.MinioUtil; import cn.bunny.common.service.utils.minio.MinioUtil;
import cn.bunny.dao.dto.system.files.FileUploadDto; import cn.bunny.dao.dto.system.files.FileUploadDto;
import cn.bunny.dao.dto.system.user.*; import cn.bunny.dao.dto.system.user.*;
import cn.bunny.dao.entity.log.UserLoginLog;
import cn.bunny.dao.entity.system.AdminUser; import cn.bunny.dao.entity.system.AdminUser;
import cn.bunny.dao.entity.system.AdminUserAndDept; import cn.bunny.dao.entity.system.AdminUserAndDept;
import cn.bunny.dao.entity.system.UserDept; import cn.bunny.dao.entity.system.UserDept;
@ -21,6 +22,7 @@ import cn.bunny.dao.vo.system.user.UserVo;
import cn.bunny.services.factory.EmailFactory; import cn.bunny.services.factory.EmailFactory;
import cn.bunny.services.factory.UserFactory; import cn.bunny.services.factory.UserFactory;
import cn.bunny.services.mapper.UserDeptMapper; import cn.bunny.services.mapper.UserDeptMapper;
import cn.bunny.services.mapper.UserLoginLogMapper;
import cn.bunny.services.mapper.UserMapper; import cn.bunny.services.mapper.UserMapper;
import cn.bunny.services.mapper.UserRoleMapper; import cn.bunny.services.mapper.UserRoleMapper;
import cn.bunny.services.service.FilesService; import cn.bunny.services.service.FilesService;
@ -39,6 +41,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList; import java.util.ArrayList;
@ -76,6 +80,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
@Autowired @Autowired
private UserRoleMapper userRoleMapper; private UserRoleMapper userRoleMapper;
@Autowired
private UserLoginLogMapper userLoginLogMapper;
/** /**
* 登录发送邮件验证码 * 登录发送邮件验证码
* *
@ -204,6 +211,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
*/ */
@Override @Override
public void forcedOffline(Long id) { public void forcedOffline(Long id) {
// 当前请求request
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (id == null) throw new BunnyException(ResultCodeEnum.REQUEST_IS_EMPTY); if (id == null) throw new BunnyException(ResultCodeEnum.REQUEST_IS_EMPTY);
// 根据id查询用户登录前缀 // 根据id查询用户登录前缀
@ -211,6 +221,16 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
String email = adminUser.getEmail(); String email = adminUser.getEmail();
String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(email); String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(email);
// 将用户登录保存在用户登录日志表中
UserLoginLog userLoginLog = new UserLoginLog();
BeanUtils.copyProperties(adminUser, userLoginLog);
userLoginLog.setUserId(adminUser.getId());
userLoginLog.setIpAddress(adminUser.getLastLoginIp());
userLoginLog.setIpRegion(adminUser.getLastLoginIpAddress());
userLoginLog.setToken(null);
userLoginLog.setType("forcedOffline");
userLoginLogMapper.insert(userLoginLog);
redisTemplate.delete(adminLoginInfoPrefix); redisTemplate.delete(adminLoginInfoPrefix);
} }

View File

@ -13,14 +13,14 @@
<id column="user_id" property="userId"/> <id column="user_id" property="userId"/>
<id column="username" property="username"/> <id column="username" property="username"/>
<id column="token" property="token"/> <id column="token" property="token"/>
<id column="ip" property="ip"/> <id column="ip_region" property="ipRegion"/>
<id column="ip_address" property="ipAddress"/> <id column="ip_address" property="ipAddress"/>
<id column="user_agent" property="userAgent"/> <id column="user_agent" property="userAgent"/>
</resultMap> </resultMap>
<!-- 通用查询结果列 --> <!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, create_time, update_time, create_user, update_user, is_deleted, user_id, username, token, ip, ip_address, user_agent id, create_time, update_time, create_user, update_user, is_deleted, user_id, username, token, ip_region, ip_address, user_agent
</sql> </sql>
<!-- 分页查询用户登录日志内容 --> <!-- 分页查询用户登录日志内容 -->
@ -38,8 +38,8 @@
<if test="dto.token != null and dto.token != ''"> <if test="dto.token != null and dto.token != ''">
and token like CONCAT('%',#{dto.token},'%') and token like CONCAT('%',#{dto.token},'%')
</if> </if>
<if test="dto.ip != null and dto.ip != ''"> <if test="dto.ipRegion != null and dto.ipRegion != ''">
and ip like CONCAT('%',#{dto.ip},'%') and ip_region like CONCAT('%',#{dto.ipRegion},'%')
</if> </if>
<if test="dto.ipAddress != null and dto.ipAddress != ''"> <if test="dto.ipAddress != null and dto.ipAddress != ''">
and ip_address like CONCAT('%',#{dto.ipAddress},'%') and ip_address like CONCAT('%',#{dto.ipAddress},'%')