Host ve Tenant Seederlar ayrıldı
This commit is contained in:
parent
2f8a8ef29c
commit
f87be95b01
5 changed files with 712 additions and 694 deletions
590
api/src/Kurs.Platform.DbMigrator/Seeds/HostDataSeeder.cs
Normal file
590
api/src/Kurs.Platform.DbMigrator/Seeds/HostDataSeeder.cs
Normal file
|
|
@ -0,0 +1,590 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Kurs.Languages.Entities;
|
||||
using Kurs.Notifications.Entities;
|
||||
using Kurs.Platform.Entities;
|
||||
using Kurs.Platform.Enums;
|
||||
using Kurs.Platform.Seeds;
|
||||
using Kurs.Settings.Entities;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.MultiTenancy;
|
||||
using Volo.Abp.PermissionManagement;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EFCore.BulkExtensions;
|
||||
using System.Collections.Generic;
|
||||
using Kurs.Platform.Contacts;
|
||||
using static Kurs.Settings.SettingsConsts;
|
||||
|
||||
namespace Kurs.Platform.Data.Seeds;
|
||||
|
||||
public class HostDataSeeder : IDataSeedContributor, ITransientDependency
|
||||
{
|
||||
private readonly IRepository<AiBot, Guid> _aiBotRepository;
|
||||
private readonly IRepository<Language, Guid> _languages;
|
||||
private readonly IRepository<LanguageKey, Guid> _languageKey;
|
||||
private readonly IRepository<LanguageText, Guid> _languagesText;
|
||||
private readonly IRepository<DataSource, Guid> _dataSources;
|
||||
private readonly IRepository<SettingDefinition, Guid> _settings;
|
||||
private readonly IRepository<BackgroundWorker, Guid> _backgroundWorkerRepository;
|
||||
private readonly IRepository<Menu, Guid> _menuRepository;
|
||||
private readonly IRepository<PermissionGroupDefinitionRecord, Guid> _permissionGroupRepository;
|
||||
private readonly IRepository<PermissionDefinitionRecord, Guid> _permissionRepository;
|
||||
private readonly IRepository<Currency, Guid> _currencyRepository;
|
||||
private readonly IRepository<CountryGroup, Guid> _countryGroupRepository;
|
||||
private readonly IRepository<Country, Guid> _countryRepository;
|
||||
private readonly IRepository<City, Guid> _cityRepository;
|
||||
private readonly IRepository<District, Guid> _districtRepository;
|
||||
private readonly IRepository<ContactTag, Guid> _contactTagRepository;
|
||||
private readonly IRepository<ContactTitle, Guid> _contactTitleRepository;
|
||||
private readonly IRepository<Route, Guid> _routeRepository;
|
||||
|
||||
public HostDataSeeder(
|
||||
IRepository<AiBot, Guid> aiBotRepository,
|
||||
IRepository<Language, Guid> languages,
|
||||
IRepository<LanguageKey, Guid> languageKey,
|
||||
IRepository<LanguageText, Guid> languagesText,
|
||||
IRepository<DataSource, Guid> dataSource,
|
||||
IRepository<SettingDefinition, Guid> settings,
|
||||
IRepository<BackgroundWorker, Guid> backgroundWorkerRepository,
|
||||
IRepository<Menu, Guid> menuRepository,
|
||||
IRepository<PermissionGroupDefinitionRecord, Guid> permissionGroupRepository,
|
||||
IRepository<PermissionDefinitionRecord, Guid> permissionRepository,
|
||||
IRepository<Currency, Guid> currencyRepository,
|
||||
IRepository<CountryGroup, Guid> countryGroupRepository,
|
||||
IRepository<Country, Guid> countryRepository,
|
||||
IRepository<City, Guid> cityRepository,
|
||||
IRepository<District, Guid> districtRepository,
|
||||
IRepository<ContactTag, Guid> contactTagRepository,
|
||||
IRepository<ContactTitle, Guid> contactTitleRepository,
|
||||
IRepository<Route, Guid> routeRepository
|
||||
)
|
||||
{
|
||||
_languages = languages;
|
||||
_languageKey = languageKey;
|
||||
_languagesText = languagesText;
|
||||
_dataSources = dataSource;
|
||||
_settings = settings;
|
||||
_backgroundWorkerRepository = backgroundWorkerRepository;
|
||||
_menuRepository = menuRepository;
|
||||
_permissionGroupRepository = permissionGroupRepository;
|
||||
_permissionRepository = permissionRepository;
|
||||
_currencyRepository = currencyRepository;
|
||||
_countryGroupRepository = countryGroupRepository;
|
||||
_countryRepository = countryRepository;
|
||||
_cityRepository = cityRepository;
|
||||
_districtRepository = districtRepository;
|
||||
_contactTagRepository = contactTagRepository;
|
||||
_contactTitleRepository = contactTitleRepository;
|
||||
_aiBotRepository = aiBotRepository;
|
||||
_routeRepository = routeRepository;
|
||||
}
|
||||
|
||||
private static IConfigurationRoot BuildConfiguration()
|
||||
{
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? ""}.json", true);
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
public async Task SeedCountyGroupsAsync()
|
||||
{
|
||||
var dbCtx = await _countryRepository.GetDbContextAsync();
|
||||
|
||||
// DB’de mevcut kodları set olarak al
|
||||
var existingCodes = (await dbCtx.Set<CountryGroup>()
|
||||
.Select(c => c.Name)
|
||||
.ToListAsync())
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
using var fs = File.OpenRead(Path.Combine("Seeds", "CountryGroups.json"));
|
||||
|
||||
var buffer = new List<CountryGroup>(capacity: 1000);
|
||||
var seenCodes = new HashSet<string>(); // JSON içindeki duplicate’leri yakalamak için
|
||||
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<CountryGroupDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
if (string.IsNullOrWhiteSpace(item.Name)) continue; // boş kodları atla
|
||||
|
||||
// hem DB’de hem JSON içinde duplicate engelle
|
||||
if (!seenCodes.Add(item.Name) || existingCodes.Contains(item.Name))
|
||||
continue;
|
||||
|
||||
buffer.Add(new CountryGroup(
|
||||
Guid.NewGuid(),
|
||||
item.Name
|
||||
));
|
||||
|
||||
if (buffer.Count >= 1000)
|
||||
{
|
||||
await BulkCountryGroupInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkCountryGroupInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkCountryGroupInsertAsync(List<CountryGroup> entities)
|
||||
{
|
||||
var dbCtx = await _countryGroupRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
BatchSize = 1000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedCountriesAsync()
|
||||
{
|
||||
var dbCtx = await _countryRepository.GetDbContextAsync();
|
||||
|
||||
// DB’de mevcut kodları set olarak al
|
||||
var existingCodes = (await dbCtx.Set<Country>()
|
||||
.Select(c => c.Code)
|
||||
.ToListAsync())
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
using var fs = File.OpenRead(Path.Combine("Seeds", "Countries.json"));
|
||||
|
||||
var buffer = new List<Country>(capacity: 1000);
|
||||
var seenCodes = new HashSet<string>(); // JSON içindeki duplicate’leri yakalamak için
|
||||
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<CountryDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
if (string.IsNullOrWhiteSpace(item.Code)) continue; // boş kodları atla
|
||||
|
||||
// hem DB’de hem JSON içinde duplicate engelle
|
||||
if (!seenCodes.Add(item.Code) || existingCodes.Contains(item.Code))
|
||||
continue;
|
||||
|
||||
buffer.Add(new Country(
|
||||
Guid.NewGuid(),
|
||||
item.Code,
|
||||
item.Name,
|
||||
item.GroupName,
|
||||
item.CurrencyCode,
|
||||
item.PhoneCode,
|
||||
item.TaxLabel
|
||||
));
|
||||
|
||||
if (buffer.Count >= 1000)
|
||||
{
|
||||
await BulkCountryInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkCountryInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkCountryInsertAsync(List<Country> entities)
|
||||
{
|
||||
var dbCtx = await _countryRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
BatchSize = 1000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedCitiesAsync()
|
||||
{
|
||||
var dbCtx = await _cityRepository.GetDbContextAsync();
|
||||
|
||||
// 1. Mevcut kayıtları çek (tek sorguda)
|
||||
var existingCities = await dbCtx.Set<City>()
|
||||
.Select(d => new { d.Code })
|
||||
.ToListAsync();
|
||||
|
||||
var existingSet = existingCities
|
||||
.Select(d => d.Code)
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
// 2. JSON’u stream et
|
||||
using FileStream fs = File.OpenRead(Path.Combine("Seeds", "Cities.json"));
|
||||
|
||||
var buffer = new List<City>(capacity: 5000);
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<CityDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
var key = $"{item.Country}.{item.Code}";
|
||||
if (existingSet.Contains(key)) continue; // duplicate kontrolü
|
||||
|
||||
buffer.Add(new City(
|
||||
Guid.NewGuid(),
|
||||
item.Country,
|
||||
item.Name,
|
||||
key,
|
||||
item.PlateCode
|
||||
));
|
||||
|
||||
if (buffer.Count >= 1000) // 3. Batch
|
||||
{
|
||||
await BulkCityInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkCityInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkCityInsertAsync(List<City> entities)
|
||||
{
|
||||
var dbCtx = await _cityRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
PreserveInsertOrder = true,
|
||||
SetOutputIdentity = true,
|
||||
BatchSize = 1000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedDistrictsAsync()
|
||||
{
|
||||
var dbCtx = await _districtRepository.GetDbContextAsync();
|
||||
|
||||
// 1. Mevcut kayıtları çek (tek sorguda)
|
||||
var existingDistricts = await dbCtx.Set<District>()
|
||||
.Select(d => new { d.Country, d.City, d.Name, d.Township, d.Street, d.ZipCode })
|
||||
.ToListAsync();
|
||||
|
||||
var existingSet = existingDistricts
|
||||
.Select(d => $"{d.Country}:{d.City}:{d.Name}:{d.Township}:{d.Street}:{d.ZipCode}")
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
// 2. JSON’u stream et
|
||||
using FileStream fs = File.OpenRead(Path.Combine("Seeds", "Districts.json"));
|
||||
|
||||
var buffer = new List<District>(capacity: 5000);
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<DistrictDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
var key = $"{item.Country}:{item.Country}.{item.City}:{item.Name}:{item.Township}:{item.Street}:{item.ZipCode}";
|
||||
var city = $"{item.Country}.{item.City}";
|
||||
if (existingSet.Contains(key)) continue;
|
||||
|
||||
buffer.Add(new District(
|
||||
Guid.NewGuid(),
|
||||
item.Country,
|
||||
city,
|
||||
item.Name,
|
||||
item.Township,
|
||||
item.Street,
|
||||
item.ZipCode
|
||||
));
|
||||
|
||||
if (buffer.Count >= 5000) // 3. Batch
|
||||
{
|
||||
await BulkDistrictInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkDistrictInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkDistrictInsertAsync(List<District> entities)
|
||||
{
|
||||
var dbCtx = await _districtRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
PreserveInsertOrder = true,
|
||||
SetOutputIdentity = true,
|
||||
BatchSize = 5000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedAsync(DataSeedContext context)
|
||||
{
|
||||
var settings = await _settings.GetListAsync();
|
||||
var dataSources = await _dataSources.GetListAsync();
|
||||
var languages = await _languages.GetListAsync();
|
||||
var keys = await _languageKey.GetListAsync();
|
||||
var texts = await _languagesText.GetListAsync();
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile(Path.Combine("Seeds", "TenantData.json"))
|
||||
.AddJsonFile(Path.Combine("Seeds", $"TenantData.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? ""}.json"), true)
|
||||
.Build();
|
||||
var items = configuration.Get<HostSeederDto>();
|
||||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
foreach (var item in items.Settings)
|
||||
{
|
||||
if (!settings.Any(a => a.Code == item.Code))
|
||||
{
|
||||
await _settings.InsertAsync(new()
|
||||
{
|
||||
Code = item.Code,
|
||||
NameKey = item.NameKey,
|
||||
DescriptionKey = item.DescriptionKey,
|
||||
DefaultValue = item.DefaultValue.Replace("\r\n", Environment.NewLine),
|
||||
IsVisibleToClients = item.IsVisibleToClients,
|
||||
IsInherited = item.IsInherited,
|
||||
IsEncrypted = item.IsEncrypted,
|
||||
MainGroupKey = item.MainGroupKey,
|
||||
SubGroupKey = item.SubGroupKey,
|
||||
RequiredPermissionName = item.RequiredPermissionName,
|
||||
DataType = item.DataType,
|
||||
Providers = item.Providers,
|
||||
SelectOptions = item.SelectOptions,
|
||||
Order = item.Order
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataSources.Any(a => a.Code == SeedConsts.DataSources.DefaultCode))
|
||||
{
|
||||
var config = BuildConfiguration();
|
||||
await _dataSources.InsertAsync(new()
|
||||
{
|
||||
Code = SeedConsts.DataSources.DefaultCode,
|
||||
DataSourceType = DefaultDatabaseProvider == DatabaseProvider.SqlServer ? DataSourceTypeEnum.Mssql : DataSourceTypeEnum.Postgresql,
|
||||
ConnectionString = config.GetConnectionString(DefaultDatabaseProvider)
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var item in items.Languages)
|
||||
{
|
||||
if (!languages.Any(a => a.CultureName == item.CultureName))
|
||||
{
|
||||
await _languages.InsertAsync(new()
|
||||
{
|
||||
CultureName = item.CultureName,
|
||||
UiCultureName = item.UiCultureName,
|
||||
DisplayName = item.DisplayName,
|
||||
IsEnabled = item.IsEnabled,
|
||||
TwoLetterISOLanguageName = new CultureInfo(item.CultureName).TwoLetterISOLanguageName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.LanguageTexts)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!keys.Any(a => a.Key == item.Key))
|
||||
{
|
||||
await _languageKey.InsertAsync(new()
|
||||
{
|
||||
Key = item.Key,
|
||||
ResourceName = item.ResourceName,
|
||||
});
|
||||
}
|
||||
if (!texts.Any(a => a.CultureName == "en" && a.Key == item.Key))
|
||||
{
|
||||
await _languagesText.InsertAsync(new()
|
||||
{
|
||||
CultureName = "en",
|
||||
Key = item.Key,
|
||||
Value = item.En,
|
||||
ResourceName = item.ResourceName,
|
||||
});
|
||||
}
|
||||
if (!texts.Any(a => a.CultureName == "tr" && a.Key == item.Key))
|
||||
{
|
||||
|
||||
await _languagesText.InsertAsync(new()
|
||||
{
|
||||
CultureName = "tr",
|
||||
Key = item.Key,
|
||||
Value = item.Tr,
|
||||
ResourceName = item.ResourceName,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"Hata veren Kod:' ResourceName='{item.ResourceName}', Key='{item.Key}' Message='{ex.Message}'");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.BackgroundWorkers)
|
||||
{
|
||||
if (!await _backgroundWorkerRepository.AnyAsync(x => x.Name == item.Name))
|
||||
{
|
||||
await _backgroundWorkerRepository.InsertAsync(new BackgroundWorker
|
||||
{
|
||||
Name = item.Name,
|
||||
Cron = item.Cron,
|
||||
WorkerType = Enum.Parse<WorkerTypeEnum>(item.WorkerType),
|
||||
IsActive = item.IsActive,
|
||||
DataSourceCode = item.DataSourceCode
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Menus)
|
||||
{
|
||||
var exists = await _menuRepository.AnyAsync(x => x.Code == item.Code);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _menuRepository.InsertAsync(new Menu
|
||||
{
|
||||
ParentCode = string.IsNullOrWhiteSpace(item.ParentCode) ? null : item.ParentCode,
|
||||
Code = item.Code,
|
||||
DisplayName = item.DisplayName,
|
||||
Order = item.Order,
|
||||
Url = item.Url,
|
||||
Icon = item.Icon,
|
||||
RequiredPermissionName = item.RequiredPermissionName,
|
||||
IsDisabled = item.IsDisabled
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.PermissionGroupDefinitionRecords)
|
||||
{
|
||||
var exists = await _permissionGroupRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _permissionGroupRepository.InsertAsync(new PermissionGroupDefinitionRecord
|
||||
{
|
||||
Name = item.Name,
|
||||
DisplayName = item.DisplayName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.PermissionDefinitionRecords)
|
||||
{
|
||||
var exists = await _permissionRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _permissionRepository.InsertAsync(new PermissionDefinitionRecord
|
||||
{
|
||||
GroupName = item.GroupName,
|
||||
Name = item.Name,
|
||||
ParentName = string.IsNullOrWhiteSpace(item.ParentName) ? null : item.ParentName,
|
||||
DisplayName = item.DisplayName,
|
||||
IsEnabled = item.IsEnabled,
|
||||
MultiTenancySide = (MultiTenancySides)item.MultiTenancySide
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Currencies)
|
||||
{
|
||||
var exists = await _currencyRepository.AnyAsync(x => x.Code == item.Code);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _currencyRepository.InsertAsync(new Currency
|
||||
{
|
||||
Code = item.Code,
|
||||
Symbol = item.Symbol,
|
||||
Name = item.Name,
|
||||
IsActive = item.IsActive
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.ContactTags)
|
||||
{
|
||||
var exists = await _contactTagRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _contactTagRepository.InsertAsync(new ContactTag
|
||||
{
|
||||
Name = item.Name,
|
||||
Category = item.Category,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.ContactTitles)
|
||||
{
|
||||
var exists = await _contactTitleRepository.AnyAsync(x => x.Title == item.Title);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _contactTitleRepository.InsertAsync(new ContactTitle
|
||||
{
|
||||
Title = item.Title,
|
||||
Abbreviation = item.Abbreviation,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.AiBots)
|
||||
{
|
||||
var exists = await _aiBotRepository.AnyAsync(x => x.BotName == item.BotName);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _aiBotRepository.InsertAsync(new AiBot
|
||||
{
|
||||
BotName = item.BotName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Routes)
|
||||
{
|
||||
var exists = await _routeRepository.AnyAsync(x => x.Key == item.Key);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _routeRepository.InsertAsync(new Route(
|
||||
item.Key,
|
||||
item.Path,
|
||||
item.ComponentPath,
|
||||
item.RouteType,
|
||||
item.Authority ?? []
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
await SeedCountyGroupsAsync();
|
||||
|
||||
await SeedCountriesAsync();
|
||||
|
||||
await SeedCitiesAsync();
|
||||
|
||||
await SeedDistrictsAsync();
|
||||
}
|
||||
}
|
||||
114
api/src/Kurs.Platform.DbMigrator/Seeds/HostSeederDto.cs
Normal file
114
api/src/Kurs.Platform.DbMigrator/Seeds/HostSeederDto.cs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
using System.Collections.Generic;
|
||||
using Kurs.Languages.Entities;
|
||||
using Kurs.Platform.Entities;
|
||||
using Kurs.Settings.Entities;
|
||||
|
||||
namespace Kurs.Platform.Seeds;
|
||||
|
||||
public class HostSeederDto
|
||||
{
|
||||
public List<AiBotSeedDto> AiBots { get; set; }
|
||||
public List<Language> Languages { get; set; }
|
||||
public List<LanguageTextsSeedDto> LanguageTexts { get; set; }
|
||||
public List<DataSource> DataSources { get; set; }
|
||||
public List<SettingDefinition> Settings { get; set; }
|
||||
public List<BackgroundWorkerSeedDto> BackgroundWorkers { get; set; }
|
||||
public List<NotificationRuleSeedDto> NotificationRules { get; set; }
|
||||
public List<MenuSeedDto> Menus { get; set; }
|
||||
public List<PermissionGroupDefinitionRecordSeedDto> PermissionGroupDefinitionRecords { get; set; }
|
||||
public List<PermissionDefinitionRecordSeedDto> PermissionDefinitionRecords { get; set; }
|
||||
public List<CurrencySeedDto> Currencies { get; set; }
|
||||
public List<ContactTagSeedDto> ContactTags { get; set; }
|
||||
public List<ContactTitleSeedDto> ContactTitles { get; set; }
|
||||
public List<RouteSeedDto> Routes { get; set; }
|
||||
}
|
||||
|
||||
public class AiBotSeedDto
|
||||
{
|
||||
public string BotName { get; set; }
|
||||
}
|
||||
|
||||
public class LanguageTextsSeedDto
|
||||
{
|
||||
public string ResourceName { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string En { get; set; }
|
||||
public string Tr { get; set; }
|
||||
}
|
||||
|
||||
public class BackgroundWorkerSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Cron { get; set; }
|
||||
public string WorkerType { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public string DataSourceCode { get; set; }
|
||||
}
|
||||
|
||||
public class NotificationRuleSeedDto
|
||||
{
|
||||
public string NotificationType { get; set; }
|
||||
public string RecipientType { get; set; }
|
||||
public string RecipientId { get; set; }
|
||||
public string Channel { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsFixed { get; set; }
|
||||
public bool IsCustomized { get; set; }
|
||||
}
|
||||
|
||||
public class MenuSeedDto
|
||||
{
|
||||
public string ParentCode { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public int Order { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Icon { get; set; }
|
||||
public string RequiredPermissionName { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
}
|
||||
|
||||
public class PermissionGroupDefinitionRecordSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
|
||||
public class PermissionDefinitionRecordSeedDto
|
||||
{
|
||||
public string GroupName { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ParentName { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
public int MultiTenancySide { get; set; }
|
||||
}
|
||||
|
||||
public class CurrencySeedDto
|
||||
{
|
||||
public string Code { get; set; }
|
||||
public string Symbol { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class ContactTagSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Category { get; set; }
|
||||
}
|
||||
|
||||
public class ContactTitleSeedDto
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Abbreviation { get; set; }
|
||||
}
|
||||
|
||||
public class RouteSeedDto
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string ComponentPath { get; set; }
|
||||
public string RouteType { get; set; }
|
||||
public string[] Authority { get; set; }
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ using AppCodes = Kurs.Platform.Data.Seeds.SeedConsts.AppCodes;
|
|||
|
||||
namespace Kurs.Platform.Data.Seeds;
|
||||
|
||||
public class PlatformListFormsSeeder : IDataSeedContributor, ITransientDependency
|
||||
public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
|
||||
{
|
||||
private readonly IRepository<ListForm, Guid> _listFormRepository;
|
||||
private readonly IRepository<ListFormField, Guid> _listFormFieldRepository;
|
||||
|
|
@ -28,7 +28,7 @@ public class PlatformListFormsSeeder : IDataSeedContributor, ITransientDependenc
|
|||
private readonly IdentityRoleManager _identityRoleManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public PlatformListFormsSeeder(
|
||||
public ListFormsSeeder(
|
||||
IRepository<ListForm, Guid> listFormRepository,
|
||||
IRepository<ListFormField, Guid> listFormFieldRepository,
|
||||
IdentityUserManager userManager,
|
||||
|
|
@ -1,53 +1,21 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Kurs.Languages.Entities;
|
||||
using Kurs.Notifications.Entities;
|
||||
using Kurs.Platform.Entities;
|
||||
using Kurs.Platform.Enums;
|
||||
using Kurs.Platform.Forum;
|
||||
using Kurs.Platform.Seeds;
|
||||
using Kurs.Settings.Entities;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Volo.Abp.Data;
|
||||
using Volo.Abp.DependencyInjection;
|
||||
using Volo.Abp.Domain.Repositories;
|
||||
using Volo.Abp.MultiTenancy;
|
||||
using Volo.Abp.PermissionManagement;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using EFCore.BulkExtensions;
|
||||
using System.Collections.Generic;
|
||||
using Kurs.Platform.Contacts;
|
||||
using static Kurs.Settings.SettingsConsts;
|
||||
|
||||
namespace Kurs.Platform.Data.Seeds;
|
||||
|
||||
public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||
public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||
{
|
||||
private readonly IRepository<AiBot, Guid> _aiBotRepository;
|
||||
private readonly IRepository<GlobalSearch, int> _globalSearch;
|
||||
private readonly IRepository<SettingDefinition, Guid> _settings;
|
||||
private readonly IRepository<Language, Guid> _languages;
|
||||
private readonly IRepository<LanguageKey, Guid> _languageKey;
|
||||
private readonly IRepository<LanguageText, Guid> _languagesText;
|
||||
private readonly IRepository<Route, Guid> _routeRepository;
|
||||
private readonly IRepository<Menu, Guid> _menuRepository;
|
||||
private readonly IRepository<DataSource, Guid> _dataSources;
|
||||
private readonly IRepository<NotificationRule, Guid> _notificationRuleRepository;
|
||||
private readonly IRepository<BackgroundWorker, Guid> _backgroundWorkerRepository;
|
||||
private readonly IRepository<ForumCategory, Guid> _forumCategoryRepository;
|
||||
|
||||
private readonly IRepository<ContactTag, Guid> _contactTagRepository;
|
||||
private readonly IRepository<ContactTitle, Guid> _contactTitleRepository;
|
||||
private readonly IRepository<Currency, Guid> _currencyRepository;
|
||||
private readonly IRepository<CountryGroup, Guid> _countryGroupRepository;
|
||||
private readonly IRepository<Country, Guid> _countryRepository;
|
||||
private readonly IRepository<City, Guid> _cityRepository;
|
||||
private readonly IRepository<District, Guid> _districtRepository;
|
||||
|
||||
private readonly IRepository<CustomEndpoint, Guid> _customEndpointRepository;
|
||||
private readonly IRepository<CustomComponent, Guid> _customComponentRepository;
|
||||
private readonly IRepository<ReportCategory, Guid> _reportCategoriesRepository;
|
||||
|
|
@ -59,9 +27,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
private readonly IRepository<BlogCategory, Guid> _blogCategoryRepository;
|
||||
private readonly IRepository<BlogPost, Guid> _blogPostsRepository;
|
||||
private readonly IRepository<Contact, Guid> _contactRepository;
|
||||
|
||||
private readonly IRepository<PermissionGroupDefinitionRecord, Guid> _permissionGroupRepository;
|
||||
private readonly IRepository<PermissionDefinitionRecord, Guid> _permissionRepository;
|
||||
private readonly IRepository<Sector, Guid> _sectorRepository;
|
||||
private readonly IRepository<SkillType, Guid> _skillTypeRepository;
|
||||
private readonly IRepository<Skill, Guid> _skillRepository;
|
||||
|
|
@ -78,6 +43,7 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
private readonly IRepository<MeetingMethod, Guid> _meetingMethodRepository;
|
||||
private readonly IRepository<MeetingResult, Guid> _meetingResultRepository;
|
||||
private readonly IRepository<Program, Guid> _programRepository;
|
||||
private readonly IRepository<ForumCategory, Guid> _forumCategoryRepository;
|
||||
private readonly IRepository<Interesting, Guid> _interestingRepository;
|
||||
private readonly IRepository<SalesRejectionReason, Guid> _salesRejectionReasonRepository;
|
||||
private readonly IRepository<Source, Guid> _sourceRepository;
|
||||
|
|
@ -85,37 +51,16 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
private readonly IRepository<NoteType, Guid> _noteTypeRepository;
|
||||
private readonly IRepository<ClassCancellationReason, Guid> _classCancellationReasonRepository;
|
||||
private readonly IRepository<WorkHour, Guid> _workHourRepository;
|
||||
|
||||
private readonly IRepository<Classroom, Guid> _classroomRepository;
|
||||
|
||||
public PlatformTenantDataSeeder(
|
||||
IRepository<AiBot, Guid> aiBotRepository,
|
||||
IRepository<Language, Guid> languages,
|
||||
IRepository<LanguageKey, Guid> languageKey,
|
||||
IRepository<LanguageText, Guid> languagesText,
|
||||
IRepository<DataSource, Guid> dataSource,
|
||||
IRepository<SettingDefinition, Guid> settings,
|
||||
public TenantDataSeeder(
|
||||
IRepository<GlobalSearch, int> globalSearch,
|
||||
IRepository<BackgroundWorker, Guid> backgroundWorkerRepository,
|
||||
IRepository<NotificationRule, Guid> notificationRuleRepository,
|
||||
IRepository<Menu, Guid> menuRepository,
|
||||
IRepository<PermissionGroupDefinitionRecord, Guid> permissionGroupRepository,
|
||||
IRepository<PermissionDefinitionRecord, Guid> permissionRepository,
|
||||
IRepository<Sector, Guid> sectorRepository,
|
||||
IRepository<UomCategory, Guid> uomCategoryRepository,
|
||||
IRepository<Uom, Guid> uomRepository,
|
||||
IRepository<Currency, Guid> currencyRepository,
|
||||
IRepository<CountryGroup, Guid> countryGroupRepository,
|
||||
IRepository<Country, Guid> countryRepository,
|
||||
IRepository<City, Guid> cityRepository,
|
||||
IRepository<District, Guid> districtRepository,
|
||||
IRepository<SkillType, Guid> skillTypeRepository,
|
||||
IRepository<Skill, Guid> skillRepository,
|
||||
IRepository<SkillLevel, Guid> skillLevelRepository,
|
||||
IRepository<ContactTag, Guid> contactTagRepository,
|
||||
IRepository<ContactTitle, Guid> contactTitleRepository,
|
||||
IRepository<ForumCategory, Guid> forumCategoryRepository,
|
||||
IRepository<Route, Guid> routeRepository,
|
||||
IRepository<CustomEndpoint, Guid> customEndpointRepository,
|
||||
IRepository<CustomComponent, Guid> customComponentRepository,
|
||||
IRepository<ReportCategory, Guid> reportCategoriesRepository,
|
||||
|
|
@ -144,38 +89,19 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
IRepository<Event, Guid> eventRepository,
|
||||
IRepository<Source, Guid> sourceRepository,
|
||||
IRepository<Interesting, Guid> interestingRepository,
|
||||
IRepository<Program, Guid> programRepository
|
||||
IRepository<Program, Guid> programRepository,
|
||||
IRepository<ForumCategory, Guid> forumCategoryRepository
|
||||
)
|
||||
{
|
||||
_languages = languages;
|
||||
_languageKey = languageKey;
|
||||
_languagesText = languagesText;
|
||||
_dataSources = dataSource;
|
||||
_settings = settings;
|
||||
_globalSearch = globalSearch;
|
||||
_backgroundWorkerRepository = backgroundWorkerRepository;
|
||||
_notificationRuleRepository = notificationRuleRepository;
|
||||
_menuRepository = menuRepository;
|
||||
_permissionGroupRepository = permissionGroupRepository;
|
||||
_permissionRepository = permissionRepository;
|
||||
_sectorRepository = sectorRepository;
|
||||
_uomCategoryRepository = uomCategoryRepository;
|
||||
_uomRepository = uomRepository;
|
||||
_currencyRepository = currencyRepository;
|
||||
_countryGroupRepository = countryGroupRepository;
|
||||
_countryRepository = countryRepository;
|
||||
_cityRepository = cityRepository;
|
||||
_districtRepository = districtRepository;
|
||||
_skillTypeRepository = skillTypeRepository;
|
||||
_skillRepository = skillRepository;
|
||||
_skillLevelRepository = skillLevelRepository;
|
||||
_contactTagRepository = contactTagRepository;
|
||||
_contactTitleRepository = contactTitleRepository;
|
||||
_blogCategoryRepository = blogCategoryRepository;
|
||||
_blogPostsRepository = blogPostsRepository;
|
||||
_forumCategoryRepository = forumCategoryRepository;
|
||||
_aiBotRepository = aiBotRepository;
|
||||
_routeRepository = routeRepository;
|
||||
_customEndpointRepository = customEndpointRepository;
|
||||
_productRepository = productRepository;
|
||||
_paymentMethodRepository = paymentMethodRepository;
|
||||
|
|
@ -203,6 +129,7 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
_sourceRepository = sourceRepository;
|
||||
_interestingRepository = interestingRepository;
|
||||
_programRepository = programRepository;
|
||||
_forumCategoryRepository = forumCategoryRepository;
|
||||
}
|
||||
|
||||
private static IConfigurationRoot BuildConfiguration()
|
||||
|
|
@ -215,251 +142,8 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
return builder.Build();
|
||||
}
|
||||
|
||||
|
||||
public async Task SeedCountyGroupsAsync()
|
||||
{
|
||||
var dbCtx = await _countryRepository.GetDbContextAsync();
|
||||
|
||||
// DB’de mevcut kodları set olarak al
|
||||
var existingCodes = (await dbCtx.Set<CountryGroup>()
|
||||
.Select(c => c.Name)
|
||||
.ToListAsync())
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
using var fs = File.OpenRead(Path.Combine("Seeds", "CountryGroups.json"));
|
||||
|
||||
var buffer = new List<CountryGroup>(capacity: 1000);
|
||||
var seenCodes = new HashSet<string>(); // JSON içindeki duplicate’leri yakalamak için
|
||||
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<CountryGroupDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
if (string.IsNullOrWhiteSpace(item.Name)) continue; // boş kodları atla
|
||||
|
||||
// hem DB’de hem JSON içinde duplicate engelle
|
||||
if (!seenCodes.Add(item.Name) || existingCodes.Contains(item.Name))
|
||||
continue;
|
||||
|
||||
buffer.Add(new CountryGroup(
|
||||
Guid.NewGuid(),
|
||||
item.Name
|
||||
));
|
||||
|
||||
if (buffer.Count >= 1000)
|
||||
{
|
||||
await BulkCountryGroupInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkCountryGroupInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkCountryGroupInsertAsync(List<CountryGroup> entities)
|
||||
{
|
||||
var dbCtx = await _countryGroupRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
BatchSize = 1000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedCountriesAsync()
|
||||
{
|
||||
var dbCtx = await _countryRepository.GetDbContextAsync();
|
||||
|
||||
// DB’de mevcut kodları set olarak al
|
||||
var existingCodes = (await dbCtx.Set<Country>()
|
||||
.Select(c => c.Code)
|
||||
.ToListAsync())
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
using var fs = File.OpenRead(Path.Combine("Seeds", "Countries.json"));
|
||||
|
||||
var buffer = new List<Country>(capacity: 1000);
|
||||
var seenCodes = new HashSet<string>(); // JSON içindeki duplicate’leri yakalamak için
|
||||
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<CountryDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
if (string.IsNullOrWhiteSpace(item.Code)) continue; // boş kodları atla
|
||||
|
||||
// hem DB’de hem JSON içinde duplicate engelle
|
||||
if (!seenCodes.Add(item.Code) || existingCodes.Contains(item.Code))
|
||||
continue;
|
||||
|
||||
buffer.Add(new Country(
|
||||
Guid.NewGuid(),
|
||||
item.Code,
|
||||
item.Name,
|
||||
item.GroupName,
|
||||
item.CurrencyCode,
|
||||
item.PhoneCode,
|
||||
item.TaxLabel
|
||||
));
|
||||
|
||||
if (buffer.Count >= 1000)
|
||||
{
|
||||
await BulkCountryInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkCountryInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkCountryInsertAsync(List<Country> entities)
|
||||
{
|
||||
var dbCtx = await _countryRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
BatchSize = 1000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedCitiesAsync()
|
||||
{
|
||||
var dbCtx = await _cityRepository.GetDbContextAsync();
|
||||
|
||||
// 1. Mevcut kayıtları çek (tek sorguda)
|
||||
var existingCities = await dbCtx.Set<City>()
|
||||
.Select(d => new { d.Code })
|
||||
.ToListAsync();
|
||||
|
||||
var existingSet = existingCities
|
||||
.Select(d => d.Code)
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
// 2. JSON’u stream et
|
||||
using FileStream fs = File.OpenRead(Path.Combine("Seeds", "Cities.json"));
|
||||
|
||||
var buffer = new List<City>(capacity: 5000);
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<CityDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
var key = $"{item.Country}.{item.Code}";
|
||||
if (existingSet.Contains(key)) continue; // duplicate kontrolü
|
||||
|
||||
buffer.Add(new City(
|
||||
Guid.NewGuid(),
|
||||
item.Country,
|
||||
item.Name,
|
||||
key,
|
||||
item.PlateCode
|
||||
));
|
||||
|
||||
if (buffer.Count >= 1000) // 3. Batch
|
||||
{
|
||||
await BulkCityInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkCityInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkCityInsertAsync(List<City> entities)
|
||||
{
|
||||
var dbCtx = await _cityRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
PreserveInsertOrder = true,
|
||||
SetOutputIdentity = true,
|
||||
BatchSize = 1000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedDistrictsAsync()
|
||||
{
|
||||
var dbCtx = await _districtRepository.GetDbContextAsync();
|
||||
|
||||
// 1. Mevcut kayıtları çek (tek sorguda)
|
||||
var existingDistricts = await dbCtx.Set<District>()
|
||||
.Select(d => new { d.Country, d.City, d.Name, d.Township, d.Street, d.ZipCode })
|
||||
.ToListAsync();
|
||||
|
||||
var existingSet = existingDistricts
|
||||
.Select(d => $"{d.Country}:{d.City}:{d.Name}:{d.Township}:{d.Street}:{d.ZipCode}")
|
||||
.ToHashSet();
|
||||
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
// 2. JSON’u stream et
|
||||
using FileStream fs = File.OpenRead(Path.Combine("Seeds", "Districts.json"));
|
||||
|
||||
var buffer = new List<District>(capacity: 5000);
|
||||
await foreach (var item in JsonSerializer.DeserializeAsyncEnumerable<DistrictDto>(fs, options))
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
var key = $"{item.Country}:{item.Country}.{item.City}:{item.Name}:{item.Township}:{item.Street}:{item.ZipCode}";
|
||||
var city = $"{item.Country}.{item.City}";
|
||||
if (existingSet.Contains(key)) continue;
|
||||
|
||||
buffer.Add(new District(
|
||||
Guid.NewGuid(),
|
||||
item.Country,
|
||||
city,
|
||||
item.Name,
|
||||
item.Township,
|
||||
item.Street,
|
||||
item.ZipCode
|
||||
));
|
||||
|
||||
if (buffer.Count >= 5000) // 3. Batch
|
||||
{
|
||||
await BulkDistrictInsertAsync(buffer);
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.Count > 0)
|
||||
{
|
||||
await BulkDistrictInsertAsync(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BulkDistrictInsertAsync(List<District> entities)
|
||||
{
|
||||
var dbCtx = await _districtRepository.GetDbContextAsync();
|
||||
await dbCtx.BulkInsertAsync(entities, new BulkConfig
|
||||
{
|
||||
PreserveInsertOrder = true,
|
||||
SetOutputIdentity = true,
|
||||
BatchSize = 5000
|
||||
});
|
||||
}
|
||||
|
||||
public async Task SeedAsync(DataSeedContext context)
|
||||
{
|
||||
var settings = await _settings.GetListAsync();
|
||||
var dataSources = await _dataSources.GetListAsync();
|
||||
var languages = await _languages.GetListAsync();
|
||||
var keys = await _languageKey.GetListAsync();
|
||||
var texts = await _languagesText.GetListAsync();
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile(Path.Combine("Seeds", "TenantData.json"))
|
||||
|
|
@ -469,96 +153,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
|
||||
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
|
||||
foreach (var item in items.Settings)
|
||||
{
|
||||
if (!settings.Any(a => a.Code == item.Code))
|
||||
{
|
||||
await _settings.InsertAsync(new()
|
||||
{
|
||||
Code = item.Code,
|
||||
NameKey = item.NameKey,
|
||||
DescriptionKey = item.DescriptionKey,
|
||||
DefaultValue = item.DefaultValue.Replace("\r\n", Environment.NewLine),
|
||||
IsVisibleToClients = item.IsVisibleToClients,
|
||||
IsInherited = item.IsInherited,
|
||||
IsEncrypted = item.IsEncrypted,
|
||||
MainGroupKey = item.MainGroupKey,
|
||||
SubGroupKey = item.SubGroupKey,
|
||||
RequiredPermissionName = item.RequiredPermissionName,
|
||||
DataType = item.DataType,
|
||||
Providers = item.Providers,
|
||||
SelectOptions = item.SelectOptions,
|
||||
Order = item.Order
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataSources.Any(a => a.Code == SeedConsts.DataSources.DefaultCode))
|
||||
{
|
||||
var config = BuildConfiguration();
|
||||
await _dataSources.InsertAsync(new()
|
||||
{
|
||||
Code = SeedConsts.DataSources.DefaultCode,
|
||||
DataSourceType = DefaultDatabaseProvider == DatabaseProvider.SqlServer ? DataSourceTypeEnum.Mssql : DataSourceTypeEnum.Postgresql,
|
||||
ConnectionString = config.GetConnectionString(DefaultDatabaseProvider)
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var item in items.Languages)
|
||||
{
|
||||
if (!languages.Any(a => a.CultureName == item.CultureName))
|
||||
{
|
||||
await _languages.InsertAsync(new()
|
||||
{
|
||||
CultureName = item.CultureName,
|
||||
UiCultureName = item.UiCultureName,
|
||||
DisplayName = item.DisplayName,
|
||||
IsEnabled = item.IsEnabled,
|
||||
TwoLetterISOLanguageName = new CultureInfo(item.CultureName).TwoLetterISOLanguageName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.LanguageTexts)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!keys.Any(a => a.Key == item.Key))
|
||||
{
|
||||
await _languageKey.InsertAsync(new()
|
||||
{
|
||||
Key = item.Key,
|
||||
ResourceName = item.ResourceName,
|
||||
});
|
||||
}
|
||||
if (!texts.Any(a => a.CultureName == "en" && a.Key == item.Key))
|
||||
{
|
||||
await _languagesText.InsertAsync(new()
|
||||
{
|
||||
CultureName = "en",
|
||||
Key = item.Key,
|
||||
Value = item.En,
|
||||
ResourceName = item.ResourceName,
|
||||
});
|
||||
}
|
||||
if (!texts.Any(a => a.CultureName == "tr" && a.Key == item.Key))
|
||||
{
|
||||
|
||||
await _languagesText.InsertAsync(new()
|
||||
{
|
||||
CultureName = "tr",
|
||||
Key = item.Key,
|
||||
Value = item.Tr,
|
||||
ResourceName = item.ResourceName,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"Hata veren Kod:' ResourceName='{item.ResourceName}', Key='{item.Key}' Message='{ex.Message}'");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.GlobalSearch)
|
||||
{
|
||||
if (!await _globalSearch.AnyAsync(x => x.System == item.System && x.Group == item.Group && x.Term == item.Term))
|
||||
|
|
@ -574,96 +168,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.BackgroundWorkers)
|
||||
{
|
||||
if (!await _backgroundWorkerRepository.AnyAsync(x => x.Name == item.Name))
|
||||
{
|
||||
await _backgroundWorkerRepository.InsertAsync(new BackgroundWorker
|
||||
{
|
||||
Name = item.Name,
|
||||
Cron = item.Cron,
|
||||
WorkerType = Enum.Parse<WorkerTypeEnum>(item.WorkerType),
|
||||
IsActive = item.IsActive,
|
||||
DataSourceCode = item.DataSourceCode
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// foreach (var item in items.NotificationRules)
|
||||
// {
|
||||
// var exists = await _notificationRuleRepository.AnyAsync(x =>
|
||||
// x.NotificationType == item.NotificationType &&
|
||||
// x.RecipientType == item.RecipientType &&
|
||||
// x.RecipientId == item.RecipientId &&
|
||||
// x.Channel == item.Channel);
|
||||
|
||||
// if (!exists)
|
||||
// {
|
||||
// await _notificationRuleRepository.InsertAsync(new NotificationRule
|
||||
// {
|
||||
// NotificationType = item.NotificationType,
|
||||
// RecipientType = item.RecipientType,
|
||||
// RecipientId = item.RecipientId,
|
||||
// Channel = item.Channel,
|
||||
// IsActive = item.IsActive,
|
||||
// IsFixed = item.IsFixed,
|
||||
// IsCustomized = item.IsCustomized
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
foreach (var item in items.Menus)
|
||||
{
|
||||
var exists = await _menuRepository.AnyAsync(x => x.Code == item.Code);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _menuRepository.InsertAsync(new Menu
|
||||
{
|
||||
ParentCode = string.IsNullOrWhiteSpace(item.ParentCode) ? null : item.ParentCode,
|
||||
Code = item.Code,
|
||||
DisplayName = item.DisplayName,
|
||||
Order = item.Order,
|
||||
Url = item.Url,
|
||||
Icon = item.Icon,
|
||||
RequiredPermissionName = item.RequiredPermissionName,
|
||||
IsDisabled = item.IsDisabled
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.PermissionGroupDefinitionRecords)
|
||||
{
|
||||
var exists = await _permissionGroupRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _permissionGroupRepository.InsertAsync(new PermissionGroupDefinitionRecord
|
||||
{
|
||||
Name = item.Name,
|
||||
DisplayName = item.DisplayName
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.PermissionDefinitionRecords)
|
||||
{
|
||||
var exists = await _permissionRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _permissionRepository.InsertAsync(new PermissionDefinitionRecord
|
||||
{
|
||||
GroupName = item.GroupName,
|
||||
Name = item.Name,
|
||||
ParentName = string.IsNullOrWhiteSpace(item.ParentName) ? null : item.ParentName,
|
||||
DisplayName = item.DisplayName,
|
||||
IsEnabled = item.IsEnabled,
|
||||
MultiTenancySide = (MultiTenancySides)item.MultiTenancySide
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Sectors)
|
||||
{
|
||||
var exists = await _sectorRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
|
@ -711,22 +215,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Currencies)
|
||||
{
|
||||
var exists = await _currencyRepository.AnyAsync(x => x.Code == item.Code);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _currencyRepository.InsertAsync(new Currency
|
||||
{
|
||||
Code = item.Code,
|
||||
Symbol = item.Symbol,
|
||||
Name = item.Name,
|
||||
IsActive = item.IsActive
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.SkillTypes)
|
||||
{
|
||||
var exists = await _skillTypeRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
|
@ -775,34 +263,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.ContactTags)
|
||||
{
|
||||
var exists = await _contactTagRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _contactTagRepository.InsertAsync(new ContactTag
|
||||
{
|
||||
Name = item.Name,
|
||||
Category = item.Category,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.ContactTitles)
|
||||
{
|
||||
var exists = await _contactTitleRepository.AnyAsync(x => x.Title == item.Title);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _contactTitleRepository.InsertAsync(new ContactTitle
|
||||
{
|
||||
Title = item.Title,
|
||||
Abbreviation = item.Abbreviation,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.BlogCategories)
|
||||
{
|
||||
var exists = await _blogCategoryRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
|
@ -868,35 +328,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.AiBots)
|
||||
{
|
||||
var exists = await _aiBotRepository.AnyAsync(x => x.BotName == item.BotName);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _aiBotRepository.InsertAsync(new AiBot
|
||||
{
|
||||
BotName = item.BotName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.Routes)
|
||||
{
|
||||
var exists = await _routeRepository.AnyAsync(x => x.Key == item.Key);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
await _routeRepository.InsertAsync(new Route(
|
||||
item.Key,
|
||||
item.Path,
|
||||
item.ComponentPath,
|
||||
item.RouteType,
|
||||
item.Authority ?? []
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in items.CustomEndpoints)
|
||||
{
|
||||
var exists = await _customEndpointRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
|
@ -1069,14 +500,6 @@ public class PlatformTenantDataSeeder : IDataSeedContributor, ITransientDependen
|
|||
}
|
||||
}
|
||||
|
||||
await SeedCountyGroupsAsync();
|
||||
|
||||
await SeedCountriesAsync();
|
||||
|
||||
await SeedCitiesAsync();
|
||||
|
||||
await SeedDistrictsAsync();
|
||||
|
||||
foreach (var item in items.Behaviors)
|
||||
{
|
||||
var exists = await _behaviorRepository.AnyAsync(x => x.Name == item.Name);
|
||||
|
|
@ -1,41 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kurs.Languages.Entities;
|
||||
using Kurs.Platform.Abouts;
|
||||
using Kurs.Platform.Contacts;
|
||||
using Kurs.Platform.Entities;
|
||||
using Kurs.Settings.Entities;
|
||||
|
||||
namespace Kurs.Platform.Seeds;
|
||||
|
||||
public class TenantSeederDto
|
||||
{
|
||||
public List<AiBotSeedDto> AiBots { get; set; }
|
||||
public List<GlobalSearchSeedDto> GlobalSearch { get; set; }
|
||||
public List<Language> Languages { get; set; }
|
||||
public List<LanguageTextsSeedDto> LanguageTexts { get; set; }
|
||||
public List<DataSource> DataSources { get; set; }
|
||||
public List<SettingDefinition> Settings { get; set; }
|
||||
public List<BackgroundWorkerSeedDto> BackgroundWorkers { get; set; }
|
||||
public List<NotificationRuleSeedDto> NotificationRules { get; set; }
|
||||
public List<MenuSeedDto> Menus { get; set; }
|
||||
public List<RouteSeedDto> Routes { get; set; }
|
||||
public List<PermissionGroupDefinitionRecordSeedDto> PermissionGroupDefinitionRecords { get; set; }
|
||||
public List<PermissionDefinitionRecordSeedDto> PermissionDefinitionRecords { get; set; }
|
||||
public List<ForumCategorySeedDto> ForumCategories { get; set; }
|
||||
public List<CustomEndpointSeedDto> CustomEndpoints { get; set; }
|
||||
public List<CustomComponentSeedDto> CustomComponents { get; set; }
|
||||
public List<ReportCategorySeedDto> ReportCategories { get; set; }
|
||||
|
||||
public List<UomCategorySeedDto> UomCategories { get; set; }
|
||||
public List<UomSeedDto> Uoms { get; set; }
|
||||
public List<CurrencySeedDto> Currencies { get; set; }
|
||||
public List<SkillTypeSeedDto> SkillTypes { get; set; }
|
||||
public List<SkillSeedDto> Skills { get; set; }
|
||||
public List<SkillLevelSeedDto> SkillLevels { get; set; }
|
||||
public List<ContactTagSeedDto> ContactTags { get; set; }
|
||||
public List<ContactTitleSeedDto> ContactTitles { get; set; }
|
||||
|
||||
public List<AboutSeedDto> Abouts { get; set; }
|
||||
public List<ServiceSeedDto> Services { get; set; }
|
||||
public List<ProductSeedDto> Products { get; set; }
|
||||
|
|
@ -44,7 +26,6 @@ public class TenantSeederDto
|
|||
public List<BlogCategorySeedDto> BlogCategories { get; set; }
|
||||
public List<BlogPostSeedDto> BlogPosts { get; set; }
|
||||
public List<ContactSeedDto> Contacts { get; set; }
|
||||
|
||||
public List<ClassroomSeedDto> Classrooms { get; set; }
|
||||
|
||||
//Tanımlamalar
|
||||
|
|
@ -67,14 +48,6 @@ public class TenantSeederDto
|
|||
public List<ProgramSeedDto> Programs { get; set; }
|
||||
}
|
||||
|
||||
public class LanguageTextsSeedDto
|
||||
{
|
||||
public string ResourceName { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string En { get; set; }
|
||||
public string Tr { get; set; }
|
||||
}
|
||||
|
||||
public class GlobalSearchSeedDto
|
||||
{
|
||||
public string System { get; set; }
|
||||
|
|
@ -84,54 +57,6 @@ public class GlobalSearchSeedDto
|
|||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
public class BackgroundWorkerSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Cron { get; set; }
|
||||
public string WorkerType { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public string DataSourceCode { get; set; }
|
||||
}
|
||||
|
||||
public class NotificationRuleSeedDto
|
||||
{
|
||||
public string NotificationType { get; set; }
|
||||
public string RecipientType { get; set; }
|
||||
public string RecipientId { get; set; }
|
||||
public string Channel { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsFixed { get; set; }
|
||||
public bool IsCustomized { get; set; }
|
||||
}
|
||||
|
||||
public class MenuSeedDto
|
||||
{
|
||||
public string ParentCode { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public int Order { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Icon { get; set; }
|
||||
public string RequiredPermissionName { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
}
|
||||
|
||||
public class PermissionGroupDefinitionRecordSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
}
|
||||
|
||||
public class PermissionDefinitionRecordSeedDto
|
||||
{
|
||||
public string GroupName { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string ParentName { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public bool IsEnabled { get; set; }
|
||||
public int MultiTenancySide { get; set; }
|
||||
}
|
||||
|
||||
public class SectorSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
@ -155,14 +80,6 @@ public class UomSeedDto
|
|||
public string UomCategoryName { get; set; }
|
||||
}
|
||||
|
||||
public class CurrencySeedDto
|
||||
{
|
||||
public string Code { get; set; }
|
||||
public string Symbol { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class SkillTypeSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
@ -182,18 +99,6 @@ public class SkillLevelSeedDto
|
|||
public string SkillTypeName { get; set; }
|
||||
}
|
||||
|
||||
public class ContactTagSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Category { get; set; }
|
||||
}
|
||||
|
||||
public class ContactTitleSeedDto
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Abbreviation { get; set; }
|
||||
}
|
||||
|
||||
public class BlogCategorySeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
@ -228,20 +133,6 @@ public class ForumCategorySeedDto
|
|||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class AiBotSeedDto
|
||||
{
|
||||
public string BotName { get; set; }
|
||||
}
|
||||
|
||||
public class RouteSeedDto
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string ComponentPath { get; set; }
|
||||
public string RouteType { get; set; }
|
||||
public string[] Authority { get; set; }
|
||||
}
|
||||
|
||||
public class CustomEndpointSeedDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue