feat: finalize core modules and gateway
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TakeoutSaaS.Application.Dictionary.Abstractions;
|
||||
using TakeoutSaaS.Domain.Dictionary.Repositories;
|
||||
using TakeoutSaaS.Infrastructure.Common.Extensions;
|
||||
using TakeoutSaaS.Infrastructure.Common.Options;
|
||||
using TakeoutSaaS.Infrastructure.Dictionary.Options;
|
||||
using TakeoutSaaS.Infrastructure.Dictionary.Persistence;
|
||||
using TakeoutSaaS.Infrastructure.Dictionary.Repositories;
|
||||
using TakeoutSaaS.Infrastructure.Dictionary.Services;
|
||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.Dictionary.Extensions;
|
||||
|
||||
@@ -19,18 +21,14 @@ public static class DictionaryServiceCollectionExtensions
|
||||
/// <summary>
|
||||
/// 注册字典模块基础设施。
|
||||
/// </summary>
|
||||
/// <param name="services">服务集合。</param>
|
||||
/// <param name="configuration">配置源。</param>
|
||||
/// <returns>服务集合。</returns>
|
||||
/// <exception cref="InvalidOperationException">缺少数据库配置时抛出。</exception>
|
||||
public static IServiceCollection AddDictionaryInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var connectionString = configuration.GetConnectionString("AppDatabase");
|
||||
if (string.IsNullOrWhiteSpace(connectionString))
|
||||
{
|
||||
throw new InvalidOperationException("缺少 AppDatabase 连接字符串配置");
|
||||
}
|
||||
|
||||
services.AddDbContext<DictionaryDbContext>(options =>
|
||||
{
|
||||
options.UseNpgsql(connectionString);
|
||||
});
|
||||
services.AddDatabaseInfrastructure(configuration);
|
||||
services.AddPostgresDbContext<DictionaryDbContext>(DatabaseConstants.AppDataSource);
|
||||
|
||||
services.AddScoped<IDictionaryRepository, EfDictionaryRepository>();
|
||||
services.AddScoped<IDictionaryCache, DistributedDictionaryCache>();
|
||||
@@ -41,4 +39,15 @@ public static class DictionaryServiceCollectionExtensions
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确保数据库连接已配置(Database 节或 ConnectionStrings)。
|
||||
/// </summary>
|
||||
/// <param name="configuration">配置源。</param>
|
||||
/// <param name="dataSourceName">数据源名称。</param>
|
||||
/// <exception cref="InvalidOperationException">未配置时抛出。</exception>
|
||||
private static void EnsureDatabaseConnectionConfigured(IConfiguration configuration, string dataSourceName)
|
||||
{
|
||||
// 保留兼容接口,当前逻辑在 DatabaseConnectionFactory 中兜底并记录日志。
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using TakeoutSaaS.Domain.Dictionary.Entities;
|
||||
using TakeoutSaaS.Infrastructure.Common.Persistence;
|
||||
using TakeoutSaaS.Shared.Abstractions.Security;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.Dictionary.Persistence;
|
||||
@@ -9,55 +10,79 @@ namespace TakeoutSaaS.Infrastructure.Dictionary.Persistence;
|
||||
/// <summary>
|
||||
/// 参数字典 DbContext。
|
||||
/// </summary>
|
||||
public sealed class DictionaryDbContext : TenantAwareDbContext
|
||||
public sealed class DictionaryDbContext(
|
||||
DbContextOptions<DictionaryDbContext> options,
|
||||
ITenantProvider tenantProvider,
|
||||
ICurrentUserAccessor? currentUserAccessor = null)
|
||||
: TenantAwareDbContext(options, tenantProvider, currentUserAccessor)
|
||||
{
|
||||
public DictionaryDbContext(DbContextOptions<DictionaryDbContext> options, ITenantProvider tenantProvider)
|
||||
: base(options, tenantProvider)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字典分组集。
|
||||
/// </summary>
|
||||
public DbSet<DictionaryGroup> DictionaryGroups => Set<DictionaryGroup>();
|
||||
|
||||
/// <summary>
|
||||
/// 字典项集。
|
||||
/// </summary>
|
||||
public DbSet<DictionaryItem> DictionaryItems => Set<DictionaryItem>();
|
||||
|
||||
/// <summary>
|
||||
/// 配置实体模型。
|
||||
/// </summary>
|
||||
/// <param name="modelBuilder">模型构建器。</param>
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
ConfigureGroup(modelBuilder.Entity<DictionaryGroup>());
|
||||
ConfigureItem(modelBuilder.Entity<DictionaryItem>());
|
||||
ApplyTenantQueryFilters(modelBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置字典分组。
|
||||
/// </summary>
|
||||
/// <param name="builder">实体构建器。</param>
|
||||
private static void ConfigureGroup(EntityTypeBuilder<DictionaryGroup> builder)
|
||||
{
|
||||
builder.ToTable("dictionary_groups");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.TenantId).IsRequired();
|
||||
builder.Property(x => x.Code).HasMaxLength(64).IsRequired();
|
||||
builder.Property(x => x.Name).HasMaxLength(128).IsRequired();
|
||||
builder.Property(x => x.Scope).HasConversion<int>().IsRequired();
|
||||
builder.Property(x => x.Description).HasMaxLength(512);
|
||||
builder.Property(x => x.IsEnabled).HasDefaultValue(true);
|
||||
builder.Property(x => x.CreatedAt).IsRequired();
|
||||
builder.Property(x => x.UpdatedAt);
|
||||
ConfigureAuditableEntity(builder);
|
||||
ConfigureSoftDeleteEntity(builder);
|
||||
|
||||
builder.HasIndex(x => x.TenantId);
|
||||
builder.HasIndex(x => new { x.TenantId, x.Code }).IsUnique();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置字典项。
|
||||
/// </summary>
|
||||
/// <param name="builder">实体构建器。</param>
|
||||
private static void ConfigureItem(EntityTypeBuilder<DictionaryItem> builder)
|
||||
{
|
||||
builder.ToTable("dictionary_items");
|
||||
builder.HasKey(x => x.Id);
|
||||
builder.Property(x => x.TenantId).IsRequired();
|
||||
builder.Property(x => x.GroupId).IsRequired();
|
||||
builder.Property(x => x.Key).HasMaxLength(64).IsRequired();
|
||||
builder.Property(x => x.Value).HasMaxLength(256).IsRequired();
|
||||
builder.Property(x => x.Description).HasMaxLength(512);
|
||||
builder.Property(x => x.SortOrder).HasDefaultValue(100);
|
||||
builder.Property(x => x.IsEnabled).HasDefaultValue(true);
|
||||
builder.Property(x => x.CreatedAt).IsRequired();
|
||||
builder.Property(x => x.UpdatedAt);
|
||||
ConfigureAuditableEntity(builder);
|
||||
ConfigureSoftDeleteEntity(builder);
|
||||
|
||||
builder.HasOne(x => x.Group)
|
||||
.WithMany(g => g.Items)
|
||||
.HasForeignKey(x => x.GroupId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
builder.HasIndex(x => x.TenantId);
|
||||
builder.HasIndex(x => new { x.GroupId, x.Key }).IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user