feat: add mini ordering catalog and order APIs
All checks were successful
Build and Deploy MiniApi / build-and-deploy (push) Successful in 23s
All checks were successful
Build and Deploy MiniApi / build-and-deploy (push) Successful in 23s
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 分类摘要。
|
||||
/// </summary>
|
||||
public sealed class MiniCategoryDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public int Sort { get; init; }
|
||||
public int ProductCount { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 结算校验请求。
|
||||
/// </summary>
|
||||
public sealed class MiniCheckoutValidationRequest
|
||||
{
|
||||
public string StoreId { get; init; } = string.Empty;
|
||||
public string Scene { get; init; } = string.Empty;
|
||||
public string Channel { get; init; } = string.Empty;
|
||||
public IReadOnlyList<MiniOrderLineInput> Items { get; init; } = [];
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 结算校验结果。
|
||||
/// </summary>
|
||||
public sealed class MiniCheckoutValidationResponse
|
||||
{
|
||||
public bool Valid { get; init; }
|
||||
public string Message { get; init; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建订单请求。
|
||||
/// </summary>
|
||||
public sealed class MiniCreateOrderRequest
|
||||
{
|
||||
public string StoreId { get; init; } = string.Empty;
|
||||
public string Scene { get; init; } = string.Empty;
|
||||
public string Channel { get; init; } = string.Empty;
|
||||
public string? Remark { get; init; }
|
||||
public string? TableNo { get; init; }
|
||||
public IReadOnlyList<MiniOrderLineInput> Items { get; init; } = [];
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 创建订单结果。
|
||||
/// </summary>
|
||||
public sealed class MiniCreateOrderResponse
|
||||
{
|
||||
public string OrderId { get; init; } = string.Empty;
|
||||
public string OrderNo { get; init; } = string.Empty;
|
||||
public string StatusText { get; init; } = string.Empty;
|
||||
public string PaymentStatusText { get; init; } = string.Empty;
|
||||
public decimal PayableAmount { get; init; }
|
||||
public string PayableAmountText { get; init; } = "0.00";
|
||||
public bool MockPayAvailable { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 菜单分组。
|
||||
/// </summary>
|
||||
public sealed class MiniMenuSectionDto
|
||||
{
|
||||
public string CategoryId { get; init; } = string.Empty;
|
||||
public string CategoryName { get; init; } = string.Empty;
|
||||
public IReadOnlyList<MiniMenuProductDto> Products { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 菜单商品卡片。
|
||||
/// </summary>
|
||||
public sealed class MiniMenuProductDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string Description { get; init; } = string.Empty;
|
||||
public string CoverImageUrl { get; init; } = string.Empty;
|
||||
public decimal Price { get; init; }
|
||||
public string PriceText { get; init; } = "0.00";
|
||||
public decimal? OriginalPrice { get; init; }
|
||||
public string? OriginalPriceText { get; init; }
|
||||
public string SalesText { get; init; } = string.Empty;
|
||||
public IReadOnlyList<string> TagTexts { get; init; } = [];
|
||||
public bool SoldOut { get; init; }
|
||||
public bool HasOptions { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 模拟支付结果。
|
||||
/// </summary>
|
||||
public sealed class MiniMockPayResponse
|
||||
{
|
||||
public string OrderId { get; init; } = string.Empty;
|
||||
public string StatusText { get; init; } = string.Empty;
|
||||
public string PaymentStatusText { get; init; } = string.Empty;
|
||||
public decimal PaidAmount { get; init; }
|
||||
public string PaidAmountText { get; init; } = "0.00";
|
||||
public string SuccessTip { get; init; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 订单详情。
|
||||
/// </summary>
|
||||
public sealed class MiniOrderDetailDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string OrderNo { get; init; } = string.Empty;
|
||||
public string StoreId { get; init; } = string.Empty;
|
||||
public string StoreName { get; init; } = string.Empty;
|
||||
public string StatusText { get; init; } = string.Empty;
|
||||
public string PaymentStatusText { get; init; } = string.Empty;
|
||||
public string Scene { get; init; } = string.Empty;
|
||||
public string CustomerName { get; init; } = string.Empty;
|
||||
public string CustomerPhone { get; init; } = string.Empty;
|
||||
public string TableNo { get; init; } = string.Empty;
|
||||
public string Remark { get; init; } = string.Empty;
|
||||
public decimal ItemsAmount { get; init; }
|
||||
public decimal PackagingFee { get; init; }
|
||||
public decimal DeliveryFee { get; init; }
|
||||
public decimal DiscountAmount { get; init; }
|
||||
public decimal PayableAmount { get; init; }
|
||||
public decimal PaidAmount { get; init; }
|
||||
public string ItemSummary { get; init; } = string.Empty;
|
||||
public string CreatedAt { get; init; } = string.Empty;
|
||||
public string? PaidAt { get; init; }
|
||||
public string ActionText { get; init; } = string.Empty;
|
||||
public IReadOnlyList<MiniOrderItemDto> Items { get; init; } = [];
|
||||
public IReadOnlyList<MiniOrderTimelineDto> Timeline { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 订单商品明细。
|
||||
/// </summary>
|
||||
public sealed class MiniOrderItemDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string ProductId { get; init; } = string.Empty;
|
||||
public string ProductName { get; init; } = string.Empty;
|
||||
public string SkuName { get; init; } = string.Empty;
|
||||
public string Unit { get; init; } = string.Empty;
|
||||
public int Quantity { get; init; }
|
||||
public decimal UnitPrice { get; init; }
|
||||
public string UnitPriceText { get; init; } = "0.00";
|
||||
public decimal SubTotal { get; init; }
|
||||
public string SubTotalText { get; init; } = "0.00";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单时间线。
|
||||
/// </summary>
|
||||
public sealed class MiniOrderTimelineDto
|
||||
{
|
||||
public int Status { get; init; }
|
||||
public string StatusText { get; init; } = string.Empty;
|
||||
public string Notes { get; init; } = string.Empty;
|
||||
public string OccurredAt { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 结算行项目输入。
|
||||
/// </summary>
|
||||
public sealed class MiniOrderLineInput
|
||||
{
|
||||
public string ProductId { get; init; } = string.Empty;
|
||||
public string? SkuId { get; init; }
|
||||
public int Quantity { get; init; }
|
||||
public IReadOnlyList<string> AddonItemIds { get; init; } = [];
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 订单摘要。
|
||||
/// </summary>
|
||||
public sealed class MiniOrderSummaryDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string OrderNo { get; init; } = string.Empty;
|
||||
public string StoreName { get; init; } = string.Empty;
|
||||
public string StatusText { get; init; } = string.Empty;
|
||||
public string PaymentStatusText { get; init; } = string.Empty;
|
||||
public string Scene { get; init; } = string.Empty;
|
||||
public string ItemSummary { get; init; } = string.Empty;
|
||||
public decimal TotalAmount { get; init; }
|
||||
public string TotalAmountText { get; init; } = "0.00";
|
||||
public string CreatedAt { get; init; } = string.Empty;
|
||||
public string ActionText { get; init; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 金额试算请求。
|
||||
/// </summary>
|
||||
public sealed class MiniPriceEstimateRequest
|
||||
{
|
||||
public string StoreId { get; init; } = string.Empty;
|
||||
public string Scene { get; init; } = string.Empty;
|
||||
public string Channel { get; init; } = string.Empty;
|
||||
public IReadOnlyList<MiniOrderLineInput> Items { get; init; } = [];
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 金额试算结果。
|
||||
/// </summary>
|
||||
public sealed class MiniPriceEstimateResponse
|
||||
{
|
||||
public string StoreId { get; init; } = string.Empty;
|
||||
public string Scene { get; init; } = string.Empty;
|
||||
public int TotalCount { get; init; }
|
||||
public decimal OriginalAmount { get; init; }
|
||||
public string OriginalAmountText { get; init; } = "0.00";
|
||||
public decimal PackagingFee { get; init; }
|
||||
public string PackagingFeeText { get; init; } = "0.00";
|
||||
public decimal DeliveryFee { get; init; }
|
||||
public string DeliveryFeeText { get; init; } = "0.00";
|
||||
public decimal DiscountAmount { get; init; }
|
||||
public string DiscountAmountText { get; init; } = "0.00";
|
||||
public decimal PayableAmount { get; init; }
|
||||
public string PayableAmountText { get; init; } = "0.00";
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 商品详情。
|
||||
/// </summary>
|
||||
public sealed class MiniProductDetailDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string StoreId { get; init; } = string.Empty;
|
||||
public string CategoryId { get; init; } = string.Empty;
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string Subtitle { get; init; } = string.Empty;
|
||||
public string Description { get; init; } = string.Empty;
|
||||
public string CoverImageUrl { get; init; } = string.Empty;
|
||||
public IReadOnlyList<string> GalleryImages { get; init; } = [];
|
||||
public string Unit { get; init; } = string.Empty;
|
||||
public decimal BasePrice { get; init; }
|
||||
public string BasePriceText { get; init; } = "0.00";
|
||||
public decimal? OriginalPrice { get; init; }
|
||||
public string? OriginalPriceText { get; init; }
|
||||
public bool SoldOut { get; init; }
|
||||
public int MonthlySales { get; init; }
|
||||
public IReadOnlyList<string> TagTexts { get; init; } = [];
|
||||
public string? DefaultSkuId { get; init; }
|
||||
public IReadOnlyList<MiniProductSkuDto> Skus { get; init; } = [];
|
||||
public IReadOnlyList<MiniProductOptionGroupDto> OptionGroups { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 商品 SKU。
|
||||
/// </summary>
|
||||
public sealed class MiniProductSkuDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public decimal Price { get; init; }
|
||||
public string PriceText { get; init; } = "0.00";
|
||||
public decimal? OriginalPrice { get; init; }
|
||||
public string? OriginalPriceText { get; init; }
|
||||
public int? StockQuantity { get; init; }
|
||||
public bool SoldOut { get; init; }
|
||||
public IReadOnlyList<string> SelectedOptionIds { get; init; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 商品选项分组。
|
||||
/// </summary>
|
||||
public sealed class MiniProductOptionGroupDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string GroupType { get; init; } = string.Empty;
|
||||
public string SelectionType { get; init; } = string.Empty;
|
||||
public bool Required { get; init; }
|
||||
public int MinSelect { get; init; }
|
||||
public int MaxSelect { get; init; }
|
||||
public IReadOnlyList<MiniProductOptionDto> Options { get; init; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 商品选项。
|
||||
/// </summary>
|
||||
public sealed class MiniProductOptionDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public decimal ExtraPrice { get; init; }
|
||||
public string ExtraPriceText { get; init; } = "0.00";
|
||||
public bool SoldOut { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 门店摘要。
|
||||
/// </summary>
|
||||
public sealed class MiniStoreSummaryDto
|
||||
{
|
||||
public string Id { get; init; } = string.Empty;
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string Address { get; init; } = string.Empty;
|
||||
public string BusinessHours { get; init; } = string.Empty;
|
||||
public IReadOnlyList<string> Supports { get; init; } = [];
|
||||
public IReadOnlyList<string> TagTexts { get; init; } = [];
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using TakeoutSaaS.Application.App.Mini.Contracts;
|
||||
|
||||
namespace TakeoutSaaS.Application.App.Mini;
|
||||
|
||||
/// <summary>
|
||||
/// 小程序真实业务服务抽象。
|
||||
/// </summary>
|
||||
public interface IMiniAppService
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询可选门店。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MiniStoreSummaryDto>> GetStoresAsync(long tenantId, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 查询门店分类。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MiniCategoryDto>> GetCategoriesAsync(long tenantId, string storeId, string scene, string channel, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 查询门店菜单。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MiniMenuSectionDto>> GetMenuAsync(long tenantId, string storeId, string scene, string channel, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 查询商品详情。
|
||||
/// </summary>
|
||||
Task<MiniProductDetailDto?> GetProductDetailAsync(long tenantId, string productId, string scene, string channel, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 试算订单金额。
|
||||
/// </summary>
|
||||
Task<MiniPriceEstimateResponse> EstimatePriceAsync(long tenantId, MiniPriceEstimateRequest request, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 校验结算请求。
|
||||
/// </summary>
|
||||
Task<MiniCheckoutValidationResponse> ValidateCheckoutAsync(long tenantId, MiniCheckoutValidationRequest request, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 查询顾客订单列表。
|
||||
/// </summary>
|
||||
Task<IReadOnlyList<MiniOrderSummaryDto>> GetOrdersAsync(long tenantId, string customerPhone, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 查询顾客订单详情。
|
||||
/// </summary>
|
||||
Task<MiniOrderDetailDto?> GetOrderDetailAsync(long tenantId, string orderId, string customerPhone, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 创建订单。
|
||||
/// </summary>
|
||||
Task<MiniCreateOrderResponse> CreateOrderAsync(long tenantId, string customerName, string customerPhone, MiniCreateOrderRequest request, CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 模拟支付。
|
||||
/// </summary>
|
||||
Task<MiniMockPayResponse> MockPayAsync(long tenantId, string orderId, string customerPhone, CancellationToken cancellationToken = default);
|
||||
}
|
||||
Reference in New Issue
Block a user