using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using SqlSugar; using Volo.Abp.Application.Services; using Volo.Abp.Users; using Yi.Framework.AiHub.Application.Contracts.Dtos.DailyTask; using Yi.Framework.AiHub.Domain.Entities; using Yi.Framework.AiHub.Domain.Entities.Chat; using Yi.Framework.AiHub.Domain.Extensions; using Yi.Framework.AiHub.Domain.Managers; using Yi.Framework.AiHub.Domain.Shared.Consts; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.AiHub.Application.Services; /// /// 每日任务服务 /// [Authorize] public class DailyTaskService : ApplicationService { private readonly ISqlSugarRepository _dailyTaskRepository; private readonly ISqlSugarRepository _messageRepository; private readonly ISqlSugarRepository _premiumPackageRepository; private readonly ILogger _logger; // 任务配置 private readonly Dictionary _taskConfigs = new() { { 1, (10000000, 1000000, "尊享包1000w token任务", "累积使用尊享包 1000w token") }, // 1000w消耗 -> 100w奖励 { 2, (30000000, 2000000, "尊享包3000w token任务", "累积使用尊享包 3000w token") } // 3000w消耗 -> 200w奖励 }; public DailyTaskService( ISqlSugarRepository dailyTaskRepository, ISqlSugarRepository messageRepository, ISqlSugarRepository premiumPackageRepository, ILogger logger) { _dailyTaskRepository = dailyTaskRepository; _messageRepository = messageRepository; _premiumPackageRepository = premiumPackageRepository; _logger = logger; } /// /// 获取今日任务状态 /// /// public async Task GetTodayTaskStatusAsync() { var userId = CurrentUser.GetId(); var today = DateTime.Today; // 1. 统计今日尊享包Token消耗量 var todayConsumed = await GetTodayPremiumTokenConsumptionAsync(userId, today); // 2. 查询今日已领取的任务 var claimedTasks = await _dailyTaskRepository._DbQueryable .Where(x => x.UserId == userId && x.TaskDate == today) .Select(x => new { x.TaskLevel, x.IsRewarded }) .ToListAsync(); // 3. 构建任务列表 var tasks = new List(); foreach (var (level, config) in _taskConfigs) { var claimed = claimedTasks.FirstOrDefault(x => x.TaskLevel == level); int status; if (claimed != null && claimed.IsRewarded) { status = 2; // 已领取 } else if (todayConsumed >= config.RequiredTokens) { status = 1; // 可领取 } else { status = 0; // 未完成 } var progress = todayConsumed >= config.RequiredTokens ? 100 : Math.Round((decimal)todayConsumed / config.RequiredTokens * 100, 2); tasks.Add(new DailyTaskItem { Level = level, Name = config.Name, Description = config.Description, RequiredTokens = config.RequiredTokens, RewardTokens = config.RewardTokens, Status = status, Progress = progress }); } return new DailyTaskStatusOutput { TodayConsumedTokens = todayConsumed, Tasks = tasks }; } /// /// 领取任务奖励 /// /// /// public async Task ClaimTaskRewardAsync(ClaimTaskRewardInput input) { var userId = CurrentUser.GetId(); var today = DateTime.Today; // 1. 验证任务等级 if (!_taskConfigs.TryGetValue(input.TaskLevel, out var taskConfig)) { throw new UserFriendlyException($"无效的任务等级: {input.TaskLevel}"); } // 2. 检查是否已领取 var existingRecord = await _dailyTaskRepository._DbQueryable .Where(x => x.UserId == userId && x.TaskDate == today && x.TaskLevel == input.TaskLevel) .FirstAsync(); if (existingRecord != null) { throw new UserFriendlyException("今日该任务奖励已领取,请明天再来!"); } // 3. 验证今日Token消耗是否达标 var todayConsumed = await GetTodayPremiumTokenConsumptionAsync(userId, today); if (todayConsumed < taskConfig.RequiredTokens) { throw new UserFriendlyException( $"Token消耗未达标!需要 {taskConfig.RequiredTokens / 10000}w,当前 {todayConsumed / 10000}w"); } // 4. 创建奖励包(使用 PremiumPackageManager) var premiumPackage = new PremiumPackageAggregateRoot(userId, taskConfig.RewardTokens, $"每日任务:{taskConfig.Name}") { PurchaseAmount = 0, // 奖励不需要付费 Remark = $"{today:yyyy-MM-dd} 每日任务奖励" }; await _premiumPackageRepository.InsertAsync(premiumPackage); // 5. 记录领取记录 var record = new DailyTaskRewardRecordAggregateRoot(userId, input.TaskLevel, today, taskConfig.RewardTokens) { Remark = $"完成任务{input.TaskLevel},名称:{taskConfig.Name},消耗 {todayConsumed / 10000}w token" }; await _dailyTaskRepository.InsertAsync(record); _logger.LogInformation( $"用户 {userId} 领取每日任务 {input.TaskLevel} 奖励成功,获得 {taskConfig.RewardTokens / 10000}w tokens"); } /// /// 获取今日尊享包Token消耗量 /// /// 用户ID /// 今日日期 /// 消耗的Token总数 private async Task GetTodayPremiumTokenConsumptionAsync(Guid userId, DateTime today) { var tomorrow = today.AddDays(1); // 查询今日所有使用尊享包模型的消息(role=system 表示消耗) var totalTokens = await _messageRepository._DbQueryable .Where(x => x.UserId == userId) .Where(x => x.Role == "system") // system角色表示实际消耗 .Where(x => PremiumPackageConst.ModeIds.Contains(x.ModelId)) // 尊享包模型 .Where(x => x.CreationTime >= today && x.CreationTime < tomorrow) .SumAsync(x => x.TokenUsage.TotalTokenCount); return totalTokens; } }