diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/ServiceProviders/UserBasketProvider.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/ServiceProviders/UserBasketProvider.cs index fd8f5b61..6dba255a 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/ServiceProviders/UserBasketProvider.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/ServiceProviders/UserBasketProvider.cs @@ -11,23 +11,20 @@ namespace EShopOnAbp.PublicWeb.ServiceProviders { public class UserBasketProvider : ITransientDependency { - protected HttpContext HttpContext => httpContextAccessor.HttpContext; + private HttpContext HttpContext => _httpContextAccessor.HttpContext; - private readonly IHttpContextAccessor httpContextAccessor; - protected readonly ILogger logger; - protected readonly IBasketAppService basketAppService; - protected readonly ICurrentUser currentUser; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ILogger _logger; + private readonly IBasketAppService _basketAppService; public UserBasketProvider( IHttpContextAccessor httpContextAccessor, ILogger logger, - IBasketAppService basketAppService, - ICurrentUser currentUser) + IBasketAppService basketAppService) { - this.httpContextAccessor = httpContextAccessor; - this.logger = logger; - this.basketAppService = basketAppService; - this.currentUser = currentUser; + _httpContextAccessor = httpContextAccessor; + _logger = logger; + _basketAppService = basketAppService; } public virtual async Task GetBasketAsync() @@ -38,26 +35,11 @@ namespace EShopOnAbp.PublicWeb.ServiceProviders HttpContext.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName, out string anonymousUserId); - if (!currentUser.IsAuthenticated) - { - logger.LogInformation($"Getting basket for anonymous user id:{anonymousUserId}."); - return await basketAppService.GetByAnonymousUserIdAsync(Guid.Parse(anonymousUserId)); - } - - //TODO: Merge with anonymously stored cart if exist - var userClaimValue = currentUser.FindClaimValue(EShopConstants.AnonymousUserClaimName); - - // Fall-back for having trouble when setting claim on user login - if (string.IsNullOrEmpty(userClaimValue)) - { - return await basketAppService.GetAsync(); - } - - return await basketAppService.MergeBasketsAsync(); + return await _basketAppService.GetAsync(Guid.Parse(anonymousUserId)); } catch (Exception ex) { - logger.LogError(ex, ex.Message); + _logger.LogError(ex, ex.Message); return null; } } diff --git a/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs b/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs index cc8d89b6..6515ddbf 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs @@ -6,9 +6,7 @@ namespace EShopOnAbp.BasketService; public interface IBasketAppService : IApplicationService { - Task GetAsync(); - Task GetByAnonymousUserIdAsync(Guid id); - Task MergeBasketsAsync(); + Task GetAsync(Guid? anonymousUserId); Task AddProductAsync(AddProductDto input); Task RemoveProductAsync(RemoveProductDto input); } \ No newline at end of file diff --git a/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs b/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs index a621a2c4..4858d8c8 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs @@ -2,12 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; using Volo.Abp.Users; using EShopOnAbp.CatalogService.Products; -using Microsoft.Extensions.Logging; using Volo.Abp; -using Volo.Abp.EventBus.Distributed; namespace EShopOnAbp.BasketService; @@ -15,59 +12,37 @@ public class BasketAppService : BasketServiceAppService, IBasketAppService { private readonly IBasketRepository _basketRepository; private readonly IBasketProductService _basketProductService; - private readonly IDistributedEventBus _distributedEventBus; public BasketAppService( IBasketRepository basketRepository, - IBasketProductService basketProductService, - IDistributedEventBus distributedEventBus) + IBasketProductService basketProductService) { _basketRepository = basketRepository; _basketProductService = basketProductService; - _distributedEventBus = distributedEventBus; } - public async Task GetAsync() + public async Task GetAsync(Guid? anonymousUserId) { - var basket = await _basketRepository.GetAsync(CurrentUser.GetId()); - return await GetBasketDtoAsync(basket); - } + if (anonymousUserId != null && CurrentUser.IsAuthenticated) + { + var userBasket = await _basketRepository.GetAsync(CurrentUser.GetId()); + var anonymousUserBasket = await _basketRepository.GetAsync(anonymousUserId.Value); - public async Task GetByAnonymousUserIdAsync(Guid id) - { - var basket = await _basketRepository.GetAsync(id); - return await GetBasketDtoAsync(basket); - } + userBasket.Merge(anonymousUserBasket); + await _basketRepository.UpdateAsync(userBasket); - public async Task MergeBasketsAsync() - { - //TODO: move to custom shared project - var anonymousUserIdString = CurrentUser.FindClaimValue("anonymous_id"); - - if (!Guid.TryParse(anonymousUserIdString, out Guid anonymousUserId)) - { - Logger.LogError($"Couldn't parse anonymous Id from claim!{anonymousUserIdString}"); - } + anonymousUserBasket.Clear(); + await _basketRepository.UpdateAsync(anonymousUserBasket); - Basket anonymousUserBasket = await _basketRepository.GetAsync(anonymousUserId); - if (!CurrentUser.IsAuthenticated) - { - Logger.LogWarning($"User is not authenticated! Merging baskets failed!"); - return await GetBasketDtoAsync(anonymousUserBasket); + return await GetBasketDtoAsync(userBasket); } - var userBasket = await _basketRepository.GetAsync(CurrentUser.GetId()); - - foreach (var item in anonymousUserBasket.Items) + if (anonymousUserId != null && !CurrentUser.IsAuthenticated) { - userBasket.AddProduct(item.ProductId, item.Count); + return await GetBasketDtoAsync(await _basketRepository.GetAsync(anonymousUserId.Value)); } - await _basketRepository.UpdateAsync(userBasket); - anonymousUserBasket.Clear(); - await _basketRepository.UpdateAsync(anonymousUserBasket); - - return await GetBasketDtoAsync(userBasket); + return await GetBasketDtoAsync(await _basketRepository.GetAsync(CurrentUser.GetId())); } public async Task AddProductAsync(AddProductDto input) diff --git a/services/basket/src/EShopOnAbp.BasketService.Domain/Basket.cs b/services/basket/src/EShopOnAbp.BasketService.Domain/Basket.cs index 30fd4abb..bafb2a90 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Domain/Basket.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Domain/Basket.cs @@ -11,7 +11,6 @@ public class Basket : AggregateRoot private Basket() { - } public Basket(Guid id) @@ -70,4 +69,12 @@ public class Basket : AggregateRoot { Items.Clear(); } + + public void Merge(Basket basket) + { + foreach (var item in basket.Items) + { + AddProduct(item.ProductId, item.Count); + } + } } \ No newline at end of file diff --git a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs index 5c819286..5bb60e34 100644 --- a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs +++ b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs @@ -9,44 +9,33 @@ using Volo.Abp.Http.Client.ClientProxying; using EShopOnAbp.BasketService; // ReSharper disable once CheckNamespace -namespace EShopOnAbp.BasketService.ClientProxies +namespace EShopOnAbp.BasketService.ClientProxies; + +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(IBasketAppService), typeof(BasketClientProxy))] +public partial class BasketClientProxy : ClientProxyBase, IBasketAppService { - [Dependency(ReplaceServices = true)] - [ExposeServices(typeof(IBasketAppService), typeof(BasketClientProxy))] - public partial class BasketClientProxy : ClientProxyBase, IBasketAppService + public virtual async Task GetAsync(Guid? anonymousUserId) { - public virtual async Task GetAsync() - { - return await RequestAsync(nameof(GetAsync)); - } - - public virtual async Task GetByAnonymousUserIdAsync(Guid id) - { - return await RequestAsync(nameof(GetByAnonymousUserIdAsync), new ClientProxyRequestTypeValue - { - { typeof(Guid), id } - }); - } - - public virtual async Task MergeBasketsAsync() + return await RequestAsync(nameof(GetAsync), new ClientProxyRequestTypeValue { - return await RequestAsync(nameof(MergeBasketsAsync)); - } + { typeof(Guid?), anonymousUserId } + }); + } - public virtual async Task AddProductAsync(AddProductDto input) + public virtual async Task AddProductAsync(AddProductDto input) + { + return await RequestAsync(nameof(AddProductAsync), new ClientProxyRequestTypeValue { - return await RequestAsync(nameof(AddProductAsync), new ClientProxyRequestTypeValue - { - { typeof(AddProductDto), input } - }); - } + { typeof(AddProductDto), input } + }); + } - public virtual async Task RemoveProductAsync(RemoveProductDto input) + public virtual async Task RemoveProductAsync(RemoveProductDto input) + { + return await RequestAsync(nameof(RemoveProductAsync), new ClientProxyRequestTypeValue { - return await RequestAsync(nameof(RemoveProductAsync), new ClientProxyRequestTypeValue - { - { typeof(RemoveProductDto), input } - }); - } + { typeof(RemoveProductDto), input } + }); } } diff --git a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.cs b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.cs index f491624c..222238f4 100644 --- a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.cs +++ b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.cs @@ -1,8 +1,7 @@ // This file is part of BasketClientProxy, you can customize it here // ReSharper disable once CheckNamespace -namespace EShopOnAbp.BasketService.ClientProxies +namespace EShopOnAbp.BasketService.ClientProxies; + +public partial class BasketClientProxy { - public partial class BasketClientProxy - { - } } diff --git a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/basket-generate-proxy.json b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/basket-generate-proxy.json index 964d0384..901caad0 100644 --- a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/basket-generate-proxy.json +++ b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/basket-generate-proxy.json @@ -23,48 +23,33 @@ } ], "actions": { - "GetAsync": { - "uniqueName": "GetAsync", + "GetAsyncByAnonymousUserId": { + "uniqueName": "GetAsyncByAnonymousUserId", "name": "GetAsync", "httpMethod": "GET", "url": "api/basket/basket", "supportedVersions": [], - "parametersOnMethod": [], - "parameters": [], - "returnValue": { - "type": "EShopOnAbp.BasketService.BasketDto", - "typeSimple": "EShopOnAbp.BasketService.BasketDto" - }, - "allowAnonymous": null, - "implementFrom": "EShopOnAbp.BasketService.IBasketAppService" - }, - "GetByAnonymousUserIdAsyncById": { - "uniqueName": "GetByAnonymousUserIdAsyncById", - "name": "GetByAnonymousUserIdAsync", - "httpMethod": "GET", - "url": "api/basket/basket/{id}/by-anonymous-user-id", - "supportedVersions": [], "parametersOnMethod": [ { - "name": "id", - "typeAsString": "System.Guid, System.Private.CoreLib", - "type": "System.Guid", - "typeSimple": "string", + "name": "anonymousUserId", + "typeAsString": "System.Nullable`1[[System.Guid, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib", + "type": "System.Guid?", + "typeSimple": "string?", "isOptional": false, "defaultValue": null } ], "parameters": [ { - "nameOnMethod": "id", - "name": "id", + "nameOnMethod": "anonymousUserId", + "name": "anonymousUserId", "jsonName": null, - "type": "System.Guid", - "typeSimple": "string", + "type": "System.Guid?", + "typeSimple": "string?", "isOptional": false, "defaultValue": null, - "constraintTypes": [], - "bindingSourceId": "Path", + "constraintTypes": null, + "bindingSourceId": "ModelBinding", "descriptorName": "" } ], @@ -75,21 +60,6 @@ "allowAnonymous": null, "implementFrom": "EShopOnAbp.BasketService.IBasketAppService" }, - "MergeBasketsAsync": { - "uniqueName": "MergeBasketsAsync", - "name": "MergeBasketsAsync", - "httpMethod": "POST", - "url": "api/basket/basket/merge-baskets", - "supportedVersions": [], - "parametersOnMethod": [], - "parameters": [], - "returnValue": { - "type": "EShopOnAbp.BasketService.BasketDto", - "typeSimple": "EShopOnAbp.BasketService.BasketDto" - }, - "allowAnonymous": null, - "implementFrom": "EShopOnAbp.BasketService.IBasketAppService" - }, "AddProductAsyncByInput": { "uniqueName": "AddProductAsyncByInput", "name": "AddProductAsync", @@ -187,21 +157,6 @@ }, "allowAnonymous": null, "implementFrom": "EShopOnAbp.BasketService.IBasketAppService" - }, - "PurchaseAsync": { - "uniqueName": "PurchaseAsync", - "name": "PurchaseAsync", - "httpMethod": "POST", - "url": "api/basket/basket/purchase", - "supportedVersions": [], - "parametersOnMethod": [], - "parameters": [], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - }, - "allowAnonymous": null, - "implementFrom": "EShopOnAbp.BasketService.IBasketAppService" } } }