feat: 新增近24小时每小时与今日模型使用量统计接口及实现
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 每小时Token使用量统计DTO(柱状图)
|
||||||
|
/// </summary>
|
||||||
|
public class HourlyTokenUsageDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 小时时间点
|
||||||
|
/// </summary>
|
||||||
|
public DateTime Hour { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 该小时总Token消耗量
|
||||||
|
/// </summary>
|
||||||
|
public long TotalTokens { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 各模型Token消耗明细
|
||||||
|
/// </summary>
|
||||||
|
public List<ModelTokenBreakdownDto> ModelBreakdown { get; set; } = new();
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模型今日使用量统计DTO(卡片列表)
|
||||||
|
/// </summary>
|
||||||
|
public class ModelTodayUsageDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 模型ID
|
||||||
|
/// </summary>
|
||||||
|
public string ModelId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 今日使用次数
|
||||||
|
/// </summary>
|
||||||
|
public int UsageCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 今日消耗总Token数
|
||||||
|
/// </summary>
|
||||||
|
public long TotalTokens { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模型Token堆叠数据DTO(用于柱状图)
|
||||||
|
/// </summary>
|
||||||
|
public class ModelTokenBreakdownDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 模型ID
|
||||||
|
/// </summary>
|
||||||
|
public string ModelId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Token消耗量
|
||||||
|
/// </summary>
|
||||||
|
public long Tokens { get; set; }
|
||||||
|
}
|
||||||
@@ -24,4 +24,16 @@ public interface IUsageStatisticsService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>尊享服务Token用量统计</returns>
|
/// <returns>尊享服务Token用量统计</returns>
|
||||||
Task<PremiumTokenUsageDto> GetPremiumTokenUsageAsync();
|
Task<PremiumTokenUsageDto> GetPremiumTokenUsageAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户近24小时每小时Token消耗统计(柱状图)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>每小时Token使用量列表,包含各模型堆叠数据</returns>
|
||||||
|
Task<List<HourlyTokenUsageDto>> GetLast24HoursTokenUsageAsync(UsageStatisticsGetInput input);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户今日各模型使用量统计(卡片列表)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>模型今日使用量列表,包含使用次数和总Token</returns>
|
||||||
|
Task<List<ModelTodayUsageDto>> GetTodayModelUsageAsync(UsageStatisticsGetInput input);
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ public class UsageStatisticsService : ApplicationService, IUsageStatisticsServic
|
|||||||
// 从Message表统计近7天的token消耗
|
// 从Message表统计近7天的token消耗
|
||||||
var dailyUsage = await _messageRepository._DbQueryable
|
var dailyUsage = await _messageRepository._DbQueryable
|
||||||
.Where(x => x.UserId == userId)
|
.Where(x => x.UserId == userId)
|
||||||
.Where(x => x.Role == "assistant" || x.Role == "system")
|
.Where(x => x.Role == "system")
|
||||||
.Where(x => x.CreationTime >= startDate && x.CreationTime < endDate.AddDays(1))
|
.Where(x => x.CreationTime >= startDate && x.CreationTime < endDate.AddDays(1))
|
||||||
.WhereIF(input.TokenId.HasValue,x => x.TokenId == input.TokenId)
|
.WhereIF(input.TokenId.HasValue,x => x.TokenId == input.TokenId)
|
||||||
.GroupBy(x => x.CreationTime.Date)
|
.GroupBy(x => x.CreationTime.Date)
|
||||||
@@ -228,4 +228,106 @@ public class UsageStatisticsService : ApplicationService, IUsageStatisticsServic
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户近24小时每小时Token消耗统计(柱状图)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>每小时Token使用量列表,包含各模型堆叠数据</returns>
|
||||||
|
public async Task<List<HourlyTokenUsageDto>> GetLast24HoursTokenUsageAsync([FromQuery]UsageStatisticsGetInput input)
|
||||||
|
{
|
||||||
|
var userId = CurrentUser.GetId();
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var startTime = now.AddHours(-23); // 滚动24小时,从23小时前到现在
|
||||||
|
var startHour = new DateTime(startTime.Year, startTime.Month, startTime.Day, startTime.Hour, 0, 0);
|
||||||
|
|
||||||
|
// 从Message表查询近24小时的数据,只选择需要的字段
|
||||||
|
var messages = await _messageRepository._DbQueryable
|
||||||
|
.Where(x => x.UserId == userId)
|
||||||
|
.Where(x => x.Role == "system")
|
||||||
|
.Where(x => x.CreationTime >= startHour)
|
||||||
|
.WhereIF(input.TokenId.HasValue, x => x.TokenId == input.TokenId)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.CreationTime,
|
||||||
|
x.ModelId,
|
||||||
|
x.TokenUsage.TotalTokenCount
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// 在内存中按小时和模型分组统计
|
||||||
|
var hourlyGrouped = messages
|
||||||
|
.GroupBy(x => new
|
||||||
|
{
|
||||||
|
Hour = new DateTime(x.CreationTime.Year, x.CreationTime.Month, x.CreationTime.Day, x.CreationTime.Hour, 0, 0),
|
||||||
|
x.ModelId
|
||||||
|
})
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
g.Key.Hour,
|
||||||
|
g.Key.ModelId,
|
||||||
|
Tokens = g.Sum(x => x.TotalTokenCount)
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
// 生成完整的24小时数据
|
||||||
|
var result = new List<HourlyTokenUsageDto>();
|
||||||
|
for (int i = 0; i < 24; i++)
|
||||||
|
{
|
||||||
|
var hour = startHour.AddHours(i);
|
||||||
|
var hourData = hourlyGrouped.Where(x => x.Hour == hour).ToList();
|
||||||
|
|
||||||
|
var modelBreakdown = hourData.Select(x => new ModelTokenBreakdownDto
|
||||||
|
{
|
||||||
|
ModelId = x.ModelId,
|
||||||
|
Tokens = x.Tokens
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
result.Add(new HourlyTokenUsageDto
|
||||||
|
{
|
||||||
|
Hour = hour,
|
||||||
|
TotalTokens = modelBreakdown.Sum(x => x.Tokens),
|
||||||
|
ModelBreakdown = modelBreakdown
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户今日各模型使用量统计(卡片列表)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>模型今日使用量列表,包含使用次数和总Token</returns>
|
||||||
|
public async Task<List<ModelTodayUsageDto>> GetTodayModelUsageAsync([FromQuery]UsageStatisticsGetInput input)
|
||||||
|
{
|
||||||
|
var userId = CurrentUser.GetId();
|
||||||
|
var todayStart = DateTime.Today; // 今天凌晨0点
|
||||||
|
var tomorrowStart = todayStart.AddDays(1);
|
||||||
|
|
||||||
|
// 从Message表查询今天的数据,只选择需要的字段
|
||||||
|
var messages = await _messageRepository._DbQueryable
|
||||||
|
.Where(x => x.UserId == userId)
|
||||||
|
.Where(x => x.Role == "system")
|
||||||
|
.Where(x => x.CreationTime >= todayStart && x.CreationTime < tomorrowStart)
|
||||||
|
.WhereIF(input.TokenId.HasValue, x => x.TokenId == input.TokenId)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.ModelId,
|
||||||
|
x.TokenUsage.TotalTokenCount
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// 在内存中按模型分组统计
|
||||||
|
var modelStats = messages
|
||||||
|
.GroupBy(x => x.ModelId)
|
||||||
|
.Select(g => new ModelTodayUsageDto
|
||||||
|
{
|
||||||
|
ModelId = g.Key,
|
||||||
|
UsageCount = g.Count(),
|
||||||
|
TotalTokens = g.Sum(x => x.TotalTokenCount)
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.TotalTokens)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
return modelStats;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user