From e657805544db23cb3e04ca0ca1ea6ba97d2b8d9e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 10 May 2026 09:40:28 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=90=8C=E6=AD=A5=E3=80=91BOOT=20?= =?UTF-8?q?=E5=92=8C=20CLOUD=20=E7=9A=84=E5=8A=9F=E8=83=BD=EF=BC=88ai=20+?= =?UTF-8?q?=20trade=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AiKnowledgeSegmentController.java | 9 +++++ .../ai/service/image/AiImageServiceImpl.java | 5 ++- .../knowledge/AiKnowledgeSegmentService.java | 7 ++++ .../AiKnowledgeSegmentServiceImpl.java | 13 ++++++ .../iocoder/yudao/module/ai/util/AiUtils.java | 40 ++++++++++++++++--- .../core/model/chat/TongYiChatModelTests.java | 22 +++++----- .../model/image/TongYiImagesModelTest.java | 17 ++++++-- .../DeliveryExpressTemplateFreeDO.java | 4 +- .../bo/DeliveryExpressTemplateRespBO.java | 4 +- .../controller/admin/user/UserController.java | 16 ++++++++ .../mysql/oauth2/OAuth2AccessTokenMapper.java | 12 ++++++ .../oauth2/OAuth2RefreshTokenMapper.java | 13 ++++++ .../service/oauth2/OAuth2TokenService.java | 15 +++++++ .../oauth2/OAuth2TokenServiceImpl.java | 33 +++++++++++++++ 14 files changed, 184 insertions(+), 26 deletions(-) diff --git a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java index 34f324491..6c87be812 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java +++ b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/knowledge/AiKnowledgeSegmentController.java @@ -83,6 +83,15 @@ public class AiKnowledgeSegmentController { return success(true); } + @DeleteMapping("/delete") + @Operation(summary = "删除段落") + @Parameter(name = "id", description = "段落编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('ai:knowledge:delete')") + public CommonResult deleteKnowledgeSegment(@RequestParam("id") Long id) { + segmentService.deleteKnowledgeSegment(id); + return success(true); + } + @GetMapping("/split") @Operation(summary = "切片内容") @Parameters({ diff --git a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java index 79214a032..3def2a9c7 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/image/AiImageServiceImpl.java @@ -109,6 +109,7 @@ public class AiImageServiceImpl implements AiImageService { } @Async + @SuppressWarnings("ConstantValue") public void executeDrawImage(AiImageDO image, AiImageDrawReqVO reqVO, AiModelDO model) { try { // 1.1 构建请求 @@ -164,8 +165,8 @@ public class AiImageServiceImpl implements AiImageService { .build(); } else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.TONG_YI.getPlatform())) { return DashScopeImageOptions.builder() - .withModel(model.getModel()).withN(1) - .withHeight(draw.getHeight()).withWidth(draw.getWidth()) + .model(model.getModel()).n(1) + .height(draw.getHeight()).width(draw.getWidth()) .build(); } else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.YI_YAN.getPlatform())) { return QianFanImageOptions.builder() diff --git a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java index 54f721705..9894e7335 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java +++ b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentService.java @@ -98,6 +98,13 @@ public interface AiKnowledgeSegmentService { */ void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO); + /** + * 删除知识库段落 + * + * @param id 段落编号 + */ + void deleteKnowledgeSegment(Long id); + /** * 重新索引知识库下的所有文档段落 * diff --git a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java index 9d64fcce9..b5038412b 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java @@ -141,6 +141,19 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService } } + @Override + public void deleteKnowledgeSegment(Long id) { + // 1. 校验段落存在 + AiKnowledgeSegmentDO segment = validateKnowledgeSegmentExists(id); + + // 2. 删除向量 + VectorStore vectorStore = getVectorStoreById(segment.getKnowledgeId()); + deleteVectorStore(vectorStore, segment); + + // 3. 删除段落记录 + segmentMapper.deleteById(id); + } + @Override public void deleteKnowledgeSegmentByDocumentId(Long documentId) { // 1. 查询需要删除的段落 diff --git a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java index dab4d5aa4..15185235a 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java +++ b/yudao-module-ai/yudao-module-ai-server/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.ai.util; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum; @@ -33,6 +35,28 @@ public class AiUtils { public static final String TOOL_CONTEXT_LOGIN_USER = "LOGIN_USER"; public static final String TOOL_CONTEXT_TENANT_ID = "TENANT_ID"; + /** + * 通义千问支持多模态的模型 + * + * @see 模型广场 + * @see 必须开启 withMultiModel 参数 + */ + public static final Set TONG_YI_MULTI_MODELS = SetUtils.asSet( + // qwen3.5 / 3.6 系列(统一多模态主干) + "qwen3.6-plus", "qwen3.6-flash", + "qwen3.5-plus", "qwen3.5-flash", + // qwen-vl 视觉理解 + "qwen3-vl-plus", "qwen3-vl-flash", + "qwen-vl-max", "qwen-vl-plus", + "qwen2.5-vl-72b-instruct", "qwen2.5-vl-32b-instruct", + "qwen2.5-vl-7b-instruct", "qwen2.5-vl-3b-instruct", + // qvq 视觉推理 + "qvq-max", "qvq-plus", + // qwen-omni 全模态 + "qwen3.5-omni-plus", "qwen3.5-omni-flash", + "qwen3-omni-flash", "qwen-omni-turbo" + ); + public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens) { return buildChatOptions(platform, model, temperature, maxTokens, null, null); } @@ -44,9 +68,10 @@ public class AiUtils { // noinspection EnhancedSwitchMigration switch (platform) { case TONG_YI: - return DashScopeChatOptions.builder().withModel(model).withTemperature(temperature).withMaxToken(maxTokens) - .withEnableThinking(true) // TODO 芋艿:默认都开启 thinking 模式,后续可以让用户配置 - .withToolCallbacks(toolCallbacks).withToolContext(toolContext).build(); + return DashScopeChatOptions.builder().model(model).temperature(temperature).maxToken(maxTokens) + .enableThinking(true) // TODO 芋艿:默认都开启 thinking 模式,后续可以让用户配置 + .multiModel(TONG_YI_MULTI_MODELS.contains(model)) // 是否多模态模型 + .toolCallbacks(toolCallbacks).toolContext(toolContext).build(); case YI_YAN: return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build(); case DEEP_SEEK: @@ -125,10 +150,13 @@ public class AiUtils { || response.getResult().getOutput() == null) { return null; } - if (response.getResult().getOutput() instanceof DeepSeekAssistantMessage) { - return ((DeepSeekAssistantMessage) (response.getResult().getOutput())).getReasoningContent(); + AssistantMessage output = response.getResult().getOutput(); + // DeepSeek 通过专属 AssistantMessage 暴露 reasoningContent + if (output instanceof DeepSeekAssistantMessage) { + return ((DeepSeekAssistantMessage) output).getReasoningContent(); } - return null; + // 通义千问等通过 metadata 透传 reasoningContent + return MapUtil.getStr(output.getMetadata(), "reasoningContent"); } } \ No newline at end of file diff --git a/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java b/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java index 23bd5d9e0..056709d4b 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java +++ b/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/TongYiChatModelTests.java @@ -34,15 +34,15 @@ public class TongYiChatModelTests { private final DashScopeChatModel chatModel = DashScopeChatModel.builder() .dashScopeApi(DashScopeApi.builder() - .apiKey("sk-47aa124781be4bfb95244cc62f63f7d0") + .apiKey("sk-cd9f39e99ea54840bd1888282325f55a") // https://bailian.console.aliyun.com/cn-beijing/?tab=model#/api-key 获取密钥 .build()) .defaultOptions(DashScopeChatOptions.builder() -// .withModel("qwen1.5-72b-chat") // 模型 - .withModel("qwen3-235b-a22b-thinking-2507") // 模型 -// .withModel("deepseek-r1") // 模型(deepseek-r1) -// .withModel("deepseek-v3") // 模型(deepseek-v3) -// .withModel("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b) -// .withEnableThinking(true) + .multiModel(true) // 注意:当使用 qwen3.6-plus 等多模态模型,需要设置为 true,可见 https://help.aliyun.com/zh/model-studio/error-code#error-url 链接 + .model("qwen3.6-plus") // 模型 +// .model("deepseek-r1") // 模型(deepseek-r1) +// .model("deepseek-v3") // 模型(deepseek-v3) +// .model("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b) +// .enableThinking(true) .build()) .build(); @@ -85,9 +85,9 @@ public class TongYiChatModelTests { List messages = new ArrayList<>(); messages.add(new UserMessage("详细分析下,如何设计一个电商系统?")); DashScopeChatOptions options = DashScopeChatOptions.builder() - .withModel("qwen3-235b-a22b-thinking-2507") + .model("qwen3.6-plus").multiModel(true) // .withModel("qwen-max-2025-01-25") - .withEnableThinking(true) // 必须设置,否则会报错 + .enableThinking(true) // 必须设置,否则会报错 .build(); // 调用 @@ -112,8 +112,8 @@ public class TongYiChatModelTests { Document document01 = new Document("abc"); Document document02 = new Document("sapring"); RerankOptions options = DashScopeRerankOptions.builder() - .withTopN(1) - .withModel("gte-rerank-v2") + .topN(1) + .model("gte-rerank-v2") .build(); RerankRequest rerankRequest = new RerankRequest( query, diff --git a/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/TongYiImagesModelTest.java b/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/TongYiImagesModelTest.java index b31c07696..a556f7922 100644 --- a/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/TongYiImagesModelTest.java +++ b/yudao-module-ai/yudao-module-ai-server/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/image/TongYiImagesModelTest.java @@ -12,23 +12,34 @@ import org.springframework.ai.image.ImageResponse; /** * {@link DashScopeImageModel} 集成测试类 * + * TODO @芋艿:注:spring-ai-alibaba-dashscope(1.1.2.2)的 {@code DashScopeImageApi#resolveImagePath} 未给 {@code wan2.7-image} 加路由分支, + * 会落到默认的 {@code text2image/image-synthesis} 异步端点 + 旧版 {@code prompt} 入参, + * 而该模型实际要求 {@code multimodal-generation/generation} 同步端点 + {@code messages} 入参, + * 端点、异步头、入参结构全部对不上,所以走 SDK 直接调用必失败。 + * + * 临时方案:改用 SDK 已支持的 {@code wan2.6-image}(异步)或 {@code qwen-image}(同步); + * 或在项目内同包同名覆盖 {@code DashScopeImageApi},把 {@code wan2.7*} 也路由到 {@code wan2.6-image} 那条 {@code image-generation/generation} 异步分支。 + * * @author fansili */ public class TongYiImagesModelTest { private final DashScopeImageModel imageModel = DashScopeImageModel.builder() .dashScopeApi(DashScopeImageApi.builder() - .apiKey("sk-47aa124781be4bfb95244cc62f63f7d0") + .apiKey("sk-cd9f39e99ea54840bd1888282325f55a") // https://bailian.console.aliyun.com/cn-beijing/?tab=model#/api-key 获取密钥 .build()) .build(); + // TODO @芋艿: @Test @Disabled public void imageCallTest() { // 准备参数 ImageOptions options = DashScopeImageOptions.builder() - .withModel("wanx-v1") - .withHeight(256).withWidth(256) + .model("wan2.7-image") +// .withSize("2k") + .height(768).width(768) + .n(1) .build(); ImagePrompt prompt = new ImagePrompt("中国长城!", options); diff --git a/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java b/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java index 07eef1be2..8bf035b70 100644 --- a/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java +++ b/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/delivery/DeliveryExpressTemplateFreeDO.java @@ -43,14 +43,14 @@ public class DeliveryExpressTemplateFreeDO extends BaseDO { /** * 包邮金额,单位:分 * - * 订单总金额 > 包邮金额时,才免运费 + * 订单总金额 >= 包邮金额时,才免运费 */ private Integer freePrice; /** * 包邮件数 * - * 订单总件数 > 包邮件数时,才免运费 + * 订单总件数 >= 包邮件数时,才免运费 */ private Integer freeCount; diff --git a/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java b/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java index db0af04eb..212efa5fe 100644 --- a/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java +++ b/yudao-module-mall/yudao-module-trade-server/src/main/java/cn/iocoder/yudao/module/trade/service/delivery/bo/DeliveryExpressTemplateRespBO.java @@ -65,14 +65,14 @@ public class DeliveryExpressTemplateRespBO { /** * 包邮金额,单位:分 * - * 订单总金额 > 包邮金额时,才免运费 + * 订单总金额 >= 包邮金额时,才免运费 */ private Integer freePrice; /** * 包邮件数 * - * 订单总件数 > 包邮件数时,才免运费 + * 订单总件数 >= 包邮件数时,才免运费 */ private Integer freeCount; } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 9a90117cf..820c13206 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -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> getUserList(@RequestParam("ids") List ids) { + List list = userService.getUserList(ids); + if (CollUtil.isEmpty(list)) { + return success(Collections.emptyList()); + } + // 拼接数据 + Map 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> getSimpleUserList() { diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java index d4a6ce6d6..c3c346a66 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/oauth2/OAuth2AccessTokenMapper.java @@ -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 { @@ -19,4 +23,13 @@ public interface OAuth2RefreshTokenMapper extends BaseMapperX 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); } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java index f738f7420..8bcff76cd 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImpl.java @@ -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; + } }