Browse Source

Use product cache item for flash-sales

pull/202/head
Jadyn 4 years ago
parent
commit
2fed214b26
  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<ProductCacheItem, Guid> ProductDistributedCache { get; }
protected IDistributedEventBus DistributedEventBus { get; }
protected IFlashSaleResultRepository FlashSaleResultRepository { get; }
@ -77,6 +79,7 @@ public class FlashSalePlanAppService :
IProductAppService productAppService,
IDistributedCache<FlashSalePlanPreOrderCacheItem> tokenDistributedCache,
IDistributedCache<FlashSalePlanCacheItem, Guid> planDistributedCache,
IDistributedCache<ProductCacheItem, Guid> 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<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.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<FlashSaleResult, FlashSaleResultDto>()
.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)
.ShouldThrowAsync<BusinessException>())
.Code.ShouldBe(FlashSalesErrorCodes.FlashSaleIsOver);
var plan4 = await CreateFlashSalePlanAsync(useSku2: true);
(await AppService.PreOrderAsync(plan4.Id)
.ShouldThrowAsync<BusinessException>())
.Code.ShouldBe(FlashSalesErrorCodes.ProductSkuInventoryExceeded);
}
[Fact]

Loading…
Cancel
Save