diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs index ac0c19b3..14d8e91c 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs @@ -58,6 +58,8 @@ public class FlashSalePlanAppService : protected IDistributedCache PlanDistributedCache { get; } + protected IDistributedCache ProductDistributedCache { get; } + protected IDistributedEventBus DistributedEventBus { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; } @@ -77,6 +79,7 @@ public class FlashSalePlanAppService : IProductAppService productAppService, IDistributedCache tokenDistributedCache, IDistributedCache planDistributedCache, + IDistributedCache productDistributedCache, IDistributedEventBus distributedEventBus, IFlashSaleResultRepository flashSaleResultRepository, IAbpDistributedLock distributedLock, @@ -90,6 +93,7 @@ public class FlashSalePlanAppService : ProductAppService = productAppService; PreOrderDistributedCache = tokenDistributedCache; PlanDistributedCache = planDistributedCache; + ProductDistributedCache = productDistributedCache; DistributedEventBus = distributedEventBus; FlashSaleResultRepository = flashSaleResultRepository; DistributedLock = distributedLock; @@ -213,7 +217,7 @@ public class FlashSalePlanAppService : await CheckPolicyAsync(PreOrderPolicyName); var plan = await GetFlashSalePlanCacheAsync(id); - var product = await ProductAppService.GetAsync(plan.ProductId); + var product = await GetProductCacheAsync(plan.ProductId); var productSku = product.GetSkuById(plan.ProductSkuId); var expiresTime = DateTimeOffset.Now.Add(Options.PreOrderExpires); @@ -381,11 +385,6 @@ public class FlashSalePlanAppService : throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } - if (productSku.Inventory < 1) - { - throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); - } - return Task.CompletedTask; } @@ -462,4 +461,21 @@ public class FlashSalePlanAppService : return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); } + + protected virtual async Task GetProductCacheAsync(Guid productId) + { + return await ProductDistributedCache.GetOrAddAsync(productId, async () => + { + var productDto = await ProductAppService.GetAsync(productId); + + var cacheItem = ObjectMapper.Map(productDto); + + if (cacheItem != null) + { + cacheItem.TenantId = CurrentTenant.Id; + } + + return cacheItem; + }); + } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs index 3f2a4324..b66c03f5 100644 --- a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs @@ -3,6 +3,8 @@ using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans; using EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; +using EasyAbp.EShop.Products.Products; +using EasyAbp.EShop.Products.Products.Dtos; namespace EasyAbp.EShop.Plugins.FlashSales; @@ -24,5 +26,8 @@ public class FlashSalesApplicationAutoMapperProfile : Profile CreateMap() .MapExtraProperties(); + + CreateMap(MemberList.Source) + .MapExtraProperties(); } } diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs new file mode 100644 index 00000000..d9d1ed46 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs @@ -0,0 +1,46 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Uow; + +namespace EasyAbp.EShop.Products.Products; + +public class ProductCacheInvalidator : + IDistributedEventHandler>, + IDistributedEventHandler>, + ITransientDependency +{ + protected IDistributedCache DistributedCache { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + + public ProductCacheInvalidator( + IDistributedCache distributedCache, + IUnitOfWorkManager unitOfWorkManager) + { + DistributedCache = distributedCache; + UnitOfWorkManager = unitOfWorkManager; + } + + public virtual async Task HandleEventAsync(EntityUpdatedEto eventData) + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + + UnitOfWorkManager.Current.OnCompleted(async () => + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + }); + } + + public virtual async Task HandleEventAsync(EntityDeletedEto eventData) + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + + UnitOfWorkManager.Current.OnCompleted(async () => + { + await DistributedCache.RemoveAsync(eventData.Entity.Id); + }); + } +} diff --git a/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs new file mode 100644 index 00000000..0c59d0f7 --- /dev/null +++ b/plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs @@ -0,0 +1,10 @@ +using System; +using EasyAbp.EShop.Products.Products.Dtos; +using Volo.Abp.MultiTenancy; + +namespace EasyAbp.EShop.Products.Products; + +public class ProductCacheItem : ProductDto, IMultiTenant +{ + public Guid? TenantId { get; set; } +} diff --git a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs index 844fe01c..6fa1d635 100644 --- a/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs +++ b/plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs @@ -342,11 +342,6 @@ public class FlashSalePlanAppServiceTests : FlashSalesApplicationTestBase (await AppService.PreOrderAsync(plan3.Id) .ShouldThrowAsync()) .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); - - var plan4 = await CreateFlashSalePlanAsync(useSku2: true); - (await AppService.PreOrderAsync(plan4.Id) - .ShouldThrowAsync()) - .Code.ShouldBe(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } [Fact]