diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Dtos/AiChatContextDto.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Dtos/AiChatContextDto.cs new file mode 100644 index 00000000..4a337f5a --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Dtos/AiChatContextDto.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.ChatHub.Application.Dtos +{ + public class AiChatContextDto + { + public AnswererTypeEnum AnswererType { get; set; } + + public string Message { get; set; } + + + public int Number { get; set; } + } + + public enum AnswererTypeEnum + { + Ai, + User + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/AiChatService.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/AiChatService.cs new file mode 100644 index 00000000..e499c1b5 --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Application/Services/AiChatService.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.SignalR; +using Volo.Abp.Application.Services; +using Yi.Framework.ChatHub.Domain.Managers; +using Yi.Framework.ChatHub.Domain.Shared.Model; +using Yi.Framework.ChatHub.Domain.SignalRHubs; + +namespace Yi.Framework.ChatHub.Application.Services +{ + public class AiChatService : ApplicationService + { + private readonly AiManager _aiManager; + private readonly UserMessageManager _userMessageManager; + public AiChatService(AiManager aiManager, UserMessageManager userMessageManager) { _aiManager = aiManager; _userMessageManager = userMessageManager; } + + [Authorize] + [HttpPost] + public async Task ChatAsync() + { + await foreach (var aiResult in _aiManager.ChatAsStreamAsync()) + { + await _userMessageManager.SendMessageAsync(MessageContext.CreateAi(aiResult, CurrentUser.Id!.Value)); + } + } + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Enums/MessageTypeEnum.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Enums/MessageTypeEnum.cs index 85d16e35..5a8c558d 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Enums/MessageTypeEnum.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Enums/MessageTypeEnum.cs @@ -9,7 +9,7 @@ namespace Yi.Framework.ChatHub.Domain.Shared.Enums public enum MessageTypeEnum { - + Ai, Personal, Group, All diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs index c02469d5..a340641e 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Model/MessageContext.cs @@ -41,6 +41,12 @@ namespace Yi.Framework.ChatHub.Domain.Shared.Model return new MessageContext() { MessageType = MessageTypeEnum.Personal, Content = content, ReceiveId = userId, SendUserId = sendUserId }; } + + public static MessageContext CreateAi(string content, Guid receiveId) + { + return new MessageContext() { MessageType = MessageTypeEnum.Ai, Content = content, ReceiveId = receiveId }; + } + public static MessageContext CreateAll(string content, Guid sendUserId) { return new MessageContext() { MessageType = MessageTypeEnum.All, Content = content, SendUserId = sendUserId }; diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Options/AiOptions.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Options/AiOptions.cs new file mode 100644 index 00000000..46affbaa --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/Options/AiOptions.cs @@ -0,0 +1,8 @@ +namespace Yi.Framework.ChatHub.Domain.Shared.Options +{ + public class AiOptions + { + public string ApiKey { get; set; } + public string BaseDomain { get; set; } + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/YiFrameworkChatHubDomainSharedModule.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/YiFrameworkChatHubDomainSharedModule.cs index e4b3d581..231f5e42 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/YiFrameworkChatHubDomainSharedModule.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain.Shared/YiFrameworkChatHubDomainSharedModule.cs @@ -1,14 +1,20 @@ -using Volo.Abp.Domain; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Domain; using Yi.Framework.Bbs.Domain.Shared; +using Yi.Framework.ChatHub.Domain.Shared.Options; namespace Yi.Framework.ChatHub.Domain.Shared { [DependsOn( typeof(AbpDddDomainSharedModule), - + typeof(YiFrameworkBbsDomainSharedModule))] public class YiFrameworkChatHubDomainSharedModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + Configure(configuration.GetSection("AiOptions")); + } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs new file mode 100644 index 00000000..be696e9a --- /dev/null +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/AiManager.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using OpenAI; +using OpenAI.Managers; +using OpenAI.ObjectModels; +using OpenAI.ObjectModels.RequestModels; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Services; +using Yi.Framework.ChatHub.Domain.Shared.Options; + +namespace Yi.Framework.ChatHub.Domain.Managers +{ + public class AiManager : DomainService, ISingletonDependency + { + public AiManager(IOptions options) + { + this.OpenAIService = new OpenAIService(new OpenAiOptions() + { + ApiKey = options.Value.ApiKey, + BaseDomain = options.Value.BaseDomain + }); + } + private OpenAIService OpenAIService { get; } + + public async IAsyncEnumerable ChatAsStreamAsync() + { + var completionResult = OpenAIService.ChatCompletion.CreateCompletionAsStream(new ChatCompletionCreateRequest + { + Messages = new List + { + ChatMessage.FromUser("特朗普是谁?"), + }, + Model = Models.Gpt_4, + }); + + await foreach (var result in completionResult) + { + if (result.Successful) + { + yield return result.Choices.FirstOrDefault()?.Message.Content??string.Empty; + } + } + + } + } +} diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs index fdb65016..06d2a9ad 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Managers/UserMessageManager.cs @@ -48,6 +48,14 @@ namespace Yi.Framework.ChatHub.Domain.Managers case MessageTypeEnum.All: await _hubContext.Clients.All.SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context); break; + case MessageTypeEnum.Ai: + var userModel2 = await GetUserAsync(context.ReceiveId.Value); + if (userModel2 is not null) + { + await _hubContext.Clients.Client(userModel2.ClientId).SendAsync(ChatConst.ClientActionReceiveMsg, context.MessageType, context); + } + break; + default: break; } diff --git a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj index f4b49527..023d8888 100644 --- a/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj +++ b/Yi.Abp.Net8/module/chat-hub/Yi.Framework.ChatHub.Domain/Yi.Framework.ChatHub.Domain.csproj @@ -7,7 +7,7 @@ - + diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json b/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json index 5d34d6cd..b5930132 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json @@ -87,5 +87,12 @@ //开启定时数据库备份 "EnableDataBaseBackup": false + }, + + + //OpenAi + "AiOptions": { + "ApiKey": "", + "BaseDomain": "" } }