feat: 新增用户数据导出功能
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 每日Token使用量统计DTO
|
||||||
|
/// </summary>
|
||||||
|
public class DailyTokenUsageDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 日期
|
||||||
|
/// </summary>
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Token消耗量
|
||||||
|
/// </summary>
|
||||||
|
public long Tokens { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模型Token使用量统计DTO
|
||||||
|
/// </summary>
|
||||||
|
public class ModelTokenUsageDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 模型ID
|
||||||
|
/// </summary>
|
||||||
|
public string Model { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 总消耗量
|
||||||
|
/// </summary>
|
||||||
|
public long Tokens { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 占比(百分比)
|
||||||
|
/// </summary>
|
||||||
|
public decimal Percentage { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
|
||||||
|
namespace Yi.Framework.AiHub.Application.Contracts.IServices;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用量统计服务接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IUsageStatisticsService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户近7天的Token消耗统计
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>每日Token使用量列表</returns>
|
||||||
|
Task<List<DailyTokenUsageDto>> GetLast7DaysTokenUsageAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户各个模型的Token消耗量及占比
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>模型Token使用量列表</returns>
|
||||||
|
Task<List<ModelTokenUsageDto>> GetModelTokenUsageAsync();
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using SqlSugar;
|
||||||
|
using Volo.Abp.Application.Services;
|
||||||
|
using Volo.Abp.Users;
|
||||||
|
using Yi.Framework.AiHub.Application.Contracts.Dtos.UsageStatistics;
|
||||||
|
using Yi.Framework.AiHub.Application.Contracts.IServices;
|
||||||
|
using Yi.Framework.AiHub.Domain.Entities;
|
||||||
|
using Yi.Framework.AiHub.Domain.Entities.Chat;
|
||||||
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
|
namespace Yi.Framework.AiHub.Application.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用量统计服务
|
||||||
|
/// </summary>
|
||||||
|
[Authorize]
|
||||||
|
public class UsageStatisticsService : ApplicationService, IUsageStatisticsService
|
||||||
|
{
|
||||||
|
private readonly ISqlSugarRepository<MessageAggregateRoot> _messageRepository;
|
||||||
|
private readonly ISqlSugarRepository<UsageStatisticsAggregateRoot> _usageStatisticsRepository;
|
||||||
|
|
||||||
|
public UsageStatisticsService(
|
||||||
|
ISqlSugarRepository<MessageAggregateRoot> messageRepository,
|
||||||
|
ISqlSugarRepository<UsageStatisticsAggregateRoot> usageStatisticsRepository)
|
||||||
|
{
|
||||||
|
_messageRepository = messageRepository;
|
||||||
|
_usageStatisticsRepository = usageStatisticsRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户近7天的Token消耗统计
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>每日Token使用量列表</returns>
|
||||||
|
public async Task<List<DailyTokenUsageDto>> GetLast7DaysTokenUsageAsync()
|
||||||
|
{
|
||||||
|
var userId = CurrentUser.GetId();
|
||||||
|
var endDate = DateTime.Today;
|
||||||
|
var startDate = endDate.AddDays(-6); // 近7天
|
||||||
|
|
||||||
|
// 从Message表统计近7天的token消耗
|
||||||
|
var dailyUsage = await _messageRepository._DbQueryable
|
||||||
|
.Where(x => x.UserId == userId)
|
||||||
|
.Where(x => x.CreationTime >= startDate && x.CreationTime < endDate.AddDays(1))
|
||||||
|
.GroupBy(x => x.CreationTime.Date)
|
||||||
|
.Select(g => new
|
||||||
|
{
|
||||||
|
Date = g.CreationTime.Date,
|
||||||
|
Tokens = SqlFunc.AggregateCount(g.TokenUsage.TotalTokenCount)
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
// 生成完整的7天数据,包括没有使用记录的日期
|
||||||
|
var result = new List<DailyTokenUsageDto>();
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
var date = startDate.AddDays(i);
|
||||||
|
var usage = dailyUsage.FirstOrDefault(x => x.Date == date);
|
||||||
|
|
||||||
|
result.Add(new DailyTokenUsageDto
|
||||||
|
{
|
||||||
|
Date = date,
|
||||||
|
Tokens = usage?.Tokens ?? 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.OrderBy(x => x.Date).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前用户各个模型的Token消耗量及占比
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>模型Token使用量列表</returns>
|
||||||
|
public async Task<List<ModelTokenUsageDto>> GetModelTokenUsageAsync()
|
||||||
|
{
|
||||||
|
var userId = CurrentUser.GetId();
|
||||||
|
|
||||||
|
// 从UsageStatistics表获取各模型的token消耗统计
|
||||||
|
var modelUsages = await _usageStatisticsRepository._DbQueryable
|
||||||
|
.Where(x => x.UserId == userId)
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.ModelId,
|
||||||
|
x.TotalTokenCount
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (!modelUsages.Any())
|
||||||
|
{
|
||||||
|
return new List<ModelTokenUsageDto>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算总token数
|
||||||
|
var totalTokens = modelUsages.Sum(x => x.TotalTokenCount);
|
||||||
|
|
||||||
|
// 计算各模型占比
|
||||||
|
var result = modelUsages.Select(x => new ModelTokenUsageDto
|
||||||
|
{
|
||||||
|
Model = x.ModelId,
|
||||||
|
Tokens = x.TotalTokenCount,
|
||||||
|
Percentage = totalTokens > 0 ? Math.Round((decimal)x.TotalTokenCount / totalTokens * 100, 2) : 0
|
||||||
|
}).OrderByDescending(x => x.Tokens).ToList();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user