feat: 菜品菜单查询与子资源替换完善
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TakeoutSaaS.Domain.Products.Entities;
|
||||
@@ -27,7 +28,7 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<Product>> SearchAsync(long tenantId, long? storeId, long? categoryId, ProductStatus? status, CancellationToken cancellationToken = default)
|
||||
public async Task<IReadOnlyList<Product>> SearchAsync(long tenantId, long? storeId, long? categoryId, ProductStatus? status, CancellationToken cancellationToken = default, DateTime? updatedAfter = null)
|
||||
{
|
||||
var query = context.Products
|
||||
.AsNoTracking()
|
||||
@@ -48,6 +49,11 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
query = query.Where(x => x.Status == status.Value);
|
||||
}
|
||||
|
||||
if (updatedAfter.HasValue)
|
||||
{
|
||||
query = query.Where(x => (x.UpdatedAt ?? x.CreatedAt) >= updatedAfter.Value);
|
||||
}
|
||||
|
||||
var products = await query
|
||||
.OrderBy(x => x.Name)
|
||||
.ToListAsync(cancellationToken);
|
||||
@@ -67,6 +73,22 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return categories;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductCategory>> GetCategoriesByStoreAsync(long tenantId, long storeId, bool onlyEnabled = true, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = context.ProductCategories
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && x.StoreId == storeId);
|
||||
if (onlyEnabled)
|
||||
{
|
||||
query = query.Where(x => x.IsEnabled);
|
||||
}
|
||||
var categories = await query
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return categories;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductSku>> GetSkusAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -79,6 +101,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return skus;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductSku>> GetSkusByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (productIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductSku>();
|
||||
}
|
||||
var skus = await context.ProductSkus
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && productIds.Contains(x.ProductId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return skus;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAddonGroup>> GetAddonGroupsAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -91,6 +128,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return groups;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAddonGroup>> GetAddonGroupsByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (productIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductAddonGroup>();
|
||||
}
|
||||
var groups = await context.ProductAddonGroups
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && productIds.Contains(x.ProductId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return groups;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAddonOption>> GetAddonOptionsAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -114,6 +166,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAddonOption>> GetAddonOptionsByGroupIdsAsync(IReadOnlyCollection<long> addonGroupIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (addonGroupIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductAddonOption>();
|
||||
}
|
||||
var options = await context.ProductAddonOptions
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && addonGroupIds.Contains(x.AddonGroupId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAttributeGroup>> GetAttributeGroupsAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -126,6 +193,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return groups;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAttributeGroup>> GetAttributeGroupsByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (productIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductAttributeGroup>();
|
||||
}
|
||||
var groups = await context.ProductAttributeGroups
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && productIds.Contains(x.ProductId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return groups;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAttributeOption>> GetAttributeOptionsAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -149,6 +231,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductAttributeOption>> GetAttributeOptionsByGroupIdsAsync(IReadOnlyCollection<long> attributeGroupIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (attributeGroupIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductAttributeOption>();
|
||||
}
|
||||
var options = await context.ProductAttributeOptions
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && attributeGroupIds.Contains(x.AttributeGroupId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductMediaAsset>> GetMediaAssetsAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -161,6 +258,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return assets;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductMediaAsset>> GetMediaAssetsByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (productIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductMediaAsset>();
|
||||
}
|
||||
var assets = await context.ProductMediaAssets
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && productIds.Contains(x.ProductId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return assets;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductPricingRule>> GetPricingRulesAsync(long productId, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -173,6 +285,21 @@ public sealed class EfProductRepository(TakeoutAppDbContext context) : IProductR
|
||||
return rules;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IReadOnlyList<ProductPricingRule>> GetPricingRulesByProductIdsAsync(IReadOnlyCollection<long> productIds, long tenantId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (productIds.Count == 0)
|
||||
{
|
||||
return Array.Empty<ProductPricingRule>();
|
||||
}
|
||||
var rules = await context.ProductPricingRules
|
||||
.AsNoTracking()
|
||||
.Where(x => x.TenantId == tenantId && productIds.Contains(x.ProductId))
|
||||
.OrderBy(x => x.SortOrder)
|
||||
.ToListAsync(cancellationToken);
|
||||
return rules;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task AddCategoryAsync(ProductCategory category, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user