添加定时器

This commit is contained in:
zpc 2024-12-02 15:16:58 +08:00
parent cfd1f964bf
commit ba0c98253c
17 changed files with 242 additions and 87 deletions

View File

@ -91,6 +91,7 @@ namespace CloudGaming.PayApi.Controllers
return "success";
}
DAO dao = new DAO(serviceProvider, appConfig);
//查询意向订单
var intentOrder = await dao.DaoUser.Context.T_User_IntentOrder.FirstOrDefaultAsync(it => it.OrderId == orderId);
if (intentOrder == null)
{
@ -126,7 +127,7 @@ namespace CloudGaming.PayApi.Controllers
T_User_OrderItems orderItems = new T_User_OrderItems();
orderItems.PayUrl = context.Request.Path;
//orderItems.
await product.OrderRewardsNoWorkAsync(user, pay, orderId, intentOrder.Price, intentOrder.CreatedAt, dao, orderItems);
await product.OrderRewardsNoWorkAsync(user, pay, orderId, intentOrder.Price, intentOrder.Channel ?? "", intentOrder.CreatedAt, dao, orderItems);
//intentOrder = await dao.daoDbMiaoYu.context.T_User_IntentOrder.FirstOrDefaultAsync(it => it.OrderId == orderId);
intentOrder.Status = (int)OrderState.;
await dao.DaoUser.Context.SaveChangesAsync();

View File

@ -71,7 +71,7 @@ public class OrderBLL : CloudGamingBase
price = (decimal)0.01;
}
(var orderId, var order, var payNotifyUrl) = await payment.CreateOrder(product.Id, product.ProductName, price, product, ip);
var t = product.ToIntentOrder(paymentMethod, orderId);
var t = product.ToIntentOrder(paymentMethod, orderId, AppRequestInfo.Channel);
t.UserId = _UserId;
if (payNotifyUrl != null && payNotifyUrl.Length > 200)
{

View File

@ -0,0 +1,82 @@
using CloudGaming.DtoModel.Other;
using HuanMeng.DotNetCore.QuartzExtend;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Monitor
{
/// <summary>
/// 游戏控制器
/// </summary>
[QuartzTrigger("GameMonitorProcessor", "* 05 4 * * ?")]
public class GameMonitorProcessor : AppJobBase
{
public GameMonitorProcessor(IServiceScopeFactory scopeFactory) : base(scopeFactory)
{
}
public override async Task AppConfigProcessLoop(AppConfig appConfig, AppMonitorInfo appMonitorInfo, IServiceProvider serviceProvider, CloudGamingBase cloudGamingBase)
{
var dao = cloudGamingBase.Dao;
var now = DateTime.Now.AddDays(-1);
int day = int.Parse(now.ToString("yyyyMMdd"));
var nowDay = DateOnly.FromDateTime(now);
var gamePlay = dao.DaoPhone.Context.T_Game_PlayGameLog.Where(it => it.CreateDay == day).AsQueryable();
//启动游戏次数
var gamePlayCount = await gamePlay.GroupBy(log => log.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());
//启动游戏人数
var gamePlayLog = await gamePlay.GroupBy(log => log.Channel).Select(group => new
{
Channel = group.Key,
UserCount = group.Select(log => log.UserId).Distinct().Count()
}).ToDictionaryAsync(it => it.Channel ?? "", it => it.UserCount);
// 游玩时间
var gamePlaySeconds = await gamePlay.GroupBy(log => log.Channel).Select(group => new
{
Channel = group.Key,
PlayGameTotalSeconds = group.Sum(it => it.PlayGameTotalSeconds)
}).ToDictionaryAsync(it => it.Channel ?? "", it => it.PlayGameTotalSeconds);
// 获取当前统计数据
var userStatistics = await dao.DaoExt.Context.T_Statistics_Game
.Where(it => it.LoginDay == day)
.ToDictionaryAsync(it => it.Channel ?? "");
// 更新或创建统计记录
void UpdateStatistics(string channel, int playGameCount, int playGameTimeCount, int startGameCount)
{
if (!userStatistics.TryGetValue(channel, out var statisticsUser))
{
statisticsUser = new T_Statistics_Game()
{
PlayGameCount = 0,
Channel = channel,
CreatedAt = DateTime.Now,
PlayGameTimeCount = 0,
StartGameCount = 0,
LoginDate = nowDay,
LoginDay = day,
UpdatedAt = DateTime.Now,
};
dao.DaoExt.Context.T_Statistics_Game.Add(statisticsUser);
userStatistics.Add(channel, statisticsUser);
}
statisticsUser.PlayGameCount = playGameCount;
statisticsUser.PlayGameTimeCount = playGameTimeCount > 0 ? playGameTimeCount / 60 / 60 : playGameTimeCount;
statisticsUser.StartGameCount = startGameCount;
statisticsUser.UpdatedAt = DateTime.Now;
}
foreach (var item in gamePlayCount)
{
UpdateStatistics(item.Key, item.Value, gamePlaySeconds.GetValueOrDefault(item.Key, 0), gamePlayLog.GetValueOrDefault(item.Key, 0));
}
await dao.DaoExt.Context.SaveChangesAsync();
}
}
}

View File

@ -0,0 +1,75 @@
using CloudGaming.DtoModel.Other;
using HuanMeng.DotNetCore.QuartzExtend;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CloudGaming.Code.Monitor
{
/// <summary>
/// 订单数据统计
/// </summary>
[QuartzTrigger("UserMonitorProcessor", "* 25 4 * * ?")]
//[QuartzTrigger("OrderMonitorProcessor", "0 0/1 * * * ?")]
public class OrderMonitorProcessor : AppJobBase
{
public OrderMonitorProcessor(IServiceScopeFactory scopeFactory) : base(scopeFactory)
{
}
public override async Task AppConfigProcessLoop(AppConfig appConfig, AppMonitorInfo appMonitorInfo, IServiceProvider serviceProvider, CloudGamingBase cloudGamingBase)
{
var dao = cloudGamingBase.Dao;
var now = DateTime.Now.AddDays(-1);
int day = int.Parse(now.ToString("yyyyMMdd"));
var nowDay = DateOnly.FromDateTime(now);
//意向订单次数
var intendedOrder = await dao.DaoUser.Context.T_User_IntentOrder.Where(it => it.CreatedDay == day).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());
//支付订单次数
var paidOrders = await dao.DaoUser.Context.T_User_Order.Where(it => it.PaymentDay == nowDay).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Count());
//支付金额
var paidOrdersPrice = await dao.DaoUser.Context.T_User_Order.Where(it => it.PaymentDay == nowDay).GroupBy(it => it.Channel).ToDictionaryAsync(it => it.Key ?? "", it => it.Sum(it => it.TotalPrice));
//数据源
var orderStatistics = await dao.DaoExt.Context.T_Statistics_Order
.Where(it => it.LoginDay == day)
.ToDictionaryAsync(it => it.Channel ?? "");
// 更新或创建统计记录
void UpdateStatistics(string channel, int intendedOrderCount, int paidOrders, decimal rechargeAmount)
{
if (!orderStatistics.TryGetValue(channel, out var statisticsUser))
{
statisticsUser = new T_Statistics_Order()
{
RechargeAmount = 0,
Channel = channel,
CreatedAt = DateTime.Now,
IntendedOrderCount = 0,
PaidOrders = 0,
LoginDate = nowDay,
LoginDay = day,
UpdatedAt = DateTime.Now,
};
dao.DaoExt.Context.T_Statistics_Order.Add(statisticsUser);
orderStatistics.Add(channel, statisticsUser);
}
statisticsUser.RechargeAmount = rechargeAmount;
statisticsUser.IntendedOrderCount = intendedOrderCount;
statisticsUser.PaidOrders = paidOrders;
statisticsUser.UpdatedAt = DateTime.Now;
}
foreach (var item in intendedOrder)
{
UpdateStatistics(item.Key, item.Value, paidOrders.GetValueOrDefault(item.Key, 0), paidOrdersPrice.GetValueOrDefault(item.Key, 0));
}
await dao.DaoExt.Context.SaveChangesAsync();
}
}
}

View File

@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace CloudGaming.Code.Monitor;
/// <summary>
/// 用户定时类
/// 用户定时类
/// </summary>
[QuartzTrigger("UserMonitorProcessor", "* 15 4 * * ?")]
public class UserMonitorProcessor : AppJobBase
@ -28,92 +28,57 @@ public class UserMonitorProcessor : AppJobBase
int day = int.Parse(now.ToString("yyyyMMdd"));
var nowDay = DateOnly.FromDateTime(now);
//今日登录人数
var todayLoggedInUsers = await cloudGamingBase.Dao.DaoExt.Context.T_User_LoginDay_Log.Where(it => it.CreateTimeDay == day)
// 获取所有用户数据
var userLoginData = cloudGamingBase.Dao.DaoExt.Context.T_User_LoginDay_Log
.Where(it => it.CreateTimeDay == day).AsQueryable();
//登录数据
var todayLoggedInUsers = await userLoginData.GroupBy(it => it.Channel ?? "")
.ToDictionaryAsync(g => g.Key, g => g.Count());
//注册数据
var todayRegisteredUsers = await userLoginData.Where(it => it.IsNew)
.GroupBy(it => it.Channel ?? "")
.ToDictionaryAsync(it => it.Key, it => it.Count());
//今日注册人数
var todayRegisteredUsers = await cloudGamingBase.Dao.DaoExt.Context.T_User_LoginDay_Log.Where(it => it.CreateTimeDay == day && it.IsNew)
.ToDictionaryAsync(g => g.Key, g => g.Count());
//活跃数据
var todayActionUsers = await userLoginData.Where(it => it.LogInDay > 1)
.GroupBy(it => it.Channel ?? "")
.ToDictionaryAsync(it => it.Key, it => it.Count());
//今日活跃人数
var todayActionUsers = await cloudGamingBase.Dao.DaoExt.Context.T_User_LoginDay_Log.Where(it => it.CreateTimeDay == day && it.LogInDay > 1)
.GroupBy(it => it.Channel ?? "")
.ToDictionaryAsync(it => it.Key, it => it.Count());
//数据库中的数据
var userStatistics = await dao.DaoExt.Context.T_Statistics_User.Where(it => it.LoginDay == day).ToDictionaryAsync(it => it.Channel ?? "");//.ToListAsync();
//
if (todayLoggedInUsers != null)
.ToDictionaryAsync(g => g.Key, g => g.Count());
// 获取当前统计数据
var userStatistics = await dao.DaoExt.Context.T_Statistics_User
.Where(it => it.LoginDay == day)
.ToDictionaryAsync(it => it.Channel ?? "");
// 更新或创建统计记
void UpdateStatistics(string channel, int loginCount, int registrCount, int activeCount)
{
foreach (var item in todayLoggedInUsers)
if (!userStatistics.TryGetValue(channel, out var statisticsUser))
{
if (!userStatistics.TryGetValue(item.Key, out var statisticsUser))
statisticsUser = new T_Statistics_User()
{
statisticsUser = new T_Statistics_User()
{
ActiveCount = 0,
Channel = item.Key,
CreatedAt = DateTime.Now,
LoginCount = 0,
RegistrCount = 0,
LoginDate = nowDay,
LoginDay = day,
UpdatedAt = DateTime.Now,
};
await dao.DaoExt.Context.T_Statistics_User.AddAsync(statisticsUser);
userStatistics.Add(item.Key, statisticsUser);
}
statisticsUser.LoginDay = item.Value;
ActiveCount = 0,
Channel = channel,
CreatedAt = DateTime.Now,
LoginCount = 0,
RegistrCount = 0,
LoginDate = nowDay,
LoginDay = day,
UpdatedAt = DateTime.Now,
};
dao.DaoExt.Context.T_Statistics_User.Add(statisticsUser);
userStatistics.Add(channel, statisticsUser);
}
statisticsUser.LoginCount = loginCount;
statisticsUser.RegistrCount = registrCount;
statisticsUser.ActiveCount = activeCount;
statisticsUser.UpdatedAt = DateTime.Now;
}
//注册
if (todayRegisteredUsers != null)
foreach (var item in todayLoggedInUsers)
{
foreach (var item in todayRegisteredUsers)
{
if (!userStatistics.TryGetValue(item.Key, out var statisticsUser))
{
statisticsUser = new T_Statistics_User()
{
ActiveCount = 0,
Channel = item.Key,
CreatedAt = DateTime.Now,
LoginCount = 0,
RegistrCount = 0,
LoginDate = nowDay,
LoginDay = day,
UpdatedAt = DateTime.Now,
};
await dao.DaoExt.Context.T_Statistics_User.AddAsync(statisticsUser);
userStatistics.Add(item.Key, statisticsUser);
}
statisticsUser.RegistrCount = item.Value;
}
}
//活跃
if (todayActionUsers != null)
{
foreach (var item in todayActionUsers)
{
if (!userStatistics.TryGetValue(item.Key, out var statisticsUser))
{
statisticsUser = new T_Statistics_User()
{
ActiveCount = 0,
Channel = item.Key,
CreatedAt = DateTime.Now,
LoginCount = 0,
RegistrCount = 0,
LoginDate = nowDay,
LoginDay = day,
UpdatedAt = DateTime.Now,
};
await dao.DaoExt.Context.T_Statistics_User.AddAsync(statisticsUser);
userStatistics.Add(item.Key, statisticsUser);
}
statisticsUser.ActiveCount = item.Value;
}
UpdateStatistics(item.Key, item.Value, todayRegisteredUsers.GetValueOrDefault(item.Key, 0), todayActionUsers.GetValueOrDefault(item.Key, 0));
}
await dao.DaoExt.Context.SaveChangesAsync();
}
}

View File

@ -29,7 +29,7 @@ public static class OrderExtend
/// <param name="intentDate"></param>
/// <param name="dao"></param>
/// <returns></returns>
public static async Task OrderRewardsNoWorkAsync(this T_Products product, T_User user, string pay, string orderId, decimal price, DateTime intentDate, DAO dao, T_User_OrderItems orderItems = null)
public static async Task OrderRewardsNoWorkAsync(this T_Products product, T_User user, string pay, string orderId, decimal price,string channel, DateTime intentDate, DAO dao, T_User_OrderItems orderItems = null)
{
var userId = user.Id;
var chargeMoneyCount = dao.DaoUser.Context.T_User_Order.Count(it => it.UserId == userId && it.ProductId == product.ProductId);
@ -68,6 +68,7 @@ public static class OrderExtend
TotalPrice = price,
UpdatedAt = DateTime.Now,
UserId = userId,
Channel= channel
};
if (orderItems == null)
{

View File

@ -164,7 +164,7 @@ public static class PaymentExtend
/// <param name="payment"></param>
/// <param name="orderId"></param>
/// <returns></returns>
public static T_User_IntentOrder ToIntentOrder(this ProductCache productCache, string payment, string orderId)
public static T_User_IntentOrder ToIntentOrder(this ProductCache productCache, string payment, string orderId, string channel)
{
T_User_IntentOrder t_User_IntentOrder = new T_User_IntentOrder()
{
@ -178,6 +178,7 @@ public static class PaymentExtend
Status = (int)OrderState.,
UpdatedAt = DateTime.Now,
OrderId = orderId,
Channel = channel
};
return t_User_IntentOrder;
}

View File

@ -195,6 +195,8 @@ public class PlayGameUserInfo
DiamondListId = DiamondListId,
GameStatus = (int)GameStatus,
GameUserOperationJson = GameUserOperation == null ? "" : JsonConvert.SerializeObject(GameUserOperation, settings),
Channel = Channel,
CreateDay = int.Parse(CreateDateTime.ToString("yyyyMMdd"))
};
return log;
}

View File

@ -239,7 +239,9 @@ public partial class CloudGamingCBTContext : DbContext
entity.Property(e => e.LoginDate).HasComment("日期");
entity.Property(e => e.LoginDay).HasComment("天");
entity.Property(e => e.PaidOrders).HasComment("支付订单次数");
entity.Property(e => e.RechargeAmount).HasComment("支付订单金额");
entity.Property(e => e.RechargeAmount)
.HasComment("支付订单金额")
.HasColumnType("decimal(18, 0)");
entity.Property(e => e.UpdatedAt)
.HasComment("修改时间")
.HasColumnType("datetime");

View File

@ -34,7 +34,7 @@ public partial class T_Statistics_Order
/// <summary>
/// 支付订单金额
/// </summary>
public virtual int RechargeAmount { get; set; }
public virtual decimal RechargeAmount { get; set; }
/// <summary>
/// 渠道号

View File

@ -1,4 +1,4 @@
using System;
using System;
namespace CloudGaming.GameModel.Db.Db_Ext;

View File

@ -209,7 +209,7 @@ public partial class CloudGamingPhoneContext : MultiTenantDbContext//DbContext
public virtual DbSet<T_Videos> T_Videos { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ // => optionsBuilder.UseSqlServer("Server=192.168.195.6;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;");
{ // => optionsBuilder.UseSqlServer("Server=192.168.195.8;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
@ -683,6 +683,9 @@ public partial class CloudGamingPhoneContext : MultiTenantDbContext//DbContext
entity.ToTable(tb => tb.HasComment("用户玩游戏日志表"));
entity.Property(e => e.Id).HasComment("主键");
entity.Property(e => e.Channel)
.HasMaxLength(10)
.HasComment("渠道号");
entity.Property(e => e.Cpu)
.HasMaxLength(50)
.HasComment("用户cpu");

View File

@ -148,4 +148,11 @@ public partial class T_Game_PlayGameLog: MultiTenantEntity
/// 用户操作内容
/// </summary>
public virtual string? GameUserOperationJson { get; set; }
/// <summary>
/// 渠道号
/// </summary>
public virtual string? Channel { get; set; }
public virtual int CreateDay { get; set; }
}

View File

@ -319,6 +319,9 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
entity.ToTable(tb => tb.HasComment("意向订单表"));
entity.Property(e => e.Id).HasComment("主键");
entity.Property(e => e.Channel)
.HasMaxLength(10)
.HasComment("渠道号");
entity.Property(e => e.CreatedAt)
.HasComment("创建时间")
.HasColumnType("datetime");
@ -430,6 +433,9 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
entity.ToTable(tb => tb.HasComment("订单完成表"));
entity.Property(e => e.Channel)
.HasMaxLength(10)
.HasComment("渠道");
entity.Property(e => e.CreatedAt)
.HasComment("创建时间")
.HasColumnType("datetime");

View File

@ -73,4 +73,9 @@ public partial class T_User_IntentOrder: MultiTenantEntity
/// 创建天
/// </summary>
public virtual int CreatedDay { get; set; }
/// <summary>
/// 渠道号
/// </summary>
public virtual string? Channel { get; set; }
}

View File

@ -70,4 +70,9 @@ public partial class T_User_Order: MultiTenantEntity
/// 订单创建天
/// </summary>
public virtual DateOnly PaymentDay { get; set; }
/// <summary>
/// 渠道
/// </summary>
public virtual string? Channel { get; set; }
}

View File

@ -7,6 +7,6 @@ dotnet ef dbcontext scaffold "Server=192.168.195.8;Database=CloudGamingUser;User
--CloudGamingPhone
dotnet ef dbcontext scaffold "Server=192.168.1.17;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer -o DbSqlServer/Db_Phone/ --use-database-names --no-pluralize --force
dotnet ef dbcontext scaffold "Server=192.168.195.6;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer -o DbSqlServer/Db_Phone/ --use-database-names --no-pluralize --force
dotnet ef dbcontext scaffold "Server=192.168.195.8;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer -o DbSqlServer/Db_Phone/ --use-database-names --no-pluralize --force
```