Files
Yi.Admin/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/UsageStatisticsService.cs

167 lines
6.2 KiB
C#
Raw Normal View History

2025-11-10 15:18:05 +08:00
using Mapster;
2025-08-09 22:55:26 +08:00
using Microsoft.AspNetCore.Authorization;
2025-11-10 15:18:05 +08:00
using Microsoft.AspNetCore.Mvc;
2025-08-09 22:55:26 +08:00
using SqlSugar;
2025-11-10 15:18:05 +08:00
using Volo.Abp.Application.Dtos;
2025-08-09 22:55:26 +08:00
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.AiHub.Domain.Extensions;
2025-11-10 15:18:05 +08:00
using Yi.Framework.Ddd.Application.Contracts;
2025-08-09 22:55:26 +08:00
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;
private readonly ISqlSugarRepository<PremiumPackageAggregateRoot> _premiumPackageRepository;
2025-08-09 22:55:26 +08:00
public UsageStatisticsService(
ISqlSugarRepository<MessageAggregateRoot> messageRepository,
ISqlSugarRepository<UsageStatisticsAggregateRoot> usageStatisticsRepository,
ISqlSugarRepository<PremiumPackageAggregateRoot> premiumPackageRepository)
2025-08-09 22:55:26 +08:00
{
_messageRepository = messageRepository;
_usageStatisticsRepository = usageStatisticsRepository;
_premiumPackageRepository = premiumPackageRepository;
2025-08-09 22:55:26 +08:00
}
/// <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.Role == "assistant" || x.Role == "system")
2025-08-09 22:55:26 +08:00
.Where(x => x.CreationTime >= startDate && x.CreationTime < endDate.AddDays(1))
.GroupBy(x => x.CreationTime.Date)
.Select(g => new
{
Date = g.CreationTime.Date,
Tokens = SqlFunc.AggregateSum(g.TokenUsage.TotalTokenCount)
2025-08-09 22:55:26 +08:00
})
.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;
}
/// <summary>
/// 获取当前用户尊享服务Token用量统计
/// </summary>
/// <returns>尊享服务Token用量统计</returns>
public async Task<PremiumTokenUsageDto> GetPremiumTokenUsageAsync()
{
var userId = CurrentUser.GetId();
// 获取尊享包Token信息
var premiumPackages = await _premiumPackageRepository._DbQueryable
.Where(x => x.UserId == userId && x.IsActive)
.ToListAsync();
var result = new PremiumTokenUsageDto();
if (premiumPackages.Any())
{
// 过滤掉已过期、禁用的包,不过滤用量负数的包
var validPackages = premiumPackages
.Where(p => p.IsAvailable(false))
.ToList();
result.PremiumTotalTokens = validPackages.Sum(x => x.TotalTokens);
result.PremiumUsedTokens = validPackages.Sum(x => x.UsedTokens);
result.PremiumRemainingTokens = validPackages.Sum(x => x.RemainingTokens);
}
return result;
}
2025-11-10 15:18:05 +08:00
/// <summary>
/// 获取当前用户尊享服务token用量统计列表
/// </summary>
/// <returns></returns>
[HttpGet("usage-statistics/premium-token-usage/list")]
public async Task<PagedResultDto<PremiumTokenUsageGetListOutput>> GetPremiumTokenUsageListAsync(
PremiumTokenUsageGetListInput input)
2025-11-10 15:18:05 +08:00
{
var userId = CurrentUser.GetId();
RefAsync<int> total = 0;
// 获取尊享包Token信息
var entities = await _premiumPackageRepository._DbQueryable
.Where(x => x.UserId == userId)
.WhereIF(input.IsFree == false, x => x.PurchaseAmount > 0)
.WhereIF(input.IsFree == true, x => x.PurchaseAmount == 0)
.WhereIF(input.StartTime is not null && input.EndTime is not null,
x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.OrderByDescending(x => x.CreationTime)
2025-11-10 15:18:05 +08:00
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<PremiumTokenUsageGetListOutput>(total,
entities.Adapt<List<PremiumTokenUsageGetListOutput>>());
2025-11-10 15:18:05 +08:00
}
2025-08-09 22:55:26 +08:00
}