using System.Globalization; using System.Text.RegularExpressions; using Abp; using Abp.Domain.Repositories; using Abp.Domain.Services; using Abp.Domain.Uow; using Abp.Localization; using Abp.Runtime.Caching; using Abp.UI; using VberZero; using VberZero.BaseSystem.MultiTenancy; // ReSharper disable once CheckNamespace - This is done to add extension methods to Microsoft.Extensions.DependencyInjection namespace namespace Microsoft.Extensions.DependencyInjection; /// /// 租户管理器为 实现域逻辑 /// public class VzTenantManager : IDomainService //, IEventHandler> //,IEventHandler> { //public AbpEditionManager EditionManager { get; set; } public ILocalizationManager LocalizationManager { get; set; } protected string LocalizationSourceName { get; set; } public ICacheManager CacheManager { get; set; } //public IFeatureManager FeatureManager { get; set; } public IUnitOfWorkManager UnitOfWorkManager { get; set; } protected IRepository TenantRepository { get; set; } //protected IRepository TenantFeatureRepository { get; set; } //private readonly IAbpZeroFeatureValueStore _featureValueStore; public VzTenantManager(IRepository tenantRepository) { //_featureValueStore = featureValueStore; TenantRepository = tenantRepository; //TenantFeatureRepository = tenantFeatureRepository; //EditionManager = editionManager; LocalizationManager = NullLocalizationManager.Instance; LocalizationSourceName = VzConsts.LocalizationSourceName; } public virtual IQueryable Tenants => TenantRepository.GetAll(); public virtual async Task CreateAsync(Tenant tenant) { await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { await ValidateTenantAsync(tenant); if (await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenant.TenancyName) != null) { throw new UserFriendlyException(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName)); } await TenantRepository.InsertAsync(tenant); }); } public virtual void Create(Tenant tenant) { UnitOfWorkManager.WithUnitOfWork(() => { ValidateTenant(tenant); if (TenantRepository.FirstOrDefault(t => t.TenancyName == tenant.TenancyName) != null) { throw new UserFriendlyException(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName)); } TenantRepository.Insert(tenant); }); } public virtual async Task UpdateAsync(Tenant tenant) { await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { if (await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenant.TenancyName && t.Id != tenant.Id) != null) { throw new UserFriendlyException(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName)); } await TenantRepository.UpdateAsync(tenant); }); } public virtual void Update(Tenant tenant) { UnitOfWorkManager.WithUnitOfWork(() => { if (TenantRepository.FirstOrDefault(t => t.TenancyName == tenant.TenancyName && t.Id != tenant.Id) != null) { throw new UserFriendlyException(string.Format(L("TenancyNameIsAlreadyTaken"), tenant.TenancyName)); } TenantRepository.Update(tenant); }); } public virtual async Task FindByIdAsync(int id) { return await UnitOfWorkManager.WithUnitOfWorkAsync(async () => await TenantRepository.FirstOrDefaultAsync(id)); } public virtual Tenant FindById(int id) { return UnitOfWorkManager.WithUnitOfWork(() => TenantRepository.FirstOrDefault(id)); } public virtual async Task GetByIdAsync(int id) { var tenant = await FindByIdAsync(id); if (tenant == null) { throw new AbpException("There is no tenant with id: " + id); } return tenant; } public virtual Tenant GetById(int id) { var tenant = FindById(id); if (tenant == null) { throw new AbpException("There is no tenant with id: " + id); } return tenant; } public virtual async Task FindByTenancyNameAsync(string tenancyName) { return await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { return await TenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName); }); } public virtual Tenant FindByTenancyName(string tenancyName) { return UnitOfWorkManager.WithUnitOfWork(() => { return TenantRepository.FirstOrDefault(t => t.TenancyName == tenancyName); }); } public virtual async Task DeleteAsync(Tenant tenant) { await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { await TenantRepository.DeleteAsync(tenant); }); } public virtual void Delete(Tenant tenant) { UnitOfWorkManager.WithUnitOfWork(() => { TenantRepository.Delete(tenant); }); } protected virtual async Task ValidateTenantAsync(Tenant tenant) { await ValidateTenancyNameAsync(tenant.TenancyName); } protected virtual void ValidateTenant(Tenant tenant) { ValidateTenancyName(tenant.TenancyName); } protected virtual Task ValidateTenancyNameAsync(string tenancyName) { if (!Regex.IsMatch(tenancyName, Tenant.TenancyNameRegex)) { throw new UserFriendlyException(L("InvalidTenancyName")); } return Task.FromResult(0); } protected virtual void ValidateTenancyName(string tenancyName) { if (!Regex.IsMatch(tenancyName, Tenant.TenancyNameRegex)) { throw new UserFriendlyException(L("InvalidTenancyName")); } } protected virtual string L(string name) { return LocalizationManager.GetString(LocalizationSourceName, name); } protected virtual string L(string name, CultureInfo cultureInfo) { return LocalizationManager.GetString(LocalizationSourceName, name, cultureInfo); } /* public Task GetFeatureValueOrNullAsync(int tenantId, string featureName) { return _featureValueStore.GetValueOrNullAsync(tenantId, featureName); } public string GetFeatureValueOrNull(int tenantId, string featureName) { return _featureValueStore.GetValueOrNull(tenantId, featureName); } public virtual async Task> GetFeatureValuesAsync(int tenantId) { var values = new List(); foreach (var feature in FeatureManager.GetAll()) { values.Add(new NameValue(feature.Name, await GetFeatureValueOrNullAsync(tenantId, feature.Name) ?? feature.DefaultValue)); } return values; } public virtual IReadOnlyList GetFeatureValues(int tenantId) { var values = new List(); foreach (var feature in FeatureManager.GetAll()) { values.Add(new NameValue(feature.Name, GetFeatureValueOrNull(tenantId, feature.Name) ?? feature.DefaultValue)); } return values; } public virtual async Task SetFeatureValuesAsync(int tenantId, params NameValue[] values) { if (values.IsNullOrEmpty()) { return; } foreach (var value in values) { await SetFeatureValueAsync(tenantId, value.Name, value.Value); } } public virtual void SetFeatureValues(int tenantId, params NameValue[] values) { if (values.IsNullOrEmpty()) { return; } foreach (var value in values) { SetFeatureValue(tenantId, value.Name, value.Value); } } public virtual async Task SetFeatureValueAsync(int tenantId, string featureName, string value) { await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { await SetFeatureValueAsync(await GetByIdAsync(tenantId), featureName, value); }); } public virtual void SetFeatureValue(int tenantId, string featureName, string value) { UnitOfWorkManager.WithUnitOfWork(() => { SetFeatureValue(GetById(tenantId), featureName, value); }); } public virtual async Task SetFeatureValueAsync(AbpTenant tenant, string featureName, string value) { await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { //No need to change if it's already equals to the current value if (await GetFeatureValueOrNullAsync(tenant.Id, featureName) == value) { return; } //Get the current feature setting TenantFeatureSetting currentSetting; using (UnitOfWorkManager.Current.EnableFilter(AbpDataFilters.MayHaveTenant)) using (UnitOfWorkManager.Current.SetTenantId(tenant.Id)) { currentSetting = await TenantFeatureRepository.FirstOrDefaultAsync(f => f.Name == featureName); } //Get the feature var feature = FeatureManager.GetOrNull(featureName); if (feature == null) { if (currentSetting != null) { await TenantFeatureRepository.DeleteAsync(currentSetting); } return; } //Determine default value var defaultValue = tenant.EditionId.HasValue ? (await EditionManager.GetFeatureValueOrNullAsync(tenant.EditionId.Value, featureName) ?? feature.DefaultValue) : feature.DefaultValue; //No need to store value if it's default if (value == defaultValue) { if (currentSetting != null) { await TenantFeatureRepository.DeleteAsync(currentSetting); } return; } //Insert/update the feature value if (currentSetting == null) { await TenantFeatureRepository.InsertAsync(new TenantFeatureSetting(tenant.Id, featureName, value)); } else { currentSetting.Value = value; } }); } public virtual void SetFeatureValue(AbpTenant tenant, string featureName, string value) { UnitOfWorkManager.WithUnitOfWork(() => { //No need to change if it's already equals to the current value if (GetFeatureValueOrNull(tenant.Id, featureName) == value) { return; } //Get the current feature setting TenantFeatureSetting currentSetting; using (UnitOfWorkManager.Current.EnableFilter(AbpDataFilters.MayHaveTenant)) using (UnitOfWorkManager.Current.SetTenantId(tenant.Id)) { currentSetting = TenantFeatureRepository.FirstOrDefault(f => f.Name == featureName); } //Get the feature var feature = FeatureManager.GetOrNull(featureName); if (feature == null) { if (currentSetting != null) { TenantFeatureRepository.Delete(currentSetting); } return; } //Determine default value var defaultValue = tenant.EditionId.HasValue ? (EditionManager.GetFeatureValueOrNull(tenant.EditionId.Value, featureName) ?? feature.DefaultValue) : feature.DefaultValue; //No need to store value if it's default if (value == defaultValue) { if (currentSetting != null) { TenantFeatureRepository.Delete(currentSetting); } return; } //Insert/update the feature value if (currentSetting == null) { TenantFeatureRepository.Insert(new TenantFeatureSetting(tenant.Id, featureName, value)); } else { currentSetting.Value = value; } }); } /// /// Resets all custom feature settings for a tenant. /// Tenant will have features according to it's edition. /// /// Tenant Id public virtual async Task ResetAllFeaturesAsync(int tenantId) { await UnitOfWorkManager.WithUnitOfWorkAsync(async () => { using (UnitOfWorkManager.Current.EnableFilter(AbpDataFilters.MayHaveTenant)) using (UnitOfWorkManager.Current.SetTenantId(tenantId)) { await TenantFeatureRepository.DeleteAsync(f => f.TenantId == tenantId); } }); } /// /// Resets all custom feature settings for a tenant. /// Tenant will have features according to it's edition. /// /// Tenant Id public virtual void ResetAllFeatures(int tenantId) { UnitOfWorkManager.WithUnitOfWork(() => { using (UnitOfWorkManager.Current.EnableFilter(AbpDataFilters.MayHaveTenant)) using (UnitOfWorkManager.Current.SetTenantId(tenantId)) { TenantFeatureRepository.Delete(f => f.TenantId == tenantId); } }); }*/ /* public void HandleEvent(EntityChangedEventData eventData) { if (eventData.Entity.IsTransient()) { return; } CacheManager.GeAbpTenantFeatureCache().Remove(eventData.Entity.Id); } public virtual void HandleEvent(EntityDeletedEventData eventData) { UnitOfWorkManager.WithUnitOfWork(() => { var relatedTenants = TenantRepository.GetAllList(t => t.EditionId == eventData.Entity.Id); foreach (var relatedTenant in relatedTenants) { relatedTenant.EditionId = null; } }); } */ }