using FoodLabeling.Th.Application.Contracts.Dtos.MultiTenancy; using FoodLabeling.Th.Application.Contracts.IServices; using FoodLabeling.Th.Application.Contracts.Options; using FoodLabeling.Th.Application.MultiTenancy; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Options; using SqlSugar; using Volo.Abp; using Volo.Abp.Application.Services; using Volo.Abp.MultiTenancy; using Yi.Framework.TenantManagement.Application.Contracts; using Yi.Framework.TenantManagement.Application.Contracts.Dtos; namespace FoodLabeling.Th.Application.Services; /// /// 泰额版租户独立库开通(平台主库 yitenant + 租户业务库) /// [Authorize] public class ThTenantProvisioningAppService : ApplicationService, IThTenantProvisioningAppService { private readonly ITenantService _tenantService; private readonly FoodLabelingThTenantDatabaseOptions _dbOptions; public ThTenantProvisioningAppService( ITenantService tenantService, IOptions dbOptions) { _tenantService = tenantService; _dbOptions = dbOptions.Value; } /// public virtual async Task ProvisionAsync(ThProvisionTenantInputVo input) { if (string.IsNullOrWhiteSpace(input.Name)) { throw new UserFriendlyException("租户名称不能为空"); } var connectionString = string.IsNullOrWhiteSpace(input.TenantConnectionString) ? TenantDatabaseConnectionStringBuilder.BuildMySqlConnectionString(_dbOptions, input.Name) : input.TenantConnectionString.Trim(); var databaseName = ExtractDatabaseName(connectionString) ?? TenantDatabaseConnectionStringBuilder.BuildDatabaseName(_dbOptions, input.Name); // 平台主库写入 yitenant(CurrentTenant 为空时走 DbConnOptions 主库) var dbType = Enum.IsDefined(typeof(DbType), input.DbType) ? (DbType)input.DbType : DbType.MySql; var created = await _tenantService.CreateAsync(new TenantCreateInput { Name = input.Name.Trim(), TenantConnectionString = connectionString, DbType = dbType }); var initialized = false; if (input.InitializeDatabase) { await _tenantService.InitAsync(created.Id); initialized = true; } return new ThProvisionTenantOutputDto { TenantId = created.Id, Name = created.Name, DatabaseName = databaseName, TenantConnectionString = connectionString, DatabaseInitialized = initialized }; } /// public virtual Task InitializeTenantDatabaseAsync(Guid tenantId) { return _tenantService.InitAsync(tenantId); } private static string? ExtractDatabaseName(string connectionString) { const string key = "database="; var idx = connectionString.IndexOf(key, StringComparison.OrdinalIgnoreCase); if (idx < 0) { return null; } var start = idx + key.Length; var end = connectionString.IndexOf(';', start); return end < 0 ? connectionString[start..].Trim() : connectionString[start..end].Trim(); } }