From 53bf517224d4b4b5d2c603c55d462f2f1dbc0607 Mon Sep 17 00:00:00 2001 From: hello Date: Wed, 20 Nov 2024 08:04:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20CQRS=20=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=20Query=20=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AutoMapper/OrdersMapConfiguration.cs | 13 ++++++ .../Controllers/OrdersController.cs | 25 ++++++++++- .../Extensions/Extensions.cs | 3 ++ .../HelloShop.OrderingService.http | 12 +++++- .../Queries/IOrderQueries.cs | 12 ++++++ .../Queries/OrderDetails.cs | 28 +++++++++++++ .../Queries/OrderDetailsItem.cs | 18 ++++++++ .../Queries/OrderQueries.cs | 41 +++++++++++++++++++ .../Queries/OrderSummary.cs | 14 +++++++ 9 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 src/HelloShop.OrderingService/Queries/IOrderQueries.cs create mode 100644 src/HelloShop.OrderingService/Queries/OrderDetails.cs create mode 100644 src/HelloShop.OrderingService/Queries/OrderDetailsItem.cs create mode 100644 src/HelloShop.OrderingService/Queries/OrderQueries.cs create mode 100644 src/HelloShop.OrderingService/Queries/OrderSummary.cs diff --git a/src/HelloShop.OrderingService/AutoMapper/OrdersMapConfiguration.cs b/src/HelloShop.OrderingService/AutoMapper/OrdersMapConfiguration.cs index 0ac190b..5948c6d 100644 --- a/src/HelloShop.OrderingService/AutoMapper/OrdersMapConfiguration.cs +++ b/src/HelloShop.OrderingService/AutoMapper/OrdersMapConfiguration.cs @@ -5,6 +5,7 @@ using AutoMapper; using HelloShop.OrderingService.Commands.Orders; using HelloShop.OrderingService.Entities.Orders; using HelloShop.OrderingService.Models.Orders; +using HelloShop.OrderingService.Queries; namespace HelloShop.OrderingService.AutoMapper { @@ -16,6 +17,18 @@ namespace HelloShop.OrderingService.AutoMapper CreateMap().ForMember(dest => dest.Units, opt => opt.MapFrom(src => src.Quantity)); CreateMap(); CreateMap(); + + CreateMap().ForMember(dest => dest.OrderId, opt => opt.MapFrom(src => src.Id)).ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.OrderStatus)); + CreateMap() + .ForMember(dest => dest.OrderId, opt => opt.MapFrom(src => src.Id)) + .ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.OrderStatus)) + .ForMember(dest => dest.Country, opt => opt.MapFrom(src => src.Address.Country)) + .ForMember(dest => dest.State, opt => opt.MapFrom(src => src.Address.State)) + .ForMember(dest => dest.City, opt => opt.MapFrom(src => src.Address.City)) + .ForMember(dest => dest.Street, opt => opt.MapFrom(src => src.Address.Street)) + .ForMember(dest => dest.ZipCode, opt => opt.MapFrom(src => src.Address.ZipCode)); + + CreateMap(); } } } diff --git a/src/HelloShop.OrderingService/Controllers/OrdersController.cs b/src/HelloShop.OrderingService/Controllers/OrdersController.cs index bc40e14..6fb28e8 100644 --- a/src/HelloShop.OrderingService/Controllers/OrdersController.cs +++ b/src/HelloShop.OrderingService/Controllers/OrdersController.cs @@ -5,6 +5,7 @@ using AutoMapper; using HelloShop.OrderingService.Commands; using HelloShop.OrderingService.Commands.Orders; using HelloShop.OrderingService.Models.Orders; +using HelloShop.OrderingService.Queries; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -62,7 +63,6 @@ public class OrdersController(ILogger logger, IMediator mediat } } - [HttpPut("Cancel/{id}")] public async Task CancelOrder([FromHeader(Name = "x-request-id")] Guid requestId, int id) { @@ -96,4 +96,27 @@ public class OrdersController(ILogger logger, IMediator mediat return Ok(); } + + [HttpGet] + public async Task GetOrders([FromServices] IOrderQueries orderQueries) + { + string? nameIdentifier = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + + if (!int.TryParse(nameIdentifier, out int userId)) + { + throw new ApplicationException("User id not found in claims."); + } + + IEnumerable orders = await orderQueries.GetOrdersFromUserAsync(userId); + + return Ok(orders); + } + + [HttpGet("{id}")] + public async Task GetOrder(int id, [FromServices] IOrderQueries orderQueries) + { + OrderDetails order = await orderQueries.GetOrderAsync(id); + + return Ok(order); + } } diff --git a/src/HelloShop.OrderingService/Extensions/Extensions.cs b/src/HelloShop.OrderingService/Extensions/Extensions.cs index d09af82..ca32352 100644 --- a/src/HelloShop.OrderingService/Extensions/Extensions.cs +++ b/src/HelloShop.OrderingService/Extensions/Extensions.cs @@ -4,6 +4,7 @@ using HelloShop.OrderingService.Behaviors; using HelloShop.OrderingService.Constants; using HelloShop.OrderingService.Infrastructure; +using HelloShop.OrderingService.Queries; using HelloShop.OrderingService.Services; using HelloShop.OrderingService.Workers; using HelloShop.ServiceDefaults.DistributedEvents.Abstractions; @@ -48,6 +49,8 @@ namespace HelloShop.OrderingService.Extensions options.AddOpenBehavior(typeof(TransactionBehavior<,>)); }); + builder.Services.AddScoped(); + builder.Services.AddModelMapper().AddModelValidator(); builder.Services.AddTransient().AddTransient(); diff --git a/src/HelloShop.OrderingService/HelloShop.OrderingService.http b/src/HelloShop.OrderingService/HelloShop.OrderingService.http index 628abfe..900eb89 100644 --- a/src/HelloShop.OrderingService/HelloShop.OrderingService.http +++ b/src/HelloShop.OrderingService/HelloShop.OrderingService.http @@ -34,4 +34,14 @@ Authorization : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwi ] } -### \ No newline at end of file +### + +GET {{HelloShop.OrderingService_HostAddress}}/api/orders +Content-Type: application/json +Authorization : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsInJvbGVpZCI6IjEiLCJuYmYiOjE3MjA1NzY3NDYsImV4cCI6MTc0MjYwODc0NiwiaWF0IjoxNzIwNTc2NzQ2fQ.ju_D3zeGLKqJYVckbb8Y3yNkp40nOqRAJrdOsISs4d4 + +### + +GET {{HelloShop.OrderingService_HostAddress}}/api/orders/1 +Content-Type: application/json +Authorization : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsInJvbGVpZCI6IjEiLCJuYmYiOjE3MjA1NzY3NDYsImV4cCI6MTc0MjYwODc0NiwiaWF0IjoxNzIwNTc2NzQ2fQ.ju_D3zeGLKqJYVckbb8Y3yNkp40nOqRAJrdOsISs4d4 diff --git a/src/HelloShop.OrderingService/Queries/IOrderQueries.cs b/src/HelloShop.OrderingService/Queries/IOrderQueries.cs new file mode 100644 index 0000000..b9177b1 --- /dev/null +++ b/src/HelloShop.OrderingService/Queries/IOrderQueries.cs @@ -0,0 +1,12 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +namespace HelloShop.OrderingService.Queries +{ + public interface IOrderQueries + { + Task GetOrderAsync(int id); + + Task> GetOrdersFromUserAsync(int userId); + } +} diff --git a/src/HelloShop.OrderingService/Queries/OrderDetails.cs b/src/HelloShop.OrderingService/Queries/OrderDetails.cs new file mode 100644 index 0000000..289d853 --- /dev/null +++ b/src/HelloShop.OrderingService/Queries/OrderDetails.cs @@ -0,0 +1,28 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +namespace HelloShop.OrderingService.Queries +{ + public class OrderDetails + { + public int OrderId { get; init; } + + public required string Status { get; init; } + + public DateTimeOffset OrderDate { get; init; } + + public required string Country { get; init; } + + public required string State { get; init; } + + public required string City { get; init; } + + public required string Street { get; init; } + + public required string ZipCode { get; init; } + + public string? Description { get; init; } + + public required List OrderItems { get; set; } + } +} \ No newline at end of file diff --git a/src/HelloShop.OrderingService/Queries/OrderDetailsItem.cs b/src/HelloShop.OrderingService/Queries/OrderDetailsItem.cs new file mode 100644 index 0000000..763d11e --- /dev/null +++ b/src/HelloShop.OrderingService/Queries/OrderDetailsItem.cs @@ -0,0 +1,18 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +namespace HelloShop.OrderingService.Queries +{ + public class OrderDetailsItem + { + public int ProductId { get; init; } + + public required string ProductName { get; init; } + + public int Units { get; init; } + + public double UnitPrice { get; init; } + + public required string PictureUrl { get; init; } + } +} \ No newline at end of file diff --git a/src/HelloShop.OrderingService/Queries/OrderQueries.cs b/src/HelloShop.OrderingService/Queries/OrderQueries.cs new file mode 100644 index 0000000..0893b21 --- /dev/null +++ b/src/HelloShop.OrderingService/Queries/OrderQueries.cs @@ -0,0 +1,41 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +using AutoMapper; +using HelloShop.OrderingService.Constants; +using HelloShop.OrderingService.Entities.Orders; +using HelloShop.OrderingService.Infrastructure; +using Microsoft.EntityFrameworkCore; + +namespace HelloShop.OrderingService.Queries +{ + public class OrderQueries : IOrderQueries + { + private readonly OrderingServiceDbContext _dbContext; + + private readonly IMapper _mapper; + + public OrderQueries(OrderingServiceDbContext dbContext, IMapper mapper, IConfiguration configuration) + { + _dbContext = dbContext; + // TODO:Provide the AddKeyedDbContext extension method on Services at https://github.com/dotnet/efcore/issues/34591 + dbContext.Database.SetConnectionString(configuration.GetConnectionString(DbConstants.SlaveConnectionStringName)); + _mapper = mapper; + } + + public async Task GetOrderAsync(int id) + { + var order = await _dbContext.Set().AsNoTracking().Include(o => o.OrderItems).SingleOrDefaultAsync(o => o.Id == id); + var orderDetails = _mapper.Map(order); + + return orderDetails; + } + + public async Task> GetOrdersFromUserAsync(int userId) + { + var orders = await _dbContext.Set().AsNoTracking().Where(o => o.BuyerId == userId).ToListAsync(); + var orderSummaries = _mapper.Map>(orders); + return orderSummaries; + } + } +} diff --git a/src/HelloShop.OrderingService/Queries/OrderSummary.cs b/src/HelloShop.OrderingService/Queries/OrderSummary.cs new file mode 100644 index 0000000..be0e134 --- /dev/null +++ b/src/HelloShop.OrderingService/Queries/OrderSummary.cs @@ -0,0 +1,14 @@ +// Copyright (c) HelloShop Corporation. All rights reserved. +// See the license file in the project root for more information. + +namespace HelloShop.OrderingService.Queries +{ + public class OrderSummary + { + public int OrderId { get; init; } + + public required string Status { get; init; } + + public DateTimeOffset OrderDate { get; init; } + } +}