using HoneyBox.Admin.Business.Models.Statistics; using HoneyBox.Admin.Business.Services.Interfaces; using HoneyBox.Model.Data; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace HoneyBox.Admin.Business.Services; /// /// 统计服务实现 /// public class StatisticsService : IStatisticsService { private readonly HoneyBoxDbContext _dbContext; private readonly ILogger _logger; public StatisticsService(HoneyBoxDbContext dbContext, ILogger logger) { _dbContext = dbContext; _logger = logger; } /// /// 获取今日订单统计数据 /// public async Task GetTodayOrderStatsAsync() { var today = DateTime.Today; var tomorrow = today.AddDays(1); // 排除测试用户的订单 var todayOrdersQuery = _dbContext.Orders .Where(o => o.CreatedAt >= today && o.CreatedAt < tomorrow) .Join(_dbContext.Users.Where(u => u.IsTest == 0), o => o.UserId, u => u.Id, (o, u) => o); // 今日已支付订单查询 var todayPaidOrdersQuery = todayOrdersQuery.Where(o => o.Status == 1); // 发起订单数(今日创建的订单总数) var initiateOrderCount = await todayOrdersQuery.CountAsync(); // 支付订单数(今日支付成功的订单数) var paidOrderCount = await todayPaidOrdersQuery.CountAsync(); // 消费人数(今日有消费的用户数,去重) var userCount = await todayPaidOrdersQuery .Select(o => o.UserId) .Distinct() .CountAsync(); // 订单总金额(今日订单折后总金额) var orderZheTotal = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.OrderZheTotal) ?? 0; // 出货总金额(今日出货奖品总价值)- 从订单详情表获取 var goodsTotalAmount = await _dbContext.OrderItems .Where(oi => oi.CreatedAt >= today && oi.CreatedAt < tomorrow) .Join(_dbContext.Users.Where(u => u.IsTest == 0), oi => oi.UserId, u => u.Id, (oi, u) => oi) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; // 优惠券抵扣(今日优惠券抵扣总额) var useCoupon = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.UseCoupon) ?? 0; // RMB支付(今日微信支付总额) var price = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.Price) ?? 0; // 钻石支付(今日钻石支付总额) var useMoney = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.UseMoney) ?? 0; // UU币支付(今日UU币支付总额) var useIntegral = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.UseIntegral) ?? 0; // 达达券支付(今日达达券支付总额) var useMoney2 = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.UseMoney2) ?? 0; return new TodayOrderStatsResponse { InitiateOrderCount = initiateOrderCount, PaidOrderCount = paidOrderCount, UserCount = userCount, OrderZheTotal = orderZheTotal, GoodsTotalAmount = goodsTotalAmount, UseCoupon = useCoupon, Price = price, UseMoney = useMoney, UseIntegral = useIntegral, UseMoney2 = useMoney2 }; } /// /// 获取货币信息统计数据 /// public async Task GetCurrencyInfoStatsAsync() { var today = DateTime.Today; var tomorrow = today.AddDays(1); var yesterday = today.AddDays(-1); // 排除测试用户 var nonTestUserIds = _dbContext.Users .Where(u => u.IsTest == 0) .Select(u => u.Id); // 钻石流水查询(ProfitMoney表) var todayMoneyQuery = _dbContext.ProfitMoneys .Where(p => p.CreatedAt >= today && p.CreatedAt < tomorrow) .Where(p => nonTestUserIds.Contains(p.UserId)); var yesterdayMoneyQuery = _dbContext.ProfitMoneys .Where(p => p.CreatedAt >= yesterday && p.CreatedAt < today) .Where(p => nonTestUserIds.Contains(p.UserId)); // 今日发放钻石(ChangeMoney > 0) var todayAddMoney = await todayMoneyQuery .Where(p => p.ChangeMoney > 0) .SumAsync(p => (decimal?)p.ChangeMoney) ?? 0; // 今日消费钻石(ChangeMoney < 0,取绝对值) var todayUseMoney = await todayMoneyQuery .Where(p => p.ChangeMoney < 0) .SumAsync(p => (decimal?)(-p.ChangeMoney)) ?? 0; // 昨日发放钻石 var yesterdayAddMoney = await yesterdayMoneyQuery .Where(p => p.ChangeMoney > 0) .SumAsync(p => (decimal?)p.ChangeMoney) ?? 0; // 昨日消费钻石 var yesterdayUseMoney = await yesterdayMoneyQuery .Where(p => p.ChangeMoney < 0) .SumAsync(p => (decimal?)(-p.ChangeMoney)) ?? 0; // UU币流水查询(ProfitIntegral表) var todayIntegralQuery = _dbContext.ProfitIntegrals .Where(p => p.CreatedAt >= today && p.CreatedAt < tomorrow) .Where(p => nonTestUserIds.Contains(p.UserId)); var yesterdayIntegralQuery = _dbContext.ProfitIntegrals .Where(p => p.CreatedAt >= yesterday && p.CreatedAt < today) .Where(p => nonTestUserIds.Contains(p.UserId)); // 今日发放UU币 var todayAddIntegral = await todayIntegralQuery .Where(p => p.ChangeMoney > 0) .SumAsync(p => (decimal?)p.ChangeMoney) ?? 0; // 今日消费UU币 var todayUseIntegral = await todayIntegralQuery .Where(p => p.ChangeMoney < 0) .SumAsync(p => (decimal?)(-p.ChangeMoney)) ?? 0; // 昨日发放UU币 var yesterdayAddIntegral = await yesterdayIntegralQuery .Where(p => p.ChangeMoney > 0) .SumAsync(p => (decimal?)p.ChangeMoney) ?? 0; // 昨日消费UU币 var yesterdayUseIntegral = await yesterdayIntegralQuery .Where(p => p.ChangeMoney < 0) .SumAsync(p => (decimal?)(-p.ChangeMoney)) ?? 0; // 达达券流水查询(ProfitMoney2表) var todayMoney2Query = _dbContext.ProfitMoney2s .Where(p => p.CreatedAt >= today && p.CreatedAt < tomorrow) .Where(p => nonTestUserIds.Contains(p.UserId)); var yesterdayMoney2Query = _dbContext.ProfitMoney2s .Where(p => p.CreatedAt >= yesterday && p.CreatedAt < today) .Where(p => nonTestUserIds.Contains(p.UserId)); // 今日发放达达券 var todayAddMoney2 = await todayMoney2Query .Where(p => p.ChangeMoney > 0) .SumAsync(p => (decimal?)p.ChangeMoney) ?? 0; // 今日消费达达券 var todayUseMoney2 = await todayMoney2Query .Where(p => p.ChangeMoney < 0) .SumAsync(p => (decimal?)(-p.ChangeMoney)) ?? 0; // 昨日发放达达券 var yesterdayAddMoney2 = await yesterdayMoney2Query .Where(p => p.ChangeMoney > 0) .SumAsync(p => (decimal?)p.ChangeMoney) ?? 0; // 昨日消费达达券 var yesterdayUseMoney2 = await yesterdayMoney2Query .Where(p => p.ChangeMoney < 0) .SumAsync(p => (decimal?)(-p.ChangeMoney)) ?? 0; return new CurrencyInfoStatsResponse { TodayAddMoney = todayAddMoney, TodayUseMoney = todayUseMoney, YesterdayAddMoney = yesterdayAddMoney, YesterdayUseMoney = yesterdayUseMoney, TodayAddIntegral = todayAddIntegral, TodayUseIntegral = todayUseIntegral, YesterdayAddIntegral = yesterdayAddIntegral, YesterdayUseIntegral = yesterdayUseIntegral, TodayAddMoney2 = todayAddMoney2, TodayUseMoney2 = todayUseMoney2, YesterdayAddMoney2 = yesterdayAddMoney2, YesterdayUseMoney2 = yesterdayUseMoney2 }; } /// /// 获取收入汇总统计数据 /// public async Task GetIncomeSummaryStatsAsync() { var today = DateTime.Today; var tomorrow = today.AddDays(1); // 排除测试用户 var nonTestUserIds = _dbContext.Users .Where(u => u.IsTest == 0) .Select(u => u.Id); // 今日已支付订单查询(排除测试用户) var todayPaidOrdersQuery = _dbContext.Orders .Where(o => o.CreatedAt >= today && o.CreatedAt < tomorrow && o.Status == 1) .Where(o => nonTestUserIds.Contains(o.UserId)); // RMB收入(今日微信支付总额) var rmbIncome = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.Price) ?? 0; // 钻石支付收入 var diamondPayment = await todayPaidOrdersQuery .SumAsync(o => (decimal?)o.UseMoney) ?? 0; // 订单收入(RMB + 钻石) var todayIncome = rmbIncome + diamondPayment; // 钻石商城收入(今日钻石商城已支付订单) var diamondIncome = await _dbContext.DiamondOrders .Where(d => d.CreatedAt >= today && d.CreatedAt < tomorrow && d.Status == "paid") .Where(d => nonTestUserIds.Contains((int)d.UserId)) .SumAsync(d => (decimal?)d.AmountPaid) ?? 0; // 其他收入(暂时设为0,可根据实际业务扩展) var otherIncome = 0m; // 订单出货(今日出货奖品总价值)- 从订单详情表获取 var shippedToday = await _dbContext.OrderItems .Where(oi => oi.CreatedAt >= today && oi.CreatedAt < tomorrow) .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; // 支出(暂时设为0,可根据实际业务扩展) var expenses = 0m; // 当天发货金额(今日申请发货的奖品总价值,status=2表示已发货) var todayShippedAmount = await _dbContext.OrderItems .Where(oi => oi.CreatedAt >= today && oi.CreatedAt < tomorrow && oi.Status == 2) .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; // 当天用户剩余达达券(所有非测试用户的达达券余额总和) var remainingCoupon = await _dbContext.Users .Where(u => u.IsTest == 0) .SumAsync(u => (decimal?)u.Money2) ?? 0; // 盒柜剩余价值(今日用户盒柜中奖品总价值,status=0表示待处理) var boxRemaining = await _dbContext.OrderItems .Where(oi => oi.Status == 0) .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; // 利润计算:收入 - 发货金额 - 用户剩余达达券 - 盒柜剩余 var profit = todayIncome - todayShippedAmount - remainingCoupon - boxRemaining; // 利润计算公式 var formula = $"利润 = 订单收入({todayIncome:F2}) - 发货金额({todayShippedAmount:F2}) - 用户剩余达达券({remainingCoupon:F2}) - 盒柜剩余({boxRemaining:F2})"; return new IncomeSummaryStatsResponse { TodayIncome = todayIncome, RmbIncome = rmbIncome, DiamondIncome = diamondIncome, OtherIncome = otherIncome, ShippedToday = shippedToday, Expenses = expenses, TodayShipped = todayShippedAmount, RemainingCoupon = remainingCoupon, BoxRemaining = boxRemaining, Profit = profit, Formula = formula }; } /// /// 获取用户统计数据 /// public async Task GetUserStatsAsync() { // 排除测试用户 var nonTestUsersQuery = _dbContext.Users.Where(u => u.IsTest == 0); var nonTestUserIds = nonTestUsersQuery.Select(u => u.Id); // 绑定手机号人数(手机号不为空且不为空字符串的用户数) var userRegisterCount = await nonTestUsersQuery .Where(u => u.Mobile != null && u.Mobile != "") .CountAsync(); // 抽奖人数(有抽奖记录的用户总数,去重) var consumingUserCount = await _dbContext.OrderItems .Where(oi => nonTestUserIds.Contains(oi.UserId)) .Select(oi => oi.UserId) .Distinct() .CountAsync(); // 用户剩余钻石(所有非测试用户的钻石余额总和) var userMoney = await nonTestUsersQuery .SumAsync(u => (decimal?)u.Money) ?? 0; // 用户剩余UU币(所有非测试用户的UU币余额总和) var userIntegral = await nonTestUsersQuery .SumAsync(u => (decimal?)u.Integral) ?? 0; // 用户剩余达达券(所有非测试用户的达达券余额总和) var userMoney2 = await nonTestUsersQuery .SumAsync(u => (decimal?)u.Money2) ?? 0; // 微信支付金额(历史微信支付总额,排除测试用户) var orderPriceTotal = await _dbContext.Orders .Where(o => o.Status == 1) .Where(o => nonTestUserIds.Contains(o.UserId)) .SumAsync(o => (decimal?)o.Price) ?? 0; // 订单支付数量(历史支付成功订单总数,排除测试用户) var orderTotalCount = await _dbContext.Orders .Where(o => o.Status == 1) .Where(o => nonTestUserIds.Contains(o.UserId)) .CountAsync(); // 用户出货总金额(所有中奖记录的奖品总价值,排除测试用户) var totalGoodsAmount = await _dbContext.OrderItems .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; // 用户盒柜剩余价值(status=0表示待处理的奖品,排除测试用户) var boxRemainingValue = await _dbContext.OrderItems .Where(oi => oi.Status == 0) .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; // 用户已兑换的达达券(status=1表示已回收的奖品回收金额总和,排除测试用户) var exchangedCoupon = await _dbContext.OrderItems .Where(oi => oi.Status == 1) .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistMoney) ?? 0; // 用户已发货金额(status=2表示已发货的奖品价值总和,排除测试用户) var shippedAmount = await _dbContext.OrderItems .Where(oi => oi.Status == 2) .Where(oi => nonTestUserIds.Contains(oi.UserId)) .SumAsync(oi => (decimal?)oi.GoodslistPrice) ?? 0; return new UserStatsResponse { UserRegisterCount = userRegisterCount, ConsumingUserCount = consumingUserCount, UserMoney = userMoney, UserIntegral = userIntegral, UserMoney2 = userMoney2, OrderPriceTotal = orderPriceTotal, OrderTotalCount = orderTotalCount, TotalGoodsAmount = totalGoodsAmount, BoxRemainingValue = boxRemainingValue, ExchangedCoupon = exchangedCoupon, ShippedAmount = shippedAmount }; } }