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
}