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
};
}
}