Merge remote-tracking branch 'origin/master-jdk17' into master-jdk17

This commit is contained in:
YunaiV
2026-05-10 09:34:55 +08:00
6 changed files with 131 additions and 0 deletions
@@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.util.Collections;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -34,6 +35,7 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 用户")
@RestController
@@ -112,6 +114,20 @@ public class UserController {
pageResult.getTotal()));
}
@GetMapping("/list")
@Operation(summary = "获得用户详情列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "[1024]")
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<List<UserRespVO>> getUserList(@RequestParam("ids") List<Long> ids) {
List<AdminUserDO> list = userService.getUserList(ids);
if (CollUtil.isEmpty(list)) {
return success(Collections.emptyList());
}
// 拼接数据
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertSet(list, AdminUserDO::getDeptId));
return success(UserConvert.INSTANCE.convertList(list, deptMap));
}
@GetMapping({"/list-all-simple", "/simple-list"})
@Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项")
public CommonResult<List<UserSimpleRespVO>> getSimpleUserList() {
@@ -6,7 +6,9 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
@@ -37,4 +39,14 @@ public interface OAuth2AccessTokenMapper extends BaseMapperX<OAuth2AccessTokenDO
OAuth2AccessTokenDO::getUserType, userType);
}
/**
* 物理删除指定过期时间之前的访问令牌
*
* @param expiresTime 最大时间
* @param limit 删除条数,防止一次删除太多
* @return 删除条数
*/
@Delete("DELETE FROM system_oauth2_access_token WHERE expires_time < #{expiresTime} LIMIT #{limit}")
Integer deleteByExpiresTimeLt(@Param("expiresTime") LocalDateTime expiresTime, @Param("limit") Integer limit);
}
@@ -4,7 +4,11 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
@Mapper
public interface OAuth2RefreshTokenMapper extends BaseMapperX<OAuth2RefreshTokenDO> {
@@ -19,4 +23,13 @@ public interface OAuth2RefreshTokenMapper extends BaseMapperX<OAuth2RefreshToken
return selectOne(OAuth2RefreshTokenDO::getRefreshToken, refreshToken);
}
/**
* 物理删除指定过期时间之前的刷新令牌
*
* @param expiresTime 最大时间
* @param limit 删除条数,防止一次删除太多
* @return 删除条数
*/
@Delete("DELETE FROM system_oauth2_refresh_token WHERE expires_time < #{expiresTime} LIMIT #{limit}")
Integer deleteByExpiresTimeLt(@Param("expiresTime") LocalDateTime expiresTime, @Param("limit") Integer limit);
}
@@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.system.job.token;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 物理删除过期 N 天的令牌的 Job
*
* @author preschooler
*/
@Component
@Slf4j
public class TokenCleanJob implements JobHandler {
@Resource
private OAuth2TokenService oauth2TokenService;
/**
* 清理过期(14)天的令牌
*/
private static final Integer JOB_CLEAN_RETAIN_DAY = 14;
/**
* 每次删除间隔的条数,如果值太高可能会造成数据库的压力过大
*/
private static final Integer DELETE_LIMIT = 100;
@Override
@TenantIgnore
public String execute(String param) {
Integer refreshCount = oauth2TokenService.cleanRefreshToken(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
log.info("[execute][定时执行清理刷新令牌数量 ({}) 个]", refreshCount);
Integer accessCount = oauth2TokenService.cleanAccessToken(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
log.info("[execute][定时执行清理访问令牌数量 ({}) 个]", accessCount);
return String.format("定时执行清理刷新令牌数量 %s 个,访问令牌数量 %s 个", refreshCount, accessCount);
}
}
@@ -88,4 +88,19 @@ public interface OAuth2TokenService {
*/
PageResult<OAuth2AccessTokenDO> getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO);
/**
* 清理过期 exceedDay 天的刷新令牌
*
* @param exceedDay 过期多少天就进行清理
* @param deleteLimit 清理的间隔条数
*/
Integer cleanRefreshToken(Integer exceedDay, Integer deleteLimit);
/**
* 清理过期 exceedDay 天的访问令牌
*
* @param exceedDay 过期多少天就进行清理
* @param deleteLimit 清理的间隔条数
*/
Integer cleanAccessToken(Integer exceedDay, Integer deleteLimit);
}
@@ -151,6 +151,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
oauth2AccessTokenRedisDAO.delete(accessToken);
// 删除刷新令牌
oauth2RefreshTokenMapper.deleteByRefreshToken(accessTokenDO.getRefreshToken());
oauth2AccessTokenRedisDAO.delete(accessTokenDO.getRefreshToken());
return accessTokenDO;
}
@@ -166,6 +167,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
oauth2AccessTokenRedisDAO.delete(accessToken.getAccessToken());
// 删除刷新令牌
oauth2RefreshTokenMapper.deleteByRefreshToken(accessToken.getRefreshToken());
oauth2AccessTokenRedisDAO.delete(accessToken.getRefreshToken());
});
}
@@ -241,4 +243,35 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
return IdUtil.fastSimpleUUID();
}
@Override
public Integer cleanRefreshToken(Integer exceedDay, Integer deleteLimit) {
int count = 0;
LocalDateTime expireDate = LocalDateTime.now().minusDays(exceedDay);
// 循环删除,直到没有满足条件的数据
for (int i = 0; i < Short.MAX_VALUE; i++) {
int deleteCount = oauth2RefreshTokenMapper.deleteByExpiresTimeLt(expireDate, deleteLimit);
count += deleteCount;
// 达到删除预期条数,说明到底了
if (deleteCount < deleteLimit) {
break;
}
}
return count;
}
@Override
public Integer cleanAccessToken(Integer exceedDay, Integer deleteLimit) {
int count = 0;
LocalDateTime expireDate = LocalDateTime.now().minusDays(exceedDay);
// 循环删除,直到没有满足条件的数据
for (int i = 0; i < Short.MAX_VALUE; i++) {
int deleteCount = oauth2AccessTokenMapper.deleteByExpiresTimeLt(expireDate, deleteLimit);
count += deleteCount;
// 达到删除预期条数,说明到底了
if (deleteCount < deleteLimit) {
break;
}
}
return count;
}
}