feat: 订单商品查询支持tenantId可选过滤

This commit is contained in:
2026-01-29 12:14:43 +00:00
parent 7661c2aea1
commit 63b05da39a
13 changed files with 166 additions and 46 deletions

View File

@@ -1,9 +1,7 @@
using MediatR;
using TakeoutSaaS.Application.App.Products.Dto;
using TakeoutSaaS.Application.App.Products.Queries;
using TakeoutSaaS.Domain.Products.Entities;
using TakeoutSaaS.Domain.Products.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Application.App.Products.Handlers;
@@ -11,18 +9,15 @@ namespace TakeoutSaaS.Application.App.Products.Handlers;
/// 商品详情查询处理器。
/// </summary>
public sealed class GetProductByIdQueryHandler(
IProductRepository productRepository,
ITenantProvider tenantProvider)
IProductRepository productRepository)
: IRequestHandler<GetProductByIdQuery, ProductDto?>
{
private readonly IProductRepository _productRepository = productRepository;
private readonly ITenantProvider _tenantProvider = tenantProvider;
/// <inheritdoc />
public async Task<ProductDto?> Handle(GetProductByIdQuery request, CancellationToken cancellationToken)
{
var tenantId = _tenantProvider.GetCurrentTenantId();
var product = await _productRepository.FindByIdAsync(request.ProductId, tenantId, cancellationToken);
// 1. 查询商品(跨租户)
var product = await productRepository.FindByIdAsync(request.ProductId, cancellationToken);
// 2. (空行后) 映射并返回
return product == null ? null : ProductMapping.ToDto(product);
}
}

View File

@@ -2,7 +2,6 @@ using MediatR;
using TakeoutSaaS.Application.App.Products.Dto;
using TakeoutSaaS.Application.App.Products.Queries;
using TakeoutSaaS.Domain.Products.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Application.App.Products.Handlers;
@@ -10,22 +9,21 @@ namespace TakeoutSaaS.Application.App.Products.Handlers;
/// 商品全量详情查询处理器。
/// </summary>
public sealed class GetProductDetailQueryHandler(
IProductRepository productRepository,
ITenantProvider tenantProvider)
IProductRepository productRepository)
: IRequestHandler<GetProductDetailQuery, ProductDetailDto?>
{
/// <inheritdoc />
public async Task<ProductDetailDto?> Handle(GetProductDetailQuery request, CancellationToken cancellationToken)
{
// 1. 读取 SPU
var tenantId = tenantProvider.GetCurrentTenantId();
var product = await productRepository.FindByIdAsync(request.ProductId, tenantId, cancellationToken);
// 1. 读取 SPU(跨租户)
var product = await productRepository.FindByIdAsync(request.ProductId, cancellationToken);
if (product is null)
{
return null;
}
// 2. 查询子项
// 2. (空行后) 读取租户并查询子项
var tenantId = product.TenantId;
var skusTask = productRepository.GetSkusAsync(product.Id, tenantId, cancellationToken);
var attrGroupsTask = productRepository.GetAttributeGroupsAsync(product.Id, tenantId, cancellationToken);
var attrOptionsTask = productRepository.GetAttributeOptionsAsync(product.Id, tenantId, cancellationToken);
@@ -36,7 +34,7 @@ public sealed class GetProductDetailQueryHandler(
await Task.WhenAll(skusTask, attrGroupsTask, attrOptionsTask, addonGroupsTask, addonOptionsTask, mediaTask, pricingTask);
// 3. 组装 DTO
// 3. (空行后) 组装 DTO
var skus = await skusTask;
var attrGroups = await attrGroupsTask;
var attrOptions = (await attrOptionsTask).ToLookup(x => x.AttributeGroupId);

View File

@@ -3,7 +3,6 @@ using TakeoutSaaS.Application.App.Products.Dto;
using TakeoutSaaS.Application.App.Products.Queries;
using TakeoutSaaS.Domain.Products.Repositories;
using TakeoutSaaS.Shared.Abstractions.Results;
using TakeoutSaaS.Shared.Abstractions.Tenancy;
namespace TakeoutSaaS.Application.App.Products.Handlers;
@@ -11,25 +10,28 @@ namespace TakeoutSaaS.Application.App.Products.Handlers;
/// 商品列表查询处理器。
/// </summary>
public sealed class SearchProductsQueryHandler(
IProductRepository productRepository,
ITenantProvider tenantProvider)
IProductRepository productRepository)
: IRequestHandler<SearchProductsQuery, PagedResult<ProductDto>>
{
private readonly IProductRepository _productRepository = productRepository;
private readonly ITenantProvider _tenantProvider = tenantProvider;
/// <inheritdoc />
public async Task<PagedResult<ProductDto>> Handle(SearchProductsQuery request, CancellationToken cancellationToken)
{
var tenantId = _tenantProvider.GetCurrentTenantId();
var products = await _productRepository.SearchAsync(tenantId, request.StoreId, request.CategoryId, request.Status, cancellationToken);
// 1. 查询商品列表(可选租户过滤)
var products = await productRepository.SearchAsync(
request.TenantId,
request.StoreId,
request.CategoryId,
request.Status,
cancellationToken);
// 2. (空行后) 排序与分页
var sorted = ApplySorting(products, request.SortBy, request.SortDescending);
var paged = sorted
.Skip((request.Page - 1) * request.PageSize)
.Take(request.PageSize)
.ToList();
// 3. (空行后) 映射 DTO 并返回分页结果
var items = paged.Select(MapToDto).ToList();
return new PagedResult<ProductDto>(items, request.Page, request.PageSize, products.Count);
}

View File

@@ -10,6 +10,11 @@ namespace TakeoutSaaS.Application.App.Products.Queries;
/// </summary>
public sealed class SearchProductsQuery : IRequest<PagedResult<ProductDto>>
{
/// <summary>
/// 租户 ID可选空表示跨租户查询
/// </summary>
public long? TenantId { get; init; }
/// <summary>
/// 门店 ID可选
/// </summary>