using HoneyBox.Admin.Business.Models; using HoneyBox.Admin.Business.Models.Order; using HoneyBox.Admin.Business.Services.Interfaces; using HoneyBox.Model.Data; using HoneyBox.Model.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace HoneyBox.Admin.Business.Services; /// /// 订单管理服务实现 /// public class OrderService : IOrderService { private readonly HoneyBoxDbContext _dbContext; private readonly ILogger _logger; // 订单状态名称映射 private static readonly Dictionary OrderStatusNames = new() { { 0, "待支付" }, { 1, "已支付" }, { 2, "已取消" } }; // 支付方式名称映射 private static readonly Dictionary PayTypeNames = new() { { 0, "未支付" }, { 1, "微信支付" }, { 2, "支付宝" } }; // 发货状态名称映射 private static readonly Dictionary ShippingStatusNames = new() { { 0, "待支付" }, { 1, "待发货" }, { 2, "已发货" }, { 3, "已签收" }, { 4, "已取消" } }; // 物流状态名称映射 private static readonly Dictionary DeliveryStatusNames = new() { { -1, "未查询" }, { 0, "在途" }, { 1, "揽收" }, { 2, "疑难" }, { 3, "签收" }, { 4, "退签" }, { 5, "派件" }, { 6, "退回" } }; // 订单项状态名称映射 private static readonly Dictionary OrderItemStatusNames = new() { { 0, "待处理" }, { 1, "已回收" }, { 2, "已发货" } }; public OrderService( HoneyBoxDbContext dbContext, ILogger logger) { _dbContext = dbContext; _logger = logger; } #region 订单查询 /// public async Task> GetOrderListAsync(OrderListRequest request) { var query = _dbContext.Orders.AsNoTracking(); // 应用过滤条件(包含手机号过滤) query = await ApplyOrderFiltersWithMobileAsync(query, request); // 获取总数 var total = await query.CountAsync(); // 获取订单列表 var orders = await query .OrderByDescending(o => o.Id) .Skip(request.Skip) .Take(request.PageSize) .ToListAsync(); // 获取用户信息 var userIds = orders.Select(o => o.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 映射结果 var list = orders.Select(o => MapToOrderListResponse(o, users)).ToList(); return PagedResult.Create(list, total, request.Page, request.PageSize); } /// public async Task GetOrderDetailAsync(int orderId) { var order = await _dbContext.Orders .AsNoTracking() .FirstOrDefaultAsync(o => o.Id == orderId); if (order == null) { return null; } // 获取用户信息 var user = await _dbContext.Users .AsNoTracking() .FirstOrDefaultAsync(u => u.Id == order.UserId); // 获取订单项 var orderItems = await _dbContext.OrderItems .AsNoTracking() .Where(oi => oi.OrderId == orderId) .ToListAsync(); // 映射基本信息 var response = MapToOrderDetailResponse(order, user); // 按prize_code分组 response.PrizeGroups = GroupOrderItemsByPrizeCode(orderItems); return response; } /// public async Task> GetStuckOrdersAsync(OrderListRequest request) { // 卡单:有订单项但状态为待处理的订单 var query = _dbContext.Orders .AsNoTracking() .Where(o => o.Status == 1); // 已支付的订单 // 应用过滤条件 query = ApplyOrderFilters(query, request); // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(o => mobileUserIds.Contains(o.UserId)); } // 只获取有待处理订单项的订单 var ordersWithStuckItems = query .Where(o => _dbContext.OrderItems.Any(oi => oi.OrderId == o.Id && oi.Status == 0)); // 获取总数 var total = await ordersWithStuckItems.CountAsync(); // 获取订单列表 var orders = await ordersWithStuckItems .OrderByDescending(o => o.Id) .Skip(request.Skip) .Take(request.PageSize) .ToListAsync(); // 获取用户信息 var userIds = orders.Select(o => o.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 映射结果 var list = orders.Select(o => MapToOrderListResponse(o, users)).ToList(); return PagedResult.Create(list, total, request.Page, request.PageSize); } /// public async Task> GetRecoveryOrdersAsync(OrderListRequest request) { var query = _dbContext.OrderItemsRecoveries.AsNoTracking(); // 应用过滤条件 if (request.UserId.HasValue) { query = query.Where(r => r.UserId == request.UserId.Value); } if (request.StartDate.HasValue) { var startTimestamp = (int)((DateTimeOffset)request.StartDate.Value).ToUnixTimeSeconds(); query = query.Where(r => r.Addtime >= startTimestamp); } if (request.EndDate.HasValue) { var endTimestamp = (int)((DateTimeOffset)request.EndDate.Value.AddDays(1)).ToUnixTimeSeconds(); query = query.Where(r => r.Addtime < endTimestamp); } // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(r => mobileUserIds.Contains(r.UserId)); } // 获取总数 var total = await query.CountAsync(); // 获取回收订单列表 var recoveries = await query .OrderByDescending(r => r.Id) .Skip(request.Skip) .Take(request.PageSize) .ToListAsync(); // 获取用户信息 var userIds = recoveries.Select(r => r.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 获取回收的奖品信息 var recoveryNums = recoveries.Select(r => r.RecoveryNum).ToList(); var recoveryItems = await _dbContext.OrderItems .AsNoTracking() .Where(oi => oi.RecoveryNum != null && recoveryNums.Contains(oi.RecoveryNum)) .ToListAsync(); // 映射结果 var list = recoveries.Select(r => MapToRecoveryOrderResponse(r, users, recoveryItems)).ToList(); return PagedResult.Create(list, total, request.Page, request.PageSize); } #endregion #region 发货管理 /// public async Task> GetShippingOrdersAsync(ShippingOrderListRequest request) { var query = _dbContext.OrderItemsSends.AsNoTracking(); // 应用过滤条件(包含手机号过滤) query = await ApplyShippingFiltersWithMobileAsync(query, request); // 获取总数 var total = await query.CountAsync(); // 获取发货订单列表 var shippingOrders = await query .OrderByDescending(s => s.Id) .Skip(request.Skip) .Take(request.PageSize) .ToListAsync(); // 获取用户信息 var userIds = shippingOrders.Select(s => s.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 映射结果(不包含奖品详情) var list = shippingOrders.Select(s => MapToShippingOrderResponse(s, users, null)).ToList(); return PagedResult.Create(list, total, request.Page, request.PageSize); } /// public async Task GetShippingOrderDetailAsync(int sendId) { var shippingOrder = await _dbContext.OrderItemsSends .AsNoTracking() .FirstOrDefaultAsync(s => s.Id == sendId); if (shippingOrder == null) { return null; } // 获取用户信息 var user = await _dbContext.Users .AsNoTracking() .FirstOrDefaultAsync(u => u.Id == shippingOrder.UserId); // 获取发货的奖品信息 var shippingItems = await _dbContext.OrderItems .AsNoTracking() .Where(oi => oi.SendNum == shippingOrder.SendNum) .ToListAsync(); var users = user != null ? new Dictionary { { user.Id, user } } : new Dictionary(); return MapToShippingOrderResponse(shippingOrder, users, shippingItems); } /// public async Task ShipOrderAsync(int sendId, ShipOrderRequest request, int operatorId) { var shippingOrder = await _dbContext.OrderItemsSends .FirstOrDefaultAsync(s => s.Id == sendId); if (shippingOrder == null) { throw new BusinessException(BusinessErrorCodes.NotFound, "发货订单不存在"); } if (shippingOrder.Status != 1) { throw new BusinessException(BusinessErrorCodes.ValidationFailed, "只有待发货状态的订单才能发货"); } // 更新发货信息 shippingOrder.CourierName = request.CourierName; shippingOrder.CourierNumber = request.CourierNumber; shippingOrder.CourierCode = request.CourierCode; shippingOrder.Status = 2; // 已发货 shippingOrder.SendTime = (int)DateTimeOffset.Now.ToUnixTimeSeconds(); shippingOrder.AdminId = operatorId; shippingOrder.UpdatedAt = DateTime.Now; var result = await _dbContext.SaveChangesAsync() > 0; // 记录操作日志 await LogOrderOperationAsync(sendId, "ship", $"发货处理: SendNum={shippingOrder.SendNum}, Courier={request.CourierName}, Number={request.CourierNumber}", operatorId); _logger.LogInformation("发货处理成功: SendId={SendId}, SendNum={SendNum}, Operator={Operator}", sendId, shippingOrder.SendNum, operatorId); return result; } /// public async Task CancelShippingOrderAsync(int sendId, int operatorId) { var shippingOrder = await _dbContext.OrderItemsSends .FirstOrDefaultAsync(s => s.Id == sendId); if (shippingOrder == null) { throw new BusinessException(BusinessErrorCodes.NotFound, "发货订单不存在"); } if (shippingOrder.Status != 1 && shippingOrder.Status != 2) { throw new BusinessException(BusinessErrorCodes.ValidationFailed, "只有待发货或已发货状态的订单才能取消"); } // 获取发货的奖品 var shippingItems = await _dbContext.OrderItems .Where(oi => oi.SendNum == shippingOrder.SendNum) .ToListAsync(); // 恢复奖品到用户盒柜(将状态改回待处理) foreach (var item in shippingItems) { item.Status = 0; // 待处理 item.SendNum = null; item.FhStatus = 0; item.UpdatedAt = DateTime.Now; } // 更新发货订单状态 shippingOrder.Status = 4; // 已取消 shippingOrder.CancelTime = (int)DateTimeOffset.Now.ToUnixTimeSeconds(); shippingOrder.AdminId = operatorId; shippingOrder.UpdatedAt = DateTime.Now; var result = await _dbContext.SaveChangesAsync() > 0; // 记录操作日志 await LogOrderOperationAsync(sendId, "cancel_ship", $"取消发货: SendNum={shippingOrder.SendNum}, 恢复奖品数量={shippingItems.Count}", operatorId); _logger.LogInformation("取消发货成功: SendId={SendId}, SendNum={SendNum}, RestoredItems={RestoredItems}, Operator={Operator}", sendId, shippingOrder.SendNum, shippingItems.Count, operatorId); return result; } #endregion #region 订单导出 /// public async Task ExportOrdersAsync(OrderExportRequest request) { var query = _dbContext.Orders.AsNoTracking(); // 应用过滤条件 if (request.UserId.HasValue) { query = query.Where(o => o.UserId == request.UserId.Value); } if (!string.IsNullOrWhiteSpace(request.OrderNum)) { query = query.Where(o => o.OrderNum.Contains(request.OrderNum)); } if (request.StartDate.HasValue) { query = query.Where(o => o.CreatedAt >= request.StartDate.Value); } if (request.EndDate.HasValue) { var endDate = request.EndDate.Value.AddDays(1); query = query.Where(o => o.CreatedAt < endDate); } if (request.Status.HasValue) { query = query.Where(o => o.Status == request.Status.Value); } if (request.OrderType.HasValue) { query = query.Where(o => o.OrderType == request.OrderType.Value); } // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(o => mobileUserIds.Contains(o.UserId)); } // 获取订单数据 var orders = await query .OrderByDescending(o => o.Id) .Take(10000) // 限制导出数量 .ToListAsync(); // 获取用户信息 var userIds = orders.Select(o => o.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 映射导出数据 var exportData = orders.Select(o => MapToOrderExportDto(o, users)).ToList(); // 生成CSV格式(简单实现,可以替换为Excel库) return GenerateCsvBytes(exportData); } /// public async Task ExportShippingOrdersAsync(ShippingExportRequest request) { var query = _dbContext.OrderItemsSends.AsNoTracking(); // 应用过滤条件 if (request.UserId.HasValue) { query = query.Where(s => s.UserId == request.UserId.Value); } if (!string.IsNullOrWhiteSpace(request.SendNum)) { query = query.Where(s => s.SendNum.Contains(request.SendNum)); } if (request.StartDate.HasValue) { var startTimestamp = (int)((DateTimeOffset)request.StartDate.Value).ToUnixTimeSeconds(); query = query.Where(s => s.Addtime >= startTimestamp); } if (request.EndDate.HasValue) { var endTimestamp = (int)((DateTimeOffset)request.EndDate.Value.AddDays(1)).ToUnixTimeSeconds(); query = query.Where(s => s.Addtime < endTimestamp); } if (request.Status.HasValue) { query = query.Where(s => s.Status == request.Status.Value); } // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(s => mobileUserIds.Contains(s.UserId)); } // 获取发货订单数据 var shippingOrders = await query .OrderByDescending(s => s.Id) .Take(10000) // 限制导出数量 .ToListAsync(); // 获取用户信息 var userIds = shippingOrders.Select(s => s.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 映射导出数据 var exportData = shippingOrders.Select(s => MapToShippingExportDto(s, users)).ToList(); // 生成CSV格式 return GenerateShippingCsvBytes(exportData); } /// public async Task ExportRecoveryOrdersAsync(RecoveryExportRequest request) { var query = _dbContext.OrderItemsRecoveries.AsNoTracking(); // 应用过滤条件 if (request.UserId.HasValue) { query = query.Where(r => r.UserId == request.UserId.Value); } if (request.StartDate.HasValue) { var startTimestamp = (int)((DateTimeOffset)request.StartDate.Value).ToUnixTimeSeconds(); query = query.Where(r => r.Addtime >= startTimestamp); } if (request.EndDate.HasValue) { var endTimestamp = (int)((DateTimeOffset)request.EndDate.Value.AddDays(1)).ToUnixTimeSeconds(); query = query.Where(r => r.Addtime < endTimestamp); } // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(r => mobileUserIds.Contains(r.UserId)); } // 获取回收订单数据 var recoveryOrders = await query .OrderByDescending(r => r.Id) .Take(10000) // 限制导出数量 .ToListAsync(); // 获取用户信息 var userIds = recoveryOrders.Select(r => r.UserId).Distinct().ToList(); var users = await _dbContext.Users .AsNoTracking() .Where(u => userIds.Contains(u.Id)) .ToDictionaryAsync(u => u.Id); // 映射导出数据 var exportData = recoveryOrders.Select(r => MapToRecoveryExportDto(r, users)).ToList(); // 生成CSV格式 return GenerateRecoveryCsvBytes(exportData); } /// public async Task GetShippingStatsAsync(ShippingOrderListRequest request) { var query = _dbContext.OrderItemsSends.AsNoTracking(); // 应用过滤条件 query = ApplyShippingFilters(query, request); // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(s => mobileUserIds.Contains(s.UserId)); } // 获取总条数 var totalCount = await query.CountAsync(); // 获取所有发货单号 var sendNums = await query.Select(s => s.SendNum).ToListAsync(); // 计算总价值(所有发货奖品的价值总和) var totalValue = await _dbContext.OrderItems .AsNoTracking() .Where(oi => oi.SendNum != null && sendNums.Contains(oi.SendNum)) .SumAsync(oi => oi.GoodslistPrice); // 获取当前页的发货单号 var pageShippingOrders = await query .OrderByDescending(s => s.Id) .Skip(request.Skip) .Take(request.PageSize) .Select(s => s.SendNum) .ToListAsync(); // 计算本页总价值 var pageValue = await _dbContext.OrderItems .AsNoTracking() .Where(oi => oi.SendNum != null && pageShippingOrders.Contains(oi.SendNum)) .SumAsync(oi => oi.GoodslistPrice); return new ShippingStatsResponse { TotalCount = totalCount, TotalValue = totalValue, PageValue = pageValue }; } #endregion #region Private Helper Methods /// /// 应用订单过滤条件 /// private IQueryable ApplyOrderFilters(IQueryable query, OrderListRequest request) { if (request.UserId.HasValue) { query = query.Where(o => o.UserId == request.UserId.Value); } if (!string.IsNullOrWhiteSpace(request.OrderNum)) { query = query.Where(o => o.OrderNum.Contains(request.OrderNum)); } if (request.StartDate.HasValue) { query = query.Where(o => o.CreatedAt >= request.StartDate.Value); } if (request.EndDate.HasValue) { var endDate = request.EndDate.Value.AddDays(1); query = query.Where(o => o.CreatedAt < endDate); } if (request.Status.HasValue) { query = query.Where(o => o.Status == request.Status.Value); } if (request.OrderType.HasValue) { query = query.Where(o => o.OrderType == request.OrderType.Value); } return query; } /// /// 应用订单过滤条件(包含手机号过滤,异步版本) /// private async Task> ApplyOrderFiltersWithMobileAsync(IQueryable query, OrderListRequest request) { query = ApplyOrderFilters(query, request); // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(o => mobileUserIds.Contains(o.UserId)); } return query; } /// /// 应用发货订单过滤条件 /// private IQueryable ApplyShippingFilters(IQueryable query, ShippingOrderListRequest request) { if (request.UserId.HasValue) { query = query.Where(s => s.UserId == request.UserId.Value); } if (!string.IsNullOrWhiteSpace(request.SendNum)) { query = query.Where(s => s.SendNum.Contains(request.SendNum)); } if (request.StartDate.HasValue) { var startTimestamp = (int)((DateTimeOffset)request.StartDate.Value).ToUnixTimeSeconds(); query = query.Where(s => s.Addtime >= startTimestamp); } if (request.EndDate.HasValue) { var endTimestamp = (int)((DateTimeOffset)request.EndDate.Value.AddDays(1)).ToUnixTimeSeconds(); query = query.Where(s => s.Addtime < endTimestamp); } if (request.Status.HasValue) { query = query.Where(s => s.Status == request.Status.Value); } return query; } /// /// 应用发货订单过滤条件(包含手机号过滤,异步版本) /// private async Task> ApplyShippingFiltersWithMobileAsync(IQueryable query, ShippingOrderListRequest request) { query = ApplyShippingFilters(query, request); // 按手机号过滤需要关联用户表 if (!string.IsNullOrWhiteSpace(request.Mobile)) { var mobileUserIds = await _dbContext.Users .AsNoTracking() .Where(u => u.Mobile != null && u.Mobile.Contains(request.Mobile)) .Select(u => u.Id) .ToListAsync(); query = query.Where(s => mobileUserIds.Contains(s.UserId)); } return query; } /// /// 映射订单到列表响应 /// private OrderListResponse MapToOrderListResponse(Order order, Dictionary users) { users.TryGetValue(order.UserId, out var user); return new OrderListResponse { Id = order.Id, OrderNum = order.OrderNum, UserId = order.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, UserUid = user?.Uid, GoodsId = order.GoodsId, GoodsTitle = order.GoodsTitle, GoodsImgUrl = order.GoodsImgurl, OrderType = order.OrderType, OrderTotal = order.OrderTotal, Discount = order.Zhe, DiscountTotal = order.OrderZheTotal, WeChatPayment = order.Price, BalancePayment = order.UseMoney, IntegralPayment = order.UseIntegral, ScorePayment = order.UseScore, CouponPayment = order.UseCoupon, Num = order.Num, PrizeNum = order.PrizeNum, Status = order.Status, StatusName = OrderStatusNames.GetValueOrDefault(order.Status, "未知"), PayType = order.PayType, PayTypeName = PayTypeNames.GetValueOrDefault(order.PayType, "未知"), CreatedAt = order.CreatedAt, PayTime = order.PayTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(order.PayTime).LocalDateTime : null }; } /// /// 映射订单到详情响应 /// private OrderDetailResponse MapToOrderDetailResponse(Order order, User? user) { return new OrderDetailResponse { Id = order.Id, OrderNum = order.OrderNum, UserId = order.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, UserUid = user?.Uid, GoodsId = order.GoodsId, GoodsTitle = order.GoodsTitle, GoodsImgUrl = order.GoodsImgurl, OrderType = order.OrderType, OrderTotal = order.OrderTotal, Discount = order.Zhe, DiscountTotal = order.OrderZheTotal, WeChatPayment = order.Price, BalancePayment = order.UseMoney, IntegralPayment = order.UseIntegral, ScorePayment = order.UseScore, CouponPayment = order.UseCoupon, Num = order.Num, PrizeNum = order.PrizeNum, Status = order.Status, StatusName = OrderStatusNames.GetValueOrDefault(order.Status, "未知"), PayType = order.PayType, PayTypeName = PayTypeNames.GetValueOrDefault(order.PayType, "未知"), CreatedAt = order.CreatedAt, PayTime = order.PayTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(order.PayTime).LocalDateTime : null, PrizeGroups = new List() }; } /// /// 按prize_code分组订单项 /// private List GroupOrderItemsByPrizeCode(List orderItems) { return orderItems .GroupBy(oi => oi.PrizeCode ?? "UNKNOWN") .Select(g => new OrderPrizeGroupDto { PrizeCode = g.Key == "UNKNOWN" ? null : g.Key, Title = g.First().GoodslistTitle, ImgUrl = g.First().GoodslistImgurl, Price = g.First().GoodslistPrice, RecoveryMoney = g.First().GoodslistMoney, Count = g.Count(), GoodsType = g.First().GoodslistType, ShangId = g.First().ShangId, Items = g.Select(oi => new OrderPrizeItemDto { Id = oi.Id, Status = oi.Status, StatusName = OrderItemStatusNames.GetValueOrDefault(oi.Status, "未知"), RecoveryNum = oi.RecoveryNum, SendNum = oi.SendNum, LuckNo = oi.LuckNo, CreatedAt = oi.CreatedAt }).ToList() }) .ToList(); } /// /// 映射回收订单响应 /// private RecoveryOrderResponse MapToRecoveryOrderResponse(OrderItemsRecovery recovery, Dictionary users, List allRecoveryItems) { users.TryGetValue(recovery.UserId, out var user); var items = allRecoveryItems .Where(oi => oi.RecoveryNum == recovery.RecoveryNum) .Select(oi => new RecoveryPrizeDto { Id = oi.Id, PrizeCode = oi.PrizeCode, Title = oi.GoodslistTitle, ImgUrl = oi.GoodslistImgurl, Price = oi.GoodslistPrice, RecoveryMoney = oi.GoodslistMoney, GoodsType = oi.GoodslistType }) .ToList(); return new RecoveryOrderResponse { Id = recovery.Id, UserId = recovery.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, UserUid = user?.Uid, RecoveryNum = recovery.RecoveryNum, Money = recovery.Money, Count = recovery.Count, CreatedAt = recovery.CreatedAt, Prizes = items }; } /// /// 映射发货订单响应 /// private ShippingOrderResponse MapToShippingOrderResponse(OrderItemsSend shippingOrder, Dictionary users, List? shippingItems) { users.TryGetValue(shippingOrder.UserId, out var user); var prizes = shippingItems?.Select(oi => new ShippingPrizeDto { Id = oi.Id, PrizeCode = oi.PrizeCode, Title = oi.GoodslistTitle, ImgUrl = oi.GoodslistImgurl, Price = oi.GoodslistPrice, GoodsType = oi.GoodslistType }).ToList() ?? new List(); return new ShippingOrderResponse { Id = shippingOrder.Id, UserId = shippingOrder.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, UserUid = user?.Uid, SendNum = shippingOrder.SendNum, Freight = shippingOrder.Freight, Status = shippingOrder.Status, StatusName = ShippingStatusNames.GetValueOrDefault(shippingOrder.Status, "未知"), Count = shippingOrder.Count, Name = shippingOrder.Name, ReceiverMobile = shippingOrder.Mobile, Address = shippingOrder.Address, Message = shippingOrder.Message, CourierNumber = shippingOrder.CourierNumber, CourierName = shippingOrder.CourierName, CourierCode = shippingOrder.CourierCode, DeliveryStatus = shippingOrder.DeliveryStatus, DeliveryStatusName = DeliveryStatusNames.GetValueOrDefault(shippingOrder.DeliveryStatus, "未知"), CreatedAt = shippingOrder.CreatedAt, PayTime = shippingOrder.PayTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(shippingOrder.PayTime).LocalDateTime : null, SendTime = shippingOrder.SendTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(shippingOrder.SendTime).LocalDateTime : null, ReceiveTime = shippingOrder.ShouTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(shippingOrder.ShouTime).LocalDateTime : null, Prizes = prizes }; } /// /// 映射订单导出数据 /// private OrderExportDto MapToOrderExportDto(Order order, Dictionary users) { users.TryGetValue(order.UserId, out var user); return new OrderExportDto { OrderNum = order.OrderNum, UserId = order.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, GoodsTitle = order.GoodsTitle, OrderTotal = order.OrderTotal, DiscountTotal = order.OrderZheTotal, WeChatPayment = order.Price, BalancePayment = order.UseMoney, IntegralPayment = order.UseIntegral, ScorePayment = order.UseScore, CouponPayment = order.UseCoupon, Num = order.Num, PrizeNum = order.PrizeNum, StatusName = OrderStatusNames.GetValueOrDefault(order.Status, "未知"), PayTypeName = PayTypeNames.GetValueOrDefault(order.PayType, "未知"), CreatedAt = order.CreatedAt, PayTime = order.PayTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(order.PayTime).LocalDateTime : null }; } /// /// 生成CSV字节数组 /// private byte[] GenerateCsvBytes(List data) { var sb = new System.Text.StringBuilder(); // 添加表头 sb.AppendLine("订单编号,用户ID,用户昵称,用户手机号,商品标题,订单总金额,折后金额,微信支付,余额支付,积分支付,钻石支付,优惠券抵扣,购买数量,中奖数量,订单状态,支付方式,创建时间,支付时间"); // 添加数据行 foreach (var item in data) { sb.AppendLine($"{item.OrderNum},{item.UserId},{EscapeCsvField(item.UserNickname)},{item.UserMobile},{EscapeCsvField(item.GoodsTitle)},{item.OrderTotal},{item.DiscountTotal},{item.WeChatPayment},{item.BalancePayment},{item.IntegralPayment},{item.ScorePayment},{item.CouponPayment ?? 0},{item.Num},{item.PrizeNum},{item.StatusName},{item.PayTypeName},{item.CreatedAt:yyyy-MM-dd HH:mm:ss},{item.PayTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""}"); } // 使用UTF-8 BOM以支持中文 var preamble = System.Text.Encoding.UTF8.GetPreamble(); var content = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); var result = new byte[preamble.Length + content.Length]; preamble.CopyTo(result, 0); content.CopyTo(result, preamble.Length); return result; } /// /// 转义CSV字段 /// private string EscapeCsvField(string? field) { if (string.IsNullOrEmpty(field)) return ""; if (field.Contains(',') || field.Contains('"') || field.Contains('\n')) { return $"\"{field.Replace("\"", "\"\"")}\""; } return field; } /// /// 映射发货订单导出数据 /// private ShippingExportDto MapToShippingExportDto(OrderItemsSend shippingOrder, Dictionary users) { users.TryGetValue(shippingOrder.UserId, out var user); return new ShippingExportDto { SendNum = shippingOrder.SendNum, UserId = shippingOrder.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, Name = shippingOrder.Name, ReceiverMobile = shippingOrder.Mobile, Address = shippingOrder.Address, Count = shippingOrder.Count, Freight = shippingOrder.Freight, StatusName = ShippingStatusNames.GetValueOrDefault(shippingOrder.Status, "未知"), CourierName = shippingOrder.CourierName, CourierNumber = shippingOrder.CourierNumber, Message = shippingOrder.Message, CreatedAt = shippingOrder.CreatedAt, SendTime = shippingOrder.SendTime > 0 ? DateTimeOffset.FromUnixTimeSeconds(shippingOrder.SendTime).LocalDateTime : null }; } /// /// 映射回收订单导出数据 /// private RecoveryExportDto MapToRecoveryExportDto(OrderItemsRecovery recovery, Dictionary users) { users.TryGetValue(recovery.UserId, out var user); return new RecoveryExportDto { RecoveryNum = recovery.RecoveryNum, UserId = recovery.UserId, UserNickname = user?.Nickname, UserMobile = user?.Mobile, Money = recovery.Money, Count = recovery.Count, CreatedAt = recovery.CreatedAt }; } /// /// 生成发货订单CSV字节数组 /// private byte[] GenerateShippingCsvBytes(List data) { var sb = new System.Text.StringBuilder(); // 添加表头 sb.AppendLine("发货单号,用户ID,用户昵称,用户手机号,收货人,收货手机号,收货地址,发货数量,运费,状态,快递公司,快递单号,备注,创建时间,发货时间"); // 添加数据行 foreach (var item in data) { sb.AppendLine($"{item.SendNum},{item.UserId},{EscapeCsvField(item.UserNickname)},{item.UserMobile},{EscapeCsvField(item.Name)},{item.ReceiverMobile},{EscapeCsvField(item.Address)},{item.Count},{item.Freight},{item.StatusName},{EscapeCsvField(item.CourierName)},{item.CourierNumber},{EscapeCsvField(item.Message)},{item.CreatedAt:yyyy-MM-dd HH:mm:ss},{item.SendTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""}"); } // 使用UTF-8 BOM以支持中文 var preamble = System.Text.Encoding.UTF8.GetPreamble(); var content = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); var result = new byte[preamble.Length + content.Length]; preamble.CopyTo(result, 0); content.CopyTo(result, preamble.Length); return result; } /// /// 生成回收订单CSV字节数组 /// private byte[] GenerateRecoveryCsvBytes(List data) { var sb = new System.Text.StringBuilder(); // 添加表头 sb.AppendLine("回收单号,用户ID,用户昵称,用户手机号,回收金额,回收数量,创建时间"); // 添加数据行 foreach (var item in data) { sb.AppendLine($"{item.RecoveryNum},{item.UserId},{EscapeCsvField(item.UserNickname)},{item.UserMobile},{item.Money},{item.Count},{item.CreatedAt:yyyy-MM-dd HH:mm:ss}"); } // 使用UTF-8 BOM以支持中文 var preamble = System.Text.Encoding.UTF8.GetPreamble(); var content = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); var result = new byte[preamble.Length + content.Length]; preamble.CopyTo(result, 0); content.CopyTo(result, preamble.Length); return result; } /// /// 记录订单操作日志 /// private async Task LogOrderOperationAsync(int orderId, string operation, string content, int operatorId) { var log = new AdminOperationLog { AdminId = operatorId, Operation = $"order:{operation}", Content = $"OrderId={orderId}, {content}", Ip = string.Empty, CreatedAt = DateTime.Now }; _dbContext.AdminOperationLogs.Add(log); await _dbContext.SaveChangesAsync(); } #endregion }