fix: 统一逐租户上下文执行
This commit is contained in:
@@ -9,6 +9,7 @@ using TakeoutSaaS.Domain.Tenants.Entities;
|
||||
using TakeoutSaaS.Domain.Tenants.Enums;
|
||||
using TakeoutSaaS.Infrastructure.App.Options;
|
||||
using TakeoutSaaS.Infrastructure.Dictionary.Persistence;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Infrastructure.App.Persistence;
|
||||
|
||||
@@ -38,10 +39,11 @@ public sealed class AppDataSeeder(
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var appDbContext = scope.ServiceProvider.GetRequiredService<TakeoutAppDbContext>();
|
||||
var dictionaryDbContext = scope.ServiceProvider.GetRequiredService<DictionaryDbContext>();
|
||||
var tenantContextAccessor = scope.ServiceProvider.GetRequiredService<ITenantContextAccessor>();
|
||||
|
||||
await EnsureSystemTenantAsync(appDbContext, cancellationToken);
|
||||
var defaultTenantId = await EnsureDefaultTenantAsync(appDbContext, cancellationToken);
|
||||
await EnsureDictionarySeedsAsync(dictionaryDbContext, defaultTenantId, cancellationToken);
|
||||
await EnsureDictionarySeedsAsync(dictionaryDbContext, tenantContextAccessor, defaultTenantId, cancellationToken);
|
||||
|
||||
logger.LogInformation("AppSeed 完成业务数据初始化");
|
||||
}
|
||||
@@ -54,6 +56,7 @@ public sealed class AppDataSeeder(
|
||||
/// </summary>
|
||||
private async Task<long?> EnsureDefaultTenantAsync(TakeoutAppDbContext dbContext, CancellationToken cancellationToken)
|
||||
{
|
||||
using var _ = dbContext.DisableSoftDeleteFilter();
|
||||
var tenantOptions = _options.DefaultTenant;
|
||||
if (tenantOptions == null || string.IsNullOrWhiteSpace(tenantOptions.Code) || string.IsNullOrWhiteSpace(tenantOptions.Name))
|
||||
{
|
||||
@@ -63,7 +66,6 @@ public sealed class AppDataSeeder(
|
||||
|
||||
var code = tenantOptions.Code.Trim();
|
||||
var existingTenant = await dbContext.Tenants
|
||||
.IgnoreQueryFilters()
|
||||
.FirstOrDefaultAsync(x => x.Code == code, cancellationToken);
|
||||
|
||||
if (existingTenant == null)
|
||||
@@ -87,6 +89,13 @@ public sealed class AppDataSeeder(
|
||||
|
||||
var updated = false;
|
||||
|
||||
if (existingTenant.DeletedAt.HasValue)
|
||||
{
|
||||
existingTenant.DeletedAt = null;
|
||||
existingTenant.DeletedBy = null;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(existingTenant.Name, tenantOptions.Name, StringComparison.Ordinal))
|
||||
{
|
||||
existingTenant.Name = tenantOptions.Name.Trim();
|
||||
@@ -136,14 +145,21 @@ public sealed class AppDataSeeder(
|
||||
/// </summary>
|
||||
private async Task EnsureSystemTenantAsync(TakeoutAppDbContext dbContext, CancellationToken cancellationToken)
|
||||
{
|
||||
using var _ = dbContext.DisableSoftDeleteFilter();
|
||||
var existingTenant = await dbContext.Tenants
|
||||
.IgnoreQueryFilters()
|
||||
.FirstOrDefaultAsync(x => x.Id == 0, cancellationToken);
|
||||
|
||||
if (existingTenant != null)
|
||||
{
|
||||
// 1. (空行后) 若历史数据仍为 PLATFORM,则自动修正为 SYSTEM
|
||||
var updated = false;
|
||||
|
||||
if (existingTenant.DeletedAt.HasValue)
|
||||
{
|
||||
existingTenant.DeletedAt = null;
|
||||
existingTenant.DeletedBy = null;
|
||||
updated = true;
|
||||
}
|
||||
if (!string.Equals(existingTenant.Code, "SYSTEM", StringComparison.Ordinal))
|
||||
{
|
||||
existingTenant.Code = "SYSTEM";
|
||||
@@ -188,7 +204,11 @@ public sealed class AppDataSeeder(
|
||||
/// <summary>
|
||||
/// 确保基础字典存在。
|
||||
/// </summary>
|
||||
private async Task EnsureDictionarySeedsAsync(DictionaryDbContext dbContext, long? defaultTenantId, CancellationToken cancellationToken)
|
||||
private async Task EnsureDictionarySeedsAsync(
|
||||
DictionaryDbContext dbContext,
|
||||
ITenantContextAccessor tenantContextAccessor,
|
||||
long? defaultTenantId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var dictionaryGroups = _options.DictionaryGroups ?? new List<DictionarySeedGroupOptions>();
|
||||
var hasDictionaryGroups = dictionaryGroups.Count > 0;
|
||||
@@ -211,9 +231,10 @@ public sealed class AppDataSeeder(
|
||||
var tenantId = groupOptions.TenantId ?? defaultTenantId ?? 0;
|
||||
var code = groupOptions.Code.Trim();
|
||||
|
||||
using var tenantScope = tenantContextAccessor.EnterTenantScope(tenantId, "app-seed");
|
||||
using var disableSoftDeleteScope = dbContext.DisableSoftDeleteFilter();
|
||||
var group = await dbContext.DictionaryGroups
|
||||
.IgnoreQueryFilters()
|
||||
.FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Code == code, cancellationToken);
|
||||
.FirstOrDefaultAsync(x => x.Code == code, cancellationToken);
|
||||
|
||||
if (group == null)
|
||||
{
|
||||
@@ -235,6 +256,13 @@ public sealed class AppDataSeeder(
|
||||
{
|
||||
var groupUpdated = false;
|
||||
|
||||
if (group.DeletedAt.HasValue)
|
||||
{
|
||||
group.DeletedAt = null;
|
||||
group.DeletedBy = null;
|
||||
groupUpdated = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(group.Name, groupOptions.Name, StringComparison.Ordinal))
|
||||
{
|
||||
group.Name = groupOptions.Name.Trim();
|
||||
@@ -269,7 +297,7 @@ public sealed class AppDataSeeder(
|
||||
}
|
||||
}
|
||||
|
||||
await EnsureSystemParametersAsync(dbContext, defaultTenantId, cancellationToken);
|
||||
await EnsureSystemParametersAsync(dbContext, tenantContextAccessor, defaultTenantId, cancellationToken);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
@@ -277,7 +305,11 @@ public sealed class AppDataSeeder(
|
||||
/// <summary>
|
||||
/// 确保系统参数以独立表形式可重复种子。
|
||||
/// </summary>
|
||||
private async Task EnsureSystemParametersAsync(DictionaryDbContext dbContext, long? defaultTenantId, CancellationToken cancellationToken)
|
||||
private async Task EnsureSystemParametersAsync(
|
||||
DictionaryDbContext dbContext,
|
||||
ITenantContextAccessor tenantContextAccessor,
|
||||
long? defaultTenantId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var systemParameters = _options.SystemParameters ?? new List<SystemParameterSeedOptions>();
|
||||
|
||||
@@ -300,9 +332,9 @@ public sealed class AppDataSeeder(
|
||||
foreach (var group in grouped)
|
||||
{
|
||||
var tenantId = group.Key;
|
||||
using var tenantScope = tenantContextAccessor.EnterTenantScope(tenantId, "app-seed");
|
||||
using var disableSoftDeleteScope = dbContext.DisableSoftDeleteFilter();
|
||||
var existingParameters = await dbContext.SystemParameters
|
||||
.IgnoreQueryFilters()
|
||||
.Where(x => x.TenantId == tenantId)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
foreach (var seed in group)
|
||||
@@ -329,6 +361,13 @@ public sealed class AppDataSeeder(
|
||||
|
||||
var updated = false;
|
||||
|
||||
if (existing.DeletedAt.HasValue)
|
||||
{
|
||||
existing.DeletedAt = null;
|
||||
existing.DeletedBy = null;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(existing.Value, seed.Value, StringComparison.Ordinal))
|
||||
{
|
||||
existing.Value = seed.Value.Trim();
|
||||
@@ -387,7 +426,6 @@ public sealed class AppDataSeeder(
|
||||
}
|
||||
|
||||
var existingItems = await dbContext.DictionaryItems
|
||||
.IgnoreQueryFilters()
|
||||
.Where(x => x.GroupId == group.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
@@ -416,6 +454,13 @@ public sealed class AppDataSeeder(
|
||||
|
||||
var updated = false;
|
||||
|
||||
if (existing.DeletedAt.HasValue)
|
||||
{
|
||||
existing.DeletedAt = null;
|
||||
existing.DeletedBy = null;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(existing.Value, seed.Value, StringComparison.Ordinal))
|
||||
{
|
||||
existing.Value = seed.Value.Trim();
|
||||
|
||||
Reference in New Issue
Block a user