Browse Source

feat: 添加租户字符串配置

pull/127/head
WangJunZzz 2 years ago
parent
commit
b4b1c9d781
  1. 40
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/AddOrUpdateConnectionStringInput.cs
  2. 9
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/DeleteConnectionStringInput.cs
  3. 19
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/PageTenantConnectionStringInput.cs
  4. 19
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/PageTenantConnectionStringOutput.cs
  5. 15
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/IVoloTenantAppService.cs
  6. 1
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/BasicManagementApplicationAutoMapperProfile.cs
  7. 2
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/BasicManagementApplicationModule.cs
  8. 87
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Tenants/VoloTenantAppService.cs
  9. 3
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Users/AccountAppService.cs
  10. 2
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/BasicManagementErrorCodes.cs
  11. 4
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Localization/BasicManagement/en.json
  12. 4
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Localization/BasicManagement/zh-Hans.json
  13. 21
      aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/Tenants/TenantController.cs
  14. 2
      aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaries/Aggregates/DataDictionary.cs
  15. 13
      aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.Domain/Data/LanguageManagementDataSeedContributor.cs
  16. 16
      aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.Domain/Languages/Aggregates/Language.cs
  17. 2
      aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.Domain/Languages/LanguageManager.cs
  18. 2
      aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.EntityFrameworkCore/EntityFrameworkCore/LanguageManagementDbContextModelCreatingExtensions.cs
  19. 5
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Etos/NotificationEto.cs
  20. 18
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/Notification.cs
  21. 18
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/NotificationSubscription.cs
  22. 12
      aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/NotificationManager.cs
  23. 13
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json
  24. 2
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.Production.json
  25. 2
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.json
  26. 2003
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.Designer.cs
  27. 104
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.cs
  28. 2002
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.Designer.cs
  29. 37
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.cs
  30. 23
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/AbpProDbContextModelSnapshot.cs
  31. 1
      vben28/src/locales/lang/en/common.ts
  32. 1
      vben28/src/locales/lang/zh-CN/common.ts
  33. 345
      vben28/src/services/ServiceProxies.ts
  34. 70
      vben28/src/views/tenants/CreateConnectionString.vue
  35. 96
      vben28/src/views/tenants/EditConnectionString.vue
  36. 69
      vben28/src/views/tenants/Tenant.ts
  37. 16
      vben28/src/views/tenants/Tenant.vue
  38. 11739
      vben28/yarn.lock

40
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/AddOrUpdateConnectionStringInput.cs

@ -0,0 +1,40 @@
namespace Lion.AbpPro.BasicManagement.Tenants.Dtos;
public class AddOrUpdateConnectionStringInput : IValidatableObject
{
/// <summary>
/// id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 连接字符串名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 连接字符串地址
/// </summary>
public string Value { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var localization = validationContext.GetRequiredService<IStringLocalizer<AbpProLocalizationResource>>();
if (Name.IsNullOrWhiteSpace())
{
yield return new ValidationResult(
localization[AbpProLocalizationErrorCodes.ErrorCode100003, nameof(Name)],
new[] { nameof(Name) }
);
}
if (Value.IsNullOrWhiteSpace())
{
yield return new ValidationResult(
localization[AbpProLocalizationErrorCodes.ErrorCode100003, nameof(Value)],
new[] { nameof(Value) }
);
}
}
}

9
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/DeleteConnectionStringInput.cs

@ -0,0 +1,9 @@
namespace Lion.AbpPro.BasicManagement.Tenants.Dtos;
public class DeleteConnectionStringInput
{
/// <summary>
/// 连接字符串名称
/// </summary>
public string Name { get; set; }
}

19
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/PageTenantConnectionStringInput.cs

@ -0,0 +1,19 @@
namespace Lion.AbpPro.BasicManagement.Tenants.Dtos;
public class PageTenantConnectionStringInput
{
/// <summary>
/// 租户id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 连接字符串名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 连接字符串地址
/// </summary>
public string Value { get; set; }
}

19
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/Dtos/PageTenantConnectionStringOutput.cs

@ -0,0 +1,19 @@
namespace Lion.AbpPro.BasicManagement.Tenants.Dtos;
public class PageTenantConnectionStringOutput
{
/// <summary>
/// 租户id
/// </summary>
public Guid TenantId { get; set; }
/// <summary>
/// 连接字符串名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 连接字符串地址
/// </summary>
public string Value { get; set; }
}

15
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application.Contracts/Tenants/IVoloTenantAppService.cs

@ -12,10 +12,19 @@ namespace Lion.AbpPro.BasicManagement.Tenants
Task DeleteAsync(IdInput input);
Task<string> GetDefaultConnectionStringAsync(IdInput input);
/// <summary>
/// 分页获取租户连接字符串
/// </summary>
Task<PagedResultDto<PageTenantConnectionStringOutput>> PageConnectionStringsAsync(PageTenantConnectionStringInput input);
Task UpdateDefaultConnectionStringAsync(UpdateConnectionStringInput input);
/// <summary>
/// 新增或者更新连接字符串
/// </summary>
Task AddOrUpdateConnectionStringAsync(AddOrUpdateConnectionStringInput input);
Task DeleteDefaultConnectionStringAsync(IdInput input);
/// <summary>
/// 删除连接字符串
/// </summary>
Task DeleteConnectionStringAsync(DeleteConnectionStringInput input);
}
}

1
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/BasicManagementApplicationAutoMapperProfile.cs

@ -34,5 +34,6 @@ public class BasicManagementApplicationAutoMapperProfile : Profile
CreateMap<IdentityRole, GetOrganizationUnitRoleOutput>();
CreateMap<IdentityRole, GetUnAddRoleOutput>();
CreateMap<IdentitySecurityLog, PagingIdentitySecurityLogOutput>();
CreateMap<TenantConnectionString, PageTenantConnectionStringOutput>();
}
}

2
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/BasicManagementApplicationModule.cs

@ -47,7 +47,7 @@ public class BasicManagementApplicationModule : AbpModule
options.Excludes.Add(SettingManagementPermissions.GroupName);
options.Excludes.Add(SettingManagementPermissions.Emailing);
options.Excludes.Add(TenantManagementPermissions.Tenants.ManageFeatures);
options.Excludes.Add(TenantManagementPermissions.Tenants.ManageConnectionStrings);
//options.Excludes.Add(TenantManagementPermissions.Tenants.ManageConnectionStrings);
});
context.Services.Configure<JwtOptions>(context.Services.GetConfiguration().GetSection("Jwt"));

87
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Tenants/VoloTenantAppService.cs

@ -1,3 +1,7 @@
using Volo.Abp.BackgroundJobs;
using Volo.Abp.FeatureManagement;
using Volo.Abp.SettingManagement;
namespace Lion.AbpPro.BasicManagement.Tenants
{
[Authorize(TenantManagementPermissions.Tenants.Default)]
@ -5,13 +9,16 @@ namespace Lion.AbpPro.BasicManagement.Tenants
{
private readonly IAbpTenantAppService _abpTenantAppService;
private readonly ITenantAppService _tenantAppService;
private readonly ITenantRepository _tenantRepository;
public VoloTenantAppService(
IAbpTenantAppService abpTenantAppService,
ITenantAppService tenantAppService)
ITenantAppService tenantAppService,
ITenantRepository tenantRepository)
{
_abpTenantAppService = abpTenantAppService;
_tenantAppService = tenantAppService;
_tenantRepository = tenantRepository;
}
[AllowAnonymous]
@ -52,23 +59,85 @@ namespace Lion.AbpPro.BasicManagement.Tenants
return _tenantAppService.DeleteAsync(input.Id);
}
[Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)]
public virtual Task<string> GetDefaultConnectionStringAsync(IdInput input)
public async Task<PagedResultDto<PageTenantConnectionStringOutput>> PageConnectionStringsAsync(PageTenantConnectionStringInput input)
{
return _tenantAppService.GetDefaultConnectionStringAsync(input.Id);
var result = new PagedResultDto<PageTenantConnectionStringOutput>();
var tenant = await _tenantRepository.FindAsync(input.Id, true);
if (tenant == null)
{
throw new BusinessException(BasicManagementErrorCodes.TenantNotExist);
}
[Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)]
public virtual Task UpdateDefaultConnectionStringAsync(UpdateConnectionStringInput input)
result.TotalCount = tenant.ConnectionStrings.Count;
var items = ObjectMapper.Map<List<TenantConnectionString>, List<PageTenantConnectionStringOutput>>(tenant.ConnectionStrings);
if (input.Name.IsNotNullOrWhiteSpace())
{
items = items.Where(e => e.Name.ToLower().Contains(input.Name.ToLower())).ToList();
}
if (input.Value.IsNotNullOrWhiteSpace())
{
return _tenantAppService.UpdateDefaultConnectionStringAsync(input.Id,
input.ConnectionString);
items = items.Where(e => e.Value.ToLower().Contains(input.Value.ToLower())).ToList();
}
result.Items = items;
return result;
}
[Authorize(TenantManagementPermissions.Tenants.ManageConnectionStrings)]
public virtual Task DeleteDefaultConnectionStringAsync(IdInput input)
public async Task AddOrUpdateConnectionStringAsync(AddOrUpdateConnectionStringInput input)
{
// abp 租户,feature,background,setting 模块不支持单独配置数据库
if (AbpTenantManagementDbProperties.ConnectionStringName.ToLower() == input.Name.ToLower() ||
AbpBackgroundJobsDbProperties.ConnectionStringName.ToLower()== input.Name.ToLower() ||
AbpFeatureManagementDbProperties.ConnectionStringName.ToLower() == input.Name.ToLower() ||
AbpSettingManagementDbProperties.ConnectionStringName.ToLower() == input.Name.ToLower())
{
throw new BusinessException(BasicManagementErrorCodes.NotSupportSetConnectionString);
}
var tenant = await _tenantRepository.FindAsync(input.Id, true);
if (tenant == null)
{
throw new BusinessException(BasicManagementErrorCodes.TenantNotExist);
}
var connectionString = tenant.ConnectionStrings.FirstOrDefault(e => e.Value == input.Name);
if (connectionString == null)
{
tenant.SetConnectionString(input.Name, input.Value);
}
else
{
if (connectionString.Value != input.Value)
{
tenant.SetConnectionString(input.Name, input.Value);
}
}
}
public async Task DeleteConnectionStringAsync(DeleteConnectionStringInput input)
{
return _tenantAppService.DeleteDefaultConnectionStringAsync(input.Id);
if (!CurrentTenant.Id.HasValue)
{
throw new BusinessException(BasicManagementErrorCodes.TenantNotExist);
}
var tenant = await _tenantRepository.FindAsync(CurrentTenant.Id.Value, true);
if (tenant == null)
{
throw new BusinessException(BasicManagementErrorCodes.TenantNotExist);
}
var connectionString = tenant.ConnectionStrings.FirstOrDefault(e => e.Value == input.Name);
if (connectionString != null)
{
tenant.RemoveConnectionString(input.Name);
}
}
}
}

3
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Application/Users/AccountAppService.cs

@ -92,8 +92,7 @@ namespace Lion.AbpPro.BasicManagement.Users
/// 生成jwt token
/// </summary>
/// <returns></returns>
private string GenerateJwt(Guid userId, string userName, string name, string email,
string tenantId, List<string> roles)
private string GenerateJwt(Guid userId, string userName, string name, string email, string tenantId, List<string> roles)
{
var dateNow = Clock.Now;
var expirationTime = dateNow.AddHours(_jwtOptions.ExpirationTime);

2
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/BasicManagementErrorCodes.cs

@ -6,4 +6,6 @@ public static class BasicManagementErrorCodes
public const string UserLockedOut = BasicManagementConsts.NameSpace + ":100002";
public const string UserOrPasswordMismatch = BasicManagementConsts.NameSpace + ":100003";
public const string UserDisabled = BasicManagementConsts.NameSpace + ":100004";
public const string TenantNotExist = BasicManagementConsts.NameSpace + ":100005";
public const string NotSupportSetConnectionString = BasicManagementConsts.NameSpace + ":100006";
}

4
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Localization/BasicManagement/en.json

@ -19,6 +19,8 @@
"Lion.AbpPro.BasicManagement:100001": "OrganizationUnit Not Exist",
"Lion.AbpPro.BasicManagement:100002": "UserLockedOut",
"Lion.AbpPro.BasicManagement:100003": "UserOrPasswordMismatch",
"Lion.AbpPro.BasicManagement:100004": "UserDisabled"
"Lion.AbpPro.BasicManagement:100004": "UserDisabled",
"Lion.AbpPro.BasicManagement:100005": "Tenant Not Exist",
"Lion.AbpPro.BasicManagement:100006": "Not Support Set ConnectionString"
}
}

4
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.Domain.Shared/Localization/BasicManagement/zh-Hans.json

@ -20,6 +20,8 @@
"Lion.AbpPro.BasicManagement:100001": "组织机构不存在",
"Lion.AbpPro.BasicManagement:100002": "用户被锁定",
"Lion.AbpPro.BasicManagement:100003": "用户名或者密码错误",
"Lion.AbpPro.BasicManagement:100004": "用户已禁用"
"Lion.AbpPro.BasicManagement:100004": "用户已禁用",
"Lion.AbpPro.BasicManagement:100005": "租户不存在",
"Lion.AbpPro.BasicManagement:100006": "当前模块不支持设置数据库连接字符串"
}
}

21
aspnet-core/modules/BasicManagement/src/Lion.AbpPro.BasicManagement.HttpApi/Tenants/TenantController.cs

@ -49,25 +49,26 @@ namespace Lion.AbpPro.BasicManagement.Tenants
return _voloTenantAppService.DeleteAsync(input);
}
[HttpPost("getConnectionString")]
[SwaggerOperation(summary: "获取租户连接字符串", Tags = new[] { "Tenants" })]
public Task<string> GetDefaultConnectionStringAsync(IdInput input)
[HttpPost("pageConnectionString")]
[SwaggerOperation(summary: "分页租户连接字符串", Tags = new[] { "Tenants" })]
public Task<PagedResultDto<PageTenantConnectionStringOutput>> PageConnectionStringsAsync(PageTenantConnectionStringInput input)
{
return _voloTenantAppService.GetDefaultConnectionStringAsync(input);
return _voloTenantAppService.PageConnectionStringsAsync(input);
}
[HttpPost("updateConnectionString")]
[SwaggerOperation(summary: "更新租户连接字符串", Tags = new[] { "Tenants" })]
public Task UpdateDefaultConnectionStringAsync(UpdateConnectionStringInput input)
[HttpPost("addOrUpdateConnectionString")]
[SwaggerOperation(summary: "新增或者更新租户所有连接字符串", Tags = new[] { "Tenants" })]
public Task AddOrUpdateConnectionStringAsync(AddOrUpdateConnectionStringInput input)
{
return _voloTenantAppService.UpdateDefaultConnectionStringAsync(input);
return _voloTenantAppService.AddOrUpdateConnectionStringAsync(input);
}
[HttpPost("deleteConnectionString")]
[SwaggerOperation(summary: "删除租户连接字符串", Tags = new[] { "Tenants" })]
public Task DeleteDefaultConnectionStringAsync(IdInput input)
public Task DeleteConnectionStringAsync(DeleteConnectionStringInput input)
{
return _voloTenantAppService.DeleteDefaultConnectionStringAsync(input);
return _voloTenantAppService.DeleteConnectionStringAsync(input);
}
}
}

2
aspnet-core/modules/DataDictionaryManagement/src/Lion.AbpPro.DataDictionaryManagement.Domain/DataDictionaries/Aggregates/DataDictionary.cs

@ -61,7 +61,7 @@ public class DataDictionary : FullAuditedAggregateRoot<Guid>, IMultiTenant
SetTenantId(tenantId);
}
public void SetTenantId(Guid? tenantId)
private void SetTenantId(Guid? tenantId)
{
TenantId = tenantId;
}

13
aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.Domain/Data/LanguageManagementDataSeedContributor.cs

@ -10,21 +10,27 @@ public class LanguageManagementDataSeedContributor : ITransientDependency, IData
private readonly IDataFilter<ISoftDelete> _softDeleteFilter;
private readonly IGuidGenerator _guidGenerator;
private readonly ISettingManager _settingManager;
private readonly ICurrentTenant _currentTenant;
public LanguageManagementDataSeedContributor(
ILanguageRepository languageRepository,
IOptions<AbpLocalizationOptions> localizationOptions,
IDataFilter<ISoftDelete> softDeleteFilter,
IGuidGenerator guidGenerator,
ISettingManager settingManager)
ISettingManager settingManager,
ICurrentTenant currentTenant)
{
_languageRepository = languageRepository;
_softDeleteFilter = softDeleteFilter;
_guidGenerator = guidGenerator;
_settingManager = settingManager;
_currentTenant = currentTenant;
_localizationOptions = localizationOptions.Value;
}
public async Task SeedAsync(DataSeedContext context)
{
using (_currentTenant.Change(context?.TenantId))
{
var defaultLanguage = await _settingManager.GetOrNullDefaultAsync(LanguageManagementConsts.SettingDefaultLanguage);
using (_softDeleteFilter.Disable())
@ -43,9 +49,12 @@ public class LanguageManagementDataSeedContributor : ITransientDependency, IData
language.DisplayName,
language.FlagIcon,
true,
isDefault));
isDefault,
_currentTenant.Id));
}
}
}
}
}
}

16
aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.Domain/Languages/Aggregates/Language.cs

@ -1,6 +1,6 @@
namespace Lion.AbpPro.LanguageManagement.Languages.Aggregates;
public class Language : FullAuditedAggregateRoot<Guid>, ILanguageInfo
public class Language : FullAuditedAggregateRoot<Guid>, ILanguageInfo, IMultiTenant
{
private Language()
{
@ -14,7 +14,8 @@ public class Language : FullAuditedAggregateRoot<Guid>, ILanguageInfo
string displayName,
string flagIcon,
bool isEnabled,
bool isDefault
bool isDefault,
Guid? tenantId = null
) : base(id)
{
SetCultureName(cultureName);
@ -23,8 +24,14 @@ public class Language : FullAuditedAggregateRoot<Guid>, ILanguageInfo
SetFlagIcon(flagIcon);
SetEnabled(isEnabled);
SetDefault(isDefault);
SetTenantId(tenantId);
}
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; private set; }
/// <summary>
/// 语言名称
/// </summary>
@ -95,6 +102,11 @@ public class Language : FullAuditedAggregateRoot<Guid>, ILanguageInfo
IsEnabled = isEnabled;
}
public void SetTenantId(Guid? tenantId)
{
TenantId = tenantId;
}
/// <summary>
/// 更新语言
/// </summary>

2
aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.Domain/Languages/LanguageManager.cs

@ -54,7 +54,7 @@ public class LanguageManager : LanguageManagementDomainService, ILanguageManager
throw new LanguageManagementDomainException(LanguageManagementErrorCodes.LanguageExist);
}
entity = new Language(id, cultureName, uiCultureName, displayName, flagIcon, isEnabled, false);
entity = new Language(id, cultureName, uiCultureName, displayName, flagIcon, isEnabled, false, CurrentTenant.Id);
entity = await _languageRepository.InsertAsync(entity);
return ObjectMapper.Map<Language, LanguageDto>(entity);
}

2
aspnet-core/modules/LanguageManagement/src/Lion.AbpPro.LanguageManagement.EntityFrameworkCore/EntityFrameworkCore/LanguageManagementDbContextModelCreatingExtensions.cs

@ -15,7 +15,7 @@ namespace Lion.AbpPro.LanguageManagement.EntityFrameworkCore
b.Property(e => e.DisplayName).IsRequired().HasMaxLength(128).HasComment("显示名称");
b.Property(e => e.FlagIcon).HasMaxLength(128).HasComment("图标");
b.Property<bool>(x => x.IsEnabled).IsRequired();
b.HasIndex(e => e.CultureName).IsUnique();
b.HasIndex(e => e.CultureName);
b.ConfigureByConvention();
});

5
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain.Shared/Notifications/Etos/NotificationEto.cs

@ -7,6 +7,11 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Etos
{
public class NotificationEto
{
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; set; }
public Guid Id { get; set; }
/// <summary>

18
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/Notification.cs

@ -1,10 +1,17 @@
using Volo.Abp.MultiTenancy;
namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
{
/// <summary>
/// 消息通知
/// </summary>
public class Notification : FullAuditedAggregateRoot<Guid>
public class Notification : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; private set; }
/// <summary>
/// 消息标题
/// </summary>
@ -50,7 +57,8 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
string content,
MessageType messageType,
MessageLevel messageLevel,
Guid senderId
Guid senderId,
Guid? tenantId = null
) : base(id)
{
NotificationSubscriptions = new List<NotificationSubscription>();
@ -62,6 +70,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
messageLevel,
senderId
);
SetTenantId(tenantId);
}
private void SetProperties(
@ -79,6 +88,11 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
SetSenderId(senderId);
}
private void SetTenantId(Guid? tenantId)
{
TenantId = tenantId;
}
private void SetSenderId(Guid senderId)
{
Guard.NotEmpty(senderId, nameof(senderId));

18
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/Aggregates/NotificationSubscription.cs

@ -1,10 +1,17 @@
using Volo.Abp.MultiTenancy;
namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
{
/// <summary>
/// 消息订阅者
/// </summary>
public class NotificationSubscription : FullAuditedEntity<Guid>
public class NotificationSubscription : FullAuditedEntity<Guid>, IMultiTenant
{
/// <summary>
/// 租户id
/// </summary>
public Guid? TenantId { get; private set; }
/// <summary>
/// 消息Id
/// </summary>
@ -33,13 +40,20 @@ namespace Lion.AbpPro.NotificationManagement.Notifications.Aggregates
public NotificationSubscription(
Guid id,
Guid notificationId,
Guid receiveId
Guid receiveId,
Guid? tenantId = null
) : base(id)
{
SetNotificationId(notificationId);
SetReceiveId(receiveId);
Read = false;
ReadTime = null;
SetTenantId(tenantId);
}
private void SetTenantId(Guid? tenantId)
{
TenantId = tenantId;
}
private void SetNotificationId(Guid notificationId)

12
aspnet-core/modules/NotificationManagement/src/Lion.AbpPro.NotificationManagement.Domain/Notifications/NotificationManager.cs

@ -53,7 +53,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Warning, senderId);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Warning, senderId, CurrentTenant.Id);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
@ -84,7 +84,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Information, senderId);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Information, senderId, CurrentTenant.Id);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
@ -112,7 +112,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Error, senderId);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Common, MessageLevel.Error, senderId, CurrentTenant.Id);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
@ -137,7 +137,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Warning, senderId);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Warning, senderId, CurrentTenant.Id);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
@ -157,7 +157,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Information, senderId);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Information, senderId, CurrentTenant.Id);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
@ -177,7 +177,7 @@ namespace Lion.AbpPro.NotificationManagement.Notifications
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Error, senderId);
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, MessageLevel.Error, senderId, CurrentTenant.Id);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
entity.AddCreatedNotificationLocalEvent(new CreatedNotificationLocalEvent(notificationEto));
await _notificationRepository.InsertAsync(entity);

13
aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json

@ -34,16 +34,16 @@
"CorsOrigins": "https://*.AbpPro.com,http://localhost:4200,http://localhost:3100"
},
"ConnectionStrings": {
"Default": "Data Source=localhost;Port=3306;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=43.139.143.143;Port=3306;Database=tenantdb;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
},
"Hangfire": {
"Redis": {
"Host": "localhost:6379,password=1q2w3E*",
"Host": "43.139.143.143:6379,password=1q2w3E*",
"DB": "2"
}
},
"Redis": {
"Configuration": "localhost:6379,password=1q2w3E*,defaultdatabase=1"
"Configuration": "43.139.143.143:6379,password=1q2w3E*,defaultdatabase=5"
},
"Jwt": {
"Audience": "Lion.AbpPro",
@ -52,11 +52,12 @@
"ExpirationTime": 2
},
"Cap": {
"Enabled": false,
"Enabled": true,
"RabbitMq": {
"HostName": "localhost",
"HostName": "43.139.143.143",
"UserName": "admin",
"Password": "admin"
"Password": "1q2w3E*",
"Port": 5672
}
},
"ElasticSearch": {

2
aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.Production.json

@ -1,5 +1,5 @@
{
"ConnectionStrings": {
"Default": "Data Source=mysql;Port=3306;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=mysql;Port=3306;Database=tenantdb;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
}
}

2
aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.json

@ -1,5 +1,5 @@
{
"ConnectionStrings": {
"Default": "Data Source=localhost;Port=3306;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=43.139.143.143;Port=3306;Database=tenantdb;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
}
}

2003
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.Designer.cs

File diff suppressed because it is too large

104
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404001711_AddTenantId.cs

@ -0,0 +1,104 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Lion.AbpPro.Migrations
{
/// <inheritdoc />
public partial class AddTenantId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Providers",
table: "AbpSettingDefinitions",
type: "varchar(1024)",
maxLength: 1024,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(128)",
oldMaxLength: 128,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "DefaultValue",
table: "AbpSettingDefinitions",
type: "varchar(2048)",
maxLength: 2048,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(256)",
oldMaxLength: 256,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "AbpNotificationSubscriptions",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "AbpNotifications",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "AbpLanguages",
type: "char(36)",
nullable: true,
collation: "ascii_general_ci");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TenantId",
table: "AbpNotificationSubscriptions");
migrationBuilder.DropColumn(
name: "TenantId",
table: "AbpNotifications");
migrationBuilder.DropColumn(
name: "TenantId",
table: "AbpLanguages");
migrationBuilder.AlterColumn<string>(
name: "Providers",
table: "AbpSettingDefinitions",
type: "varchar(128)",
maxLength: 128,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(1024)",
oldMaxLength: 1024,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AlterColumn<string>(
name: "DefaultValue",
table: "AbpSettingDefinitions",
type: "varchar(256)",
maxLength: 256,
nullable: true,
oldClrType: typeof(string),
oldType: "varchar(2048)",
oldMaxLength: 2048,
oldNullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
.OldAnnotation("MySql:CharSet", "utf8mb4");
}
}
}

2002
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.Designer.cs

File diff suppressed because it is too large

37
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/20240404004344_RemoveLanguageIndex.cs

@ -0,0 +1,37 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Lion.AbpPro.Migrations
{
/// <inheritdoc />
public partial class RemoveLanguageIndex : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages");
migrationBuilder.CreateIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages",
column: "CultureName");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages");
migrationBuilder.CreateIndex(
name: "IX_AbpLanguages_CultureName",
table: "AbpLanguages",
column: "CultureName",
unique: true);
}
}
}

23
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/Migrations/AbpProDbContextModelSnapshot.cs

@ -290,6 +290,10 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<string>("UiCultureName")
.IsRequired()
.HasMaxLength(128)
@ -298,8 +302,7 @@ namespace Lion.AbpPro.Migrations
b.HasKey("Id");
b.HasIndex("CultureName")
.IsUnique();
b.HasIndex("CultureName");
b.ToTable("AbpLanguages", (string)null);
});
@ -365,6 +368,10 @@ namespace Lion.AbpPro.Migrations
b.Property<Guid>("SenderId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<string>("Title")
.IsRequired()
.HasMaxLength(256)
@ -422,6 +429,10 @@ namespace Lion.AbpPro.Migrations
b.Property<Guid>("ReceiveId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("NotificationId");
@ -1668,8 +1679,8 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("char(36)");
b.Property<string>("DefaultValue")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.Property<string>("Description")
.HasMaxLength(512)
@ -1699,8 +1710,8 @@ namespace Lion.AbpPro.Migrations
.HasColumnType("varchar(128)");
b.Property<string>("Providers")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.HasKey("Id");

1
vben28/src/locales/lang/en/common.ts

@ -20,6 +20,7 @@ export default {
locked: 'Locked',
unLocked: 'UnLocked',
createText: 'Create',
createOrUpdateText: 'Create Or Update',
tip: 'Tip',
askDelete: 'Are you sure you want to delete',
operationSuccess: 'Operation Success',

1
vben28/src/locales/lang/zh-CN/common.ts

@ -27,6 +27,7 @@ export default {
locked: '已锁定',
unLocked: '未锁定',
createText: '新增',
createOrUpdateText: '新增或编辑',
tip: '提示',
askDelete: '确认删除吗',
disEnabledSelf: '不能禁用自己',

345
vben28/src/services/ServiceProxies.ts

@ -6132,12 +6132,12 @@ export class TenantsServiceProxy extends ServiceProxyBase {
}
/**
*
*
* @param body (optional)
* @return Success
*/
getConnectionString(body: IdInput | undefined , cancelToken?: CancelToken | undefined): Promise<string> {
let url_ = this.baseUrl + "/Tenants/getConnectionString";
pageConnectionString(body: PageTenantConnectionStringInput | undefined , cancelToken?: CancelToken | undefined): Promise<PageTenantConnectionStringOutputPagedResultDto> {
let url_ = this.baseUrl + "/Tenants/pageConnectionString";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
@ -6162,11 +6162,11 @@ export class TenantsServiceProxy extends ServiceProxyBase {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processGetConnectionString(_response));
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processPageConnectionString(_response));
});
}
protected processGetConnectionString(response: AxiosResponse): Promise<string> {
protected processPageConnectionString(response: AxiosResponse): Promise<PageTenantConnectionStringOutputPagedResultDto> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
@ -6180,9 +6180,8 @@ export class TenantsServiceProxy extends ServiceProxyBase {
const _responseText = response.data;
let result200: any = null;
let resultData200 = _responseText;
result200 = resultData200 !== undefined ? resultData200 : <any>null;
return Promise.resolve<string>(result200);
result200 = PageTenantConnectionStringOutputPagedResultDto.fromJS(resultData200);
return Promise.resolve<PageTenantConnectionStringOutputPagedResultDto>(result200);
} else if (status === 403) {
const _responseText = response.data;
@ -6230,16 +6229,16 @@ export class TenantsServiceProxy extends ServiceProxyBase {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<string>(null as any);
return Promise.resolve<PageTenantConnectionStringOutputPagedResultDto>(null as any);
}
/**
*
*
* @param body (optional)
* @return Success
*/
updateConnectionString(body: UpdateConnectionStringInput | undefined , cancelToken?: CancelToken | undefined): Promise<void> {
let url_ = this.baseUrl + "/Tenants/updateConnectionString";
addOrUpdateConnectionString(body: AddOrUpdateConnectionStringInput | undefined , cancelToken?: CancelToken | undefined): Promise<void> {
let url_ = this.baseUrl + "/Tenants/addOrUpdateConnectionString";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
@ -6263,11 +6262,11 @@ export class TenantsServiceProxy extends ServiceProxyBase {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processUpdateConnectionString(_response));
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processAddOrUpdateConnectionString(_response));
});
}
protected processUpdateConnectionString(response: AxiosResponse): Promise<void> {
protected processAddOrUpdateConnectionString(response: AxiosResponse): Promise<void> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
@ -6335,7 +6334,7 @@ export class TenantsServiceProxy extends ServiceProxyBase {
* @param body (optional)
* @return Success
*/
deleteConnectionString(body: IdInput | undefined , cancelToken?: CancelToken | undefined): Promise<void> {
deleteConnectionString(body: DeleteConnectionStringInput | undefined , cancelToken?: CancelToken | undefined): Promise<void> {
let url_ = this.baseUrl + "/Tenants/deleteConnectionString";
url_ = url_.replace(/[?&]$/, "");
@ -7382,6 +7381,56 @@ export interface IActionApiDescriptionModel {
implementFrom: string | undefined;
}
export class AddOrUpdateConnectionStringInput implements IAddOrUpdateConnectionStringInput {
/** id */
id!: string;
/** 连接字符串名称 */
name!: string | undefined;
/** 连接字符串地址 */
value!: string | undefined;
constructor(data?: IAddOrUpdateConnectionStringInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.name = _data["name"];
this.value = _data["value"];
}
}
static fromJS(data: any): AddOrUpdateConnectionStringInput {
data = typeof data === 'object' ? data : {};
let result = new AddOrUpdateConnectionStringInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["name"] = this.name;
data["value"] = this.value;
return data;
}
}
export interface IAddOrUpdateConnectionStringInput {
/** id */
id: string;
/** 连接字符串名称 */
name: string | undefined;
/** 连接字符串地址 */
value: string | undefined;
}
export class AddRoleToOrganizationUnitInput implements IAddRoleToOrganizationUnitInput {
roleId!: string[] | undefined;
organizationUnitId!: string;
@ -7842,7 +7891,7 @@ export class ApplicationLocalizationConfigurationDto implements IApplicationLoca
this.values = {} as any;
for (let key in _data["values"]) {
if (_data["values"].hasOwnProperty(key))
(<any>this.values)![key] = _data["values"][key];
(<any>this.values)![key] = _data["values"][key] !== undefined ? _data["values"][key] : {};
}
}
if (_data["resources"]) {
@ -7863,14 +7912,14 @@ export class ApplicationLocalizationConfigurationDto implements IApplicationLoca
this.languagesMap = {} as any;
for (let key in _data["languagesMap"]) {
if (_data["languagesMap"].hasOwnProperty(key))
(<any>this.languagesMap)![key] = _data["languagesMap"][key] ? _data["languagesMap"][key].map((i: any) => NameValue.fromJS(i)) : <any>undefined;
(<any>this.languagesMap)![key] = _data["languagesMap"][key] ? _data["languagesMap"][key].map((i: any) => NameValue.fromJS(i)) : [];
}
}
if (_data["languageFilesMap"]) {
this.languageFilesMap = {} as any;
for (let key in _data["languageFilesMap"]) {
if (_data["languageFilesMap"].hasOwnProperty(key))
(<any>this.languageFilesMap)![key] = _data["languageFilesMap"][key] ? _data["languageFilesMap"][key].map((i: any) => NameValue.fromJS(i)) : <any>undefined;
(<any>this.languageFilesMap)![key] = _data["languageFilesMap"][key] ? _data["languageFilesMap"][key].map((i: any) => NameValue.fromJS(i)) : [];
}
}
}
@ -8832,6 +8881,44 @@ export interface IDateTimeFormatDto {
longTimePattern: string | undefined;
}
export class DeleteConnectionStringInput implements IDeleteConnectionStringInput {
/** 连接字符串名称 */
name!: string | undefined;
constructor(data?: IDeleteConnectionStringInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.name = _data["name"];
}
}
static fromJS(data: any): DeleteConnectionStringInput {
data = typeof data === 'object' ? data : {};
let result = new DeleteConnectionStringInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["name"] = this.name;
return data;
}
}
export interface IDeleteConnectionStringInput {
/** 连接字符串名称 */
name: string | undefined;
}
export class DeleteDataDictionaryDetailInput implements IDeleteDataDictionaryDetailInput {
dataDictionaryId!: string;
dataDictionayDetailId!: string;
@ -11327,19 +11414,19 @@ export enum HttpStatusCode {
ExpectationFailed = 426,
MisdirectedRequest = 428,
UnprocessableEntity = 429,
Locked = 431,
FailedDependency = 451,
UpgradeRequired = 500,
PreconditionRequired = 501,
TooManyRequests = 502,
RequestHeaderFieldsTooLarge = 503,
UnavailableForLegalReasons = 504,
InternalServerError = 505,
NotImplemented = 506,
BadGateway = 507,
ServiceUnavailable = 508,
GatewayTimeout = 510,
HttpVersionNotSupported = 511,
UnprocessableContent = 431,
Locked = 451,
FailedDependency = 500,
UpgradeRequired = 501,
PreconditionRequired = 502,
TooManyRequests = 503,
RequestHeaderFieldsTooLarge = 504,
UnavailableForLegalReasons = 505,
InternalServerError = 506,
NotImplemented = 507,
BadGateway = 508,
ServiceUnavailable = 510,
GatewayTimeout = 511,
}
export class IanaTimeZone implements IIanaTimeZone {
@ -11814,9 +11901,11 @@ export class IdentityUserDto implements IIdentityUserDto {
phoneNumberConfirmed!: boolean;
isActive!: boolean;
lockoutEnabled!: boolean;
accessFailedCount!: number;
lockoutEnd!: dayjs.Dayjs | undefined;
concurrencyStamp!: string | undefined;
entityVersion!: number;
lastPasswordChangeTime!: dayjs.Dayjs | undefined;
constructor(data?: IIdentityUserDto) {
if (data) {
@ -11854,9 +11943,11 @@ export class IdentityUserDto implements IIdentityUserDto {
this.phoneNumberConfirmed = _data["phoneNumberConfirmed"];
this.isActive = _data["isActive"];
this.lockoutEnabled = _data["lockoutEnabled"];
this.accessFailedCount = _data["accessFailedCount"];
this.lockoutEnd = _data["lockoutEnd"] ? dayjs(_data["lockoutEnd"].toString()) : <any>undefined;
this.concurrencyStamp = _data["concurrencyStamp"];
this.entityVersion = _data["entityVersion"];
this.lastPasswordChangeTime = _data["lastPasswordChangeTime"] ? dayjs(_data["lastPasswordChangeTime"].toString()) : <any>undefined;
}
}
@ -11894,9 +11985,11 @@ export class IdentityUserDto implements IIdentityUserDto {
data["phoneNumberConfirmed"] = this.phoneNumberConfirmed;
data["isActive"] = this.isActive;
data["lockoutEnabled"] = this.lockoutEnabled;
data["accessFailedCount"] = this.accessFailedCount;
data["lockoutEnd"] = this.lockoutEnd ? this.lockoutEnd.toLocaleString() : <any>undefined;
data["concurrencyStamp"] = this.concurrencyStamp;
data["entityVersion"] = this.entityVersion;
data["lastPasswordChangeTime"] = this.lastPasswordChangeTime ? this.lastPasswordChangeTime.toLocaleString() : <any>undefined;
return data;
}
}
@ -11921,9 +12014,11 @@ export interface IIdentityUserDto {
phoneNumberConfirmed: boolean;
isActive: boolean;
lockoutEnabled: boolean;
accessFailedCount: number;
lockoutEnd: dayjs.Dayjs | undefined;
concurrencyStamp: string | undefined;
entityVersion: number;
lastPasswordChangeTime: dayjs.Dayjs | undefined;
}
export class IdentityUserDtoPagedResultDto implements IIdentityUserDtoPagedResultDto {
@ -13053,6 +13148,154 @@ export interface IPageLanguageTextOutputPagedResultDto {
totalCount: number;
}
export class PageTenantConnectionStringInput implements IPageTenantConnectionStringInput {
/** 租户id */
id!: string;
/** 连接字符串名称 */
name!: string | undefined;
/** 连接字符串地址 */
value!: string | undefined;
constructor(data?: IPageTenantConnectionStringInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.name = _data["name"];
this.value = _data["value"];
}
}
static fromJS(data: any): PageTenantConnectionStringInput {
data = typeof data === 'object' ? data : {};
let result = new PageTenantConnectionStringInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["name"] = this.name;
data["value"] = this.value;
return data;
}
}
export interface IPageTenantConnectionStringInput {
/** 租户id */
id: string;
/** 连接字符串名称 */
name: string | undefined;
/** 连接字符串地址 */
value: string | undefined;
}
export class PageTenantConnectionStringOutput implements IPageTenantConnectionStringOutput {
/** 租户id */
tenantId!: string;
/** 连接字符串名称 */
name!: string | undefined;
/** 连接字符串地址 */
value!: string | undefined;
constructor(data?: IPageTenantConnectionStringOutput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.tenantId = _data["tenantId"];
this.name = _data["name"];
this.value = _data["value"];
}
}
static fromJS(data: any): PageTenantConnectionStringOutput {
data = typeof data === 'object' ? data : {};
let result = new PageTenantConnectionStringOutput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["tenantId"] = this.tenantId;
data["name"] = this.name;
data["value"] = this.value;
return data;
}
}
export interface IPageTenantConnectionStringOutput {
/** 租户id */
tenantId: string;
/** 连接字符串名称 */
name: string | undefined;
/** 连接字符串地址 */
value: string | undefined;
}
export class PageTenantConnectionStringOutputPagedResultDto implements IPageTenantConnectionStringOutputPagedResultDto {
items!: PageTenantConnectionStringOutput[] | undefined;
totalCount!: number;
constructor(data?: IPageTenantConnectionStringOutputPagedResultDto) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
if (Array.isArray(_data["items"])) {
this.items = [] as any;
for (let item of _data["items"])
this.items!.push(PageTenantConnectionStringOutput.fromJS(item));
}
this.totalCount = _data["totalCount"];
}
}
static fromJS(data: any): PageTenantConnectionStringOutputPagedResultDto {
data = typeof data === 'object' ? data : {};
let result = new PageTenantConnectionStringOutputPagedResultDto();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
if (Array.isArray(this.items)) {
data["items"] = [];
for (let item of this.items)
data["items"].push(item.toJSON());
}
data["totalCount"] = this.totalCount;
return data;
}
}
export interface IPageTenantConnectionStringOutputPagedResultDto {
items: PageTenantConnectionStringOutput[] | undefined;
totalCount: number;
}
export class PagingAuditLogActionOutput implements IPagingAuditLogActionOutput {
id!: string;
tenantId!: string | undefined;
@ -15791,46 +16034,6 @@ export interface ITypeApiDescriptionModel {
properties: PropertyApiDescriptionModel[] | undefined;
}
export class UpdateConnectionStringInput implements IUpdateConnectionStringInput {
id!: string;
connectionString!: string | undefined;
constructor(data?: IUpdateConnectionStringInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.id = _data["id"];
this.connectionString = _data["connectionString"];
}
}
static fromJS(data: any): UpdateConnectionStringInput {
data = typeof data === 'object' ? data : {};
let result = new UpdateConnectionStringInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["connectionString"] = this.connectionString;
return data;
}
}
export interface IUpdateConnectionStringInput {
id: string;
connectionString: string | undefined;
}
export class UpdateDataDictinaryInput implements IUpdateDataDictinaryInput {
id!: string;
code!: string | undefined;

70
vben28/src/views/tenants/CreateConnectionString.vue

@ -0,0 +1,70 @@
<template>
<BasicModal :title="t('common.createOrUpdateText')" :canFullscreen="false" @ok="submit" @cancel="cancel"
@register="registerModal">
<BasicForm @register="registerTenantForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createConnectionStringFormSchema, addOrUpdateConnectionString } from '/@/views/tenants/Tenant';
import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: 'CreateConnectionString',
components: {
BasicModal,
BasicForm,
},
emits: ['reload', 'register'],
setup(_, { emit }) {
const { t } = useI18n();
const [registerTenantForm, { getFieldsValue, setFieldsValue }] = useForm({
labelWidth: 120,
schemas: createConnectionStringFormSchema,
showActionButtonGroup: false,
});
const [registerModal, { closeModal }] = useModalInner((data) => {
setFieldsValue({
id: data.id,
})
});
const submit = async () => {
const request = getFieldsValue();
await addOrUpdateConnectionString({ request });
setFieldsValue({
name: '',
})
setFieldsValue({
value: '',
})
emit('reload');
closeModal();
};
const cancel = () => {
setFieldsValue({
name: '',
})
setFieldsValue({
value: '',
})
closeModal();
};
return {
t,
registerModal,
registerTenantForm,
submit,
cancel,
};
},
});
</script>
<style lang="less" scoped></style>

96
vben28/src/views/tenants/EditConnectionString.vue

@ -1,73 +1,81 @@
<template>
<BasicModal
:title="t('common.editText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerModal"
:minHeight="100"
>
<BasicForm @register="registerApiScopeForm" />
<BasicModal :title="t('common.editText')" :canFullscreen="false" :showCancelBtn="false" @register="registerModal"
@ok="submit" :defaultFullscreen="true">
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button type="primary" preIcon="ant-design:plus-circle-outlined"
@click="handlerOpenCreateConnectionStringModal">
{{ t('common.createOrUpdateText') }}
</a-button>
</template>
</BasicTable>
<CreateConnectionString @register="registerCreateConnectionStringModal" @reload="reload"
:bodyStyle="{ 'padding-top': '0' }" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import {
updateConnectionStringFormSchema,
updateConnectionStringAsync,
getConnectionStringAsync,
} from '/@/views/tenants/Tenant';
import { updateConnectionStringFormSchema, editConnectionStringtableColumns, pageConnectionStringAsync } from '/@/views/tenants/Tenant';
import { useI18n } from '/@/hooks/web/useI18n';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import CreateConnectionString from './CreateConnectionString.vue';
import { useModal } from '/@/components/Modal';
export default defineComponent({
name: 'EditConnectionString',
name: 'EditTenant',
components: {
BasicModal,
BasicForm,
BasicTable,
TableAction,
CreateConnectionString
},
emits: ['reload', 'register'],
setup(_, { emit }) {
setup() {
const { t } = useI18n();
const [registerApiScopeForm, { getFieldsValue, resetFields, setFieldsValue }] = useForm({
labelWidth: 120,
const [registerTable, { reload, getForm }] = useTable({
columns: editConnectionStringtableColumns,
formConfig: {
labelWidth: 100,
schemas: updateConnectionStringFormSchema,
showActionButtonGroup: false,
showResetButton: false
},
api: pageConnectionStringAsync,
useSearchForm: true,
showTableSetting: true,
bordered: true,
canResize: true,
showIndexColumn: true
});
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(async (data) => {
const connectionString = await getConnectionStringAsync({ id: data.record.id });
await setFieldsValue({
const [registerCreateConnectionStringModal, { openModal: openCreateConnectionStringModal }] =
useModal();
const [registerModal, { closeModal }] = useModalInner((data) => {
getForm().setFieldsValue({
id: data.record.id,
connectionString: connectionString,
});
})
});
const submit = async () => {
try {
const request = getFieldsValue();
changeOkLoading(true);
await updateConnectionStringAsync({ request });
await resetFields();
emit('reload');
} finally {
changeOkLoading(false);
closeModal();
}
//
const handlerOpenCreateConnectionStringModal = () => {
openCreateConnectionStringModal(true, { id: getForm().getFieldsValue().id });
};
const cancel = () => {
resetFields();
const submit = async () => {
closeModal();
};
return {
t,
registerTable,
registerModal,
registerApiScopeForm,
submit,
cancel,
registerCreateConnectionStringModal,
reload,
handlerOpenCreateConnectionStringModal
};
},
});

69
vben28/src/views/tenants/Tenant.ts

@ -2,7 +2,7 @@ import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
import { TenantsServiceProxy, PagingTenantInput, IdInput } from '/@/services/ServiceProxies';
import { TenantsServiceProxy, PagingTenantInput, IdInput, PageTenantConnectionStringInput} from '/@/services/ServiceProxies';
export const searchFormSchema: FormSchema[] = [
{
field: 'filter',
@ -21,6 +21,8 @@ export const tableColumns: BasicColumn[] = [
},
];
export const createFormSchema: FormSchema[] = [
{
field: 'name',
@ -66,7 +68,8 @@ export const editFormSchema: FormSchema[] = [
colProps: { span: 20 },
},
];
export const updateConnectionStringFormSchema: FormSchema[] = [
export const createConnectionStringFormSchema: FormSchema[] = [
{
field: 'id',
label: 'Id',
@ -77,13 +80,62 @@ export const updateConnectionStringFormSchema: FormSchema[] = [
colProps: { span: 20 },
},
{
field: 'connectionString',
field: 'name',
label: t('routes.tenant.name'),
helpMessage: ['请谨慎修改', '请谨慎修改', '请谨慎修改'],
component: 'Input',
labelWidth: 150,
colProps: { span: 20 },
},
{
field: 'value',
label: t('routes.tenant.connectionString'),
helpMessage: ['请检查连接字符串正确性', '请检查连接字符串正确性', '请检查连接字符串正确性'],
component: 'Input',
labelWidth: 150,
colProps: { span: 20 },
},
];
export const updateConnectionStringFormSchema: FormSchema[] = [
{
field: 'id',
label: 'Id',
component: 'Input',
required: true,
labelWidth: 150,
show: false,
colProps: { span: 20 },
},
{
field: 'name',
label: t('routes.tenant.name'),
component: 'Input',
labelWidth: 150,
colProps: { span: 6 },
},
{
field: 'value',
label: t('routes.tenant.connectionString'),
component: 'Input',
labelWidth: 150,
colProps: { span: 12 },
},
];
export const editConnectionStringtableColumns: BasicColumn[] = [
{
title: t('routes.tenant.name'),
dataIndex: 'name',
width: 240,
},
{
title: t('routes.tenant.connectionString'),
dataIndex: 'value',
},
];
export async function getTenantListAsync(request: PagingTenantInput) {
const _tenantsServiceProxy = new TenantsServiceProxy();
return await _tenantsServiceProxy.page(request);
@ -112,13 +164,12 @@ export async function deleteTenantAsync({ id }) {
request.id = id;
await _tenantsServiceProxy.delete(request);
}
export async function getConnectionStringAsync({ id }) {
export async function pageConnectionStringAsync( request :PageTenantConnectionStringInput) {
const _tenantsServiceProxy = new TenantsServiceProxy();
let request = new IdInput();
request.id = id;
return await _tenantsServiceProxy.getConnectionString(request);
return await _tenantsServiceProxy.pageConnectionString(request);
}
export async function updateConnectionStringAsync({ request }) {
export async function addOrUpdateConnectionString({ request }) {
const _tenantsServiceProxy = new TenantsServiceProxy();
return await _tenantsServiceProxy.updateConnectionString(request);
return await _tenantsServiceProxy.addOrUpdateConnectionString(request);
}

16
vben28/src/views/tenants/Tenant.vue

@ -21,14 +21,14 @@
label: t('common.editText'),
onClick: handleEdit.bind(null, record),
},
]"
:dropDownActions="[
// {
// auth: 'AbpTenantManagement.Tenants.ManageConnectionStrings',
// label: t('routes.tenant.connectionString'),
// onClick: handleConnectionString.bind(null, record),
// },
{
icon: 'ant-design:edit-outlined',
auth: 'AbpTenantManagement.Tenants.ManageConnectionStrings',
label: t('routes.tenant.connectionString'),
onClick: handleConnectionString.bind(null, record),
},
{
icon: 'ant-design:minus-outlined',
auth: 'AbpTenantManagement.Tenants.Delete',
label: t('common.delText'),
onClick: handleDelete.bind(null, record),
@ -106,7 +106,7 @@
slots: {
customRender: 'action',
},
width: 120,
width: 250,
fixed: 'right',
},
});

11739
vben28/yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save