diff --git a/HuanMengProject.sln b/HuanMengProject.sln index 2a5c74e..ab28366 100644 --- a/HuanMengProject.sln +++ b/HuanMengProject.sln @@ -44,7 +44,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuanMeng.MiaoYu.Code", "src EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuanMeng.MiaoYu.WebApi", "src\2-api\HuanMeng.MiaoYu.WebApi\HuanMeng.MiaoYu.WebApi.csproj", "{729950F2-71EE-42C0-8B46-295740DE20BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HuanMeng.Utility", "src\0-core\HuanMeng.Utility\HuanMeng.Utility.csproj", "{48E1532F-8B50-477C-BB78-8AEA89A167CE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HuanMeng.Utility", "src\0-core\HuanMeng.Utility\HuanMeng.Utility.csproj", "{48E1532F-8B50-477C-BB78-8AEA89A167CE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/0-core/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs b/src/0-core/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs new file mode 100644 index 0000000..92148b4 --- /dev/null +++ b/src/0-core/HuanMeng.DotNetCore/CustomExtension/CorsExtension.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; + + +namespace HuanMeng.DotNetCore.CustomExtension +{ + /// + /// 添加跨域 + /// + public static class CorsExtension + { + /// + /// 添加跨域 + /// + /// + /// + public static void AddCustomCors(this IServiceCollection services, string policyName) + { + services.AddCors(options => + { + options.AddPolicy(policyName, + builder => + { + builder + .AllowAnyOrigin() + .AllowAnyHeader() + .AllowAnyMethod(); + }); + }); + + + } + } +} diff --git a/src/0-core/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj b/src/0-core/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj index cad8e59..b25005e 100644 --- a/src/0-core/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj +++ b/src/0-core/HuanMeng.DotNetCore/HuanMeng.DotNetCore.csproj @@ -7,11 +7,13 @@ + + diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/BaseClaudeChatChatParams.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/BaseClaudeChatChatParams.cs new file mode 100644 index 0000000..0a9e1d2 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/BaseClaudeChatChatParams.cs @@ -0,0 +1,37 @@ +using HuanMeng.MiaoYu.Code.Chat.Contract; + +using Newtonsoft.Json; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Claude +{ + /// + /// Claude3 通用参数 + /// + public class BaseClaudeChatChatParams : BaseChatParams + { + /// + /// 模型 + /// + public string Model { get; set; } + /// + /// 最大token数 + /// + [JsonProperty("max_tokens")] + public int MaxTokens { get; set; } + /// + /// 上下文 + /// + public string System { get; set; } + + /// + /// 消息内容 + /// + public ClaudeChatMessage[] Messages { get; set; } + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChat.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChat.cs new file mode 100644 index 0000000..202a568 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChat.cs @@ -0,0 +1,71 @@ +using HuanMeng.MiaoYu.Code.Chat.Contract; + +using Microsoft.Extensions.Primitives; + +using Newtonsoft.Json; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Headers; +using System.Net.Http; +using System.Net.Http.Json; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Serialization; + +namespace HuanMeng.MiaoYu.Code.Chat.Claude +{ + /// + /// Claude3 https://docs.anthropic.com/en/api/messages ClaudeChatInfo + /// + public class ClaudeChat(ClaudeChatConfig claudeChatConfig, IHttpClientFactory factory) : IChat + { + public async Task MessagesAsync(BaseChatParams chatParams) + { + var claudeChatChatParams = chatParams as ClaudeChatChatParams; + if (claudeChatChatParams == null) + { + throw new ArgumentException("参数异常"); + } + //添加默认值 + if (claudeChatChatParams.MaxTokens == 0) + { + claudeChatChatParams.MaxTokens = claudeChatConfig.MaxTokens; + } + //添加默认值 + if (!string.IsNullOrEmpty(claudeChatChatParams.Model)) + { + claudeChatChatParams.Model = claudeChatChatParams.Model; + } + //去线程池里拿http线程 + using (var httpClient = factory.CreateClient()) + { + // 设置请求头 + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + httpClient.DefaultRequestHeaders.Add("x-api-key", claudeChatConfig.ApiKey); + httpClient.DefaultRequestHeaders.Add("anthropic-version", claudeChatConfig.AnthropicVersion); + + var settings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + string json = JsonConvert.SerializeObject(chatParams, settings); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + //HttpClientHandler httpClientHandler = new HttpClientHandler(); + //HttpContent httpContent = new JsonContent(); + var response = await httpClient.PostAsync(claudeChatConfig.RequestUrl, content); + if (response.IsSuccessStatusCode) + { + var chatInfo = response.Content.ReadFromJsonAsync(); + } + } + throw new NotImplementedException(); + } + + public IAsyncEnumerable MessagesStreamAsync(BaseChatParams chatParams) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatChatParams.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatChatParams.cs new file mode 100644 index 0000000..a74971c --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatChatParams.cs @@ -0,0 +1,18 @@ +using HuanMeng.MiaoYu.Code.Chat.Contract; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Claude +{ + /// + /// Claude3 请求的参数 + /// + public class ClaudeChatChatParams : BaseClaudeChatChatParams + { + + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatConfig.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatConfig.cs new file mode 100644 index 0000000..e3e73ae --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatConfig.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Claude +{ + /// + /// 配置类 + /// + public class ClaudeChatConfig + { + /// + /// 模型 + /// + public string Model { get; set; } + /// + /// 最大token数 + /// + public int MaxTokens { get; set; } + + /// + /// api key + /// + public string ApiKey { get; set; } + + /// + /// 模型版本 + /// + public string AnthropicVersion { get; set; } + + /// + /// 请求地址 = "api.gptsapi.net"; + /// + public string RequestUrl { get; set; } + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatInfo.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatInfo.cs new file mode 100644 index 0000000..473a82e --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatInfo.cs @@ -0,0 +1,20 @@ +using HuanMeng.MiaoYu.Code.Chat.Contract; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Claude +{ + /// + /// 返回内容 + /// + public class ClaudeChatInfo : BaseChatInfo + { + + } + + +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatMessage.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatMessage.cs new file mode 100644 index 0000000..ebb1247 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Claude/ClaudeChatMessage.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Claude +{ + /// + /// Claude发送消息内容 + /// + public class ClaudeChatMessage + { + /// + /// 角色 + /// + public string Role { get; set; } + /// + /// 内容 + /// + public string Content { get; set; } + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatInfo.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatInfo.cs new file mode 100644 index 0000000..7cbfe33 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatInfo.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Contract +{ + /// + /// 聊天返回的实体类 + /// + public class BaseChatInfo + { + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatParams.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatParams.cs new file mode 100644 index 0000000..b727aab --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatParams.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Contract +{ + /// + /// 聊天请求参数 + /// + public class BaseChatParams + { + + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatStream.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatStream.cs new file mode 100644 index 0000000..ef9c37b --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/BaseChatStream.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Contract +{ + /// + /// 聊天实时流 + /// + public class BaseChatStream + { + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/IChat.cs b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/IChat.cs new file mode 100644 index 0000000..c135c20 --- /dev/null +++ b/src/0-core/HuanMeng.MiaoYu.Code/Chat/Contract/IChat.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HuanMeng.MiaoYu.Code.Chat.Contract +{ + /// + /// 聊天接口 + /// + public interface IChat + { + /// + /// 发送消息 + /// + /// + /// + Task MessagesAsync(BaseChatParams chatParams); + + /// + /// 发送消息 + /// + /// + /// + IAsyncEnumerable MessagesStreamAsync(BaseChatParams chatParams); + } +} diff --git a/src/0-core/HuanMeng.MiaoYu.Model/HuanMeng.MiaoYu.Model.csproj b/src/0-core/HuanMeng.MiaoYu.Model/HuanMeng.MiaoYu.Model.csproj index 1e8b420..db3d3b9 100644 --- a/src/0-core/HuanMeng.MiaoYu.Model/HuanMeng.MiaoYu.Model.csproj +++ b/src/0-core/HuanMeng.MiaoYu.Model/HuanMeng.MiaoYu.Model.csproj @@ -19,7 +19,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/0-core/HuanMeng.StableDiffusion.TextGeneration/BLL/TextGenerationBLL.cs b/src/0-core/HuanMeng.StableDiffusion.TextGeneration/BLL/TextGenerationBLL.cs index 1b73872..d849745 100644 --- a/src/0-core/HuanMeng.StableDiffusion.TextGeneration/BLL/TextGenerationBLL.cs +++ b/src/0-core/HuanMeng.StableDiffusion.TextGeneration/BLL/TextGenerationBLL.cs @@ -1,4 +1,4 @@ -using HuanMeng.StableDiffusion.TextGeneration.api; +using HuanMeng.StableDiffusion.TextGeneration.api; using HuanMeng.StableDiffusion.TextGeneration.Models; using Microsoft.EntityFrameworkCore; diff --git a/src/0-core/HuanMeng.StableDiffusion.TextGeneration/api/TextGenerationRequestHttpApi.cs b/src/0-core/HuanMeng.StableDiffusion.TextGeneration/api/TextGenerationRequestHttpApi.cs index 4c9654d..3e1bb2b 100644 --- a/src/0-core/HuanMeng.StableDiffusion.TextGeneration/api/TextGenerationRequestHttpApi.cs +++ b/src/0-core/HuanMeng.StableDiffusion.TextGeneration/api/TextGenerationRequestHttpApi.cs @@ -1,4 +1,4 @@ -using HuanMeng.StableDiffusion.TextGeneration.Abstractions; +using HuanMeng.StableDiffusion.TextGeneration.Abstractions; using Newtonsoft.Json; @@ -30,6 +30,7 @@ namespace HuanMeng.StableDiffusion.TextGeneration.api } public override async IAsyncEnumerable SendMessageAsync() { + using (var httpClient = new HttpClient()) { // 设置请求头 diff --git a/src/0-core/HuanMeng.Utility/AssemblyHelper/AssemblyInfoHelper.cs b/src/0-core/HuanMeng.Utility/AssemblyHelper/AssemblyInfoHelper.cs index 88f72c6..371a6bf 100644 --- a/src/0-core/HuanMeng.Utility/AssemblyHelper/AssemblyInfoHelper.cs +++ b/src/0-core/HuanMeng.Utility/AssemblyHelper/AssemblyInfoHelper.cs @@ -23,9 +23,9 @@ namespace HuanMeng.Utility.AssemblyHelper // 创建并填充 AssemblyInfo 对象的相关属性 var assemblyInfo = new AssemblyInfo { - Version = assembly.GetCustomAttributes().FirstOrDefault()?.Version ?? "", + Version = assembly.GetName().Version.ToString(), FileVersion = assembly.GetCustomAttributes().FirstOrDefault()?.Version ?? "", - AssemblyVersion = assembly.GetName().Version.ToString(), + AssemblyVersion = assembly.GetCustomAttributes().FirstOrDefault()?.Version ?? "", InformationalVersion = assembly.GetCustomAttributes().FirstOrDefault()?.InformationalVersion ?? "", //Company = assembly.GetCustomAttributes().FirstOrDefault()?.Company ?? "", //Product = assembly.GetCustomAttributes().FirstOrDefault()?.Product ?? "", diff --git a/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs b/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs index 3e94cac..587d526 100644 --- a/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs +++ b/src/2-api/HuanMeng.MiaoYu.WebApi/Program.cs @@ -9,28 +9,16 @@ using HuanMeng.MiaoYu.Code.Users.UserAccount.VerificationCodeManager; using HuanMeng.MiaoYu.Code.JwtUtil; using Microsoft.AspNetCore.Authentication.JwtBearer; using HuanMeng.Utility.AssemblyHelper; +using HuanMeng.DotNetCore.CustomExtension; var builder = WebApplication.CreateBuilder(args); + // 检索程序集信息 AssemblyInfo assemblyInfo = AssemblyInfoHelper.GetAssemblyInfo(); -// Add services to the container. +// Add services to the container. builder.Services.AddHttpContextAccessor(); //添加httpContext注入访问 #region 添加跨域 var _myAllowSpecificOrigins = "_myAllowSpecificOrigins"; - -builder.Services.AddCors(options => -options.AddPolicy(_myAllowSpecificOrigins, -builder => -{ - //builder.AllowAnyHeader().AllowAnyMethod(). - //AllowAnyOrigin(); - //builder.AllowAnyHeader() - // .AllowAnyMethod() - // .SetIsOriginAllowed((host) => true)//限制允许跨域请求的特定源 - // .AllowCredentials();//允许跨域请求发送凭据,如 Cookies、HTTP 认证信息等。启用该配置可能会增加安全风险,因为浏览器会在请求头中包含凭据信息。因此,在设置 AllowCredentials 时,应该确保服务器端的安全性,并且仅允许受信任的源发送包含凭据的请求。 - builder.AllowAnyHeader() - .AllowAnyMethod() - .AllowAnyOrigin();// 许来自任意源的跨域请求 -})); +builder.Services.AddCustomCors(_myAllowSpecificOrigins); #endregion builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies().Where(it => it.FullName.Contains("HuanMeng") || it.FullName.Contains("XLib.")).ToList()); builder.Services.AddControllers(); @@ -73,6 +61,8 @@ builder.Services.AddSwaggerGen(c => c.ParameterFilter(); c.RequestBodyFilter(); }); +//配置路由选项,使URL全部小写 +builder.Services.AddRouting(options => options.LowercaseUrls = true); //添加多租户 builder.AddMultiTenantMiaoYu(); //添加腾讯云管理 @@ -94,8 +84,8 @@ app.UseSwaggerUI(c => c.DefaultModelsExpandDepth(3); c.DefaultModelExpandDepth(3); c.EnableFilter("true"); - //c.RoutePrefix = "swagger"; - //c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1"); + //c.RoutePrefix = string.Empty; + c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1"); }); //}