using MediatR; using TakeoutSaaS.Application.App.Orders.Dto; using TakeoutSaaS.Application.App.Orders.Queries; using TakeoutSaaS.Domain.Orders.Entities; using TakeoutSaaS.Domain.Orders.Enums; using TakeoutSaaS.Domain.Orders.Repositories; namespace TakeoutSaaS.Application.App.Orders.Handlers; /// /// 获取订单看板数据查询处理器。 /// public sealed class GetOrderBoardQueryHandler(IOrderRepository orderRepository) : IRequestHandler { /// public async Task Handle(GetOrderBoardQuery request, CancellationToken cancellationToken) { // 1. 查询活跃订单 var activeOrders = await orderRepository.GetActiveOrdersAsync( request.TenantId, request.StoreId, cancellationToken); // 2. 查询今日已完成订单(限 20 条) var todayStart = DateTime.UtcNow.Date; var completedOrders = await orderRepository.GetOrdersChangedSinceAsync( request.TenantId, request.StoreId, todayStart, cancellationToken); var todayCompleted = completedOrders .Where(o => o.Status == OrderStatus.Completed) .OrderByDescending(o => o.FinishedAt) .Take(20) .ToList(); // 3. 合并并按渠道筛选 var allOrders = activeOrders.Concat(todayCompleted).ToList(); if (request.Channel.HasValue) { allOrders = allOrders.Where(o => o.Channel == request.Channel.Value).ToList(); } // 4. 获取商品摘要 var orderIds = allOrders.Select(o => o.Id).ToList(); var itemsMap = orderIds.Count > 0 ? await orderRepository.GetItemsByOrderIdsAsync(orderIds, request.TenantId, cancellationToken) : new Dictionary>(); // 5. 按状态分组 var cards = allOrders.Select(o => MapToCard(o, itemsMap)).ToList(); return new OrderBoardResultDto { Pending = cards.Where(c => c.Status == OrderStatus.AwaitingPreparation) .OrderBy(c => c.CreatedAt).ToList(), Making = cards.Where(c => c.Status == OrderStatus.InProgress) .OrderBy(c => c.AcceptedAt).ToList(), Delivering = cards.Where(c => c.Status == OrderStatus.Ready) .OrderBy(c => c.ReadyAt).ToList(), Completed = cards.Where(c => c.Status == OrderStatus.Completed) .OrderByDescending(c => c.CreatedAt).ToList() }; } private static OrderBoardCardDto MapToCard( Order order, IReadOnlyDictionary> itemsMap) { var items = itemsMap.TryGetValue(order.Id, out var list) ? list : []; var summary = items.Count > 0 ? string.Join("、", items.Take(3).Select(x => x.ProductName)) + (items.Count > 3 ? $" 等{items.Count}件" : string.Empty) : string.Empty; return new OrderBoardCardDto { Id = order.Id, OrderNo = order.OrderNo, StoreId = order.StoreId, Channel = order.Channel, DeliveryType = order.DeliveryType, Status = order.Status, CustomerName = order.CustomerName, CustomerPhone = order.CustomerPhone, TableNo = order.TableNo, QueueNumber = order.QueueNumber, ItemsSummary = summary, PaidAmount = order.PaidAmount, CreatedAt = order.CreatedAt }; } }