zhengyuxuan
2025-04-01 e08d70b9e610a2c176b88cb092d580754e009de5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
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;
 
namespace LifePayment.Application.LifePay
{
    public class StatisticsService : ApplicationService, IStatisticsService
    {
        private readonly IRepository<LifePayOrder, Guid> _lifePayOrderRepository;
        private readonly IRepository<LifePayUser, Guid> _lifePayUserRepository;
        private readonly IRepository<DallyStatistics, Guid> _dallyStatisticsRepository;
        private readonly IRepository<LifePayChannlesRake, Guid> _lifePayChannlesRakeRepository;
        private readonly IRepository<LifePayChannles, Guid> _lifePayChannlesRep;
 
        public StatisticsService(
                              IRepository<LifePayOrder, Guid> lifePayOrderRepository,
                              IRepository<LifePayUser, Guid> lifePayUserRepository,
                            IRepository<DallyStatistics, Guid> dallyStatisticsRepository,
                            IRepository<LifePayChannlesRake, Guid> lifePayChannlesRakeRepository,
                            IRepository<LifePayChannles, Guid> lifePayChannlesRep)
        {
            _lifePayOrderRepository = lifePayOrderRepository;
            _lifePayUserRepository = lifePayUserRepository;
            _dallyStatisticsRepository = dallyStatisticsRepository;
            _lifePayChannlesRakeRepository = lifePayChannlesRakeRepository;
            _lifePayChannlesRep = lifePayChannlesRep;
        }
 
        /// <summary>
        /// 顶部统计
        /// </summary>
        /// <param name="channleId"></param>
        /// <returns></returns>
        public async Task<TopStatisticsOutput> GetTopStatistics(List<string> 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();
            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.Amount += entity.Amount;
                        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;
                    }
                }
                return topStatisticsOutput;
            }
            else
            {
                TopStatisticsOutput topStatisticsOutput = new TopStatisticsOutput()
                {
                    Amount = statistics.Sum(s => s.Amount),
                    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),
                };
                return topStatisticsOutput;
            }
        }
 
        /// <summary>
        /// 近30日收款数据
        /// </summary>
        /// <param name="channleList"></param>
        /// <returns></returns>
        public async Task<ReceiptsListOutPut> GetReceiptsList(List<string> 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.ToString("yyyy-MM-dd"),
                    Amount = item.TotalReceiptsYesterday
                };
                ReceiptsDetail income = new ReceiptsDetail()
                {
                    CreationTime = item.CreationTime.ToString("yyyy-MM-dd"),
                    Amount = item.TotalIncomeYesterday
                };
                receiptsListOutPut.ReceiveList.Add(receive);
                receiptsListOutPut.IncomeList.Add(income);
            }
 
            return receiptsListOutPut;
 
        }
 
        public async Task<ChannelDataListOutPut> GetChannelDataList(List<string> channleList)
        {
 
            var statistics = await _lifePayChannlesRakeRepository.Where(x => x.IsDeleted == false)
                            .WhereIf(channleList.Count() > 0, x => channleList.Contains(x.ChannelId))
                            .ToListAsync();
            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()
                {
                    ChannelId = item.ChannelId,
                    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()
                {
                    ChannelId = item.ChannelId,
                    Number = item.Number,
                };
                if (channelDataList.UserNumberList.Count() < 5)
                {
                    channelDataList.UserNumberList.Add(usernumber);
                }
            }
 
 
 
            return channelDataList;
 
        }
 
 
        private async Task<DallyStatistics> 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).WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.CreationChannleNum == channleId).CountAsync();
            /// 昨日活跃用户
            var yesterdayActiveUsers = await _lifePayUserRepository.Where(x => x.IsDeleted == false).WhereIf(!string.IsNullOrWhiteSpace(channleId), x => x.CreationChannleNum == channleId).Where(x => x.LastLoginTime >= today.AddDays(-1)).CountAsync();
 
 
            var entity = new DallyStatistics()
            {
                Id = GuidGenerator.Create(),
                CreationTime = today,
                Amount = 0,
                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
            };
            await _dallyStatisticsRepository.InsertAsync(entity);
            return entity;
        }
    }
}