Browse Source

Merge pull request #202 from EasyAbp/jadyn/flash-sales-product-cache

Use product cache item for flash-sales
pull/203/head
Super 4 years ago
committed by GitHub
parent
commit
1138d8c30b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs
  2. 5
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalesApplicationAutoMapperProfile.cs
  3. 46
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheInvalidator.cs
  4. 10
      plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Products/Products/ProductCacheItem.cs
  5. 5
      plugins/FlashSales/test/EasyAbp.EShop.Plugins.FlashSales.Application.Tests/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppServiceTests.cs

28
plugins/FlashSales/src/EasyAbp.EShop.Plugins.FlashSales.Application/EasyAbp/EShop/Plugins/FlashSales/FlashSalePlans/FlashSalePlanAppService.cs

@ -58,6 +58,8 @@ public class FlashSalePlanAppService :
protected IDistributedCache<FlashSalePlanCacheItem, Guid> PlanDistributedCache { get; } protected IDistributedCache<FlashSalePlanCacheItem, Guid> PlanDistributedCache { get; }
protected IDistributedCache<ProductCacheItem, Guid> ProductDistributedCache { get; }
protected IDistributedEventBus DistributedEventBus { get; } protected IDistributedEventBus DistributedEventBus { get; }
protected IFlashSaleResultRepository FlashSaleResultRepository { get; } protected IFlashSaleResultRepository FlashSaleResultRepository { get; }
@ -77,6 +79,7 @@ public class FlashSalePlanAppService :
IProductAppService productAppService, IProductAppService productAppService,
IDistributedCache<FlashSalePlanPreOrderCacheItem> tokenDistributedCache, IDistributedCache<FlashSalePlanPreOrderCacheItem> tokenDistributedCache,
IDistributedCache<FlashSalePlanCacheItem, Guid> planDistributedCache, IDistributedCache<FlashSalePlanCacheItem, Guid> planDistributedCache,
IDistributedCache<ProductCacheItem, Guid> productDistributedCache,
IDistributedEventBus distributedEventBus, IDistributedEventBus distributedEventBus,
IFlashSaleResultRepository flashSaleResultRepository, IFlashSaleResultRepository flashSaleResultRepository,
IAbpDistributedLock distributedLock, IAbpDistributedLock distributedLock,
@ -90,6 +93,7 @@ public class FlashSalePlanAppService :
ProductAppService = productAppService; ProductAppService = productAppService;
PreOrderDistributedCache = tokenDistributedCache; PreOrderDistributedCache = tokenDistributedCache;
PlanDistributedCache = planDistributedCache; PlanDistributedCache = planDistributedCache;
ProductDistributedCache = productDistributedCache;
DistributedEventBus = distributedEventBus; DistributedEventBus = distributedEventBus;
FlashSaleResultRepository = flashSaleResultRepository; FlashSaleResultRepository = flashSaleResultRepository;
DistributedLock = distributedLock; DistributedLock = distributedLock;
@ -213,7 +217,7 @@ public class FlashSalePlanAppService :
await CheckPolicyAsync(PreOrderPolicyName); await CheckPolicyAsync(PreOrderPolicyName);
var plan = await GetFlashSalePlanCacheAsync(id); 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 productSku = product.GetSkuById(plan.ProductSkuId);
var expiresTime = DateTimeOffset.Now.Add(Options.PreOrderExpires); var expiresTime = DateTimeOffset.Now.Add(Options.PreOrderExpires);
@ -381,11 +385,6 @@ public class FlashSalePlanAppService :
throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver);
} }
if (productSku.Inventory < 1)
{
throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded);
}
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -462,4 +461,21 @@ public class FlashSalePlanAppService :
return await FlashSaleResultRepository.InsertAsync(result, autoSave: true); return await FlashSaleResultRepository.InsertAsync(result, autoSave: true);
} }
protected virtual async Task<ProductCacheItem> GetProductCacheAsync(Guid productId)
{
return await ProductDistributedCache.GetOrAddAsync(productId, async () =>
{
var productDto = await ProductAppService.GetAsync(productId);
var cacheItem = ObjectMapper.Map<ProductDto, ProductCacheItem>(productDto);
if (cacheItem != null)
{
cacheItem.TenantId = CurrentTenant.Id;
}
return cacheItem;
});
}
} }

5
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.FlashSalePlans.Dtos;
using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults;
using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos; using EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.Dtos;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
namespace EasyAbp.EShop.Plugins.FlashSales; namespace EasyAbp.EShop.Plugins.FlashSales;
@ -24,5 +26,8 @@ public class FlashSalesApplicationAutoMapperProfile : Profile
CreateMap<FlashSaleResult, FlashSaleResultDto>() CreateMap<FlashSaleResult, FlashSaleResultDto>()
.MapExtraProperties(); .MapExtraProperties();
CreateMap<ProductDto, ProductCacheItem>(MemberList.Source)
.MapExtraProperties();
} }
} }

46
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<EntityUpdatedEto<ProductEto>>,
IDistributedEventHandler<EntityDeletedEto<ProductEto>>,
ITransientDependency
{
protected IDistributedCache<ProductCacheItem, Guid> DistributedCache { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
public ProductCacheInvalidator(
IDistributedCache<ProductCacheItem, Guid> distributedCache,
IUnitOfWorkManager unitOfWorkManager)
{
DistributedCache = distributedCache;
UnitOfWorkManager = unitOfWorkManager;
}
public virtual async Task HandleEventAsync(EntityUpdatedEto<ProductEto> eventData)
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
UnitOfWorkManager.Current.OnCompleted(async () =>
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
});
}
public virtual async Task HandleEventAsync(EntityDeletedEto<ProductEto> eventData)
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
UnitOfWorkManager.Current.OnCompleted(async () =>
{
await DistributedCache.RemoveAsync(eventData.Entity.Id);
});
}
}

10
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; }
}

5
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) (await AppService.PreOrderAsync(plan3.Id)
.ShouldThrowAsync<BusinessException>()) .ShouldThrowAsync<BusinessException>())
.Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver); .Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver);
var plan4 = await CreateFlashSalePlanAsync(useSku2: true);
(await AppService.PreOrderAsync(plan4.Id)
.ShouldThrowAsync<BusinessException>())
.Code.ShouldBe(FlashSalesErrorCodes.ProductSkuInventoryExceeded);
} }
[Fact] [Fact]

Loading…
Cancel
Save