mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-05-06 18:22:44 +08:00
Refactor face clustering service and related interfaces
This commit is contained in:
28
Extensions/ApiExtensions.cs
Normal file
28
Extensions/ApiExtensions.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Scalar.AspNetCore;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// API相关的扩展方法
|
||||
/// </summary>
|
||||
public static class ApiExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加应用程序OpenAPI
|
||||
/// </summary>
|
||||
public static IServiceCollection AddApplicationOpenApi(this IServiceCollection services)
|
||||
{
|
||||
services.AddOpenApi(opt => { opt.AddDocumentTransformer<BearerSecuritySchemeTransformer>(); });
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用应用程序OpenAPI
|
||||
/// </summary>
|
||||
public static WebApplication UseApplicationOpenApi(this WebApplication app)
|
||||
{
|
||||
app.MapOpenApi();
|
||||
app.MapScalarApiReference();
|
||||
return app;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Scalar.AspNetCore;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
public static class ApplicationBuilderExtensions
|
||||
{
|
||||
public static void UseApplicationStaticFiles(this WebApplication app)
|
||||
{
|
||||
var uploadsPath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads");
|
||||
if (!Directory.Exists(uploadsPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadsPath);
|
||||
}
|
||||
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(uploadsPath),
|
||||
RequestPath = "/Uploads"
|
||||
});
|
||||
}
|
||||
|
||||
public static void UseApplicationOpenApi(this WebApplication app)
|
||||
{
|
||||
app.MapOpenApi();
|
||||
app.MapScalarApiReference();
|
||||
}
|
||||
}
|
||||
56
Extensions/ApplicationConfigurationExtensions.cs
Normal file
56
Extensions/ApplicationConfigurationExtensions.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Foxel.Services.Initializer;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序配置扩展方法
|
||||
/// </summary>
|
||||
public static class ApplicationConfigurationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置应用程序中间件管道
|
||||
/// </summary>
|
||||
public static WebApplication ConfigureApplicationPipeline(this WebApplication app)
|
||||
{
|
||||
// 转发头处理
|
||||
app.UseForwardedHeaders();
|
||||
|
||||
// 静态文件
|
||||
app.UseApplicationStaticFiles();
|
||||
|
||||
// 开发环境特定配置
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
// API文档
|
||||
app.UseApplicationOpenApi();
|
||||
|
||||
// CORS
|
||||
app.UseCors("MyAllowSpecificOrigins");
|
||||
|
||||
// 身份验证和授权
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
// 路由
|
||||
app.MapControllers();
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化应用程序
|
||||
/// </summary>
|
||||
public static async Task<WebApplication> InitializeApplicationAsync(this WebApplication app)
|
||||
{
|
||||
using var scope = app.Services.CreateScope();
|
||||
var initializer = scope.ServiceProvider.GetRequiredService<IDatabaseInitializer>();
|
||||
await initializer.InitializeAsync();
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
40
Extensions/ApplicationServiceExtensions.cs
Normal file
40
Extensions/ApplicationServiceExtensions.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序服务配置扩展方法
|
||||
/// </summary>
|
||||
public static class ApplicationServiceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加所有应用程序服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddApplicationServices(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
// 基础服务
|
||||
services.AddControllers();
|
||||
services.AddHttpServices();
|
||||
|
||||
// 数据库
|
||||
services.AddApplicationDbContext(configuration);
|
||||
|
||||
// 核心业务服务
|
||||
services.AddCoreServices();
|
||||
services.AddManagementServices();
|
||||
services.AddBackgroundServices();
|
||||
services.AddAiServices();
|
||||
services.AddInitializationServices();
|
||||
|
||||
// 身份验证和授权
|
||||
services.AddApplicationAuthentication();
|
||||
services.AddApplicationAuthorization();
|
||||
services.AddApplicationCors();
|
||||
|
||||
// API文档
|
||||
services.AddApplicationOpenApi();
|
||||
|
||||
// HTTP相关
|
||||
services.AddForwardedHeaders();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
75
Extensions/AuthenticationExtensions.cs
Normal file
75
Extensions/AuthenticationExtensions.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text;
|
||||
using Foxel.Services.Configuration;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 身份验证和授权相关的扩展方法
|
||||
/// </summary>
|
||||
public static class AuthenticationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加应用程序身份验证
|
||||
/// </summary>
|
||||
public static IServiceCollection AddApplicationAuthentication(this IServiceCollection services)
|
||||
{
|
||||
// 构建临时服务提供者来获取配置服务
|
||||
using var serviceProvider = services.BuildServiceProvider();
|
||||
var configuration = serviceProvider.GetRequiredService<IConfigService>();
|
||||
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidIssuer = configuration["Jwt:Issuer"],
|
||||
ValidAudience = configuration["Jwt:Audience"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]))
|
||||
};
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加应用程序授权
|
||||
/// </summary>
|
||||
public static IServiceCollection AddApplicationAuthorization(this IServiceCollection services)
|
||||
{
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.DefaultPolicy = new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
|
||||
.RequireAuthenticatedUser()
|
||||
.Build();
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加应用程序CORS配置
|
||||
/// </summary>
|
||||
public static IServiceCollection AddApplicationCors(this IServiceCollection services)
|
||||
{
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(name: "MyAllowSpecificOrigins",
|
||||
policy => { policy.WithOrigins().AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); });
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
94
Extensions/CoreServiceExtensions.cs
Normal file
94
Extensions/CoreServiceExtensions.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using Foxel.Services;
|
||||
using Foxel.Services.AI;
|
||||
using Foxel.Services.Auth;
|
||||
using Foxel.Services.Background;
|
||||
using Foxel.Services.Background.Processors;
|
||||
using Foxel.Services.Configuration;
|
||||
using Foxel.Services.Initializer;
|
||||
using Foxel.Services.Management;
|
||||
using Foxel.Services.Mapping;
|
||||
using Foxel.Services.Media;
|
||||
using Foxel.Services.Storage;
|
||||
using Foxel.Services.VectorDb;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 核心业务服务相关的扩展方法
|
||||
/// </summary>
|
||||
public static class CoreServiceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加核心业务服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddCoreServices(this IServiceCollection services)
|
||||
{
|
||||
// 配置服务
|
||||
services.AddSingleton<IConfigService, ConfigService>();
|
||||
|
||||
// 核心业务服务
|
||||
services.AddSingleton<IAiService, AiService>();
|
||||
services.AddSingleton<IPictureService, PictureService>();
|
||||
services.AddSingleton<IAuthService, AuthService>();
|
||||
services.AddSingleton<ITagService, TagService>();
|
||||
services.AddSingleton<IAlbumService, AlbumService>();
|
||||
services.AddSingleton<IStorageService, StorageService>();
|
||||
services.AddSingleton<IMappingService, MappingService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加管理服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddManagementServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IUserManagementService, UserManagementService>();
|
||||
services.AddSingleton<IPictureManagementService, PictureManagementService>();
|
||||
services.AddSingleton<IAlbumManagementService, AlbumManagementService>();
|
||||
services.AddSingleton<ILogManagementService, LogManagementService>();
|
||||
services.AddSingleton<IStorageManagementService, StorageManagementService>();
|
||||
services.AddSingleton<IFaceManagementService, FaceManagementService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加后台任务服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddBackgroundServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
|
||||
services.AddHostedService<QueuedHostedService>();
|
||||
|
||||
// 任务处理器
|
||||
services.AddSingleton<PictureTaskProcessor>();
|
||||
services.AddSingleton<FaceRecognitionTaskProcessor>();
|
||||
services.AddSingleton<VisualRecognitionTaskProcessor>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加AI和向量数据库服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddAiServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IFaceClusteringService, FaceClusteringService>();
|
||||
services.AddSingleton<VectorDbManager>();
|
||||
services.AddSingleton<IVectorDbService>(provider =>
|
||||
provider.GetRequiredService<VectorDbManager>());
|
||||
services.AddHostedService<VectorDbInitializer>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加初始化服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddInitializationServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IDatabaseInitializer, DatabaseInitializer>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
27
Extensions/DatabaseExtensions.cs
Normal file
27
Extensions/DatabaseExtensions.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库相关的扩展方法
|
||||
/// </summary>
|
||||
public static class DatabaseExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加应用程序数据库上下文
|
||||
/// </summary>
|
||||
public static IServiceCollection AddApplicationDbContext(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var connectionString = configuration.GetConnectionString("DefaultConnection");
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
connectionString = Environment.GetEnvironmentVariable("DEFAULT_CONNECTION");
|
||||
}
|
||||
|
||||
Console.WriteLine($"数据库连接: {connectionString}");
|
||||
services.AddDbContextFactory<MyDbContext>(options =>
|
||||
options.UseNpgsql(connectionString));
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
56
Extensions/HttpExtensions.cs
Normal file
56
Extensions/HttpExtensions.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// HTTP相关的扩展方法
|
||||
/// </summary>
|
||||
public static class HttpExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加HTTP相关服务
|
||||
/// </summary>
|
||||
public static IServiceCollection AddHttpServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddHttpClient();
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddMemoryCache();
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置转发头信息
|
||||
/// </summary>
|
||||
public static IServiceCollection AddForwardedHeaders(this IServiceCollection services)
|
||||
{
|
||||
services.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
options.KnownNetworks.Clear();
|
||||
options.KnownProxies.Clear();
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用应用程序静态文件
|
||||
/// </summary>
|
||||
public static WebApplication UseApplicationStaticFiles(this WebApplication app)
|
||||
{
|
||||
var uploadsPath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads");
|
||||
if (!Directory.Exists(uploadsPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadsPath);
|
||||
}
|
||||
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(uploadsPath),
|
||||
RequestPath = "/Uploads"
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using Foxel.Services;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text;
|
||||
using Foxel.Services.AI;
|
||||
using Foxel.Services.Auth;
|
||||
using Foxel.Services.Background;
|
||||
using Foxel.Services.Configuration;
|
||||
using Foxel.Services.Initializer;
|
||||
using Foxel.Services.Management;
|
||||
using Foxel.Services.Media;
|
||||
using Foxel.Services.Storage;
|
||||
using Foxel.Services.Background.Processors;
|
||||
using Foxel.Services.Mapping;
|
||||
using Foxel.Services.VectorDb;
|
||||
|
||||
namespace Foxel.Extensions;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static void AddCoreServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigService, ConfigService>();
|
||||
services.AddSingleton<IAiService, AiService>();
|
||||
services.AddSingleton<IPictureService, PictureService>();
|
||||
services.AddSingleton<IAuthService, AuthService>();
|
||||
services.AddSingleton<ITagService, TagService>();
|
||||
services.AddSingleton<IAlbumService, AlbumService>();
|
||||
services.AddSingleton<IUserManagementService, UserManagementService>();
|
||||
services.AddSingleton<IPictureManagementService, PictureManagementService>();
|
||||
services.AddSingleton<IAlbumManagementService, AlbumManagementService>();
|
||||
services.AddSingleton<ILogManagementService, LogManagementService>();
|
||||
services.AddSingleton<IStorageManagementService, StorageManagementService>();
|
||||
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
|
||||
services.AddHostedService<QueuedHostedService>();
|
||||
services.AddSingleton<IStorageService, StorageService>();
|
||||
services.AddSingleton<PictureTaskProcessor>();
|
||||
services.AddSingleton<FaceRecognitionTaskProcessor>();
|
||||
services.AddSingleton<VisualRecognitionTaskProcessor>();
|
||||
services.AddSingleton<IDatabaseInitializer, DatabaseInitializer>();
|
||||
services.AddSingleton<IMappingService, MappingService>();
|
||||
services.AddSingleton<IFaceManagementService, FaceManagementService>();
|
||||
services.AddSingleton<IFaceClusteringService, FaceClusteringService>();
|
||||
|
||||
}
|
||||
|
||||
public static void AddApplicationDbContext(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var connectionString = configuration.GetConnectionString("DefaultConnection");
|
||||
if (string.IsNullOrEmpty(connectionString))
|
||||
{
|
||||
connectionString = Environment.GetEnvironmentVariable("DEFAULT_CONNECTION");
|
||||
}
|
||||
|
||||
Console.WriteLine($"数据库连接: {connectionString}");
|
||||
services.AddDbContextFactory<MyDbContext>(options =>
|
||||
options.UseNpgsql(connectionString));
|
||||
}
|
||||
|
||||
public static void AddApplicationOpenApi(this IServiceCollection services)
|
||||
{
|
||||
services.AddOpenApi(opt => { opt.AddDocumentTransformer<BearerSecuritySchemeTransformer>(); });
|
||||
}
|
||||
|
||||
public static void AddApplicationAuthentication(this IServiceCollection services)
|
||||
{
|
||||
IConfigService configuration = services.BuildServiceProvider().GetRequiredService<IConfigService>();
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
|
||||
})
|
||||
.AddJwtBearer(options =>
|
||||
{
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
ValidateAudience = true,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidIssuer = configuration["Jwt:Issuer"],
|
||||
ValidAudience = configuration["Jwt:Audience"],
|
||||
IssuerSigningKey = new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddApplicationAuthorization(this IServiceCollection services)
|
||||
{
|
||||
services.AddAuthorization(options =>
|
||||
{
|
||||
options.DefaultPolicy = new Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder()
|
||||
.RequireAuthenticatedUser()
|
||||
.Build();
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddApplicationCors(this IServiceCollection services)
|
||||
{
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(name: "MyAllowSpecificOrigins",
|
||||
policy => { policy.WithOrigins().AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); });
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddVectorDbServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<VectorDbManager>();
|
||||
services.AddSingleton<IVectorDbService>(provider =>
|
||||
provider.GetRequiredService<VectorDbManager>());
|
||||
}
|
||||
}
|
||||
8
Models/BatchDeleteResult.cs
Normal file
8
Models/BatchDeleteResult.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Foxel.Models;
|
||||
|
||||
public class BatchDeleteResult
|
||||
{
|
||||
public int SuccessCount { get; set; }
|
||||
public int FailedCount { get; set; }
|
||||
public List<int> FailedIds { get; set; } = new();
|
||||
}
|
||||
53
Program.cs
53
Program.cs
@@ -1,52 +1,27 @@
|
||||
using Foxel.Extensions;
|
||||
using Foxel.Services.Initializer;
|
||||
using Foxel.Services.VectorDb;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var environment = builder.Environment;
|
||||
|
||||
Console.WriteLine($"当前环境: {environment.EnvironmentName}");
|
||||
|
||||
// 配置日志记录
|
||||
builder.Logging.AddDatabaseLogging(config =>
|
||||
{
|
||||
config.MinLevel = LogLevel.Information;
|
||||
config.Enabled = true;
|
||||
});
|
||||
builder.Services.AddMemoryCache();
|
||||
builder.Services.AddApplicationDbContext(builder.Configuration);
|
||||
builder.Services.AddApplicationOpenApi();
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddHttpClient();
|
||||
builder.Services.AddCoreServices();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddApplicationAuthentication();
|
||||
builder.Services.AddApplicationAuthorization();
|
||||
builder.Services.AddApplicationCors();
|
||||
builder.Services.AddVectorDbServices();
|
||||
builder.Services.AddHostedService<VectorDbInitializer>();
|
||||
builder.Services.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
options.KnownNetworks.Clear();
|
||||
options.KnownProxies.Clear();
|
||||
});
|
||||
|
||||
// 添加所有应用程序服务
|
||||
builder.Services.AddApplicationServices(builder.Configuration);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var initializer = scope.ServiceProvider.GetRequiredService<IDatabaseInitializer>();
|
||||
await initializer.InitializeAsync();
|
||||
}
|
||||
app.UseForwardedHeaders();
|
||||
app.UseApplicationStaticFiles();
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
app.UseHsts();
|
||||
}
|
||||
app.UseApplicationOpenApi();
|
||||
app.UseCors("MyAllowSpecificOrigins");
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.MapControllers();
|
||||
app.UseHttpsRedirection();
|
||||
// 初始化应用程序
|
||||
await app.InitializeApplicationAsync();
|
||||
|
||||
// 配置中间件管道
|
||||
app.ConfigureApplicationPipeline();
|
||||
|
||||
// 启动应用程序
|
||||
app.Run();
|
||||
@@ -12,11 +12,4 @@ public interface IUserManagementService
|
||||
Task<UserResponse> UpdateUserAsync(int id, string userName, string email, string role);
|
||||
Task<bool> DeleteUserAsync(int id);
|
||||
Task<BatchDeleteResult> BatchDeleteUsersAsync(List<int> ids);
|
||||
}
|
||||
|
||||
public class BatchDeleteResult
|
||||
{
|
||||
public int SuccessCount { get; set; }
|
||||
public int FailedCount { get; set; }
|
||||
public List<int> FailedIds { get; set; } = new();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user