diff --git a/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java b/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java index 9337d4e..4af12f9 100644 --- a/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java +++ b/common/common-generator/src/main/java/cn/bunny/common/generator/generator/WebGeneratorCode.java @@ -3,7 +3,11 @@ package cn.bunny.common.generator.generator; import cn.bunny.common.generator.entity.BaseField; import cn.bunny.common.generator.entity.BaseResultMap; 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.vo.log.UserLoginLogVo; import com.baomidou.mybatisplus.annotation.TableName; import com.google.common.base.CaseFormat; import io.swagger.v3.oas.annotations.media.Schema; @@ -48,10 +52,10 @@ public class WebGeneratorCode { public static void main(String[] args) throws Exception { Class originalClass = UserLoginLog.class; - Class dtoClass = UserLoginLog.class; - Class addDtoClass = UserLoginLog.class; - Class updateDtoClass = UserLoginLog.class; - Class voClass = UserLoginLog.class; + Class dtoClass = UserLoginLogDto.class; + Class addDtoClass = UserLoginLogAddDto.class; + Class updateDtoClass = UserLoginLogUpdateDto.class; + Class voClass = UserLoginLogVo.class; // 设置velocity资源加载器 Properties prop = new Properties(); diff --git a/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogAddDto.java b/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogAddDto.java new file mode 100644 index 0000000..9a56874 --- /dev/null +++ b/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogAddDto.java @@ -0,0 +1,86 @@ +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 = "ipAddress", title = "登录Ip") + private String ipAddress; + + @Schema(name = "ipRegion", title = "登录Ip归属地") + private String ipRegion; + + @Schema(name = "userAgent", title = "登录时代理") + private String userAgent; + + @Schema(name = "type", title = "操作类型") + private String type; + + @Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的") + private String xRequestedWith; + + @Schema(name = "secChUa", title = "用户代理的品牌和版本") + private String secChUa; + + @Schema(name = "secChUaArch", title = "用户代理的底层平台架构") + private String secChUaArch; + + @Schema(name = "secChUaBitness", title = "用户代理的底层CPU架构位数") + private String secChUaBitness; + + @Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行") + private String secChUaMobile; + + @Schema(name = "secChUaModel", title = "用户代理的设备模型") + private String secChUaModel; + + @Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台") + private String secChUaPlatform; + + @Schema(name = "secChUaPlatformVersion", title = "用户代理的底层操作系统版本") + private String secChUaPlatformVersion; + + @Schema(name = "contentDpr", title = "客户端设备像素比") + private String contentDpr; + + @Schema(name = "deviceMemory", title = "客户端RAM内存的近似值") + private String deviceMemory; + + @Schema(name = "dpr", title = "客户端设备像素比") + private String dpr; + + @Schema(name = "viewportWidth", title = "布局视口宽度") + private String viewportWidth; + + @Schema(name = "width", title = "所需资源宽度") + private String width; + + @Schema(name = "downlink", title = "客户端连接到服务器的近似带宽") + private String downlink; + + @Schema(name = "ect", title = "有效连接类型") + private String ect; + + @Schema(name = "rtt", title = "应用层往返时间") + private String rtt; + +} + diff --git a/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogDto.java b/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogDto.java index d1126f8..c2a8bfa 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogDto.java @@ -22,10 +22,10 @@ public class UserLoginLogDto { @Schema(name = "token", title = "登录token") private String token; - @Schema(name = "ipAddress", title = "登录Ip地点") + @Schema(name = "ipAddress", title = "登录Ip") private String ipAddress; - @Schema(name = "ipRegion", title = "登录Ip") + @Schema(name = "ipRegion", title = "登录Ip归属地") private String ipRegion; @Schema(name = "userAgent", title = "登录时代理") @@ -34,5 +34,17 @@ public class UserLoginLogDto { @Schema(name = "type", title = "操作类型") private String type; + @Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的") + private String xRequestedWith; + + @Schema(name = "secChUa", title = "用户代理的品牌和版本") + private String secChUa; + + @Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行") + private String secChUaMobile; + + @Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台") + private String secChUaPlatform; + } diff --git a/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogUpdateDto.java b/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogUpdateDto.java index 2db78f2..700f717 100644 --- a/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogUpdateDto.java +++ b/dao/src/main/java/cn/bunny/dao/dto/log/UserLoginLogUpdateDto.java @@ -22,10 +22,10 @@ public class UserLoginLogUpdateDto { @Schema(name = "token", title = "登录token") private String token; - @Schema(name = "ipAddress", title = "登录Ip地点") + @Schema(name = "ipAddress", title = "登录Ip") private String ipAddress; - @Schema(name = "ipRegion", title = "登录Ip") + @Schema(name = "ipRegion", title = "登录Ip归属地") private String ipRegion; @Schema(name = "userAgent", title = "登录时代理") @@ -34,4 +34,16 @@ public class UserLoginLogUpdateDto { @Schema(name = "type", title = "操作类型") private String type; + @Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的") + private String xRequestedWith; + + @Schema(name = "secChUa", title = "用户代理的品牌和版本") + private String secChUa; + + @Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行") + private String secChUaMobile; + + @Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台") + private String secChUaPlatform; + } \ No newline at end of file diff --git a/dao/src/main/java/cn/bunny/dao/entity/log/UserLoginLog.java b/dao/src/main/java/cn/bunny/dao/entity/log/UserLoginLog.java index f3440b5..2ce28e7 100644 --- a/dao/src/main/java/cn/bunny/dao/entity/log/UserLoginLog.java +++ b/dao/src/main/java/cn/bunny/dao/entity/log/UserLoginLog.java @@ -13,7 +13,7 @@ import lombok.experimental.Accessors; *

* * @author Bunny - * @since 2024-10-18 + * @since 2024-10-19 */ @Getter @Setter @@ -43,4 +43,16 @@ public class UserLoginLog extends BaseEntity { @Schema(name = "type", title = "操作类型") private String type; + @Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的") + private String xRequestedWith; + + @Schema(name = "secChUa", title = "用户代理的品牌和版本") + private String secChUa; + + @Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行") + private String secChUaMobile; + + @Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台") + private String secChUaPlatform; + } diff --git a/dao/src/main/java/cn/bunny/dao/vo/log/UserLoginLogVo.java b/dao/src/main/java/cn/bunny/dao/vo/log/UserLoginLogVo.java index 7ad9190..d333d7e 100644 --- a/dao/src/main/java/cn/bunny/dao/vo/log/UserLoginLogVo.java +++ b/dao/src/main/java/cn/bunny/dao/vo/log/UserLoginLogVo.java @@ -1,6 +1,7 @@ package cn.bunny.dao.vo.log; import cn.bunny.dao.vo.common.BaseVo; +import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -21,10 +22,10 @@ public class UserLoginLogVo extends BaseVo { @Schema(name = "token", title = "登录token") private String token; - @Schema(name = "ipAddress", title = "登录Ip地点") + @Schema(name = "ipAddress", title = "登录Ip") private String ipAddress; - @Schema(name = "ipRegion", title = "登录Ip") + @Schema(name = "ipRegion", title = "登录Ip归属地") private String ipRegion; @Schema(name = "userAgent", title = "登录时代理") @@ -33,4 +34,17 @@ public class UserLoginLogVo extends BaseVo { @Schema(name = "type", title = "操作类型") private String type; + @Schema(name = "xRequestedWith", title = "标识客户端是否是通过Ajax发送请求的") + @JsonProperty("xRequestedWith") + private String xRequestedWith; + + @Schema(name = "secChUa", title = "用户代理的品牌和版本") + private String secChUa; + + @Schema(name = "secChUaMobile", title = "用户代理是否在手机设备上运行") + private String secChUaMobile; + + @Schema(name = "secChUaPlatform", title = "用户代理的底层操作系统/平台") + private String secChUaPlatform; + } \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/controller/UserLoginLogController.java b/service/src/main/java/cn/bunny/services/controller/UserLoginLogController.java index 0f46f4c..809a082 100644 --- a/service/src/main/java/cn/bunny/services/controller/UserLoginLogController.java +++ b/service/src/main/java/cn/bunny/services/controller/UserLoginLogController.java @@ -1,7 +1,6 @@ package cn.bunny.services.controller; 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.pojo.result.PageResult; import cn.bunny.dao.pojo.result.Result; @@ -12,7 +11,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Mono; @@ -25,7 +23,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-18 22:36:07 + * @since 2024-10-19 01:01:01 */ @Tag(name = "用户登录日志", description = "用户登录日志相关接口") @RestController @@ -48,13 +46,6 @@ public class UserLoginLogController { return Mono.just(Result.success(pageResult)); } - @Operation(summary = "更新用户登录日志", description = "更新用户登录日志") - @PutMapping("updateUserLoginLog") - public Mono> updateUserLoginLog(@Valid @RequestBody UserLoginLogUpdateDto dto) { - userLoginLogService.updateUserLoginLog(dto); - return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS)); - } - @Operation(summary = "删除用户登录日志", description = "删除用户登录日志") @DeleteMapping("deleteUserLoginLog") public Mono> deleteUserLoginLog(@RequestBody List ids) { diff --git a/service/src/main/java/cn/bunny/services/factory/UserFactory.java b/service/src/main/java/cn/bunny/services/factory/UserFactory.java index 44d2a3e..134b0c0 100644 --- a/service/src/main/java/cn/bunny/services/factory/UserFactory.java +++ b/service/src/main/java/cn/bunny/services/factory/UserFactory.java @@ -53,37 +53,53 @@ public class UserFactory { @Autowired private MinioUtil minioUtil; - public LoginVo buildUserVo(AdminUser user, long readMeDay) { // 创建token Long userId = user.getId(); String email = user.getEmail(); String token = JwtHelper.createToken(userId, email, (int) readMeDay); - String avatar = user.getAvatar(); // 获取IP地址 String ipAddr = IpUtil.getCurrentUserIpAddress().getIpAddr(); String ipRegion = IpUtil.getCurrentUserIpAddress().getIpRegion(); - // 当前请求request - ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + // 更新用户登录信息 + setUpdateUser(userId, ipAddr, ipRegion); + + // 设置用户返回信息 + LoginVo loginVo = setLoginVo(user, token, readMeDay, ipAddr, ipRegion); + + // 将用户登录保存在用户登录日志表中 + UserLoginLog userLoginLog = new UserLoginLog(); + userLoginLog.setUsername(user.getUsername()); + userLoginLog.setUserId(userId); + userLoginLog.setIpAddress(ipAddr); + userLoginLog.setIpRegion(ipRegion); + userLoginLog.setToken(token); + userLoginLog.setType("login"); + setUserLoginLog(userLoginLog); + userLoginLogMapper.insert(userLoginLog); + + // 将信息保存在Redis中 + redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS); + + // 将Redis中验证码删除 + redisTemplate.delete(RedisUserConstant.getAdminUserEmailCodePrefix(email)); + + return loginVo; + } + + + /** + * * 设置更新用户设置内容 + */ + public LoginVo setLoginVo(AdminUser user, String token, long readMeDay, String ipAddr, String ipRegion) { + Long userId = user.getId(); // 判断用户是否有头像,如果没有头像设置默认头像 + String avatar = user.getAvatar(); avatar = StringUtils.hasText(avatar) ? minioUtil.getObjectNameFullPath(avatar) : UserConstant.USER_AVATAR; - // 设置用户IP地址,并更新用户信息 - AdminUser updateUser = new AdminUser(); - updateUser.setId(userId); - updateUser.setLastLoginIp(ipAddr); - updateUser.setLastLoginIpAddress(ipRegion); - userMapper.updateById(updateUser); - - // 计算过期时间,并格式化返回 - LocalDateTime localDateTime = LocalDateTime.now(); - LocalDateTime plusDay = localDateTime.plusDays(readMeDay); - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH); - String expires = plusDay.format(dateTimeFormatter); - // 查找用户橘色 List roles = new ArrayList<>(roleMapper.selectListByUserId(userId).stream().map(Role::getRoleCode).toList()); List permissions = new ArrayList<>(); @@ -94,6 +110,12 @@ public class UserFactory { permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList(); } + // 计算过期时间,并格式化返回 + LocalDateTime localDateTime = LocalDateTime.now(); + LocalDateTime plusDay = localDateTime.plusDays(readMeDay); + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(LocalDateTimeConstant.YYYY_MM_DD_HH_MM_SS_SLASH); + String expires = plusDay.format(dateTimeFormatter); + // 构建返回对象,设置用户需要内容 LoginVo loginVo = new LoginVo(); BeanUtils.copyProperties(user, loginVo); @@ -108,27 +130,53 @@ public class UserFactory { loginVo.setUpdateUser(userId); 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中 - redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS); - - // 将Redis中验证码删除 - redisTemplate.delete(RedisUserConstant.getAdminUserEmailCodePrefix(email)); - return loginVo; } + + /** + * * 设置更新用户设置内容 + * + * @param userId 用户ID + */ + public void setUpdateUser(Long userId, String ipAddr, String ipRegion) { + // 设置用户IP地址,并更新用户信息 + AdminUser updateUser = new AdminUser(); + updateUser.setId(userId); + updateUser.setLastLoginIp(ipAddr); + updateUser.setLastLoginIpAddress(ipRegion); + userMapper.updateById(updateUser); + } + + /** + * * 设置用户登录日志内容 + * + * @param userLoginLog 用户登录日志 + */ + public void setUserLoginLog(UserLoginLog userLoginLog) { + // 当前请求request + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (requestAttributes == null) return; + + HttpServletRequest request = requestAttributes.getRequest(); + + // 获取User-Agent + String userAgent = request.getHeader("User-Agent"); + userLoginLog.setUserAgent(userAgent); + + // 获取X-Requested-With + String xRequestedWith = request.getHeader("X-Requested-With"); + userLoginLog.setXRequestedWith(xRequestedWith); + + // 获取Sec-CH-UA + String secCHUA = request.getHeader("sec-ch-ua"); + userLoginLog.setSecChUa(secCHUA); + + // 获取Sec-CH-UA-Mobile + String secCHUAMobile = request.getHeader("Sec-CH-UA-Mobile"); + userLoginLog.setSecChUaMobile(secCHUAMobile); + + // 获取Sec-CH-UA-Platform + String secCHUAPlatform = request.getHeader("Sec-CH-UA-Platform"); + userLoginLog.setSecChUaPlatform(secCHUAPlatform); + } } \ No newline at end of file diff --git a/service/src/main/java/cn/bunny/services/mapper/UserLoginLogMapper.java b/service/src/main/java/cn/bunny/services/mapper/UserLoginLogMapper.java index 06b9815..015b415 100644 --- a/service/src/main/java/cn/bunny/services/mapper/UserLoginLogMapper.java +++ b/service/src/main/java/cn/bunny/services/mapper/UserLoginLogMapper.java @@ -16,7 +16,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-18 22:36:07 + * @since 2024-10-19 01:01:01 */ @Mapper public interface UserLoginLogMapper extends BaseMapper { diff --git a/service/src/main/java/cn/bunny/services/service/UserLoginLogService.java b/service/src/main/java/cn/bunny/services/service/UserLoginLogService.java index bfecdfa..c21470e 100644 --- a/service/src/main/java/cn/bunny/services/service/UserLoginLogService.java +++ b/service/src/main/java/cn/bunny/services/service/UserLoginLogService.java @@ -1,13 +1,11 @@ package cn.bunny.services.service; 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.pojo.result.PageResult; import cn.bunny.dao.vo.log.UserLoginLogVo; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import jakarta.validation.Valid; import java.util.List; @@ -17,7 +15,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-18 22:36:07 + * @since 2024-10-19 01:01:01 */ public interface UserLoginLogService extends IService { @@ -28,13 +26,6 @@ public interface UserLoginLogService extends IService { */ PageResult getUserLoginLogList(Page pageParams, UserLoginLogDto dto); - /** - * * 更新用户登录日志 - * - * @param dto 更新表单 - */ - void updateUserLoginLog(@Valid UserLoginLogUpdateDto dto); - /** * * 删除|批量删除用户登录日志类型 * diff --git a/service/src/main/java/cn/bunny/services/service/impl/UserLoginLogServiceImpl.java b/service/src/main/java/cn/bunny/services/service/impl/UserLoginLogServiceImpl.java index a5f49bb..dc75e9c 100644 --- a/service/src/main/java/cn/bunny/services/service/impl/UserLoginLogServiceImpl.java +++ b/service/src/main/java/cn/bunny/services/service/impl/UserLoginLogServiceImpl.java @@ -1,7 +1,6 @@ package cn.bunny.services.service.impl; 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.pojo.result.PageResult; import cn.bunny.dao.vo.log.UserLoginLogVo; @@ -10,7 +9,6 @@ import cn.bunny.services.service.UserLoginLogService; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import jakarta.validation.Valid; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -22,7 +20,7 @@ import java.util.List; *

* * @author Bunny - * @since 2024-10-18 22:36:07 + * @since 2024-10-19 01:01:01 */ @Service public class UserLoginLogServiceImpl extends ServiceImpl implements UserLoginLogService { @@ -53,19 +51,6 @@ public class UserLoginLogServiceImpl extends ServiceImpl implemen */ @Override public void forcedOffline(Long id) { - // 当前请求request - ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - if (id == null) throw new BunnyException(ResultCodeEnum.REQUEST_IS_EMPTY); // 根据id查询用户登录前缀 diff --git a/service/src/main/resources/mapper/UserLoginLogMapper.xml b/service/src/main/resources/mapper/UserLoginLogMapper.xml index e4b452b..b9706cf 100644 --- a/service/src/main/resources/mapper/UserLoginLogMapper.xml +++ b/service/src/main/resources/mapper/UserLoginLogMapper.xml @@ -13,14 +13,19 @@ - + + + + + + - id, create_time, update_time, create_user, update_user, is_deleted, user_id, username, token, ip_region, ip_address, user_agent + id, create_time, update_time, create_user, update_user, is_deleted, user_id, username, token, ip_address, ip_region, user_agent, type, x_requested_with, sec_ch_ua, sec_ch_ua_mobile, sec_ch_ua_platform @@ -38,17 +43,31 @@ and token like CONCAT('%',#{dto.token},'%') - - and ip_region like CONCAT('%',#{dto.ipRegion},'%') - and ip_address like CONCAT('%',#{dto.ipAddress},'%') + + and ip_region like CONCAT('%',#{dto.ipRegion},'%') + and user_agent like CONCAT('%',#{dto.userAgent},'%') + + and type like CONCAT('%',#{dto.type},'%') + + + and x_requested_with like CONCAT('%',#{dto.xRequestedWith},'%') + + + and sec_ch_ua like CONCAT('%',#{dto.secChUa},'%') + + + and sec_ch_ua_mobile like CONCAT('%',#{dto.secChUaMobile},'%') + + + and sec_ch_ua_platform like CONCAT('%',#{dto.secChUaPlatform},'%') + - order by update_time desc