using Microsoft.EntityFrameworkCore; using Tiku.Application.Commerce; using Tiku.Infrastructure.Security; namespace Tiku.Infrastructure.Commerce; internal sealed class CommerceOrderAdministrationService(CommerceAdministrationDependencies dependencies) : CommerceAdministrationServiceBase(dependencies), ICommerceOrderAdministrationService { public async Task GetOrdersAsync( CommerceAdminActor actor, CommerceAdminQuery query, CancellationToken cancellationToken = default) { await AssertAdminAsync(actor, cancellationToken); var scope = await RequireDataScopeAsync(actor, cancellationToken); var regionIds = scope.RegionIds.ToArray(); var orders = dbContext.Orders.AsNoTracking() .Where(item => item.TenantId == actor.TenantId) .ApplyDataScope( scope, item => item.UserId == actor.UserId, item => item.RegionId.HasValue && regionIds.Contains(item.RegionId.Value)); if (!string.IsNullOrWhiteSpace(query.Status)) orders = orders.Where(item => item.Status == ParseOrderStatus(query.Status)); var items = await orders .OrderByDescending(item => item.CreatedAt) .Take(Math.Clamp(query.Limit ?? 50, 1, 200)) .ToArrayAsync(cancellationToken); return new AdminOrderList(items.Select(ToOrderItem).ToArray()); } public async Task GetPaymentsAsync( CommerceAdminActor actor, CommerceAdminQuery query, CancellationToken cancellationToken = default) { await AssertAdminAsync(actor, cancellationToken); var scope = await RequireDataScopeAsync(actor, cancellationToken); var regionIds = scope.RegionIds.ToArray(); var scopedOrders = dbContext.Orders.AsNoTracking() .Where(order => order.TenantId == actor.TenantId) .ApplyDataScope( scope, order => order.UserId == actor.UserId, order => order.RegionId.HasValue && regionIds.Contains(order.RegionId.Value)); var payments = from payment in dbContext.Payments.AsNoTracking() join order in scopedOrders on new { payment.TenantId, payment.OrderId } equals new { order.TenantId, OrderId = order.Id } where payment.TenantId == actor.TenantId select new { payment, order.OrderNo }; if (!string.IsNullOrWhiteSpace(query.Provider)) { var provider = NormalizeProvider(query.Provider); payments = payments.Where(item => item.payment.Provider == provider); } if (!string.IsNullOrWhiteSpace(query.Status)) payments = payments.Where(item => item.payment.Status == ParsePaymentStatus(query.Status)); var rows = await payments .OrderByDescending(item => item.payment.CreatedAt) .Take(Math.Clamp(query.Limit ?? 50, 1, 200)) .ToArrayAsync(cancellationToken); return new AdminPaymentList(rows.Select(item => ToPaymentItem(item.payment, item.OrderNo)).ToArray()); } }