feat(product): add product schedule management api
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 46s

This commit is contained in:
2026-02-21 11:46:55 +08:00
parent ad65ef3bf6
commit d41f69045f
21 changed files with 9760 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
using TakeoutSaaS.Shared.Abstractions.Entities;
namespace TakeoutSaaS.Domain.Products.Entities;
/// <summary>
/// 商品时段规则(门店维度)。
/// </summary>
public sealed class ProductSchedule : MultiTenantEntityBase
{
/// <summary>
/// 所属门店。
/// </summary>
public long StoreId { get; set; }
/// <summary>
/// 规则名称。
/// </summary>
public string Name { get; set; } = string.Empty;
/// <summary>
/// 开始时间。
/// </summary>
public TimeSpan StartTime { get; set; }
/// <summary>
/// 结束时间。
/// </summary>
public TimeSpan EndTime { get; set; }
/// <summary>
/// 星期位掩码(周一到周日)。
/// </summary>
public int WeekDaysMask { get; set; }
/// <summary>
/// 是否启用。
/// </summary>
public bool IsEnabled { get; set; } = true;
}

View File

@@ -0,0 +1,24 @@
using TakeoutSaaS.Shared.Abstractions.Entities;
namespace TakeoutSaaS.Domain.Products.Entities;
/// <summary>
/// 时段规则与商品关联关系。
/// </summary>
public sealed class ProductScheduleProduct : MultiTenantEntityBase
{
/// <summary>
/// 所属门店。
/// </summary>
public long StoreId { get; set; }
/// <summary>
/// 时段规则 ID。
/// </summary>
public long ScheduleId { get; set; }
/// <summary>
/// 商品 ID。
/// </summary>
public long ProductId { get; set; }
}

View File

@@ -58,6 +58,11 @@ public interface IProductRepository
/// </summary>
Task<IReadOnlyList<ProductLabel>> GetLabelsByStoreAsync(long tenantId, long storeId, CancellationToken cancellationToken = default);
/// <summary>
/// 按门店读取商品时段规则。
/// </summary>
Task<IReadOnlyList<ProductSchedule>> GetSchedulesByStoreAsync(long tenantId, long storeId, CancellationToken cancellationToken = default);
/// <summary>
/// 依据标识读取规格做法模板。
/// </summary>
@@ -73,6 +78,11 @@ public interface IProductRepository
/// </summary>
Task<ProductLabel?> FindLabelByIdAsync(long labelId, long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 依据标识读取商品时段规则。
/// </summary>
Task<ProductSchedule?> FindScheduleByIdAsync(long scheduleId, long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 判断门店内模板名称是否已存在。
/// </summary>
@@ -88,6 +98,11 @@ public interface IProductRepository
/// </summary>
Task<bool> ExistsLabelNameAsync(long tenantId, long storeId, string name, long? excludeLabelId = null, CancellationToken cancellationToken = default);
/// <summary>
/// 判断门店内时段规则名称是否已存在。
/// </summary>
Task<bool> ExistsScheduleNameAsync(long tenantId, long storeId, string name, long? excludeScheduleId = null, CancellationToken cancellationToken = default);
/// <summary>
/// 按模板读取规格做法选项。
/// </summary>
@@ -103,6 +118,11 @@ public interface IProductRepository
/// </summary>
Task<Dictionary<long, int>> CountLabelProductsByLabelIdsAsync(long tenantId, long storeId, IReadOnlyCollection<long> labelIds, CancellationToken cancellationToken = default);
/// <summary>
/// 读取时段规则关联商品。
/// </summary>
Task<IReadOnlyList<ProductScheduleProduct>> GetScheduleProductsByScheduleIdsAsync(IReadOnlyCollection<long> scheduleIds, long tenantId, long storeId, CancellationToken cancellationToken = default);
/// <summary>
/// 过滤门店内真实存在的商品 ID。
/// </summary>
@@ -245,6 +265,16 @@ public interface IProductRepository
/// </summary>
Task AddLabelAsync(ProductLabel label, CancellationToken cancellationToken = default);
/// <summary>
/// 新增时段规则。
/// </summary>
Task AddScheduleAsync(ProductSchedule schedule, CancellationToken cancellationToken = default);
/// <summary>
/// 新增时段规则关联商品。
/// </summary>
Task AddScheduleProductsAsync(IEnumerable<ProductScheduleProduct> relations, CancellationToken cancellationToken = default);
/// <summary>
/// 新增商品。
/// </summary>
@@ -337,6 +367,11 @@ public interface IProductRepository
/// </summary>
Task UpdateLabelAsync(ProductLabel label, CancellationToken cancellationToken = default);
/// <summary>
/// 更新时段规则。
/// </summary>
Task UpdateScheduleAsync(ProductSchedule schedule, CancellationToken cancellationToken = default);
/// <summary>
/// 删除分类。
/// </summary>
@@ -356,6 +391,11 @@ public interface IProductRepository
/// </summary>
Task DeleteLabelAsync(long labelId, long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 删除时段规则。
/// </summary>
Task DeleteScheduleAsync(long scheduleId, long tenantId, CancellationToken cancellationToken = default);
/// <summary>
/// 删除商品下的 SKU。
/// </summary>
@@ -380,6 +420,11 @@ public interface IProductRepository
/// </summary>
Task RemoveLabelProductsAsync(long labelId, long tenantId, long storeId, CancellationToken cancellationToken = default);
/// <summary>
/// 删除时段规则关联商品。
/// </summary>
Task RemoveScheduleProductsAsync(long scheduleId, long tenantId, long storeId, CancellationToken cancellationToken = default);
/// <summary>
/// 删除商品下的加料组及选项。
/// </summary>