diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/DailyTask/DailyTaskConfigCacheDto.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/DailyTask/DailyTaskConfigCacheDto.cs
new file mode 100644
index 00000000..a1998211
--- /dev/null
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/DailyTask/DailyTaskConfigCacheDto.cs
@@ -0,0 +1,43 @@
+namespace Yi.Framework.AiHub.Application.Contracts.Dtos.DailyTask;
+
+///
+/// 每日任务配置缓存DTO
+///
+public class DailyTaskConfigCacheDto
+{
+ ///
+ /// 任务配置列表
+ ///
+ public List Tasks { get; set; } = new();
+}
+
+///
+/// 每日任务配置项
+///
+public class DailyTaskConfigItem
+{
+ ///
+ /// 任务等级
+ ///
+ public int Level { get; set; }
+
+ ///
+ /// 需要消耗的Token数量
+ ///
+ public long RequiredTokens { get; set; }
+
+ ///
+ /// 奖励的Token数量
+ ///
+ public long RewardTokens { get; set; }
+
+ ///
+ /// 任务名称
+ ///
+ public string Name { get; set; } = string.Empty;
+
+ ///
+ /// 任务描述
+ ///
+ public string Description { get; set; } = string.Empty;
+}
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs
index 33394c9a..4a66601a 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Activities/DailyTaskService.cs
@@ -1,8 +1,10 @@
using Medallion.Threading;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using SqlSugar;
using Volo.Abp.Application.Services;
+using Volo.Abp.Caching;
using Volo.Abp.Users;
using Yi.Framework.AiHub.Application.Contracts.Dtos.DailyTask;
using Yi.Framework.AiHub.Domain.Entities;
@@ -25,27 +27,33 @@ public class DailyTaskService : ApplicationService
private readonly ISqlSugarRepository _messageRepository;
private readonly ISqlSugarRepository _premiumPackageRepository;
private readonly ILogger _logger;
+ private readonly IDistributedCache _taskConfigCache;
private IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetRequiredService();
private readonly ISqlSugarRepository _aiModelRepository;
- // 任务配置
- private readonly Dictionary
- _taskConfigs = new()
- {
- { 1, (10000000, 1000000, "尊享包1000w token任务", "累积使用尊享包 1000w token") }, // 1000w消耗 -> 100w奖励
- { 2, (30000000, 2000000, "尊享包3000w token任务", "累积使用尊享包 3000w token") } // 3000w消耗 -> 200w奖励
- };
+
+ private const string TaskConfigCacheKey = "AiHub:DailyTaskConfig";
+
+ // 默认任务配置(当Redis中没有配置时使用)
+ private static readonly List DefaultTaskConfigs = new()
+ {
+ new DailyTaskConfigItem { Level = 1, RequiredTokens = 10000000, RewardTokens = 1000000, Name = "尊享包1000w token任务", Description = "累积使用尊享包 1000w token" },
+ new DailyTaskConfigItem { Level = 2, RequiredTokens = 30000000, RewardTokens = 2000000, Name = "尊享包3000w token任务", Description = "累积使用尊享包 3000w token" }
+ };
public DailyTaskService(
ISqlSugarRepository dailyTaskRepository,
ISqlSugarRepository messageRepository,
ISqlSugarRepository premiumPackageRepository,
- ILogger logger, ISqlSugarRepository aiModelRepository)
+ ILogger logger,
+ ISqlSugarRepository aiModelRepository,
+ IDistributedCache taskConfigCache)
{
_dailyTaskRepository = dailyTaskRepository;
_messageRepository = messageRepository;
_premiumPackageRepository = premiumPackageRepository;
_logger = logger;
_aiModelRepository = aiModelRepository;
+ _taskConfigCache = taskConfigCache;
}
///
@@ -57,20 +65,23 @@ public class DailyTaskService : ApplicationService
var userId = CurrentUser.GetId();
var today = DateTime.Today;
- // 1. 统计今日尊享包Token消耗量
+ // 1. 获取任务配置
+ var taskConfigs = await GetTaskConfigsAsync();
+
+ // 2. 统计今日尊享包Token消耗量
var todayConsumed = await GetTodayPremiumTokenConsumptionAsync(userId, today);
- // 2. 查询今日已领取的任务
+ // 3. 查询今日已领取的任务
var claimedTasks = await _dailyTaskRepository._DbQueryable
.Where(x => x.UserId == userId && x.TaskDate == today)
.Select(x => new { x.TaskLevel, x.IsRewarded })
.ToListAsync();
- // 3. 构建任务列表
+ // 4. 构建任务列表
var tasks = new List();
- foreach (var (level, config) in _taskConfigs)
+ foreach (var config in taskConfigs)
{
- var claimed = claimedTasks.FirstOrDefault(x => x.TaskLevel == level);
+ var claimed = claimedTasks.FirstOrDefault(x => x.TaskLevel == config.Level);
int status;
if (claimed != null && claimed.IsRewarded)
@@ -92,7 +103,7 @@ public class DailyTaskService : ApplicationService
tasks.Add(new DailyTaskItem
{
- Level = level,
+ Level = config.Level,
Name = config.Name,
Description = config.Description,
RequiredTokens = config.RequiredTokens,
@@ -120,17 +131,20 @@ public class DailyTaskService : ApplicationService
//自旋等待,防抖
await using var handle =
await DistributedLock.AcquireLockAsync($"Yi:AiHub:ClaimTaskRewardLock:{userId}");
-
-
+
var today = DateTime.Today;
- // 1. 验证任务等级
- if (!_taskConfigs.TryGetValue(input.TaskLevel, out var taskConfig))
+ // 1. 获取任务配置
+ var taskConfigs = await GetTaskConfigsAsync();
+ var taskConfig = taskConfigs.FirstOrDefault(x => x.Level == input.TaskLevel);
+
+ // 2. 验证任务等级
+ if (taskConfig == null)
{
throw new UserFriendlyException($"无效的任务等级: {input.TaskLevel}");
}
- // 2. 检查是否已领取
+ // 3. 检查是否已领取
var existingRecord = await _dailyTaskRepository._DbQueryable
.Where(x => x.UserId == userId && x.TaskDate == today && x.TaskLevel == input.TaskLevel)
.FirstAsync();
@@ -140,7 +154,7 @@ public class DailyTaskService : ApplicationService
throw new UserFriendlyException("今日该任务奖励已领取,请明天再来!");
}
- // 3. 验证今日Token消耗是否达标
+ // 4. 验证今日Token消耗是否达标
var todayConsumed = await GetTodayPremiumTokenConsumptionAsync(userId, today);
if (todayConsumed < taskConfig.RequiredTokens)
{
@@ -148,18 +162,17 @@ public class DailyTaskService : ApplicationService
$"Token消耗未达标!需要 {taskConfig.RequiredTokens / 10000}w,当前 {todayConsumed / 10000}w");
}
- // 4. 创建奖励包(使用 PremiumPackageManager)
-
+ // 5. 创建奖励包
var premiumPackage =
new PremiumPackageAggregateRoot(userId, taskConfig.RewardTokens, $"每日任务:{taskConfig.Name}")
{
- PurchaseAmount = 0, // 奖励不需要付费
+ PurchaseAmount = 0,
Remark = $"{today:yyyy-MM-dd} 每日任务奖励"
};
await _premiumPackageRepository.InsertAsync(premiumPackage);
- // 5. 记录领取记录
+ // 6. 记录领取记录
var record = new DailyTaskRewardRecordAggregateRoot(userId, input.TaskLevel, today, taskConfig.RewardTokens)
{
Remark = $"完成任务{input.TaskLevel},名称:{taskConfig.Name},消耗 {todayConsumed / 10000}w token"
@@ -197,4 +210,21 @@ public class DailyTaskService : ApplicationService
return totalTokens;
}
+
+ ///
+ /// 从Redis获取任务配置,如果不存在则写入默认配置
+ ///
+ private async Task> GetTaskConfigsAsync()
+ {
+ var cacheData = await _taskConfigCache.GetOrAddAsync(
+ TaskConfigCacheKey,
+ () => Task.FromResult(new DailyTaskConfigCacheDto { Tasks = DefaultTaskConfigs }),
+ () => new DistributedCacheEntryOptions
+ {
+ // 不设置过期时间,永久缓存,需要手动更新
+ }
+ );
+
+ return cacheData?.Tasks ?? DefaultTaskConfigs;
+ }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs
index 69ef325e..bec50005 100644
--- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs
+++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs
@@ -94,6 +94,7 @@ public class AiChatService : ApplicationService
public async Task> GetModelAsync()
{
var output = await _aiModelRepository._DbQueryable
+ .Where(x=>x.IsEnabled==true)
.Where(x => x.ModelType == ModelTypeEnum.Chat)
.Where(x => x.ModelApiType == ModelApiTypeEnum.OpenAi)
.OrderByDescending(x => x.OrderNum)