From 4326c41258e2fa2dc929cbe8e072e704597ec328 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 19 Dec 2025 16:13:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=BA=E9=A2=86=E5=A5=96=E4=B8=8E?= =?UTF-8?q?=E5=85=91=E6=8D=A2=E6=B5=81=E7=A8=8B=E6=B7=BB=E5=8A=A0=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E9=94=81=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E9=87=8D=E5=A4=8D=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 DailyTaskService 与 ActivationCodeService 中引入 Medallion.Threading。 - 通过 LazyServiceProvider 获取 IDistributedLockProvider(DistributedLock 属性)。 - 在 ClaimTaskRewardAsync(DailyTaskService)和 RedeemAsync(ActivationCodeService)中使用 AcquireLockAsync 加锁(基于 userId / activation code),用于自旋等待、防抖,避免并发导致的重复发放或重复兑换问题。 --- .../Services/ActivationCodeService.cs | 7 ++++++- .../Services/Activities/DailyTaskService.cs | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/ActivationCodeService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/ActivationCodeService.cs index 009af46e..799e8764 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/ActivationCodeService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/ActivationCodeService.cs @@ -1,3 +1,4 @@ +using Medallion.Threading; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Volo.Abp; @@ -19,7 +20,7 @@ public class ActivationCodeService : ApplicationService, IActivationCodeService private readonly ActivationCodeManager _activationCodeManager; private readonly IRechargeService _rechargeService; private readonly PremiumPackageManager _premiumPackageManager; - + private IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetRequiredService(); public ActivationCodeService( ActivationCodeManager activationCodeManager, IRechargeService rechargeService, @@ -68,6 +69,10 @@ public class ActivationCodeService : ApplicationService, IActivationCodeService [HttpPost("activationCode/Redeem")] public async Task RedeemAsync(ActivationCodeRedeemInput input) { + //自旋等待,防抖 + await using var handle = + await DistributedLock.AcquireLockAsync($"Yi:AiHub:ActivationCodeLock:{input.Code}"); + var userId = CurrentUser.GetId(); var redeemContext = await _activationCodeManager.RedeemAsync(userId, input.Code); var goodsType = redeemContext.ActivationCode.GoodsType; diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs index 6bf90d36..013a82f4 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs @@ -1,3 +1,4 @@ +using Medallion.Threading; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using SqlSugar; @@ -23,7 +24,7 @@ public class DailyTaskService : ApplicationService private readonly ISqlSugarRepository _messageRepository; private readonly ISqlSugarRepository _premiumPackageRepository; private readonly ILogger _logger; - + private IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetRequiredService(); // 任务配置 private readonly Dictionary _taskConfigs = new() @@ -113,6 +114,11 @@ public class DailyTaskService : ApplicationService public async Task ClaimTaskRewardAsync(ClaimTaskRewardInput input) { var userId = CurrentUser.GetId(); + //自旋等待,防抖 + await using var handle = + await DistributedLock.AcquireLockAsync($"Yi:AiHub:ClaimTaskRewardLock:{userId}"); + + var today = DateTime.Today; // 1. 验证任务等级