using LifePayment.Application.Contracts; using LifePayment.Domain.LifePay; using LifePayment.Domain.Models; using LifePayment.Domain.Shared; using LifePayment.Domain; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Volo.Abp.Application.Services; using Volo.Abp.Data; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; using static Nest.FileSystemStats; using Microsoft.EntityFrameworkCore; using System.Threading.Channels; using ZeroD.Util; using NPOI.SS.Formula.Functions; using System.Security.Principal; using StackExchange.Redis; namespace LifePayment.Application.LifePay { public class StatisticsService : ApplicationService, IStatisticsService { private readonly IRepository _lifePayOrderRepository; private readonly IRepository _lifePayUserRepository; private readonly IRepository _dallyStatisticsRepository; private readonly IRepository _lifePayChannlesRakeRepository; private readonly IRepository _lifePayRechargeReceiptsRepository; private readonly IRepository _lifePayChannlesRep; public StatisticsService( IRepository lifePayOrderRepository, IRepository lifePayUserRepository, IRepository dallyStatisticsRepository, IRepository lifePayChannlesRakeRepository, IRepository lifePayRechargeReceiptsRepository, IRepository lifePayChannlesRep) { _lifePayOrderRepository = lifePayOrderRepository; _lifePayUserRepository = lifePayUserRepository; _dallyStatisticsRepository = dallyStatisticsRepository; _lifePayChannlesRakeRepository = lifePayChannlesRakeRepository; _lifePayRechargeReceiptsRepository = lifePayRechargeReceiptsRepository; _lifePayChannlesRep = lifePayChannlesRep; } /// /// 顶部统计 /// /// /// public async Task GetTopStatistics(List channleList) { var today = DateTime.Now.Date; var statistics = await _dallyStatisticsRepository.Where(x => x.CreationTime.Date == today) .WhereIf(channleList.Count() > 0, x => channleList.Contains(x.ChannelId)) .ToListAsync(); var totalRechargeReceipts = await _lifePayRechargeReceiptsRepository.Where(x => x.IsDeleted == false && x.CreationTime < today).SumAsync(x => x.RechargeAmount); if (statistics == null || statistics.Count() == 0) { TopStatisticsOutput topStatisticsOutput = new TopStatisticsOutput() { }; var allChannle = await _lifePayChannlesRep.Where(x => x.IsDeleted == false).ToListAsync(); foreach (var item in allChannle) { var entity = await TopStatistics(item.ChannlesNum, today); if (channleList.Count() == 0 || channleList.Contains(item.ChannlesNum)) { topStatisticsOutput.AccumulatedReceipts += entity.AccumulatedReceipts; topStatisticsOutput.AccumulatedIncome += entity.AccumulatedIncome; topStatisticsOutput.ReceiptsYesterday += entity.ReceiptsYesterday; topStatisticsOutput.AccumulatedOrders += entity.AccumulatedOrders; topStatisticsOutput.OrdersNumYesterday += entity.OrdersNumYesterday; topStatisticsOutput.YesterdaySuccess += entity.YesterdaySuccess; topStatisticsOutput.YesterdayFail += entity.YesterdayFail; topStatisticsOutput.AccumulatedUsers += entity.AccumulatedUsers; topStatisticsOutput.YesterdayActiveUsers += entity.YesterdayActiveUsers; topStatisticsOutput.AccumulatedChannlesRakePrice += entity.AccumulatedChannlesRakePrice; } } if (channleList.Count() == 0) { /// 账户余额 var accountBalance = totalRechargeReceipts - await _lifePayOrderRepository.Where(x => x.ACOOLYStatus == ACOOLYStatusEnum.充值成功 || x.ACOOLYStatus == ACOOLYStatusEnum.已完成 || x.ACOOLYStatus == ACOOLYStatusEnum.部分充值成功) .SumAsync(x => x.PlatformDeductionAmount); topStatisticsOutput.Amount = accountBalance ?? 0; } return topStatisticsOutput; } else { TopStatisticsOutput topStatisticsOutput = new TopStatisticsOutput() { AccumulatedReceipts = statistics.Sum(s => s.AccumulatedReceipts), AccumulatedIncome = statistics.Sum(s => s.AccumulatedIncome), ReceiptsYesterday = statistics.Sum(s => s.ReceiptsYesterday), AccumulatedOrders = statistics.Sum(s => s.AccumulatedOrders), OrdersNumYesterday = statistics.Sum(s => s.OrdersNumYesterday), YesterdaySuccess = statistics.Sum(s => s.YesterdaySuccess), YesterdayFail = statistics.Sum(s => s.YesterdayFail), AccumulatedUsers = statistics.Sum(s => s.AccumulatedUsers), YesterdayActiveUsers = statistics.Sum(s => s.YesterdayActiveUsers), AccumulatedChannlesRakePrice = statistics.Sum(s => s.AccumulatedChannlesRakePrice) }; if (channleList.Count() == 0) { /// 账户余额 var accountBalance = totalRechargeReceipts - await _lifePayOrderRepository.Where(x => x.ACOOLYStatus == ACOOLYStatusEnum.充值成功 || x.ACOOLYStatus == ACOOLYStatusEnum.已完成 || x.ACOOLYStatus == ACOOLYStatusEnum.部分充值成功) .SumAsync(x => x.PlatformDeductionAmount); topStatisticsOutput.Amount = accountBalance ?? 0; } return topStatisticsOutput; } } /// /// 近30日收款数据 /// /// /// public async Task GetReceiptsList(List channleList) { var today = DateTime.Now.Date; var statistics = await _dallyStatisticsRepository.Where(x => x.CreationTime.Date <= today && x.CreationTime.Date >= today.AddDays(-30)) .WhereIf(channleList.Count() > 0, x => channleList.Contains(x.ChannelId)) .OrderBy(o => o.CreationTime) .ToListAsync(); var groupedStatistics = statistics .GroupBy(x => x.CreationTime) .Select(g => new { CreationTime = g.Key, TotalReceiptsYesterday = g.Sum(x => x.ReceiptsYesterday), TotalIncomeYesterday = g.Sum(x => x.IncomeYesterday) }) .ToList(); ReceiptsListOutPut receiptsListOutPut = new ReceiptsListOutPut(); foreach (var item in groupedStatistics) { ReceiptsDetail receive = new ReceiptsDetail() { CreationTime = item.CreationTime.AddDays(-1).ToString("yyyy-MM-dd"), Amount = item.TotalReceiptsYesterday }; ReceiptsDetail income = new ReceiptsDetail() { CreationTime = item.CreationTime.AddDays(-1).ToString("yyyy-MM-dd"), Amount = item.TotalIncomeYesterday }; receiptsListOutPut.ReceiveList.Add(receive); receiptsListOutPut.IncomeList.Add(income); } return receiptsListOutPut; } public async Task GetChannlesRakeList(List channleList) { var today = DateTime.Now.Date; var statistics = await _lifePayChannlesRakeRepository.Where(x => x.IsDeleted == false && x.FinishTime.Date <= today && x.FinishTime.Date >= today.AddDays(-30)) .WhereIf(channleList.Count() > 0, x => channleList.Contains(x.ChannelId)) .ToListAsync(); var groupedStatistics = statistics .GroupBy(x => x.FinishTime.ToString("yyyy-MM-dd")) .Select(g => new { FinishTime = g.Key, ChannlesRakePrice = g.Sum(x => x.ChannlesRakePrice), }) .ToList(); ChannlesRakeListOutPut channlesRakeListOutPut = new ChannlesRakeListOutPut(); foreach (var item in groupedStatistics) { ReceiptsDetail receive = new ReceiptsDetail() { CreationTime = item.FinishTime, Amount = item.ChannlesRakePrice }; channlesRakeListOutPut.ChannlesRakeList.Add(receive); } return channlesRakeListOutPut; } public async Task GetChannelDataList(List channleList) { var statistics = await _lifePayChannlesRakeRepository.Where(x => x.IsDeleted == false) .WhereIf(channleList != null && channleList.Count() > 0, x => channleList.Contains(x.ChannelId)) .ToListAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(statistics == null, "统计失败"); var groupedStatistics = statistics .GroupBy(x => x.ChannelId) .Select(g => new { ChannelId = g.Key, ReceivePrice = g.Sum(x => x.PayAmount), ChannlesRakePrice = g.Sum(x => x.ChannlesRakePrice), }) .OrderByDescending(o => o.ReceivePrice) .ToList(); ChannelDataListOutPut channelDataList = new ChannelDataListOutPut(); foreach (var item in groupedStatistics) { ChannelDataReceive receive = new ChannelDataReceive() { ChannelName = _lifePayChannlesRep.Where(x => x.ChannlesNum == item.ChannelId).FirstOrDefault()?.ChannlesName, ReceivePrice = item.ReceivePrice, ChannlesRakePrice = item.ChannlesRakePrice, }; if (channelDataList.ReceiveList.Count() < 5) { channelDataList.ReceiveList.Add(receive); } } /// 累计用户 var users = await _lifePayUserRepository.Where(x => x.IsDeleted == false).WhereIf(channleList.Count() > 0, x => channleList.Contains(x.CreationChannleNum)) .ToListAsync(); var groupedUsers = users .GroupBy(x => x.CreationChannleNum) .Select(g => new { ChannelId = g.Key, Number = g.Count(), }) .OrderByDescending(o => o.Number) .ToList(); foreach (var item in groupedUsers) { ChannelDataUserNumber usernumber = new ChannelDataUserNumber() { ChannelName = _lifePayChannlesRep.Where(x => x.ChannlesNum == item.ChannelId).FirstOrDefault()?.ChannlesName, Number = item.Number, }; if (channelDataList.UserNumberList.Count() < 5) { channelDataList.UserNumberList.Add(usernumber); } } return channelDataList; } public async Task StatisticsByDate(int days) { var today = DateTime.Now.Date; for (var i = 0; i < days; i++) { var statistics = await _dallyStatisticsRepository.Where(x => x.CreationTime.Date == today) .ToListAsync(); if (statistics == null || statistics.Count() == 0) { TopStatisticsOutput topStatisticsOutput = new TopStatisticsOutput() { }; var allChannle = await _lifePayChannlesRep.Where(x => x.IsDeleted == false).ToListAsync(); foreach (var item in allChannle) { var entity = await TopStatistics(item.ChannlesNum, today); } } today = today.AddDays(-1); } } private async Task TopStatistics(string channleId, DateTime today) { /// 累计收款:统计平台账户下订单创建时间在昨天及之前收到的【用户支付成功的金额-退款给用户的金额】; var accumulatedReceipts = await _lifePayOrderRepository.Where(x => x.CreationTime < today && x.PayStatus != LifePayStatusEnum.未支付) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => x.PayAmount) - await _lifePayOrderRepository.Where(x => x.CreationTime < today && x.LifePayRefundStatus == LifePayRefundStatusEnum.已退款) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => (x.RefundPrice ?? 0)); /// 昨日收款:统计平台账户下订单创建时间在昨天收到的【用户支付成功的金额-退款给用户的金额】; var receiptsYesterday = await _lifePayOrderRepository.Where(x => x.CreationTime >= today.AddDays(-1) && x.CreationTime < today && x.PayStatus == LifePayStatusEnum.已支付) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => x.PayAmount) - await _lifePayOrderRepository.Where(x => x.CreationTime >= today.AddDays(-1) && x.CreationTime < today && x.LifePayRefundStatus == LifePayRefundStatusEnum.已退款) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => (x.RefundPrice ?? 0)); /// 累计收入:统计平台账户下订单状态为“已完成”且订单创建时间在昨天及之前收到的【用户实付金额-平台扣款金额-部分退款金额】; var accumulatedIncome = await _lifePayOrderRepository.Where(x => x.CreationTime < today && x.LifePayOrderStatus == LifePayOrderStatusEnum.已完成) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => x.PayAmount - (x.PlatformDeductionAmount ?? 0) - (x.RefundPrice ?? 0)); /// 昨日收入:统计平台账户下订单状态为“已完成”且订单创建时间在昨天收到的【用户实付金额-平台扣款金额-部分退款金额】; var yesterdayIncome = await _lifePayOrderRepository.Where(x => x.CreationTime >= today.AddDays(-1) && x.CreationTime < today && x.LifePayOrderStatus == LifePayOrderStatusEnum.已完成) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => x.PayAmount - (x.PlatformDeductionAmount ?? 0) - (x.RefundPrice ?? 0)); /// 累计下单:统计平台中订单下单时间在昨天及之前时间的订单记录; var accumulatedOrders = await _lifePayOrderRepository.Where(x => x.CreationTime < today).WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).CountAsync(); /// 昨日下单:统计平台中订单下单时间在昨天的订单记录; var ordersNumYesterday = await _lifePayOrderRepository.Where(x => x.CreationTime >= today.AddDays(-1) && x.CreationTime < today) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).CountAsync(); /// 昨日成功:统计平台中订单状态为“已完成/部分充值成功”且订单下单时间在昨天的订单记录; var yesterdaySuccess = await _lifePayOrderRepository.Where(x => x.CreationTime >= today.AddDays(-1) && x.CreationTime < today && x.LifePayOrderStatus == LifePayOrderStatusEnum.已完成) .WhereIf(string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).CountAsync(); /// 昨日失败:统计平台中订单状态为“充值失败/已退款”且订单下单时间在昨天的订单记录; var yesterdayFail = await _lifePayOrderRepository.Where(x => x.CreationTime >= today.AddDays(-1) && x.CreationTime < today && x.LifePayOrderStatus == LifePayOrderStatusEnum.已退款) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).CountAsync(); /// 累计用户 var accumulatedUsers = await _lifePayUserRepository.Where(x => x.IsDeleted == false && x.CreationTime < today) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.CreationChannleNum == channleId).CountAsync(); /// 昨日活跃用户 var yesterdayActiveUsers = await (from a in _lifePayUserRepository join b in _lifePayOrderRepository on a.Id equals b.UserId where b.CreationTime >= today.AddDays(-1) && b.CreationTime < today && (b.ACOOLYStatus == ACOOLYStatusEnum.充值中 || b.ACOOLYStatus == ACOOLYStatusEnum.充值成功 || b.ACOOLYStatus == ACOOLYStatusEnum.已完成 || b.ACOOLYStatus == ACOOLYStatusEnum.部分充值成功) select b).Distinct().CountAsync(); /// 累计佣金 var accumulatedChannlesRakePrice = await _lifePayChannlesRakeRepository.Where(x => x.IsDeleted == false && x.FinishTime < today) .WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.ChannelId == channleId).SumAsync(x => x.ChannlesRakePrice); var entity = new DallyStatistics() { Id = GuidGenerator.Create(), CreationTime = today, AccumulatedReceipts = accumulatedReceipts ?? 0, AccumulatedIncome = accumulatedIncome ?? 0, IncomeYesterday = yesterdayIncome ?? 0, ReceiptsYesterday = receiptsYesterday ?? 0, AccumulatedOrders = accumulatedOrders, OrdersNumYesterday = ordersNumYesterday, YesterdaySuccess = yesterdaySuccess, YesterdayFail = yesterdayFail, AccumulatedUsers = accumulatedUsers, YesterdayActiveUsers = yesterdayActiveUsers, ChannelId = channleId, AccumulatedChannlesRakePrice = accumulatedChannlesRakePrice, Date = today.AddDays(-1) }; await _dallyStatisticsRepository.InsertAsync(entity); return entity; } } }