feat: 完成ai-hub第一期功能

This commit is contained in:
chenchun
2025-06-25 17:12:09 +08:00
parent 4f71d874bd
commit 695aaedfba
18 changed files with 360 additions and 103 deletions

View File

@@ -5,17 +5,17 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Client;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using OpenAI.Chat;
using Volo.Abp.Application.Services;
using Volo.Abp.Users;
using Yi.Framework.AiHub.Application.Contracts.Dtos;
using Yi.Framework.AiHub.Application.Contracts.Options;
using Yi.Framework.AiHub.Domain.Entities;
using Yi.Framework.AiHub.Domain.Managers;
using Yi.Framework.Rbac.Application.Contracts.IServices;
using Yi.Framework.Rbac.Domain.Shared.Dtos;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.AiHub.Application.Services;
@@ -24,16 +24,17 @@ namespace Yi.Framework.AiHub.Application.Services;
/// </summary>
public class AiChatService : ApplicationService
{
private readonly AiGateWayOptions _options;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly AiMessageManager _aiMessageManager;
private readonly ISqlSugarRepository<AiModelEntity> _aiModelRepository;
private readonly AiBlacklistManager _aiBlacklistManager;
public AiChatService(IOptions<AiGateWayOptions> options, IHttpContextAccessor httpContextAccessor,
AiMessageManager aiMessageManager)
public AiChatService(IHttpContextAccessor httpContextAccessor,
AiMessageManager aiMessageManager, AiBlacklistManager aiBlacklistManager)
{
_options = options.Value;
this._httpContextAccessor = httpContextAccessor;
_aiMessageManager = aiMessageManager;
_aiBlacklistManager = aiBlacklistManager;
}
@@ -56,18 +57,20 @@ public class AiChatService : ApplicationService
/// <returns></returns>
public async Task<List<ModelGetListOutput>> GetModelAsync()
{
var output = _options.Chats.SelectMany(x => x.Value.ModelIds)
.Select(x => new ModelGetListOutput()
{
Id = 001,
Category = "chat",
ModelName = x,
ModelDescribe = "这是一个直连模型",
ModelPrice = 4,
ModelType = "1",
ModelShow = "0",
Remark = "直连模型"
}).ToList();
var output = await _aiModelRepository._DbQueryable.Select(x => new ModelGetListOutput
{
Id = x.Id,
Category = "chat",
ModelName = x.Name,
ModelDescribe = x.Description,
ModelPrice = 0,
ModelType = "1",
ModelShow = "0",
SystemPrompt = null,
ApiHost = null,
ApiKey = null,
Remark = x.Description
}).ToListAsync();
return output;
}
@@ -79,6 +82,25 @@ public class AiChatService : ApplicationService
/// <param name="cancellationToken"></param>
public async Task PostSendAsync(SendMessageInput input, CancellationToken cancellationToken)
{
//除了免费模型,其他的模型都要校验
if (input.Model != "DeepSeek-R1-0528")
{
//有token需要黑名单校验
if (CurrentUser.IsAuthenticated)
{
await _aiBlacklistManager.VerifiyAiBlacklist(CurrentUser.GetId());
if (!CurrentUser.Roles.Contains("YiXinAi-Vip"))
{
throw new UserFriendlyException("该模型需要VIP用户才能使用请购买VIP后重新登录重试");
}
}
else
{
throw new UserFriendlyException("未登录用户只能使用未加速的DeepSeek-R1请登录后重试");
}
}
//前面都是校验,后面才是真正的调用
var httpContext = this._httpContextAccessor.HttpContext;
var response = httpContext.Response;
// 设置响应头,声明是 SSE 流
@@ -116,7 +138,7 @@ public class AiChatService : ApplicationService
// 启动一个后台任务来消费队列
var outputTask = Task.Run(async () =>
{
while (!(isComplete&&messageQueue.IsEmpty))
while (!(isComplete && messageQueue.IsEmpty))
{
if (messageQueue.TryDequeue(out var message))
{
@@ -153,16 +175,15 @@ public class AiChatService : ApplicationService
await outputTask;
if (CurrentUser.IsAuthenticated && input.SessionId.HasValue)
{
// 等待接入token
// await _aiMessageManager.CreateMessageAsync(CurrentUser.GetId(), input.SessionId.Value, new MessageInputDto
// {
// Content = null,
// Role = null,
// DeductCost = 0,
// TotalTokens = 0,
// ModelId = null,
// Remark = null
// });
await _aiMessageManager.CreateMessageAsync(CurrentUser.GetId(), input.SessionId.Value, new MessageInputDto
{
Content = input.Messages.LastOrDefault().Content,
Role = input.Messages.LastOrDefault().Role,
DeductCost = 0,
TotalTokens = 0,
ModelId = input.Model,
Remark = null
});
}
}