From 0de07e733a4edc7780bd742c7060ae242acf7eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Thu, 12 Feb 2026 15:53:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Learn.VideoAnalysis.API/Program.cs | 40 ++++----- VideoAnalysis/Program.cs | 56 +++++-------- VideoAnalysis/Properties/launchSettings.json | 18 +---- VideoAnalysis/appsettings.json | 7 ++ VideoAnalysisCore/Common/AppConfig.cs | 2 +- .../Common/Expand/AppConfigExpand.cs | 81 ++++++++++++++++++- .../Common/Expand/ServiceSystem.cs | 77 ++++++++++++++++++ .../Common/Expand/SqlSugarExpand.cs | 2 +- VideoAnalysisCore/VideoAnalysisCore.csproj | 6 -- 10 files changed, 204 insertions(+), 86 deletions(-) create mode 100644 VideoAnalysisCore/Common/Expand/ServiceSystem.cs diff --git a/.gitignore b/.gitignore index 6bd25cf..4d3f223 100644 --- a/.gitignore +++ b/.gitignore @@ -368,3 +368,4 @@ VideoAnalysisCore/AICore/_Static/ VideoAnalysis/WebUI/node_modules/ VideoAnalysis/WebUI/dist/ VideoAnalysis/WebUI/.vscode/ +/VideoAnalysis/device_id.config diff --git a/Learn.VideoAnalysis.API/Program.cs b/Learn.VideoAnalysis.API/Program.cs index fe52835..5272232 100644 --- a/Learn.VideoAnalysis.API/Program.cs +++ b/Learn.VideoAnalysis.API/Program.cs @@ -1,4 +1,4 @@ - + using Learn.VideoAnalysis.API.Expand; using Mapster; using Microsoft.AspNetCore.Hosting.Server.Features; @@ -25,29 +25,29 @@ namespace Learn.VideoAnalysis.API builder.Services.AddControllers(options => { - // ȫģ͸ֵĬֵ ͳһظʽ + // 全局模型赋值默认值 和 统一返回格式处理 options.Filters.Add(); }).AddJsonOptions(options => { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//תʱʹUnicode - //options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// ĬСշ null շ + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//中文转换时不使用Unicode + //options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰 }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { - var file = Path.Combine(AppContext.BaseDirectory, "Learn.VideoAnalysis.API.xml"); // xmlĵ· - var file1 = Path.Combine(AppContext.BaseDirectory, "VideoAnalysisCore.xml"); // xmlĵ· - c.IncludeXmlComments(file, true); // true : ʾע - c.IncludeXmlComments(file1, true); // true : ʾע - c.OrderActionsBy(o => o.RelativePath); // actionƽжͿԿЧˡ + var file = Path.Combine(AppContext.BaseDirectory, "Learn.VideoAnalysis.API.xml"); // xml文档绝对路径 + var file1 = Path.Combine(AppContext.BaseDirectory, "VideoAnalysisCore.xml"); // xml文档绝对路径 + c.IncludeXmlComments(file, true); // true : 显示控制器层注释 + c.IncludeXmlComments(file1, true); // true : 显示控制器层注释 + c.OrderActionsBy(o => o.RelativePath); // 对action的名称进行排序,如果有多个,就可以看见效果了。 }); builder.Services.AddMapster(); - //ʼ - builder.Configuration.AddAppConfig(args); + //初始化 插件 + builder.AddAppConfig(args); builder.Services.AddHttpClient(); builder.Services.AddSqlSugarExpand(); @@ -77,23 +77,13 @@ namespace Learn.VideoAnalysis.API app.MapControllers(); - //Զ Ӧ + //自定义 应用 app.UseCorsExpand(); app.UseSqlSugarExpand(); app.UseCoravelExpand(); - // עĻص - app.Lifetime.ApplicationStarted.Register(() => - { - var server = app.Services.GetRequiredService(); - var addressFeature = server.Features.Get(); - Console.WriteLine("==========================================="); - Console.WriteLine($"Kestrel ַ: "); - foreach (var address in addressFeature.Addresses) - { - Console.WriteLine($"{address}"); - } - Console.WriteLine("==========================================="); - }); + // 注册启动后的回调 + app.UseServiceSystem(); + app.Run(); } diff --git a/VideoAnalysis/Program.cs b/VideoAnalysis/Program.cs index 5ed3ecb..0a82ed1 100644 --- a/VideoAnalysis/Program.cs +++ b/VideoAnalysis/Program.cs @@ -1,4 +1,4 @@ -using VideoAnalysisCore.Common; +using VideoAnalysisCore.Common; using Microsoft.OpenApi.Models; using VideoAnalysisCore.AICore.SherpaOnnx; using Mapster; @@ -27,44 +27,46 @@ namespace Learn.VideoAnalysis { public static void Main(string[] args) { + //交互式环境选择函数 + AppConfigExpand.SelectEnvironment(ref args); var builder = WebApplication.CreateBuilder(args); - //ýӿ100m + //设置接口请求体最大100m builder.WebHost.ConfigureKestrel(serverOptions => { serverOptions.Limits.MaxRequestBodySize = 100_000_000; // 100MB }); builder.Services.AddLogging(loggingBuilder => { - loggingBuilder.ClearProviders(); // Ĭϵ־ṩ - loggingBuilder.AddConsole(); // ӿ̨־ṩ - loggingBuilder.SetMinimumLevel(LogLevel.Warning); // С־Ϊ Warning + loggingBuilder.ClearProviders(); // 清除默认的日志提供程序 + loggingBuilder.AddConsole(); // 添加控制台日志提供程序 + loggingBuilder.SetMinimumLevel(LogLevel.Warning); // 设置最小日志级别为 Warning }); - // appsetting - builder.Configuration.AddAppConfig(args); - //ʼ + //绑定 appsetting 配置 + builder.AddAppConfig(args); + //初始化 插件 builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerExpand("AIƵ"); + builder.Services.AddSwaggerExpand("AI视频分析"); builder.Services.AddPermissionAuthentication(); builder.Services.AddSqlSugarExpand(); builder.Services.AddRedisExpand(); - // + //工作流 builder.Services.AddSimpleTexOcrClient(); builder.Services.AddDownloadFileExpand(); builder.Services.AddFFMPGEExpand(); builder.Services.AddAlibabaCloudVod(); builder.Services.AddAliyunOSS(); - //תд + //语音转写 builder.Services.AddSenseVoiceExpand(); builder.Services.AddFunASRNanoExpand(); builder.Services.AddSherpaVadExpand(); //builder.Services.AddSpeakerAI(); - //ʱ + //定时任务 builder.Services.AddCoravel(); - //쳣 + //异常过滤器 builder.Services.AddControllersWithViews(options => { options.Filters.Add(typeof(ExceptionFilter)); @@ -72,8 +74,8 @@ namespace Learn.VideoAnalysis builder.Services.AddControllers() .AddJsonOptions(options => { - options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//תʱʹUnicode - options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// ĬСշ null շ + options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//中文转换时不使用Unicode + options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰 options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; }); @@ -104,15 +106,15 @@ namespace Learn.VideoAnalysis AppCommon.Services = app.Services; app.UseMiddleware("Swagger"); // Configure the HTTP request pipeline. - //redisз + //开启redis队列服务 _ = app.Services.GetRequiredService(); app.UseSwagger(); app.UseSwaggerUI(); app.UseExceptionHandler("/Error"); - //wwwroot ̬Ŀ¼ + //添加wwwroot 静态目录 app.UseStaticFiles(); - // Զ ̬Ŀ¼ + //添加 自定义 静态目录 app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(AppCommon.TaskCachedFile), @@ -127,25 +129,11 @@ namespace Learn.VideoAnalysis app.MapControllers(); - //Զ Ӧ + //自定义 应用 app.UseCorsExpand(); app.UseSqlSugarExpand(); app.UseCoravelExpand(); - - // עĻص - app.Lifetime.ApplicationStarted.Register(() => - { - var server = app.Services.GetRequiredService(); - var addressFeature = server.Features.Get(); - Console.WriteLine("==========================================="); - Console.WriteLine($"Kestrel ַ: "); - foreach (var address in addressFeature.Addresses) - { - Console.WriteLine($"{address}"); - } - Console.WriteLine("==========================================="); - }); - + app.UseServiceSystem(); app.Run(); diff --git a/VideoAnalysis/Properties/launchSettings.json b/VideoAnalysis/Properties/launchSettings.json index cc4737e..a82d71a 100644 --- a/VideoAnalysis/Properties/launchSettings.json +++ b/VideoAnalysis/Properties/launchSettings.json @@ -1,31 +1,15 @@ { "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:9624", - "sslPort": 0 - } - }, "profiles": { "http:5238": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "ui/index.html", - "applicationUrl": "http://*:5238", + "applicationUrl": "http://*:7532", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } } } diff --git a/VideoAnalysis/appsettings.json b/VideoAnalysis/appsettings.json index 39b9fd6..9bb72db 100644 --- a/VideoAnalysis/appsettings.json +++ b/VideoAnalysis/appsettings.json @@ -1,4 +1,11 @@ { + "Kestrel": { + "Endpoints": { + "Http": { + "Url": "http://*:7532" + } + } + }, "Logging": { "LogLevel": { "Default": "Warning", diff --git a/VideoAnalysisCore/Common/AppConfig.cs b/VideoAnalysisCore/Common/AppConfig.cs index 00be2fd..89f9d27 100644 --- a/VideoAnalysisCore/Common/AppConfig.cs +++ b/VideoAnalysisCore/Common/AppConfig.cs @@ -16,7 +16,7 @@ namespace VideoAnalysisCore.Common /// /// 程序ID /// - public string ID { get; set; } = string.Empty; + public ushort ID { get; set; } = 0; /// /// Admin /// diff --git a/VideoAnalysisCore/Common/Expand/AppConfigExpand.cs b/VideoAnalysisCore/Common/Expand/AppConfigExpand.cs index 37236b5..41b56e6 100644 --- a/VideoAnalysisCore/Common/Expand/AppConfigExpand.cs +++ b/VideoAnalysisCore/Common/Expand/AppConfigExpand.cs @@ -1,6 +1,8 @@ using Coravel; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; using System.Collections.Generic; +using System.Net.NetworkInformation; using VideoAnalysisCore.Common; using VideoAnalysisCore.Job; @@ -8,16 +10,45 @@ namespace VideoAnalysisCore.Common.Expand { public static class AppConfigExpand { - public static void AddAppConfig(this IConfigurationManager cm, string[] args) + public static ushort GenerateIdFromIpPower() + { + var mac = NetworkInterface.GetAllNetworkInterfaces() + .Where(n => n.OperationalStatus == OperationalStatus.Up && n.NetworkInterfaceType != NetworkInterfaceType.Loopback) + .Select(n => n.GetPhysicalAddress()) + .FirstOrDefault(addr => addr.GetAddressBytes().Length > 0); + + if (mac == null) return 0; + + byte[] bytes = mac.GetAddressBytes(); + // 取 MAC 地址的最后两个字节生成 ushort + return (ushort)((bytes[^2] << 8) | bytes[^1]); + } + public static ushort GetPersistentDeviceId() + { + string path = "device_id.config"; + if (File.Exists(path)) + { + return ushort.Parse(File.ReadAllText(path)); + } + + // 首次启动,生成 ID (比如用你之前的 IP 幂运算法) + ushort newId = GenerateIdFromIpPower(); + File.WriteAllText(path, newId.ToString()); + return newId; + } + public static void AddAppConfig(this IHostApplicationBuilder hb, string[] args) { Console.WriteLine($"{DateTime.Now}=>初始化 AppConfig"); - cm.GetSection("AppConfig").Bind(AppCommon.Config); + hb.Configuration.GetSection("AppConfig").Bind(AppCommon.Config); + AppCommon.Config.ID = GetPersistentDeviceId(); var argList = args.ToList(); var eArgs = Environment.GetEnvironmentVariable("va_args"); if (!string.IsNullOrEmpty(eArgs)) argList.AddRange(eArgs.Split(",")); Console.WriteLine("==========================================="); + Console.WriteLine($"设备ID:{AppCommon.Config.ID}"); + Console.WriteLine($"当前环境: {hb.Environment.EnvironmentName}"); Console.WriteLine("启动参数如下:"); Console.WriteLine(string.Join(',', args)); Console.WriteLine("==========================================="); @@ -25,5 +56,51 @@ namespace VideoAnalysisCore.Common.Expand if (args.Contains("IS_Server")) AppCommon.Config.TaskSetting.IS_Server = true; } + + /// + /// 交互式环境选择函数 + /// + public static void SelectEnvironment(ref string[] args) + { + // 如果没有控制台(如在某些后台服务或重定向中),则跳过交互 + if (Console.IsInputRedirected) return; + + Console.Title = "ASP.NET Core 环境选择器"; + Console.WriteLine("=================================================="); + Console.WriteLine(" 请选择程序运行环境 (直接回车默认使用开发环境)"); + Console.WriteLine("=================================================="); + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine(" [1] 生产环境 (Production)"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(" [2] 测试环境 (Staging)"); + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine(" [3] 开发环境 (Development)"); + Console.ResetColor(); + Console.WriteLine("=================================================="); + Console.Write(" 请输入编号 [1/2/3] (默认 3): "); + + // 获取输入 + string? input = Console.ReadLine()?.Trim(); + + // 映射逻辑 + string selectedEnv = input switch + { + "1" => Environments.Production, + "2" => Environments.Staging, + "3" => Environments.Development, + _ => Environments.Development // 输入错误或直接回车,默认走开发环境 + }; + + // 核心:在 Build 之前覆盖环境名 + args = args.Concat( new[] { "--environment", selectedEnv }).ToArray(); + + // 成功反馈 + Console.Clear(); + Console.BackgroundColor = ConsoleColor.DarkBlue; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine($" 已确认切换至: {selectedEnv} 模式 "); + Console.ResetColor(); + Console.WriteLine(); + } } } diff --git a/VideoAnalysisCore/Common/Expand/ServiceSystem.cs b/VideoAnalysisCore/Common/Expand/ServiceSystem.cs new file mode 100644 index 0000000..9423ac3 --- /dev/null +++ b/VideoAnalysisCore/Common/Expand/ServiceSystem.cs @@ -0,0 +1,77 @@ +using Coravel; +using Coravel.Scheduling.Schedule; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using VideoAnalysisCore.Job; +using Microsoft.Extensions.Hosting; +using VideoAnalysisCore.Common; +using System.Diagnostics; + +namespace VideoAnalysisCore.Common.Expand +{ + public static class ServiceSystemExpand + { + /// + /// 系统服务 + /// + /// + public static void UseServiceSystem(this IHost app1) + { + var app = app1.Services; + // 注册启动后的回调 + app.GetRequiredService() + .ApplicationStarted.Register(() => + { + var server = AppCommon.Services.GetRequiredService(); + var addressFeature = server.Features.Get(); + Console.WriteLine("==========================================="); + Console.WriteLine($"Kestrel 监听地址: "); + foreach (var address in addressFeature.Addresses) + { + Console.WriteLine($"{address}"); + } + Console.WriteLine("==========================================="); + // 将 "*" 替换为 "localhost" 或 "127.0.0.1",因为 Uri 类不直接支持带有通配符的 Host + var normalizedAddress = addressFeature.Addresses.First() + .Replace("*", "127.0.0.1") + .Replace("+", "127.0.0.1"); + var uri = new Uri(normalizedAddress); + int port = uri.Port; // 这里的 port 就是你要的数字 (int) + OpenBrowser($"http://localhost:{uri.Port}/ui/index.html"); + }); + } + + // 跨平台打开浏览器的方法 + static void OpenBrowser(string url) + { + try + { + if (OperatingSystem.IsWindows()) + { + Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); + } + else if (OperatingSystem.IsLinux()) + { + Process.Start("xdg-open", url); + } + else if (OperatingSystem.IsMacOS()) + { + Process.Start("open", url); + } + } + catch (Exception ex) + { + Console.WriteLine($"无法自动打开浏览器: {ex.Message}"); + } + } + } +} diff --git a/VideoAnalysisCore/Common/Expand/SqlSugarExpand.cs b/VideoAnalysisCore/Common/Expand/SqlSugarExpand.cs index 7942bf6..d3b0eed 100644 --- a/VideoAnalysisCore/Common/Expand/SqlSugarExpand.cs +++ b/VideoAnalysisCore/Common/Expand/SqlSugarExpand.cs @@ -28,7 +28,7 @@ namespace VideoAnalysisCore.Common.Expand HttpServiceCollectionExtensions.AddHttpContextAccessor(services); Console.WriteLine($"{DateTime.Now}=>初始化 YitId雪花ID"); - var options = new IdGeneratorOptions(ushort.Parse(AppCommon.Config.ID)); + var options = new IdGeneratorOptions((ushort)(AppCommon.Config.ID % 63)); YitIdHelper.SetIdGenerator(options); #region SqlSugar注入 diff --git a/VideoAnalysisCore/VideoAnalysisCore.csproj b/VideoAnalysisCore/VideoAnalysisCore.csproj index ae987c4..a9fc04c 100644 --- a/VideoAnalysisCore/VideoAnalysisCore.csproj +++ b/VideoAnalysisCore/VideoAnalysisCore.csproj @@ -35,10 +35,4 @@ - - - - Never - -