Browse Source

集成identiyserver面板,cap,hangfire

pull/10/head
王军 5 years ago
parent
commit
f36a371231
  1. 4
      aspnet-core/frameworks/CAP/src/CompanyName.ProjectName.CAP/AbpCapConsumerServiceSelector.cs
  2. 2
      aspnet-core/frameworks/CAP/src/CompanyName.ProjectName.CAP/AbpCapServiceCollectionExtensions.cs
  3. 2
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/CompanyName.ProjectName.NotificationManagement.Application.Contracts.csproj
  4. 10
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationListInput.cs
  5. 8
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/ICommandNotificationAppService.cs
  6. 20
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/INotificationAppService.cs
  7. 61
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/IQueryNotificationAppService.cs
  8. 1
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/CompanyName.ProjectName.NotificationManagement.Application.csproj
  9. 2
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/NotificationManagementApplicationModule.cs
  10. 12
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/CommandNotificationAppService.cs
  11. 32
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/DistributedEventHandlers/CreatedNotificationDistributedEventHandler.cs
  12. 10
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/NotificationAppService.cs
  13. 112
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/QueryNotificationAppService.cs
  14. 13
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain.Shared/Notifications/Dtos/PagingNotificationListOutput.cs
  15. 15
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/NotificationDomainAutoMapperProfile.cs
  16. 2
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/NotificationManagementDbProperties.cs
  17. 6
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/Notifications/Aggregates/Notification.cs
  18. 50
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/Notifications/IDapperNotificationRepository.cs
  19. 57
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/Notifications/NotificationManager.cs
  20. 1
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.csproj
  21. 4
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/INotificationManagementDbContext.cs
  22. 4
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContext.cs
  23. 19
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContextModelCreatingExtensions.cs
  24. 159
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/DapperNotificationRepository.cs
  25. 1
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.HttpApi/CompanyName.ProjectName.NotificationManagement.HttpApi.csproj
  26. 65
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.HttpApi/Notifications/NotificationController.cs
  27. 33
      aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.HttpApi/Samples/SampleController.cs
  28. 60
      aspnet-core/services/src/CompanyName.ProjectName.Application.Contracts/Permissions/ProjectNamePermissionDefinitionProvider.cs
  29. 61
      aspnet-core/services/src/CompanyName.ProjectName.Application.Contracts/Permissions/ProjectNamePermissions.cs
  30. 1
      aspnet-core/services/src/CompanyName.ProjectName.Application/CompanyName.ProjectName.Application.csproj
  31. 4
      aspnet-core/services/src/CompanyName.ProjectName.Application/ProjectNameApplicationModule.cs
  32. 9
      aspnet-core/services/src/CompanyName.ProjectName.Application/Roles/RoleAppService.cs
  33. 2
      aspnet-core/services/src/CompanyName.ProjectName.DbMigrator/appsettings.json
  34. 10
      aspnet-core/services/src/CompanyName.ProjectName.Domain.Shared/Localization/ProjectName/en.json
  35. 17
      aspnet-core/services/src/CompanyName.ProjectName.Domain.Shared/Localization/ProjectName/zh-Hans.json
  36. 2
      aspnet-core/services/src/CompanyName.ProjectName.Domain.Shared/ProjectNameDomainSharedModule.cs
  37. 1
      aspnet-core/services/src/CompanyName.ProjectName.Domain/CompanyName.ProjectName.Domain.csproj
  38. 4
      aspnet-core/services/src/CompanyName.ProjectName.Domain/ProjectNameDomainModule.cs
  39. 6
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ProjectNameMigrationsDbContext.cs
  40. 599
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210903085042_Init.Designer.cs
  41. 985
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210903085042_Init.cs
  42. 597
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/ProjectNameMigrationsDbContextModelSnapshot.cs
  43. 1
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore/CompanyName.ProjectName.EntityFrameworkCore.csproj
  44. 5
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore/EntityFrameworkCore/ProjectNameDbContext.cs
  45. 4
      aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs
  46. 4
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj
  47. 77912
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/Logs/logs.txt
  48. 138
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs
  49. 18
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/appsettings.json
  50. 1
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/CompanyName.ProjectName.HttpApi.csproj
  51. 6
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/ApiResourceController.cs
  52. 6
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/ApiScopeController.cs
  53. 14
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/ClientController.cs
  54. 6
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/IdentityResourceController.cs
  55. 8
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/Systems/AuditLogController.cs
  56. 3
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/Systems/RoleController.cs
  57. 7
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/Systems/UserController.cs
  58. 4
      aspnet-core/services/src/CompanyName.ProjectName.HttpApi/ProjectNameHttpApiModule.cs
  59. 4
      vben271/.env
  60. 104
      vben271/package-lock.json
  61. 1
      vben271/package.json
  62. 2
      vben271/src/components/Table/src/hooks/useColumns.ts
  63. 26
      vben271/src/hooks/web/useSignalR.ts
  64. 130
      vben271/src/layouts/default/header/components/notify/NoticeList.vue
  65. 193
      vben271/src/layouts/default/header/components/notify/data.ts
  66. 45
      vben271/src/layouts/default/header/components/notify/index.vue
  67. 40
      vben271/src/layouts/default/header/index.vue
  68. 17
      vben271/src/locales/lang/en/common.ts
  69. 67
      vben271/src/locales/lang/en/routes/admin.ts
  70. 10
      vben271/src/locales/lang/zh-CN/common.ts
  71. 16
      vben271/src/locales/lang/zh-CN/routes/admin.ts
  72. 25
      vben271/src/router/routes/modules/admin.ts
  73. 24
      vben271/src/router/routes/modules/identityServer.ts
  74. 625
      vben271/src/services/ServiceProxies.ts
  75. 4
      vben271/src/services/ServiceProxyBase.ts
  76. 8
      vben271/src/views/admin/auditLog/AuditLog.ts
  77. 54
      vben271/src/views/admin/roles/AbpRole.vue
  78. 32
      vben271/src/views/admin/roles/PermissionAbpRole.vue
  79. 68
      vben271/src/views/admin/users/AbpUser.ts
  80. 67
      vben271/src/views/admin/users/AbpUser.vue
  81. 17
      vben271/src/views/admin/users/EditAbpUser.vue
  82. 38
      vben271/src/views/identityServers/apiResources/ApiResources.ts
  83. 29
      vben271/src/views/identityServers/apiResources/ApiResources.vue
  84. 6
      vben271/src/views/identityServers/apiResources/CreateApiResource.vue
  85. 10
      vben271/src/views/identityServers/apiResources/EditApiResources.vue
  86. 47
      vben271/src/views/identityServers/apiScopes/ApiScopes.ts
  87. 49
      vben271/src/views/identityServers/apiScopes/ApiScopes.vue
  88. 14
      vben271/src/views/identityServers/apiScopes/CreateApiScope.vue
  89. 26
      vben271/src/views/identityServers/apiScopes/EditApiScope.vue
  90. 31
      vben271/src/views/identityServers/clients/ClientUri.vue
  91. 40
      vben271/src/views/identityServers/clients/Clients.ts
  92. 44
      vben271/src/views/identityServers/clients/Clients.vue
  93. 16
      vben271/src/views/identityServers/clients/CreateClient.vue
  94. 7
      vben271/src/views/identityServers/clients/EditClientBasic.vue
  95. 10
      vben271/src/views/identityServers/identityResources/CreateIdentityResource.vue
  96. 2
      vben271/src/views/identityServers/identityResources/EditIdentityResources.vue
  97. 42
      vben271/src/views/identityServers/identityResources/IdentityResources.ts
  98. 55
      vben271/src/views/identityServers/identityResources/IdentityResources.vue
  99. 19
      vue3/.editorconfig
  100. 9
      vue3/.env

4
aspnet-core/frameworks/CAP/src/CompanyName.ProjectName.CAP/AbpCapConsumerServiceSelector.cs

@ -14,7 +14,7 @@ namespace CompanyName.ProjectName.CAP
{
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)]
[ExposeServices(typeof(IConsumerServiceSelector))]
public class BeeAbpCapConsumerServiceSelector : ConsumerServiceSelector
public class AbpCapConsumerServiceSelector : ConsumerServiceSelector
{
protected AbpDistributedEventBusOptions AbpDistributedEventBusOptions { get; }
protected IServiceProvider ServiceProvider { get; }
@ -22,7 +22,7 @@ namespace CompanyName.ProjectName.CAP
/// <summary>
/// Creates a new <see cref="T:DotNetCore.CAP.Internal.ConsumerServiceSelector" />.
/// </summary>
public BeeAbpCapConsumerServiceSelector(
public AbpCapConsumerServiceSelector(
IServiceProvider serviceProvider,
IOptions<AbpDistributedEventBusOptions> distributedEventBusOptions)
: base(serviceProvider)

2
aspnet-core/frameworks/CAP/src/CompanyName.ProjectName.CAP/AbpCapServiceCollectionExtensions.cs

@ -14,7 +14,7 @@ namespace CompanyName.ProjectName.CAP
Action<CapOptions> capAction)
{
context.Services.AddCap(capAction);
context.Services.AddSingleton<IConsumerServiceSelector, BeeAbpCapConsumerServiceSelector>();
context.Services.AddSingleton<IConsumerServiceSelector, AbpCapConsumerServiceSelector>();
context.Services.AddSingleton<IDistributedEventBus, AbpCapDistributedEventBus>();
return context;
}

2
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/CompanyName.ProjectName.NotificationManagement.Application.Contracts.csproj

@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="$(AbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Authorization" Version="$(AbpPackageVersion)" />
<ProjectReference Include="..\..\..\QueryManagement\src\CompanyName.ProjectName.QueryManagement.Domain.Shared\CompanyName.ProjectName.QueryManagement.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\..\frameworks\Extensions\src\CompanyName.ProjectName.Extensions\CompanyName.ProjectName.Extensions.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.NotificationManagement.Domain.Shared\CompanyName.ProjectName.NotificationManagement.Domain.Shared.csproj" />
</ItemGroup>

10
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/Dtos/PagingNotificationListInput.cs

@ -0,0 +1,10 @@
using System;
using CompanyName.ProjectName.Extensions.Customs;
namespace CompanyName.ProjectName.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationListInput:PagingBase
{
}
}

8
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/ICommandNotificationAppService.cs

@ -12,5 +12,13 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
/// <param name="input"></param>
/// <returns></returns>
Task SetReadAsync(SetReadInput input);
/// <summary>
/// 创建一个消息
/// 测试使用
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task CreateAsync(CreateNotificationInput input);
}
}

20
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/INotificationAppService.cs

@ -12,25 +12,5 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
/// </summary>
/// <returns></returns>
Task SendMessageAsync(string title, string content, MessageType messageType, List<string> users);
/// <summary>
/// 发送消息到客户端
/// </summary>
/// <returns></returns>
Task SendMessageToClientByUserIdAsync(SendNotificationDto sendNotificationDto, List<string> userIds);
/// <summary>
/// 发送消息到所有客户端
/// </summary>
/// <param name="sendNotificationDto"></param>
Task SendMessageToAllClientAsync(SendNotificationDto sendNotificationDto);
/// <summary>
/// 创建一个消息
/// 测试使用
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task CreateAsync(CreateNotificationInput input);
}
}

61
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application.Contracts/Notifications/IQueryNotificationAppService.cs

@ -1,30 +1,31 @@
// using System.Threading;
// using System.Threading.Tasks;
// using Volo.Abp.Application.Services;
// using Volo.Abp.Application.Dtos;
//
// namespace CompanyName.ProjectName.NotificationManagement.Notifications
// {
// public interface IQueryNotificationAppService : IApplicationService
// {
// /// <summary>
// /// 分页获取用户普通文本消息
// /// </summary>
// /// <param name="input"></param>
// /// <param name="cancellationToken"></param>
// /// <returns></returns>
// Task<PagedResultDto<QueryTextNotificationOutput>> GetPageTextNotificationByUserIdAsync(
// QueryTextNotificationInput input,
// CancellationToken cancellationToken = default);
//
// /// <summary>
// /// 分页获取广播消息
// /// </summary>
// /// <param name="input"></param>
// /// <param name="cancellationToken"></param>
// /// <returns></returns>
// Task<PagedResultDto<QueryTextNotificationOutput>> GetPageBroadCastNotificationByUserIdAsync(
// QueryTextNotificationInput input,
// CancellationToken cancellationToken = default);
// }
// }
using System.Threading;
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Application.Dtos;
namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
public interface IQueryNotificationAppService : IApplicationService
{
/// <summary>
/// 分页获取用户普通文本消息
/// </summary>
/// <param name="listInput"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<PagedResultDto<PagingNotificationListOutput>> GetPageTextNotificationByUserIdAsync(
PagingNotificationListInput listInput,
CancellationToken cancellationToken = default);
/// <summary>
/// 分页获取广播消息
/// </summary>
/// <param name="listInput"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<PagedResultDto<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(
PagingNotificationListInput listInput,
CancellationToken cancellationToken = default);
}
}

1
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/CompanyName.ProjectName.NotificationManagement.Application.csproj

@ -12,7 +12,6 @@
<PackageReference Include="Volo.Abp.AspNetCore.SignalR" Version="4.4.0" />
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(AbpPackageVersion)" />
<ProjectReference Include="..\..\..\QueryManagement\src\CompanyName.ProjectName.QueryManagement.Domain\CompanyName.ProjectName.QueryManagement.Domain.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.NotificationManagement.Application.Contracts\CompanyName.ProjectName.NotificationManagement.Application.Contracts.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.NotificationManagement.Domain\CompanyName.ProjectName.NotificationManagement.Domain.csproj" />
</ItemGroup>

2
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/NotificationManagementApplicationModule.cs

@ -2,7 +2,6 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.Application;
using CompanyName.ProjectName.QueryManagement;
using Microsoft.Extensions.Configuration;
using Volo.Abp.AspNetCore.SignalR;
@ -13,7 +12,6 @@ namespace CompanyName.ProjectName.NotificationManagement
typeof(NotificationManagementApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule),
typeof(QueryManagementDomainModule),
typeof(AbpAspNetCoreSignalRModule)
)]
public class NotificationManagementApplicationModule : AbpModule

12
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/CommandNotificationAppService.cs

@ -1,5 +1,6 @@
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.Dtos;
using Volo.Abp.Users;
namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
@ -7,14 +8,23 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
private readonly NotificationManager _notificationManager;
public CommandNotificationAppService(NotificationManager notificationManager)
private readonly ICurrentUser _currentUser;
public CommandNotificationAppService(NotificationManager notificationManager, ICurrentUser currentUser)
{
_notificationManager = notificationManager;
_currentUser = currentUser;
}
public Task SetReadAsync(SetReadInput input)
{
return _notificationManager.SetReadAsync(input.Id, input.ReceiveId);
}
public async Task CreateAsync(CreateNotificationInput input)
{
if (_currentUser.Id != null)
await _notificationManager.CreateAsync(input.Title, input.Content, _currentUser.Id.Value, input.ReceiveIds,
input.MessageType);
}
}
}

32
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/DistributedEventHandlers/CreatedNotificationDistributedEventHandler.cs

@ -0,0 +1,32 @@
using System.Linq;
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.DistributedEvents;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace CompanyName.ProjectName.NotificationManagement.Notifications.DistributedEventHandlers
{
/// <summary>
/// 创建消息事件处理
/// </summary>
public class
CreatedNotificationDistributedEventHandler : IDistributedEventHandler<CreatedNotificationDistributedEvent>,
ITransientDependency
{
private readonly INotificationAppService _hubAppService;
public CreatedNotificationDistributedEventHandler(INotificationAppService hubAppService)
{
_hubAppService = hubAppService;
}
public Task HandleEventAsync(CreatedNotificationDistributedEvent eventData)
{
return _hubAppService.SendMessageAsync(
eventData.NotificationEto.Title,
eventData.NotificationEto.Content,
eventData.NotificationEto.MessageType,
eventData.NotificationEto.NotificationSubscriptions.Select(e => e.ReceiveId.ToString()).ToList());
}
}
}

10
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/NotificationAppService.cs

@ -49,7 +49,7 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
/// <param name="sendNotificationDto"></param>
/// <param name="users"></param>
/// <returns></returns>
public async Task SendMessageToClientByUserIdAsync(SendNotificationDto sendNotificationDto,
private async Task SendMessageToClientByUserIdAsync(SendNotificationDto sendNotificationDto,
List<string> users)
{
if (users is {Count: > 0})
@ -65,16 +65,10 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
/// 广播消息
/// </summary>
/// <param name="sendNotificationDto"></param>
public async Task SendMessageToAllClientAsync(SendNotificationDto sendNotificationDto)
private async Task SendMessageToAllClientAsync(SendNotificationDto sendNotificationDto)
{
await _hubContext.Clients.All.ReceiveBroadCastMessageAsync(sendNotificationDto);
}
public async Task CreateAsync(CreateNotificationInput input)
{
await _notificationManager.CreateAsync(input.Title, input.Content, _currentUser.Id.Value, input.ReceiveIds,
input.MessageType);
}
}
}

112
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Application/Notifications/QueryNotificationAppService.cs

@ -1,44 +1,68 @@
// using System.Threading;
// using System.Threading.Tasks;
// using Bee.Abp.Dto;
// using Humanizer;
// using CompanyName.ProjectName.QueryManagement.Notifications;
//
// namespace CompanyName.ProjectName.NotificationManagement.Notifications
// {
// public class QueryNotificationAppService : NotificationManagementAppService,IQueryNotificationAppService
// {
// private readonly INotificationFreeSqlRepository _notificationFreeSqlRepository;
//
// public QueryNotificationAppService(INotificationFreeSqlRepository notificationFreeSqlRepository)
// {
// _notificationFreeSqlRepository = notificationFreeSqlRepository;
// }
//
// /// <summary>
// /// 分页获取用户普通文本消息
// /// </summary>
// /// <param name="input"></param>
// /// <param name="cancellationToken"></param>
// /// <returns></returns>
// public Task<BeePagedResultDto<QueryTextNotificationOutput>> GetPageTextNotificationByUserIdAsync(
// QueryTextNotificationInput input,
// CancellationToken cancellationToken = default)
// {
// return _notificationFreeSqlRepository.GetPageTextNotificationByUserIdAsync(input, cancellationToken);
// }
//
// /// <summary>
// /// 分页获取广播消息
// /// </summary>
// /// <param name="input"></param>
// /// <param name="cancellationToken"></param>
// /// <returns></returns>
// public Task<BeePagedResultDto<QueryTextNotificationOutput>> GetPageBroadCastNotificationByUserIdAsync(
// QueryTextNotificationInput input,
// CancellationToken cancellationToken = default)
// {
// return _notificationFreeSqlRepository.GetPageBroadCastNotificationByUserIdAsync(input, cancellationToken);
// }
// }
// }
using System.Threading;
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.Dtos;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Users;
namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
public class QueryNotificationAppService : NotificationManagementAppService, IQueryNotificationAppService
{
private readonly IDapperNotificationRepository _dapperNotificationRepository;
private readonly ICurrentUser _currentUser;
public QueryNotificationAppService(IDapperNotificationRepository dapperNotificationRepository, ICurrentUser currentUser)
{
_dapperNotificationRepository = dapperNotificationRepository;
_currentUser = currentUser;
}
/// <summary>
/// 分页获取用户普通文本消息
/// </summary>
/// <param name="listInput"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<PagedResultDto<PagingNotificationListOutput>> GetPageTextNotificationByUserIdAsync(
PagingNotificationListInput listInput,
CancellationToken cancellationToken = default)
{
if (!_currentUser.Id.HasValue)
{
return null;
}
var totalCount =
await _dapperNotificationRepository.GetPageTextNotificationCountByUserIdAsync(_currentUser.Id.Value, cancellationToken);
var list = await _dapperNotificationRepository.GetPageTextNotificationByUserIdAsync(_currentUser.Id.Value,
listInput.PageSize,
listInput.SkipCount, cancellationToken);
return new PagedResultDto<PagingNotificationListOutput>(totalCount, list);
}
/// <summary>
/// 分页获取广播消息
/// </summary>
/// <param name="listInput"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<PagedResultDto<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(
PagingNotificationListInput listInput,
CancellationToken cancellationToken = default)
{
if (!_currentUser.Id.HasValue)
{
return null;
}
var totalCount =
await _dapperNotificationRepository.GetPageBroadCastNotificationCountByUserIdAsync(_currentUser.Id.Value,
cancellationToken);
var list = await _dapperNotificationRepository.GetPageBroadCastNotificationByUserIdAsync(_currentUser.Id.Value,
listInput.PageSize,
listInput.SkipCount, cancellationToken);
return new PagedResultDto<PagingNotificationListOutput>(totalCount, list);
}
}
}

13
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain.Shared/Notifications/Dtos/PagingNotificationListOutput.cs

@ -0,0 +1,13 @@
using System;
namespace CompanyName.ProjectName.NotificationManagement.Notifications.Dtos
{
public class PagingNotificationListOutput
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreationTime { get; set; }
public bool Read { get; set; }
}
}

15
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/NotificationDomainAutoMapperProfile.cs

@ -0,0 +1,15 @@
using AutoMapper;
using CompanyName.ProjectName.NotificationManagement.Notifications;
using CompanyName.ProjectName.NotificationManagement.Notifications.Etos;
namespace CompanyName.ProjectName.NotificationManagement
{
public class NotificationDomainAutoMapperProfile:Profile
{
public NotificationDomainAutoMapperProfile()
{
CreateMap<Notification, NotificationEto>();
CreateMap<NotificationSubscription, NotificationSubscriptionEto>();
}
}
}

2
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/NotificationManagementDbProperties.cs

@ -4,7 +4,7 @@ namespace CompanyName.ProjectName.NotificationManagement
{
public static string DbTablePrefix { get; set; } = "";
public static string DbSchema { get; set; } = "notification";
public static string DbSchema { get; set; } = null;
public const string ConnectionStringName = "NotificationManagement";
}

6
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/Notifications/Aggregates/Notification.cs

@ -119,7 +119,11 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
/// <param name="receiveId"></param>
public void AddBroadCastNotificationSubscription(Guid notificationSubscriptionId, Guid receiveId)
{
if (NotificationSubscriptions.Any(e => e.ReceiveId != receiveId))
if (NotificationSubscriptions.Any(e => e.ReceiveId == receiveId))
{
return;
}
else
{
var temp = new NotificationSubscription(notificationSubscriptionId, receiveId);
temp.SetRead();

50
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/Notifications/IDapperNotificationRepository.cs

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.Dtos;
using Volo.Abp.DependencyInjection;
namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
public interface IDapperNotificationRepository : ITransientDependency
{
/// <summary>
/// 分页查询广播消息
/// </summary>
/// <returns></returns>
Task<List<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(
Guid userId,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取广播消息总条数
/// </summary>
/// <returns></returns>
Task<int> GetPageBroadCastNotificationCountByUserIdAsync(
Guid userId,
CancellationToken cancellationToken = default);
/// <summary>
/// 分页查询文本消息
/// </summary>
/// <returns></returns>
Task<List<PagingNotificationListOutput>> GetPageTextNotificationByUserIdAsync(
Guid userId,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取文本息总条数
/// </summary>
/// <returns></returns>
Task<int> GetPageTextNotificationCountByUserIdAsync(
Guid userId,
CancellationToken cancellationToken = default);
}
}

57
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.Domain/Notifications/NotificationManager.cs

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.DistributedEvents;
using CompanyName.ProjectName.NotificationManagement.Notifications.Etos;
using Volo.Abp.Users;
namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
@ -11,12 +12,64 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
private readonly INotificationRepository _notificationRepository;
public NotificationManager(INotificationRepository notificationRepository)
private readonly ICurrentUser _currentUser;
public NotificationManager(INotificationRepository notificationRepository, ICurrentUser currentUser)
{
_notificationRepository = notificationRepository;
_currentUser = currentUser;
}
/// <summary>
/// 发送普通文本消息
/// </summary>
/// <returns></returns>
/// <exception cref="NotificationManagementDomainException"></exception>
public async Task<Notification> SendCommonTextAsync(string title, string content, List<Guid> receiveIds)
{
if (receiveIds is {Count: 0})
{
throw new NotificationManagementDomainException("消息接收人不能为空");
}
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
{
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.Text, senderId);
foreach (var item in receiveIds)
{
entity.AddNotificationSubscription(GuidGenerator.Create(), item);
}
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationDistributedEvent(new CreatedNotificationDistributedEvent(notificationEto));
return entity = await _notificationRepository.InsertAsync(entity);
}
/// <summary>
/// 发送广播消息
/// </summary>
/// <returns></returns>
/// <exception cref="NotificationManagementDomainException"></exception>
public async Task<Notification> SendBroadCastTextAsync(string title, string content)
{
var senderId = Guid.Empty;
if (_currentUser?.Id != null)
{
senderId = _currentUser.Id.Value;
}
var entity = new Notification(GuidGenerator.Create(), title, content, MessageType.BroadCast, senderId);
var notificationEto = ObjectMapper.Map<Notification, NotificationEto>(entity);
// 发送集成事件
entity.AddCreatedNotificationDistributedEvent(new CreatedNotificationDistributedEvent(notificationEto));
return entity = await _notificationRepository.InsertAsync(entity);
}
/// <summary>
/// 新增消息
@ -58,6 +111,7 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
public async Task SetReadAsync(Guid id, Guid receiveId)
{
var notification = await _notificationRepository.FindByIdAsync(id);
if (notification == null) throw new NotificationManagementDomainException(message: "消息不存在");
if (notification.MessageType == MessageType.BroadCast)
{
// 如果类型是广播消息,用户设置为已读,在插入一条数据
@ -65,7 +119,6 @@ namespace CompanyName.ProjectName.NotificationManagement.Notifications
}
else
{
if (notification == null) throw new NotificationManagementDomainException(message: "消息不存在");
var notificationSubscription =
notification.NotificationSubscriptions.FirstOrDefault(e => e.ReceiveId == receiveId);
if (notificationSubscription == null)

1
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.csproj

@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Dapper" Version="$(AbpPackageVersion)" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="$(AbpPackageVersion)" />
<ProjectReference Include="..\CompanyName.ProjectName.NotificationManagement.Domain\CompanyName.ProjectName.NotificationManagement.Domain.csproj" />
</ItemGroup>

4
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/INotificationManagementDbContext.cs

@ -1,3 +1,5 @@
using CompanyName.ProjectName.NotificationManagement.Notifications;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
@ -9,5 +11,7 @@ namespace CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore
/* Add DbSet for each Aggregate Root here. Example:
* DbSet<Question> Questions { get; }
*/
DbSet<Notification> Questions { get; set; }
}
}

4
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContext.cs

@ -1,3 +1,4 @@
using CompanyName.ProjectName.NotificationManagement.Notifications;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
@ -16,6 +17,7 @@ namespace CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore
{
}
public DbSet<Notification> Questions { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
@ -23,5 +25,7 @@ namespace CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore
builder.ConfigureNotificationManagement();
}
}
}

19
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/NotificationManagementDbContextModelCreatingExtensions.cs

@ -43,21 +43,16 @@ namespace CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore
builder.Entity<Notification>(b =>
{
builder.Entity<Notification>(b =>
{
b.ToTable(NotificationManagementDbProperties.DbTablePrefix + nameof(Notification),
NotificationManagementDbProperties.DbSchema);
b.ConfigureByConvention();
});
b.ToTable(NotificationManagementDbProperties.DbTablePrefix + nameof(Notification),
NotificationManagementDbProperties.DbSchema);
b.ConfigureByConvention();
});
builder.Entity<NotificationSubscription>(b =>
{
builder.Entity<NotificationSubscription>(b =>
{
b.ToTable(NotificationManagementDbProperties.DbTablePrefix + nameof(NotificationSubscription),
NotificationManagementDbProperties.DbSchema);
b.ConfigureByConvention();
});
b.ToTable(NotificationManagementDbProperties.DbTablePrefix + nameof(NotificationSubscription),
NotificationManagementDbProperties.DbSchema);
b.ConfigureByConvention();
});
}
}

159
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore/EntityFrameworkCore/Notifications/DapperNotificationRepository.cs

@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications;
using CompanyName.ProjectName.NotificationManagement.Notifications.Dtos;
using Dapper;
using Volo.Abp.Domain.Repositories.Dapper;
using Volo.Abp.EntityFrameworkCore;
namespace CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.Notifications
{
public class DapperNotificationRepository : DapperRepository<INotificationManagementDbContext>,
IDapperNotificationRepository
{
public DapperNotificationRepository(IDbContextProvider<INotificationManagementDbContext> dbContextProvider) :
base(dbContextProvider)
{
}
/// <summary>
/// 分页查询广播消息
/// </summary>
/// <returns></returns>
public async Task<List<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(
Guid userId,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var sql = BuildPageBroadCastSql();
sql += $" LIMIT {maxResultCount} OFFSET {skipCount}";
var tran = await GetDbTransactionAsync();
return (await (await GetDbConnectionAsync()).QueryAsync<PagingNotificationListOutput>(sql, new {userId},
transaction: tran))
.ToList();
}
/// <summary>
/// 获取广播消息总条数
/// </summary>
/// <returns></returns>
public async Task<int> GetPageBroadCastNotificationCountByUserIdAsync(
Guid userId,
CancellationToken cancellationToken = default)
{
var sql = BuildPageBroadCastCountSql();
var tran = await GetDbTransactionAsync();
return (await (await GetDbConnectionAsync()).QueryAsync<int>(sql, new {userId}, transaction: tran))
.FirstOrDefault();
}
/// <summary>
/// 分页查询文本消息
/// </summary>
/// <returns></returns>
public async Task<List<PagingNotificationListOutput>> GetPageTextNotificationByUserIdAsync(
Guid userId,
int maxResultCount = 10,
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var sql = BuildPageTextSql();
sql += $" LIMIT {maxResultCount} OFFSET {skipCount}";
var tran = await GetDbTransactionAsync();
return (await (await GetDbConnectionAsync()).QueryAsync<PagingNotificationListOutput>(sql, new {userId},
transaction: tran))
.ToList();
}
/// <summary>
/// 获取文本息总条数
/// </summary>
/// <returns></returns>
public async Task<int> GetPageTextNotificationCountByUserIdAsync(
Guid userId,
CancellationToken cancellationToken = default)
{
var sql = BuildPageTextCountSql();
var tran = await GetDbTransactionAsync();
return (await (await GetDbConnectionAsync()).QueryAsync<int>(sql, new {userId}, transaction: tran))
.FirstOrDefault();
}
private string BuildPageTextSql()
{
return "select "
+ "a.Id,"
+ "a.Title,"
+ "a.Content,"
+ "a.CreationTime, "
+ "b.Read "
+ "from Notification a "
+ "left join NotificationSubscription b on b.NotificationId=a.Id "
+ "where a.IsDeleted=0 "
+ "and a.MessageType=20 "
+ "and b.ReceiveId=@userId "
+ "order by b.Read, CreationTime desc ";
}
private string BuildPageTextCountSql()
{
return "select "
+ "count(1) as count "
+ "from Notification a "
+ "left join NotificationSubscription b on b.NotificationId=a.Id "
+ "where a.IsDeleted=0 "
+ "and a.MessageType=20 "
+ "and b.ReceiveId=@userId ";
}
private string BuildPageBroadCastCountSql()
{
return "select count(1) as count from ("
+ "select a.Id, a.Title, a.Content, a.CreationTime, a.SenderId, false as \"Read\" "
+ "from Notification a "
+ "where a.IsDeleted = 0 "
+ "and a.MessageType = 10 "
+ "and a.Id not in "
+ " (select NotificationId "
+ "from NotificationSubscription b "
+ " where b.ReceiveId = '39febd0a-4c5d-d3b8-b223-ef49e7a3d7e2') "
+ "union "
+ " select a.Id, a.Title, a.Content, a.CreationTime, a.SenderId, true as \"Read\" "
+ "from Notification a "
+ " where a.IsDeleted = 0 "
+ " and a.MessageType = 10 "
+ "and a.Id in "
+ " (select NotificationId "
+ "from NotificationSubscription b "
+ "where b.ReceiveId = @userId) "
+ " ) as tt ";
}
private string BuildPageBroadCastSql()
{
return "select * from ("
+ "select a.Id, a.Title, a.Content, a.CreationTime, a.SenderId, false as \"Read\" "
+ "from Notification a "
+ "where a.IsDeleted = 0 "
+ "and a.MessageType = 10 "
+ "and a.Id not in "
+ " (select NotificationId "
+ "from NotificationSubscription b "
+ " where b.ReceiveId = '39febd0a-4c5d-d3b8-b223-ef49e7a3d7e2') "
+ "union"
+ " select a.Id, a.Title, a.Content, a.CreationTime, a.SenderId, true as \"Read\" "
+ "from Notification a "
+ " where a.IsDeleted = 0 "
+ " and a.MessageType = 10 "
+ "and a.Id in "
+ " (select NotificationId "
+ "from NotificationSubscription b "
+ "where b.ReceiveId = @userId)"
+ " ) as tt order by tt.Read,tt.CreationTime ";
}
}
}

1
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.HttpApi/CompanyName.ProjectName.NotificationManagement.HttpApi.csproj

@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.1.4" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(AbpPackageVersion)" />
<ProjectReference Include="..\CompanyName.ProjectName.NotificationManagement.Application.Contracts\CompanyName.ProjectName.NotificationManagement.Application.Contracts.csproj" />
</ItemGroup>

65
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.HttpApi/Notifications/NotificationController.cs

@ -0,0 +1,65 @@
using System.Threading.Tasks;
using CompanyName.ProjectName.NotificationManagement.Notifications.Dtos;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.AspNetCore.Mvc;
namespace CompanyName.ProjectName.NotificationManagement.Notifications
{
[Route("Notification")]
public class NotificationController : AbpController, IApplicationService
{
private readonly IQueryNotificationAppService _queryNotificationAppService;
private readonly ICommandNotificationAppService _commandNotificationAppService;
public NotificationController(IQueryNotificationAppService queryNotificationAppService,
ICommandNotificationAppService commandNotificationAppService)
{
_queryNotificationAppService = queryNotificationAppService;
_commandNotificationAppService = commandNotificationAppService;
}
/// <summary>
/// 分页获取用户普通文本消息
/// </summary>
/// <param name="listInput"></param>
/// <returns></returns>
[HttpPost("Text")]
[SwaggerOperation(summary: "分页查询普通消息", Tags = new[] {"Notification"})]
public Task<PagedResultDto<PagingNotificationListOutput>> GetPageTextNotificationByUserIdAsync(
PagingNotificationListInput listInput)
{
return _queryNotificationAppService.GetPageTextNotificationByUserIdAsync(listInput);
}
/// <summary>
/// 分页获取广播消息
/// </summary>
/// <param name="listInput"></param>
/// <returns></returns>
[HttpPost("BroadCast")]
[SwaggerOperation(summary: "分页查询广播消息", Tags = new[] {"Notification"})]
public Task<PagedResultDto<PagingNotificationListOutput>> GetPageBroadCastNotificationByUserIdAsync(
PagingNotificationListInput listInput)
{
return _queryNotificationAppService.GetPageBroadCastNotificationByUserIdAsync(listInput);
}
[HttpPost("Read")]
[SwaggerOperation(summary: "消息设置为已读", Tags = new[] {"Notification"})]
public Task SetReadAsync(SetReadInput input)
{
return _commandNotificationAppService.SetReadAsync(input);
}
[HttpPost("Create")]
[SwaggerOperation(summary: "创建消息-测试使用", Tags = new[] {"Notification"})]
public Task CreateAsync(CreateNotificationInput input)
{
return _commandNotificationAppService.CreateAsync(input);
}
}
}

33
aspnet-core/modules/NotificationManagement/src/CompanyName.ProjectName.NotificationManagement.HttpApi/Samples/SampleController.cs

@ -1,33 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
namespace CompanyName.ProjectName.NotificationManagement.Samples
{
[RemoteService]
[Route("api/NotificationManagement/sample")]
public class SampleController : NotificationManagementController, ISampleAppService
{
private readonly ISampleAppService _sampleAppService;
public SampleController(ISampleAppService sampleAppService)
{
_sampleAppService = sampleAppService;
}
[HttpGet]
public async Task<SampleDto> GetAsync()
{
return await _sampleAppService.GetAsync();
}
[HttpGet]
[Route("authorized")]
[Authorize]
public async Task<SampleDto> GetAuthorizedAsync()
{
return await _sampleAppService.GetAsync();
}
}
}

60
aspnet-core/services/src/CompanyName.ProjectName.Application.Contracts/Permissions/ProjectNamePermissionDefinitionProvider.cs

@ -1,5 +1,6 @@
using CompanyName.ProjectName.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Identity;
using Volo.Abp.Localization;
namespace CompanyName.ProjectName.Permissions
@ -8,17 +9,64 @@ namespace CompanyName.ProjectName.Permissions
{
public override void Define(IPermissionDefinitionContext context)
{
var abpIdentityGroup = context.GetGroup(IdentityPermissions.GroupName);
var userManagement = abpIdentityGroup.GetPermissionOrNull(IdentityPermissions.Users.Default);
userManagement.AddChild(ProjectNamePermissions.SystemManagement.UserEnable, L("Permission:Enable"));
var abpIdentityGroup = context.GetGroup(ProjectNamePermissions.AbpIdentityGroupName);
var userManagement = abpIdentityGroup.GetPermissionOrNull(ProjectNamePermissions.AbpIdentityExtend.Users);
var auditManagement =
abpIdentityGroup.AddPermission(ProjectNamePermissions.SystemManagement.AuditLog, L("Permission:AuditLogManagement"));
userManagement.AddChild(ProjectNamePermissions.AbpIdentityExtend.UserEnable, L("Permissions:Enable"));
userManagement.AddChild(ProjectNamePermissions.AbpIdentityExtend.UserQuery, L("Permissions:Query"));
var hangfireManagement =
abpIdentityGroup.AddPermission(ProjectNamePermissions.SystemManagement.Hangfire, L("Permission:HangfireManagement"));
var roleManagement = abpIdentityGroup.GetPermissionOrNull(ProjectNamePermissions.AbpIdentityExtend.Roles);
roleManagement.AddChild(ProjectNamePermissions.AbpIdentityExtend.RoleQuery, L("Permissions:Query"));
var capManagement = abpIdentityGroup.AddPermission(ProjectNamePermissions.SystemManagement.Cap, L("Permission:CapManagement"));
#region IdentityServer
var identityServerManagementGroup =
context.AddGroup(ProjectNamePermissions.IdentityServer.IdentityServerManagement, L("Permission:IdentityServerManagement"));
var clientManagment = identityServerManagementGroup.AddPermission(ProjectNamePermissions.IdentityServer.Client.Default,
L("Permission:IdentityServerManagement:Client"));
clientManagment.AddChild(ProjectNamePermissions.IdentityServer.Client.Create,
L("Permission:Create"));
clientManagment.AddChild(ProjectNamePermissions.IdentityServer.Client.Update,
L("Permission:Update"));
clientManagment.AddChild(ProjectNamePermissions.IdentityServer.Client.Delete,
L("Permission:Delete"));
clientManagment.AddChild(ProjectNamePermissions.IdentityServer.Client.Enable,
L("Permission:Enable"));
var apiResourceManagment = identityServerManagementGroup.AddPermission(ProjectNamePermissions.IdentityServer.ApiResource.Default,
L("Permission:IdentityServerManagement:ApiResource"));
apiResourceManagment.AddChild(ProjectNamePermissions.IdentityServer.ApiResource.Create,
L("Permission:Create"));
apiResourceManagment.AddChild(ProjectNamePermissions.IdentityServer.ApiResource.Update,
L("Permission:Update"));
apiResourceManagment.AddChild(ProjectNamePermissions.IdentityServer.ApiResource.Delete,
L("Permission:Delete"));
var apiScopeManagment = identityServerManagementGroup.AddPermission(ProjectNamePermissions.IdentityServer.ApiScope.Default,
L("Permission:IdentityServerManagement:ApiScope"));
apiScopeManagment.AddChild(ProjectNamePermissions.IdentityServer.ApiScope.Create,
L("Permission:Create"));
apiScopeManagment.AddChild(ProjectNamePermissions.IdentityServer.ApiScope.Update,
L("Permission:Update"));
apiScopeManagment.AddChild(ProjectNamePermissions.IdentityServer.ApiScope.Delete,
L("Permission:Delete"));
var identityResourcesManagment = identityServerManagementGroup.AddPermission(ProjectNamePermissions.IdentityServer.IdentityResources.Default,
L("Permission:IdentityServerManagement:IdentityResources"));
identityResourcesManagment.AddChild(ProjectNamePermissions.IdentityServer.IdentityResources.Create,
L("Permission:Create"));
identityResourcesManagment.AddChild(ProjectNamePermissions.IdentityServer.IdentityResources.Update,
L("Permission:Update"));
identityResourcesManagment.AddChild(ProjectNamePermissions.IdentityServer.IdentityResources.Delete,
L("Permission:Delete"));
#endregion
}
private static LocalizableString L(string name)

61
aspnet-core/services/src/CompanyName.ProjectName.Application.Contracts/Permissions/ProjectNamePermissions.cs

@ -1,4 +1,6 @@
namespace CompanyName.ProjectName.Permissions
using CompanyName.ProjectName.IdentityServers.Clients;
namespace CompanyName.ProjectName.Permissions
{
public static class ProjectNamePermissions
{
@ -12,16 +14,55 @@
/// <summary>
/// 系统管理扩展权限
/// </summary>
public static class AbpIdentityExtend
public static class SystemManagement
{
public const string Default = "System";
public const string UserEnable = Default + ".Users.Enable";
public const string AuditLog = Default + ".AuditLog";
public const string Hangfire = Default + ".Hangfire";
public const string Cap = Default + ".Cap";
}
public static class IdentityServer
{
public const string Default = "AbpIdentity";
public const string Users = Default + ".Users";
public const string Roles = Default + ".Roles";
public const string AuditLogs = Default + ".AuditLogs";
public const string UserEnable = Users + ".Users.Enable";
public const string UserQuery = Users + ".Query";
public const string RoleQuery = Roles + ".Query";
public const string AuditLogQuery = AuditLogs + "AuditLog";
public const string IdentityServerManagement = "IdentityServerManagement";
public static class Client
{
public const string Default = IdentityServerManagement + ".Client";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
public const string Enable = Default + ".Enable";
}
public static class ApiResource
{
public const string Default = IdentityServerManagement + ".ApiResource";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
}
public static class ApiScope
{
public const string Default = IdentityServerManagement + ".ApiScope";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
}
public static class IdentityResources
{
public const string Default = IdentityServerManagement + ".IdentityResources";
public const string Create = Default + ".Create";
public const string Update = Default + ".Update";
public const string Delete = Default + ".Delete";
}
}
}
}

1
aspnet-core/services/src/CompanyName.ProjectName.Application/CompanyName.ProjectName.Application.csproj

@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.Application\CompanyName.ProjectName.DataDictionaryManagement.Application.csproj" />
<ProjectReference Include="..\..\..\modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.Application\CompanyName.ProjectName.NotificationManagement.Application.csproj" />
<ProjectReference Include="..\..\..\modules\QueryManagement\src\CompanyName.ProjectName.QueryManagement.Domain\CompanyName.ProjectName.QueryManagement.Domain.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.Domain\CompanyName.ProjectName.Domain.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.Application.Contracts\CompanyName.ProjectName.Application.Contracts.csproj" />

4
aspnet-core/services/src/CompanyName.ProjectName.Application/ProjectNameApplicationModule.cs

@ -1,4 +1,5 @@
using CompanyName.ProjectName.DataDictionaryManagement;
using CompanyName.ProjectName.NotificationManagement;
using CompanyName.ProjectName.QueryManagement;
using Volo.Abp.Account;
using Volo.Abp.AuditLogging;
@ -23,7 +24,8 @@ namespace CompanyName.ProjectName
typeof(AbpSettingManagementApplicationModule),
typeof(AbpAuditLoggingDomainModule),
typeof(QueryManagementDomainModule),
typeof(DataDictionaryManagementApplicationModule)
typeof(DataDictionaryManagementApplicationModule),
typeof(NotificationManagementApplicationModule)
)]
public class ProjectNameApplicationModule : AbpModule
{

9
aspnet-core/services/src/CompanyName.ProjectName.Application/Roles/RoleAppService.cs

@ -10,7 +10,7 @@ using Volo.Abp.PermissionManagement;
namespace CompanyName.ProjectName.Roles
{
public class RoleAppService : ApplicationService, IRoleAppService
public class RoleAppService : ProjectNameAppService, IRoleAppService
{
private readonly IIdentityRoleAppService _identityRoleAppService;
private readonly IPermissionAppService _permissionAppService;
@ -124,7 +124,9 @@ namespace CompanyName.ProjectName.Roles
"AbpTenantManagement.Tenants.Update",
"AbpTenantManagement.Tenants.Delete",
"AbpTenantManagement.Tenants.ManageFeatures",
"AbpTenantManagement.Tenants.ManageConnectionStrings"
"AbpTenantManagement.Tenants.ManageConnectionStrings",
"SettingManagement",
"SettingManagement.Emailing"
};
var permissions = new List<PermissionTreeDto>();
@ -137,6 +139,9 @@ namespace CompanyName.ProjectName.Roles
}
var groupPermission = new PermissionTreeDto {Key = @group.Name, Title = @group.DisplayName};
groupPermission.Key = group.Name;
groupPermission.Title =
group.Name == "AbpIdentity" ? L["Permission:SystemManagement"] : group.DisplayName;
foreach (var item in group.Permissions)
{
result.AllGrants.Add(item.Name);

2
aspnet-core/services/src/CompanyName.ProjectName.DbMigrator/appsettings.json

@ -1,7 +1,7 @@
{
"ConnectionStrings": {
"Default": "Data Source=localhost;Database=CompanyNameProjectNameDB;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true",
"DataDictionaryManagement": "Data Source=localhost;Database=DataDictionaryManagement;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
// "DataDictionaryManagement": "Data Source=localhost;Database=DataDictionaryManagement;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
},
"IdentityServer": {
"Clients": {

10
aspnet-core/services/src/CompanyName.ProjectName.Domain.Shared/Localization/ProjectName/en.json

@ -9,6 +9,14 @@
"Permission:Update": "Update",
"Permission:Delete": "Delete",
"Permission:Enable": "Enable|Disable",
"Permission:AuditLogManagement": "AuditLog"
"Permission:SystemManagement": "SystemManagement",
"Permission:AuditLogManagement": "AuditLog",
"Permission:HangfireManagement": "BackgroundTask",
"Permission:CapManagement": "IntegratedEvent",
"Permission:IdentityServerManagement": "IdentityServer",
"Permission:IdentityServerManagement:Client": "Client",
"Permission:IdentityServerManagement:ApiResource": "ApiResource",
"Permission:IdentityServerManagement:ApiScope": "ApiScope",
"Permission:IdentityServerManagement:IdentityResources": "IdentityResources"
}
}

17
aspnet-core/services/src/CompanyName.ProjectName.Domain.Shared/Localization/ProjectName/zh-Hans.json

@ -3,6 +3,21 @@
"texts": {
"Menu:Home": "首页",
"Welcome": "欢迎",
"LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io."
"LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io.",
"Permission:Query": "查询",
"Permission:Create": "创建",
"Permission:Update": "编辑",
"Permission:Delete": "删除",
"Permission:Enable": "启用|禁用",
"Permission:AuditLogManagement": "审计日志",
"Permission:SystemManagement": "系统管理",
"Permission:HangfireManagement": "后台任务",
"Permission:CapManagement": "集成事件",
"Permission:IdentityServerManagement": "IdentityServer",
"Permission:IdentityServerManagement:Client": "客户端",
"Permission:IdentityServerManagement:ApiResource": "Api资源",
"Permission:IdentityServerManagement:ApiScope": "ApiScope",
"Permission:IdentityServerManagement:IdentityResources": "Identity资源"
}
}

2
aspnet-core/services/src/CompanyName.ProjectName.Domain.Shared/ProjectNameDomainSharedModule.cs

@ -37,7 +37,7 @@ namespace CompanyName.ProjectName
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<ProjectNameDomainSharedModule>();
options.FileSets.AddEmbedded<ProjectNameDomainSharedModule>("CompanyName.ProjectName");
});
Configure<AbpLocalizationOptions>(options =>

1
aspnet-core/services/src/CompanyName.ProjectName.Domain/CompanyName.ProjectName.Domain.csproj

@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.Domain\CompanyName.ProjectName.DataDictionaryManagement.Domain.csproj" />
<ProjectReference Include="..\..\..\modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.Domain\CompanyName.ProjectName.NotificationManagement.Domain.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.Domain.Shared\CompanyName.ProjectName.Domain.Shared.csproj" />
</ItemGroup>

4
aspnet-core/services/src/CompanyName.ProjectName.Domain/ProjectNameDomainModule.cs

@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using CompanyName.ProjectName.MultiTenancy;
using CompanyName.ProjectName.NotificationManagement;
using Volo.Abp.AuditLogging;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Emailing;
@ -29,7 +30,8 @@ namespace CompanyName.ProjectName
typeof(AbpSettingManagementDomainModule),
typeof(AbpTenantManagementDomainModule),
typeof(AbpEmailingModule),
typeof(DataDictionaryManagementDomainModule)
typeof(DataDictionaryManagementDomainModule),
typeof(NotificationManagementDomainModule)
)]
public class ProjectNameDomainModule : AbpModule
{

6
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ProjectNameMigrationsDbContext.cs

@ -1,4 +1,5 @@
using CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore;
using CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
@ -23,7 +24,6 @@ namespace CompanyName.ProjectName.EntityFrameworkCore
public ProjectNameMigrationsDbContext(DbContextOptions<ProjectNameMigrationsDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
@ -46,7 +46,9 @@ namespace CompanyName.ProjectName.EntityFrameworkCore
builder.ConfigureProjectName();
// 数据字典
//builder.ConfigureDataDictionaryManagement();
builder.ConfigureDataDictionaryManagement();
builder.ConfigureNotificationManagement();
}
}
}

599
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210813172555_Init.Designer.cs → aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210903085042_Init.Designer.cs

File diff suppressed because it is too large

985
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210813172555_Init.cs → aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/20210903085042_Init.cs

File diff suppressed because it is too large

597
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore.DbMigrations/Migrations/ProjectNameMigrationsDbContextModelSnapshot.cs

File diff suppressed because it is too large

1
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore/CompanyName.ProjectName.EntityFrameworkCore.csproj

@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore\CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore\CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\..\modules\QueryManagement\src\CompanyName.ProjectName.QueryManagement.FreeSqlMySql\CompanyName.ProjectName.QueryManagement.FreeSqlMySql.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.Domain\CompanyName.ProjectName.Domain.csproj" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore.MySQL" Version="$(AbpPackageVersion)" />

5
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore/EntityFrameworkCore/ProjectNameDbContext.cs

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using CompanyName.ProjectName.Users;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
@ -53,6 +54,8 @@ namespace CompanyName.ProjectName.EntityFrameworkCore
/* Configure your own tables/entities inside the ConfigureProjectName method */
builder.ConfigureProjectName();
}
}
}

4
aspnet-core/services/src/CompanyName.ProjectName.EntityFrameworkCore/EntityFrameworkCore/ProjectNameEntityFrameworkCoreModule.cs

@ -1,4 +1,5 @@
using CompanyName.ProjectName.DataDictionaryManagement.EntityFrameworkCore;
using CompanyName.ProjectName.NotificationManagement.EntityFrameworkCore;
using CompanyName.ProjectName.QueryManagement.FreeSqlMySql;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
@ -27,7 +28,8 @@ namespace CompanyName.ProjectName.EntityFrameworkCore
typeof(AbpTenantManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(QueryManagementFreeSqlMySqlModule),
typeof(DataDictionaryManagementEntityFrameworkCoreModule)
typeof(DataDictionaryManagementEntityFrameworkCoreModule),
typeof(NotificationManagementEntityFrameworkCoreModule)
)]
public class ProjectNameEntityFrameworkCoreModule : AbpModule
{

4
aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/CompanyName.ProjectName.HttpApi.Host.csproj

@ -36,9 +36,13 @@
<PackageReference Include="AspNetCore.HealthChecks.MySql" Version="5.0.1" />
<PackageReference Include="AspNetCore.HealthChecks.Redis" Version="5.0.2" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.7" />
<PackageReference Include="DotNetCore.CAP.MySql" Version="5.1.1" />
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="5.1.1" />
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="5.1.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\frameworks\CAP\src\CompanyName.ProjectName.CAP\CompanyName.ProjectName.CAP.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.Application\CompanyName.ProjectName.Application.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.EntityFrameworkCore.DbMigrations\CompanyName.ProjectName.EntityFrameworkCore.DbMigrations.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.HttpApi\CompanyName.ProjectName.HttpApi.csproj" />

77912
aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/Logs/logs.txt

File diff suppressed because it is too large

138
aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/ProjectNameHttpApiHostModule.cs

@ -41,6 +41,7 @@ using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Volo.Abp.VirtualFileSystem;
using System.Threading.Tasks;
using CompanyName.ProjectName.CAP;
namespace CompanyName.ProjectName
{
@ -55,7 +56,8 @@ namespace CompanyName.ProjectName
typeof(AbpSwashbuckleModule),
typeof(AbpAccountWebModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpBackgroundJobsHangfireModule)
typeof(AbpBackgroundJobsHangfireModule),
typeof(AbpCapModule)
)]
public class ProjectNameHttpApiHostModule : AbpModule
{
@ -75,7 +77,7 @@ namespace CompanyName.ProjectName
//ConfigureConventionalControllers();
//ConfigureAuthentication(context, configuration);
ConfigureLocalization();
ConfigureCache(configuration);
ConfigureCache(context);
ConfigureVirtualFileSystem(context);
ConfigureRedis(context, configuration, hostingEnvironment);
ConfigureCors(context, configuration);
@ -84,6 +86,7 @@ namespace CompanyName.ProjectName
ConfigureHealthChecks(context);
ConfigureJwtAuthentication(context, configuration);
ConfigureHangfireMysql(context);
ConfigurationCap(context);
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -134,7 +137,8 @@ namespace CompanyName.ProjectName
app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); });
app.UseHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new[] {new CustomHangfireAuthorizeFilter()}
Authorization = new[] {new CustomHangfireAuthorizeFilter()},
IgnoreAntiforgeryToken = true
});
}
@ -143,7 +147,7 @@ namespace CompanyName.ProjectName
Configure<AbpBackgroundJobOptions>(options => { options.IsJobExecutionEnabled = true; });
context.Services.AddHangfire(config =>
{
config.UseStorage(new MySqlStorage(context.Services.GetConfiguration().GetConnectionString("Hangfire"),
config.UseStorage(new MySqlStorage(context.Services.GetConfiguration().GetConnectionString("Default"),
new MySqlStorageOptions()
{
//CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
@ -196,25 +200,23 @@ namespace CompanyName.ProjectName
currentContext.Token = accessToken;
}
// 如果请求来自hangfire
if (!path.ToString().StartsWith("/hangfire"))
// 如果请求来自hangfire 或者cap
if (path.ToString().StartsWith("/hangfire") || path.ToString().StartsWith("/cap"))
{
return Task.CompletedTask;
}
currentContext.HttpContext.Response.Headers.Remove("X-Frame-Options");
if (!string.IsNullOrEmpty(accessToken))
{
currentContext.Token = accessToken;
currentContext.HttpContext.Response.Cookies
.Append("HangfireCookie", accessToken);
}
else
{
var cookies = currentContext.Request.Cookies;
if (cookies.ContainsKey("HangfireCookie"))
currentContext.HttpContext.Response.Headers.Remove("X-Frame-Options");
if (!string.IsNullOrEmpty(accessToken))
{
currentContext.Token = accessToken;
currentContext.HttpContext.Response.Cookies
.Append("ProjectNameCookie", accessToken);
}
else
{
currentContext.Token = cookies["HangfireCookie"];
var cookies = currentContext.Request.Cookies;
if (cookies.ContainsKey("ProjectNameCookie"))
{
currentContext.Token = cookies["ProjectNameCookie"];
}
}
}
@ -233,33 +235,44 @@ namespace CompanyName.ProjectName
context.Services.Configure<JwtOptions>(context.Services.GetConfiguration().GetSection("Jwt"));
}
private void ConfigureCache(IConfiguration configuration)
/// <summary>
/// Redis缓存
/// </summary>
private void ConfigureCache(ServiceConfigurationContext context)
{
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "ProjectName:"; });
var redisConnectionString =
context.Services.GetConfiguration().GetValue<string>("Cache:Redis:ConnectionString");
var redisDatabaseId = context.Services.GetConfiguration().GetValue<int>("Cache:Redis:DatabaseId");
var password = context.Services.GetConfiguration().GetValue<string>("Cache:Redis:Password");
var connectString = $"{redisConnectionString},password={password},defaultdatabase={redisDatabaseId}";
var redis = ConnectionMultiplexer.Connect(connectString);
context.Services.AddStackExchangeRedisCache(options => { options.Configuration = connectString; });
}
private void ConfigureVirtualFileSystem(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
if (hostingEnvironment.IsDevelopment())
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameDomainSharedModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Domain.Shared"));
options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameDomainModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Domain"));
options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameApplicationContractsModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Application.Contracts"));
options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameApplicationModule>(
Path.Combine(hostingEnvironment.ContentRootPath,
$"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Application"));
});
}
Configure<AbpVirtualFileSystemOptions>(options => { options.FileSets.AddEmbedded<ProjectNameHttpApiHostModule>(); });
// var hostingEnvironment = context.Services.GetHostingEnvironment();
//
// if (hostingEnvironment.IsDevelopment())
// {
// Configure<AbpVirtualFileSystemOptions>(options =>
// {
// options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameDomainSharedModule>(
// Path.Combine(hostingEnvironment.ContentRootPath,
// $"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Domain.Shared"));
// options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameDomainModule>(
// Path.Combine(hostingEnvironment.ContentRootPath,
// $"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Domain"));
// options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameApplicationContractsModule>(
// Path.Combine(hostingEnvironment.ContentRootPath,
// $"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Application.Contracts"));
// options.FileSets.ReplaceEmbeddedByPhysical<ProjectNameApplicationModule>(
// Path.Combine(hostingEnvironment.ContentRootPath,
// $"..{Path.DirectorySeparatorChar}CompanyName.ProjectName.Application"));
// });
// }
}
private void ConfigureConventionalControllers()
@ -278,11 +291,11 @@ namespace CompanyName.ProjectName
private void ConfigureHealthChecks(ServiceConfigurationContext context)
{
var redisConnectionString =
context.Services.GetConfiguration().GetValue<string>("Redis:Configuration")
+ ",defaultdatabase="
+ context.Services.GetConfiguration().GetValue<int>("Redis:DatabaseId", 1);
var mysqlConnectionString = context.Services.GetConfiguration().GetConnectionString("Default");
context.Services.AddHealthChecks().AddRedis(redisConnectionString).AddMySql(mysqlConnectionString);
context.Services.GetConfiguration().GetValue<string>("Cache:Redis:ConnectionString");
var redisDatabaseId = context.Services.GetConfiguration().GetValue<int>("Cache:Redis:DatabaseId");
var password = context.Services.GetConfiguration().GetValue<string>("Cache:Redis:Password");
var connectString = $"{redisConnectionString},password={password},defaultdatabase={redisDatabaseId}";
context.Services.AddHealthChecks().AddRedis(redisConnectionString).AddMySql(connectString);
}
private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
@ -368,9 +381,10 @@ namespace CompanyName.ProjectName
if (!hostingEnvironment.IsDevelopment())
{
var redisConnectionString =
context.Services.GetConfiguration().GetValue<string>("Redis:Configuration")
+ ",defaultdatabase="
+ context.Services.GetConfiguration().GetValue<int>("Redis:DatabaseId", 1);
context.Services.GetConfiguration().GetValue<string>("Cache:Redis:ConnectionString");
var redisDatabaseId = context.Services.GetConfiguration().GetValue<int>("Cache:Redis:DatabaseId");
var password = context.Services.GetConfiguration().GetValue<string>("Cache:Redis:Password");
var connectString = $"{redisConnectionString},password={password},defaultdatabase={redisDatabaseId}";
var redis = ConnectionMultiplexer.Connect(redisConnectionString);
context.Services
.AddDataProtection()
@ -400,5 +414,27 @@ namespace CompanyName.ProjectName
});
});
}
private void ConfigurationCap(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.AddAbpCap(capOptions =>
{
capOptions.UseEntityFramework<ProjectNameDbContext>();
capOptions.UseRabbitMQ(option =>
{
option.HostName = configuration.GetValue<string>("RabbitMq:HostName");
option.UserName = configuration.GetValue<string>("RabbitMq:UserName");
option.Password = configuration.GetValue<string>("RabbitMq:Password");
});
var hostingEnvironment = context.Services.GetHostingEnvironment();
bool auth = !hostingEnvironment.IsDevelopment();
capOptions.UseDashboard(options =>
{
options.UseAuth = auth;
});
});
}
}
}

18
aspnet-core/services/src/CompanyName.ProjectName.HttpApi.Host/appsettings.json

@ -4,12 +4,15 @@
},
"ConnectionStrings": {
"Default": "Data Source=localhost;Database=CompanyNameProjectNameDB;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true",
"DataDictionaryManagement": "Data Source=localhost;Database=DataDictionaryManagement;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true",
"Hangfire": "Data Source=localhost;Database=CompanyNameProjectNameHangfireDB;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
// "DataDictionaryManagement": "Data Source=localhost;Database=DataDictionaryManagement;uid=root;pwd=mypassword;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true",
},
"Redis": {
"Configuration": "localhost,password=mypassword",
"DatabaseId": 1
"Cache": {
"Redis": {
"ConnectionString": "localhost",
"Password": "mypassword",
"DatabaseId": 1
}
},
"AuthServer": {
"Authority": "https://localhost:44354",
@ -29,6 +32,11 @@
"ExpirationTime": 24
// hour
},
"RabbitMq": {
"HostName": "localhost",
"UserName": "admin",
"Password": "admin"
},
"LogToElasticSearch": {
"Enabled": "true",
"ElasticSearch": {

1
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/CompanyName.ProjectName.HttpApi.csproj

@ -9,6 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\modules\DataDictionaryManagement\src\CompanyName.ProjectName.DataDictionaryManagement.HttpApi\CompanyName.ProjectName.DataDictionaryManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\..\modules\NotificationManagement\src\CompanyName.ProjectName.NotificationManagement.HttpApi\CompanyName.ProjectName.NotificationManagement.HttpApi.csproj" />
<ProjectReference Include="..\CompanyName.ProjectName.Application.Contracts\CompanyName.ProjectName.Application.Contracts.csproj" />
</ItemGroup>

6
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/ApiResourceController.cs

@ -2,7 +2,9 @@
using System.Threading.Tasks;
using CompanyName.ProjectName.IdentityServers;
using CompanyName.ProjectName.IdentityServers.Dtos;
using CompanyName.ProjectName.Permissions;
using CompanyName.ProjectName.Publics.Dtos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Volo.Abp.Application.Dtos;
@ -10,6 +12,7 @@ using Volo.Abp.Application.Dtos;
namespace CompanyName.ProjectName.Controllers.IdentityServers
{
[Route("IdentityServer/ApiResource")]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiResource.Default)]
public class ApiResourceController : ProjectNameController
{
private readonly IApiResourceAppService _apiResourceAppService;
@ -36,6 +39,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("create")]
[SwaggerOperation(summary: "新增ApiResource", Tags = new[] {"ApiResource"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiResource.Create)]
public Task CreateAsync(CreateApiResourceInput input)
{
return _apiResourceAppService.CreateAsync(input);
@ -44,6 +48,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("delete")]
[SwaggerOperation(summary: "删除ApiResource", Tags = new[] {"ApiResource"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiResource.Delete)]
public async Task DeleteAsync(IdInput input)
{
await _apiResourceAppService.DeleteAsync(input);
@ -51,6 +56,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("update")]
[SwaggerOperation(summary: "删除ApiResource", Tags = new[] {"ApiResource"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiResource.Update)]
public Task UpdateAsync(UpdateApiResourceInput input)
{
return _apiResourceAppService.UpdateAsync(input);

6
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/ApiScopeController.cs

@ -4,7 +4,9 @@ using System.Threading.Tasks;
using CompanyName.ProjectName.Extensions.Customs.Dtos;
using CompanyName.ProjectName.IdentityServers.ApiScopes;
using CompanyName.ProjectName.IdentityServers.ApiScopes.Dtos;
using CompanyName.ProjectName.Permissions;
using CompanyName.ProjectName.Publics.Dtos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Volo.Abp.Application.Dtos;
@ -12,6 +14,7 @@ using Volo.Abp.Application.Dtos;
namespace CompanyName.ProjectName.Controllers.IdentityServers
{
[Route("IdentityServer/ApiScope")]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiScope.Default)]
public class ApiScopeController:ProjectNameController
{
private readonly IApiScopeAppService _apiScopeAppService;
@ -30,6 +33,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("create")]
[SwaggerOperation(summary: "创建ApiScope", Tags = new[] {"ApiScope"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiScope.Create)]
public Task CreateAsync(CreateApiScopeInput input)
{
return _apiScopeAppService.CreateAsync(input);
@ -37,6 +41,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("update")]
[SwaggerOperation(summary: "更新ApiScope", Tags = new[] {"ApiScope"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiScope.Update)]
public Task UpdateAsync(UpdateCreateApiScopeInput input)
{
return _apiScopeAppService.UpdateAsync(input);
@ -44,6 +49,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("delete")]
[SwaggerOperation(summary: "删除ApiScope", Tags = new[] {"ApiScope"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.ApiScope.Delete)]
public Task DeleteAsync(IdInput input)
{
return _apiScopeAppService.DeleteAsync(input);

14
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/ClientController.cs

@ -1,6 +1,8 @@
using System.Threading.Tasks;
using CompanyName.ProjectName.IdentityServers.Clients;
using CompanyName.ProjectName.Permissions;
using CompanyName.ProjectName.Publics.Dtos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Volo.Abp.Application.Dtos;
@ -8,6 +10,7 @@ using Volo.Abp.Application.Dtos;
namespace CompanyName.ProjectName.Controllers.IdentityServers
{
[Route("IdentityServer/Client")]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Default)]
public class ClientController : ProjectNameController
{
private readonly IIdentityServerClientAppService _identityServerClientAppService;
@ -27,6 +30,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("create")]
[SwaggerOperation(summary: "创建Client", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Create)]
public Task CreateAsync(CreateClientInput input)
{
return _identityServerClientAppService.CreateAsync(input);
@ -34,6 +38,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("delete")]
[SwaggerOperation(summary: "删除client", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Delete)]
public Task DeleteAsync(IdInput input)
{
return _identityServerClientAppService.DeleteAsync(input);
@ -41,6 +46,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("updateBasic")]
[SwaggerOperation(summary: "更新基本信息", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task UpdateBasicDataAsync(UpdataBasicDataInput input)
{
return _identityServerClientAppService.UpdateBasicDataAsync(input);
@ -48,6 +54,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("updateScopes")]
[SwaggerOperation(summary: "更新client scopes", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task UpdateScopesAsync(UpdateScopeInput input)
{
return _identityServerClientAppService.UpdateScopesAsync(input);
@ -55,6 +62,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("addRedirectUri")]
[SwaggerOperation(summary: "新增回调地址", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task AddRedirectUriAsync(AddRedirectUriInput input)
{
return _identityServerClientAppService.AddRedirectUriAsync(input);
@ -62,6 +70,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("removeRedirectUri")]
[SwaggerOperation(summary: "删除回调地址", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task RemoveRedirectUriAsync(RemoveRedirectUriInput input)
{
return _identityServerClientAppService.RemoveRedirectUriAsync(input);
@ -69,6 +78,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("addLogoutRedirectUri")]
[SwaggerOperation(summary: "新增Logout回调地址", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task AddLogoutRedirectUriAsync(AddRedirectUriInput input)
{
return _identityServerClientAppService.AddLogoutRedirectUriAsync(input);
@ -76,6 +86,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("removeLogoutRedirectUri")]
[SwaggerOperation(summary: "删除Logout回调地址", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task RemoveLogoutRedirectUriAsync(RemoveRedirectUriInput input)
{
return _identityServerClientAppService.RemoveLogoutRedirectUriAsync(input);
@ -83,6 +94,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("addCors")]
[SwaggerOperation(summary: "添加cors", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task AddCorsAsync(AddCorsInput input)
{
return _identityServerClientAppService.AddCorsAsync(input);
@ -90,6 +102,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("removeCors")]
[SwaggerOperation(summary: "删除cors", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Update)]
public Task RemoveCorsAsync(RemoveCorsInput input)
{
return _identityServerClientAppService.RemoveCorsAsync(input);
@ -97,6 +110,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("enabled")]
[SwaggerOperation(summary: "禁用client", Tags = new[] {"Client"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.Client.Enable)]
public Task EnabledAsync(EnabledInput input)
{
return _identityServerClientAppService.EnabledAsync(input);

6
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/IdentityServers/IdentityResourceController.cs

@ -1,7 +1,9 @@
using System.Threading.Tasks;
using CompanyName.ProjectName.IdentityServers.IdentityResources;
using CompanyName.ProjectName.IdentityServers.IdentityResources.Dtos;
using CompanyName.ProjectName.Permissions;
using CompanyName.ProjectName.Publics.Dtos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Volo.Abp.Application.Dtos;
@ -9,6 +11,7 @@ using Volo.Abp.Application.Dtos;
namespace CompanyName.ProjectName.Controllers.IdentityServers
{
[Route("IdentityServer/IdentityResource")]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.IdentityResources.Default)]
public class IdentityResourceController : ProjectNameController
{
private readonly IIdentityResourceAppService _identityResourceAppService;
@ -28,6 +31,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("create")]
[SwaggerOperation(summary: "创建IdentityResource", Tags = new[] {"IdentityResource"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.IdentityResources.Create)]
public Task CreateAsync(CreateIdentityResourceInput input)
{
return _identityResourceAppService.CreateAsync(input);
@ -35,6 +39,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("update")]
[SwaggerOperation(summary: "更新IdentityResource", Tags = new[] {"IdentityResource"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.IdentityResources.Update)]
public Task UpdateAsync(UpdateIdentityResourceInput input)
{
return _identityResourceAppService.UpdateAsync(input);
@ -42,6 +47,7 @@ namespace CompanyName.ProjectName.Controllers.IdentityServers
[HttpPost("delete")]
[SwaggerOperation(summary: "删除IdentityResource", Tags = new[] {"IdentityResource"})]
[Authorize(Policy = ProjectNamePermissions.IdentityServer.IdentityResources.Delete)]
public Task DeleteAsync(IdInput input)
{
return _identityResourceAppService.DeleteAsync(input);

8
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/Systems/AuditLogController.cs

@ -11,8 +11,8 @@ using Volo.Abp.Identity;
namespace CompanyName.ProjectName.Controllers.Systems
{
[Route("AuditLogs")]
//[Authorize]
public class AuditLogController:ProjectNameController
[Authorize(Policy = IdentityPermissions.Users.Default)]
public class AuditLogController : ProjectNameController
{
private readonly IAuditLogAppService _auditLogAppService;
@ -22,8 +22,8 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("page")]
//[Authorize(ProjectNamePermissions.AbpIdentityExtend.AuditLogQuery)]
[SwaggerOperation(summary: "分页获取用户信息", Tags = new[] { "AuditLogs" })]
[Authorize(Policy = ProjectNamePermissions.SystemManagement.AuditLog)]
[SwaggerOperation(summary: "分页获取用户信息", Tags = new[] {"AuditLogs"})]
public Task<PagedResultDto<GetAuditLogPageListOutput>> ListAsync(PagingAuditLogListInput input)
{
return _auditLogAppService.GetListAsync(input);

3
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/Systems/RoleController.cs

@ -13,6 +13,7 @@ using Volo.Abp.Identity;
namespace CompanyName.ProjectName.Controllers.Systems
{
[Route("Roles")]
[Authorize(Policy = IdentityPermissions.Roles.Default)]
public class RoleController : ProjectNameController
{
private readonly IRoleAppService _roleAppService;
@ -23,7 +24,6 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("all")]
[Authorize(IdentityPermissions.Roles.Default)]
[SwaggerOperation(summary: "获取所有角色", Tags = new[] { "Roles" })]
public Task<ListResultDto<IdentityRoleDto>> AllListAsync()
{
@ -31,7 +31,6 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("page")]
[Authorize(IdentityPermissions.Roles.Default)]
[SwaggerOperation(summary: "分页获取角色", Tags = new[] { "Roles" })]
public Task<PagedResultDto<IdentityRoleDto>> ListAsync(PagingRoleListInput input)
{

7
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/Controllers/Systems/UserController.cs

@ -13,7 +13,7 @@ using Volo.Abp.Identity;
namespace CompanyName.ProjectName.Controllers.Systems
{
[Route("Users")]
[Authorize]
[Authorize(Policy = IdentityPermissions.Users.Default)]
public class UserContoller:ProjectNameController
{
private readonly IUserAppService _userAppService;
@ -24,7 +24,6 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("page")]
[Authorize(IdentityPermissions.Users.Default)]
[SwaggerOperation(summary: "分页获取用户信息", Tags = new[] { "Users" })]
public Task<PagedResultDto<IdentityUserDto>> ListAsync(PagingUserListInput input)
{
@ -56,7 +55,6 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("role")]
[Authorize(IdentityPermissions.Users.Default)]
[SwaggerOperation(summary: "获取用户角色信息", Tags = new[] { "Users" })]
public Task<ListResultDto<IdentityRoleDto>> GetRoleByUserId(IdInput input)
{
@ -64,7 +62,6 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("changePassword")]
[Authorize(IdentityPermissions.Users.Default)]
[SwaggerOperation(summary: "修改当前用户密码", Tags = new[] { "Users" })]
public Task<bool> ChangePasswordAsync(ChangePasswordInput input)
{
@ -72,7 +69,7 @@ namespace CompanyName.ProjectName.Controllers.Systems
}
[HttpPost("lock")]
[Authorize(ProjectNamePermissions.AbpIdentityExtend.UserEnable)]
[Authorize(ProjectNamePermissions.SystemManagement.UserEnable)]
[SwaggerOperation(summary: "锁定用户", Tags = new[] { "Users" })]
public Task LockAsync(LockUserInput input)
{

4
aspnet-core/services/src/CompanyName.ProjectName.HttpApi/ProjectNameHttpApiModule.cs

@ -1,6 +1,7 @@
using CompanyName.ProjectName.DataDictionaryManagement;
using Localization.Resources.AbpUi;
using CompanyName.ProjectName.Localization;
using CompanyName.ProjectName.NotificationManagement;
using Volo.Abp.Account;
using Volo.Abp.FeatureManagement;
using Volo.Abp.Identity;
@ -20,7 +21,8 @@ namespace CompanyName.ProjectName
typeof(AbpTenantManagementHttpApiModule),
typeof(AbpFeatureManagementHttpApiModule),
typeof(AbpSettingManagementHttpApiModule),
typeof(DataDictionaryManagementHttpApiModule)
typeof(DataDictionaryManagementHttpApiModule),
typeof(NotificationManagementHttpApiModule)
)]
public class ProjectNameHttpApiModule : AbpModule
{

4
vben271/.env

@ -2,7 +2,7 @@
VITE_PORT = 4200
# spa-title
VITE_GLOB_APP_TITLE = Abp Vnext
VITE_GLOB_APP_TITLE = ProjectName
# spa shortname
VITE_GLOB_APP_SHORT_NAME = Abp Vnext
VITE_GLOB_APP_SHORT_NAME = ProjectName

104
vben271/package-lock.json

@ -2045,6 +2045,28 @@
"preact": "^10.4.8"
}
},
"@microsoft/signalr": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-5.0.9.tgz",
"integrity": "sha512-pQufk3+mChfystnmYpglyRYQFp+036QmOxbZUFr2cFf2iiS8ekBX5uVBOG8OexKcsG4TcJNAU/ref90Y9+3ZiA==",
"requires": {
"abort-controller": "^3.0.0",
"eventsource": "^1.0.7",
"fetch-cookie": "^0.7.3",
"node-fetch": "^2.6.0",
"ws": "^6.0.0"
},
"dependencies": {
"ws": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
"requires": {
"async-limiter": "~1.0.0"
}
}
}
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -3221,6 +3243,14 @@
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
"dev": true
},
"abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"requires": {
"event-target-shim": "^5.0.0"
}
},
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
@ -3490,6 +3520,11 @@
"lodash": "^4.17.14"
}
},
"async-limiter": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"async-validator": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz",
@ -6380,6 +6415,11 @@
"is-symbol": "^1.0.2"
}
},
"es6-denodeify": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/es6-denodeify/-/es6-denodeify-0.1.5.tgz",
"integrity": "sha1-MdTV/pxVA+ElRgQ5MQ4WoqPznB8="
},
"esbuild": {
"version": "0.12.24",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.24.tgz",
@ -6797,12 +6837,25 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
},
"event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
},
"eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true
},
"eventsource": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz",
"integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==",
"requires": {
"original": "^1.0.0"
}
},
"exec-buffer": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz",
@ -7192,6 +7245,26 @@
"pend": "~1.2.0"
}
},
"fetch-cookie": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.7.3.tgz",
"integrity": "sha512-rZPkLnI8x5V+zYAiz8QonAHsTb4BY+iFowFBI1RFn0zrO343AVp9X7/yUj/9wL6Ef/8fLls8b/vGtzUvmyAUGA==",
"requires": {
"es6-denodeify": "^0.1.1",
"tough-cookie": "^2.3.3"
},
"dependencies": {
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"requires": {
"psl": "^1.1.28",
"punycode": "^2.1.1"
}
}
}
},
"figures": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
@ -12027,6 +12100,14 @@
}
}
},
"original": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
"integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
"requires": {
"url-parse": "^1.4.3"
}
},
"os-filter-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz",
@ -13202,8 +13283,7 @@
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
"dev": true
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
"pug": {
"version": "3.0.2",
@ -13342,8 +13422,7 @@
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"q": {
"version": "1.5.1",
@ -13385,6 +13464,11 @@
"strict-uri-encode": "^1.0.0"
}
},
"querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -13738,8 +13822,7 @@
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resize-observer-polyfill": {
"version": "1.5.1",
@ -16458,6 +16541,15 @@
"integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=",
"dev": true
},
"url-parse": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"url-parse-lax": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",

1
vben271/package.json

@ -33,6 +33,7 @@
"gen:icon": "esno ./build/generate/icon/index.ts"
},
"dependencies": {
"@microsoft/signalr": "^5.0.8",
"@iconify/iconify": "^2.0.3",
"@logicflow/core": "^0.6.9",
"@logicflow/extension": "^0.6.9",

2
vben271/src/components/Table/src/hooks/useColumns.ts

@ -65,7 +65,7 @@ function handleIndexColumn(
columns.unshift({
flag: INDEX_COLUMN_FLAG,
width: 50,
width: 70,
title: t('component.table.index'),
align: 'center',
customRender: ({ index }) => {

26
vue3/src/hooks/web/useSignalR.ts → vben271/src/hooks/web/useSignalR.ts

@ -1,19 +1,20 @@
import * as signalR from "@microsoft/signalr";
import * as signalR from '@microsoft/signalr';
import { useMessage } from '/@/hooks/web/useMessage';
import { useUserStoreWithOut } from '/@/store/modules/user';
export function useSignalR() {
/**
* SignalR
*/
function startConnect(): void {
let connection = connectionsignalR()
let connection = connectionsignalR();
//接收普通文本消息
connection.on("ReceiveTextMessageAsync", ReceiveTextMessageHandlerAsync);
connection.on('ReceiveTextMessageAsync', ReceiveTextMessageHandlerAsync);
//接收广播消息
connection.on("ReceiveBroadCastMessageAsync", ReceiveBroadCastMessageHandlerAsync);
connection.on('ReceiveBroadCastMessageAsync', ReceiveBroadCastMessageHandlerAsync);
//开始连接
connection.start().catch((err) => { console.error('SignalR连接失败:' + err) });
connection.start().catch((err) => {
console.error('SignalR连接失败:' + err);
});
// 当连接关闭时,尝试重新连接
connection.onclose(() => {
try {
@ -24,7 +25,7 @@ export function useSignalR() {
connection = connectionsignalR();
}, 5000);
}
})
});
}
/**
@ -33,8 +34,11 @@ export function useSignalR() {
function connectionsignalR(): signalR.HubConnection {
const userStore = useUserStoreWithOut();
const token = userStore.getToken;
const url = import.meta.env.VITE_API_URL as string + '/signalr/notification';
const connection = new signalR.HubConnectionBuilder().withUrl(url, { accessTokenFactory: () => token }).withAutomaticReconnect([1000, 3000, 5000, 8000, 10000, 15000]).build();
const url = (import.meta.env.VITE_API_URL as string) + '/signalr/notification';
const connection = new signalR.HubConnectionBuilder()
.withUrl(url, { accessTokenFactory: () => token })
.withAutomaticReconnect([1000, 3000, 5000, 8000, 10000, 15000])
.build();
return connection;
}
@ -53,7 +57,6 @@ export function useSignalR() {
});
}
/**
* 广
* @param message
@ -65,8 +68,7 @@ export function useSignalR() {
message: message.title,
description: message.content,
});
}
return { startConnect }
return { startConnect };
}

130
vben271/src/layouts/default/header/components/notify/NoticeList.vue

@ -1,50 +1,37 @@
<template>
<a-list :class="prefixCls" bordered :pagination="getPagination">
<template v-for="item in getData" :key="item.id">
<a-list :class="prefixCls" bordered>
<template v-for="item in list" :key="item.id">
<a-list-item class="list-item">
<a-list-item-meta>
<template #title>
<div class="title">
<a-typography-paragraph
@click="handleTitleClick(item)"
style="width: 100%; margin-bottom: 0 !important"
:style="{ cursor: isTitleClickable ? 'pointer' : '' }"
:delete="!!item.titleDelete"
:ellipsis="
$props.titleRows && $props.titleRows > 0
? { rows: $props.titleRows, tooltip: !!item.title }
: false
"
:ellipsis="titleRows > 0 ? { rows: titleRows, tooltip: item.title } : false"
:content="item.title"
/>
<div class="extra" v-if="item.extra">
<a-tag class="tag" :color="item.color">
{{ item.extra }}
<div>
<a-tag class="tag" :color="item.read ? 'green' : 'red'">
{{ item.read ? '已读' : '未读' }}
</a-tag>
<a-tag v-if="!item.read" class="tag" color="green" @click="onSetRead(item)">
{{ '标记为已读' }}
</a-tag>
</div>
</div>
</template>
<template #avatar>
<a-avatar v-if="item.avatar" class="avatar" :src="item.avatar" />
<span v-else> {{ item.avatar }}</span>
</template>
<template #description>
<div>
<div class="description" v-if="item.description">
<div class="description">
<a-typography-paragraph
style="width: 100%; margin-bottom: 0 !important"
:ellipsis="
$props.descRows && $props.descRows > 0
? { rows: $props.descRows, tooltip: !!item.description }
: false
"
:content="item.description"
:ellipsis="descRows > 0 ? { rows: descRows, tooltip: item.content } : false"
:content="item.content"
/>
</div>
<div class="datetime">
{{ item.datetime }}
{{ dateFormat(item.creationTime) }}
</div>
</div>
</template>
@ -54,14 +41,14 @@
</a-list>
</template>
<script lang="ts">
import { computed, defineComponent, PropType, ref, watch, unref } from 'vue';
import { ListItem } from './data';
import { defineComponent, PropType } from 'vue';
import { setReadAsync } from './data';
import { useDesign } from '/@/hooks/web/useDesign';
import { List, Avatar, Tag, Typography } from 'ant-design-vue';
import { isNumber } from '/@/utils/is';
import { List, Tag, Typography } from 'ant-design-vue';
import { PagingNotificationListOutput, SetReadInput } from '/@/services/ServiceProxies';
import { useUserStoreWithOut } from '/@/store/modules/user';
export default defineComponent({
components: {
[Avatar.name]: Avatar,
[List.name]: List,
[List.Item.name]: List.Item,
AListItemMeta: List.Item.Meta,
@ -70,69 +57,43 @@
},
props: {
list: {
type: Array as PropType<ListItem[]>,
type: Array as PropType<PagingNotificationListOutput[]>,
default: () => [],
},
pageSize: {
type: [Boolean, Number] as PropType<Boolean | Number>,
default: 5,
},
currentPage: {
type: Number,
default: 1,
},
titleRows: {
type: Number,
default: 1,
},
descRows: {
type: Number,
default: 2,
},
onTitleClick: {
type: Function as PropType<(Recordable) => void>,
default: 1,
},
},
emits: ['update:currentPage'],
setup(props, { emit }) {
const { prefixCls } = useDesign('header-notify-list');
const current = ref(props.currentPage || 1);
const getData = computed(() => {
const { pageSize, list } = props;
if (pageSize === false) return [];
let size = isNumber(pageSize) ? pageSize : 5;
return list.slice(size * (unref(current) - 1), size * unref(current));
});
watch(
() => props.currentPage,
(v) => {
current.value = v;
}
);
const isTitleClickable = computed(() => !!props.onTitleClick);
const getPagination = computed(() => {
const { list, pageSize } = props;
if (pageSize > 0 && list && list.length > pageSize) {
return {
total: list.length,
pageSize,
//size: 'small',
current: unref(current),
onChange(page) {
current.value = page;
emit('update:currentPage', page);
},
};
} else {
return false;
}
});
setup() {
const userStore = useUserStoreWithOut();
const userInfo = userStore.getUserInfo;
function handleTitleClick(item: ListItem) {
props.onTitleClick && props.onTitleClick(item);
}
return { prefixCls, getPagination, getData, handleTitleClick, isTitleClickable };
const onSetRead = async (record: PagingNotificationListOutput) => {
let request = new SetReadInput();
request.id = record.id;
request.receiveId = userInfo.userId as string;
await setReadAsync(request);
record.read = true;
console.log(record);
};
const dateFormat = (time) => {
let date = new Date(time);
let year = date.getFullYear();
let month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
let day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
let minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
let seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
//
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
};
const { prefixCls } = useDesign('header-notify-list');
return { prefixCls, dateFormat, onSetRead };
},
});
</script>
@ -165,10 +126,9 @@
font-weight: normal;
.tag {
margin-right: 0;
font-weight: normal;
}
}
.avatar {
margin-top: 4px;
}

193
vben271/src/layouts/default/header/components/notify/data.ts

@ -1,3 +1,9 @@
import {
NotificationServiceProxy,
PagingNotificationListOutput,
PagingNotificationListInput,
PagingNotificationListOutputPagedResultDto,
} from '/@/services/ServiceProxies';
export interface ListItem {
id: string;
avatar: string;
@ -17,177 +23,38 @@ export interface ListItem {
export interface TabItem {
key: string;
name: string;
list: ListItem[];
list?: PagingNotificationListOutput[];
unreadlist?: ListItem[];
}
export const tabListData: TabItem[] = [
{
key: '1',
name: '通知',
list: [
{
id: '000000001',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
title: '你收到了 14 份新周报',
description: '',
datetime: '2017-08-09',
type: '1',
},
{
id: '000000002',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
title: '你推荐的 曲妮妮 已通过第三轮面试',
description: '',
datetime: '2017-08-08',
type: '1',
},
{
id: '000000003',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
title: '这种模板可以区分多种通知类型',
description: '',
datetime: '2017-08-07',
// read: true,
type: '1',
},
{
id: '000000004',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
description: '',
datetime: '2017-08-07',
type: '1',
},
{
id: '000000005',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title:
'标题可以设置自动显示省略号,本例中标题行数已设为1行,如果内容超过1行将自动截断并支持tooltip显示完整标题。',
description: '',
datetime: '2017-08-07',
type: '1',
},
{
id: '000000006',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
description: '',
datetime: '2017-08-07',
type: '1',
},
{
id: '000000007',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
description: '',
datetime: '2017-08-07',
type: '1',
},
{
id: '000000008',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
description: '',
datetime: '2017-08-07',
type: '1',
},
{
id: '000000009',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
description: '',
datetime: '2017-08-07',
type: '1',
},
{
id: '000000010',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
title: '左侧图标用于区分不同的类型',
description: '',
datetime: '2017-08-07',
type: '1',
},
],
},
{
key: '2',
name: '消息',
list: [
{
id: '000000006',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
title: '曲丽丽 评论了你',
description: '描述信息描述信息描述信息',
datetime: '2017-08-07',
type: '2',
clickClose: true,
},
{
id: '000000007',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
title: '朱偏右 回复了你',
description: '这种模板用于提醒谁与你发生了互动',
datetime: '2017-08-07',
type: '2',
clickClose: true,
},
{
id: '000000008',
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
title: '标题',
description:
'请将鼠标移动到此处,以便测试超长的消息在此处将如何处理。本例中设置的描述最大行数为2,超过2行的描述内容将被省略并且可以通过tooltip查看完整内容',
datetime: '2017-08-07',
type: '2',
clickClose: true,
},
],
list: [],
},
{
key: '3',
name: '待办',
list: [
{
id: '000000009',
avatar: '',
title: '任务名称',
description: '任务需要在 2017-01-12 20:00 前启动',
datetime: '',
extra: '未开始',
color: '',
type: '3',
},
{
id: '000000010',
avatar: '',
title: '第三方紧急代码变更',
description: '冠霖 需在 2017-01-07 前完成代码变更任务',
datetime: '',
extra: '马上到期',
color: 'red',
type: '3',
},
{
id: '000000011',
avatar: '',
title: '信息安全考试',
description: '指派竹尔于 2017-01-09 前完成更新并发布',
datetime: '',
extra: '已耗时 8 天',
color: 'gold',
type: '3',
},
{
id: '000000012',
avatar: '',
title: 'ABCD 版本发布',
description: '指派竹尔于 2017-01-09 前完成更新并发布',
datetime: '',
extra: '进行中',
color: 'blue',
type: '3',
},
],
key: '2',
name: '通知',
list: [],
},
];
export async function getTextAsync(): Promise<PagingNotificationListOutputPagedResultDto> {
let request = new PagingNotificationListInput();
request.pageSize = 5;
const _notificationServiceProxy = new NotificationServiceProxy();
return await _notificationServiceProxy.text(request);
}
export async function getBroadCastAsync(): Promise<PagingNotificationListOutputPagedResultDto> {
let request = new PagingNotificationListInput();
request.pageSize = 5;
const _notificationServiceProxy = new NotificationServiceProxy();
return await _notificationServiceProxy.broadCast(request);
}
export async function setReadAsync(request) {
const _notificationServiceProxy = new NotificationServiceProxy();
await _notificationServiceProxy.read(request);
}

45
vben271/src/layouts/default/header/components/notify/index.vue

@ -1,7 +1,7 @@
<template>
<div :class="prefixCls">
<Popover title="" trigger="click" :overlayClassName="`${prefixCls}__overlay`">
<Badge :count="count" dot :numberStyle="numberStyle">
<Badge dot :numberStyle="numberStyle">
<BellOutlined />
</Badge>
<template #content>
@ -10,10 +10,9 @@
<TabPane>
<template #tab>
{{ item.name }}
<span v-if="item.list.length !== 0">({{ item.list.length }})</span>
</template>
<!-- 绑定title-click事件的通知列表中标题是可点击-->
<NoticeList :list="item.list" v-if="item.key === '1'" @title-click="onNoticeClick" />
<NoticeList :list="item.list" v-if="item.key === '1'" />
<NoticeList :list="item.list" v-else />
</TabPane>
</template>
@ -23,40 +22,32 @@
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import { defineComponent, computed } from 'vue';
import { Popover, Tabs, Badge } from 'ant-design-vue';
import { BellOutlined } from '@ant-design/icons-vue';
import { tabListData, ListItem } from './data';
import { PagingNotificationListOutput } from '/@/services/ServiceProxies';
import { tabListData } from './data';
import NoticeList from './NoticeList.vue';
import { useDesign } from '/@/hooks/web/useDesign';
import { useMessage } from '/@/hooks/web/useMessage';
import { string } from 'vue-types';
export default defineComponent({
components: { Popover, BellOutlined, Tabs, TabPane: Tabs.TabPane, Badge, NoticeList },
setup() {
props: {
textMessage: Array as PropType<PagingNotificationListOutput[]>,
broadCastMessage: Array as PropType<PagingNotificationListOutput[]>,
ff: string,
},
setup(props) {
const { prefixCls } = useDesign('header-notify');
const { createMessage } = useMessage();
const listData = ref(tabListData);
const count = computed(() => {
let count = 0;
for (let i = 0; i < tabListData.length; i++) {
count += tabListData[i].list.length;
}
return count;
const listData = computed(() => {
tabListData[0].list = props.textMessage;
tabListData[1].list = props.broadCastMessage;
return tabListData;
});
function onNoticeClick(record: ListItem) {
createMessage.success('你点击了通知,ID=' + record.id);
// 线,线
record.titleDelete = !record.titleDelete;
}
return {
prefixCls,
listData,
count,
onNoticeClick,
numberStyle: {},
};
},
@ -69,11 +60,11 @@
padding-top: 2px;
&__overlay {
max-width: 360px;
width: 320px;
}
.ant-tabs-content {
width: 300px;
width: 320px;
}
.ant-badge {

40
vben271/src/layouts/default/header/index.vue

@ -33,11 +33,14 @@
<!-- action -->
<div :class="`${prefixCls}-action`">
<AppSearch :class="`${prefixCls}-action__item `" v-if="getShowSearch" />
<ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" />
<Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" />
<Notify
:class="`${prefixCls}-action__item notify-item`"
:textMessage="textMessage"
:broadCastMessage="broadCastMessage"
@click="clickNotify"
/>
<FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" />
@ -55,7 +58,7 @@
</Header>
</template>
<script lang="ts">
import { defineComponent, unref, computed } from 'vue';
import { defineComponent, unref, computed, onMounted, reactive, toRefs } from 'vue';
import { propTypes } from '/@/utils/propTypes';
@ -80,7 +83,12 @@
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
import { useLocale } from '/@/locales/useLocale';
import { useSignalR } from '/@/hooks/web/useSignalR';
import { PagingNotificationListOutput } from '/@/services/ServiceProxies';
import {
getTextAsync,
getBroadCastAsync,
} from '/@/layouts/default/header/components/notify/data';
export default defineComponent({
name: 'LayoutHeader',
components: {
@ -169,7 +177,25 @@
const getMenuMode = computed(() => {
return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
});
const { startConnect } = useSignalR();
onMounted(() => {
startConnect();
});
let textMessage: PagingNotificationListOutput[] = [];
let broadCastMessage: PagingNotificationListOutput[] = [];
const notifiData = reactive({
textMessage,
broadCastMessage,
});
const clickNotify = async () => {
notifiData.textMessage = (await (
await getTextAsync()
).items) as PagingNotificationListOutput[];
notifiData.broadCastMessage = (await (
await getBroadCastAsync()
).items) as PagingNotificationListOutput[];
console.log(notifiData);
};
return {
prefixCls,
getHeaderClass,
@ -192,6 +218,8 @@
getShowSettingButton,
getShowSetting,
getShowSearch,
clickNotify,
...toRefs(notifiData),
};
},
});

17
vben271/src/locales/lang/en/common.ts

@ -8,13 +8,24 @@ export default {
resetText: 'Reset',
searchText: 'Search',
queryText: 'Search',
editText: 'Edit',
inputText: 'Please enter',
chooseText: 'Please choose',
redo: 'Refresh',
back: 'Back',
light: 'Light',
dark: 'Dark',
enabled: 'Enabled',
disEnabled: 'DisEnabled',
locked: 'Locked',
unLocked: 'UnLocked',
createText: 'Create',
tip: 'Tip',
askDelete: 'Are you sure you want to delete',
operationSuccess: 'Operation Success',
disEnabledSelf: "You can't disable yourself",
true: 'True',
false: 'False',
key: 'Key',
action: 'Action',
};

67
vben271/src/locales/lang/en/routes/admin.ts

@ -2,42 +2,49 @@ export default {
systemManagement: 'SystemManagement',
userManagement: 'UserManagement',
roleManagement: 'RoleManagement',
audit: 'Audit',
dictionary: 'Dictionary',
operationLog:'OperationLog',
sequenceManagement: 'SequenceManagement',
userManagement_userName: 'UserName',
userManagement_name: "Name",
userManagement_email: "Email",
userManagement_phone: "phone",
userManagement_createTime: "CreateTime",
userManagement_name: 'Name',
userManagement_email: 'Email',
userManagement_phone: 'phone',
userManagement_createTime: 'CreateTime',
userManagement_create_user: 'Create User',
userManagement_password: "Password",
userManagement_edit_user: 'Edit User',
userManagement_password: 'Password',
userManagement_comfirm_password: 'Password(Confirm)',
userManagement_userInfo: 'UserInfo',
userManagement_role: 'Role',
userManagement_roleName: 'RoleName',
roleManagement_name: "Name",
roleManagement_default: "Default",
roleManagement_edit: "Edit Role",
roleManagement_create_role: "Create Role",
roleManagement_permission: "Permission",
userManagement_locked: "Locked",
roleManagement_name: 'Name',
roleManagement_default: 'Default',
roleManagement_edit: 'Edit Role',
roleManagement_create_role: 'Create Role',
roleManagement_permission: 'Permission',
userManagement_locked: 'Locked',
audit_executeTime: "ExecutionTime",
audit_endTime: "EndTime",
audit_userName: "UserName",
audit_httpMethod: "HttpMethod",
audit_httpStatusCode: "HttpStatusCode",
audit_httpRequest: "HttpRequest",
audit_ipAdrress: "IP Address",
audit_time: "Time",
audit_duration: "Execution Duration(ms)",
audit_url: "URL",
audit_entityInfo: "EntityInformation",
audit_message: "Message",
audit_applicationName: "ApplicationName",
grantedMessage: "Authorization Successful, Please Login Again.",
close: "close"
audit_executeTime: 'ExecutionTime',
audit_endTime: 'EndTime',
audit_userName: 'UserName',
audit_httpMethod: 'HttpMethod',
audit_httpStatusCode: 'HttpStatusCode',
audit_httpRequest: 'HttpRequest',
audit_ipAdrress: 'IP Address',
audit_time: 'Time',
audit_duration: 'Execution Duration(ms)',
audit_url: 'URL',
audit_entityInfo: 'EntityInformation',
audit_message: 'Message',
audit_applicationName: 'ApplicationName',
grantedMessage: 'Authorization Successful, Please Login Again.',
close: 'close',
auditLog: 'AuditLog',
backgroundTask: 'BackgroundTask',
integratedEvent: 'IntegratedEvent',
tenant: 'Tenant',
identityServer: 'IdentityServer',
client: 'Client',
apiResource: 'ApiResource',
apiSocpe: 'ApiSocpe',
identityResource: 'IdentityResource',
};

10
vben271/src/locales/lang/zh-CN/common.ts

@ -9,7 +9,6 @@ export default {
searchText: '搜索',
editText: '编辑',
queryText: '查询',
createText: '新增',
inputText: '请输入',
chooseText: '请选择',
action: '操作',
@ -23,4 +22,13 @@ export default {
operationFail: '操作失败',
authorityText: '登陆过期',
systemErrorText: '系统异常',
enabled: '启用',
disEnabled: '禁用',
locked: '已锁定',
unLocked: '未锁定',
createText: '新增',
tip: '提示',
askDelete: '确认删除吗',
disEnabledSelf: '不能禁用自己',
key: '关键字',
};

16
vben271/src/locales/lang/zh-CN/routes/admin.ts

@ -2,10 +2,6 @@ export default {
systemManagement: '系统管理',
userManagement: '用户管理',
roleManagement: '角色管理',
audit: '审计日志',
dictionary: '字典',
operationLog: '操作日志',
sequenceManagement: '有序规则',
userManagement_userName: '账户',
userManagement_name: '用户姓名',
@ -13,7 +9,9 @@ export default {
userManagement_phone: '手机号码',
userManagement_createTime: '创建时间',
userManagement_password: '密码',
userManagement_comfirm_password: '密码(再次确认)',
userManagement_create_user: '新增用户',
userManagement_edit_user: '编辑用户',
userManagement_userInfo: '用户信息',
userManagement_role: '角色',
userManagement_roleName: '角色名称',
@ -38,4 +36,14 @@ export default {
audit_applicationName: '应用名称',
grantedMessage: '授权成功,请重新登录.',
close: '关闭',
auditLog: '审计日志',
backgroundTask: '后台任务',
integratedEvent: '集成事件',
tenant: '租户',
identityServer: '身份认证中心',
client: '客户端',
apiResource: 'Api资源',
apiSocpe: 'ApiSocpe',
identityResource: 'Identity资源',
};

25
vben271/src/router/routes/modules/admin.ts

@ -23,7 +23,7 @@ const admin: AppRouteModule = {
component: () => import('/@/views/admin/users/AbpUser.vue'),
meta: {
title: t('routes.admin.userManagement'),
policy: 'AbpIdentity.Users.Query',
policy: 'AbpIdentity.Users',
icon: 'ant-design:skin-outlined',
},
},
@ -33,7 +33,7 @@ const admin: AppRouteModule = {
component: () => import('/@/views/admin/roles/AbpRole.vue'),
meta: {
title: t('routes.admin.roleManagement'),
//policy: 'AbpIdentity.Roles.Query',
policy: 'AbpIdentity.Roles',
icon: 'ant-design:lock-outlined',
},
},
@ -42,22 +42,33 @@ const admin: AppRouteModule = {
name: 'AuditLogs',
component: () => import('/@/views/admin/auditLog/AuditLog.vue'),
meta: {
title: '审计日志',
//policy: 'AbpIdentity.Roles.Query',
title: t('routes.admin.auditLog'),
policy: 'System.AuditLog',
icon: 'ant-design:snippets-twotone',
},
},
{
path: 'hangfire',
name: '后台任务',
name: 'Hangfire',
component: IFrame,
meta: {
frameSrc: import.meta.env.VITE_API_URL + '/hangfire?access_token=' + token,
title: '后台任务',
//policy: 'AbpIdentity.Hangfire.Dashboard',
title: t('routes.admin.backgroundTask'),
policy: 'System.Hangfire',
icon: 'ant-design:clock-circle-outlined',
},
},
{
path: 'cap',
name: 'Cap',
component: IFrame,
meta: {
frameSrc: import.meta.env.VITE_API_URL + '/cap?access_token=' + token,
title: t('routes.admin.integratedEvent'),
policy: 'System.Cap',
icon: 'ant-design:sync-outlined',
},
},
],
};

24
vben271/src/router/routes/modules/identityServer.ts

@ -1,6 +1,6 @@
import type { AppRouteModule } from '/@/router/types';
import { LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const identityServer: AppRouteModule = {
path: '/identityServer',
name: 'IentityServer',
@ -9,7 +9,7 @@ const identityServer: AppRouteModule = {
meta: {
orderNo: 30,
icon: 'ion:grid-outline',
title: 'IdentityServer',
title: t('routes.admin.identityServer'),
},
children: [
{
@ -17,8 +17,9 @@ const identityServer: AppRouteModule = {
name: 'Clients',
component: () => import('/@/views/identityServers/clients/Clients.vue'),
meta: {
title: 'Clients',
icon: 'ant-design:skin-outlined',
title: t('routes.admin.client'),
icon: 'ant-design:copyright-circle-outlined',
policy: 'IdentityServerManagement.Client',
},
},
{
@ -26,8 +27,9 @@ const identityServer: AppRouteModule = {
name: 'ApiResources',
component: () => import('/@/views/identityServers/apiResources/ApiResources.vue'),
meta: {
title: 'ApiResources',
icon: 'ant-design:skin-outlined',
title: t('routes.admin.apiResource'),
icon: 'ant-design:euro-outlined',
policy: 'IdentityServerManagement.ApiResource',
},
},
{
@ -35,8 +37,9 @@ const identityServer: AppRouteModule = {
name: 'ApiScopes',
component: () => import('/@/views/identityServers/apiScopes/ApiScopes.vue'),
meta: {
title: 'ApiScopes',
icon: 'ant-design:skin-outlined',
title: t('routes.admin.apiSocpe'),
icon: 'ant-design:compass-outlined',
policy: 'IdentityServerManagement.ApiScope',
},
},
{
@ -44,8 +47,9 @@ const identityServer: AppRouteModule = {
name: 'IdentityResources',
component: () => import('/@/views/identityServers/identityResources/IdentityResources.vue'),
meta: {
title: 'IdentityResources',
icon: 'ant-design:skin-outlined',
title: t('routes.admin.identityResource'),
icon: 'ant-design:usergroup-delete-outlined',
policy: 'IdentityServerManagement.IdentityResources',
},
},
],

625
vben271/src/services/ServiceProxies.ts

@ -3315,6 +3315,386 @@ export class IdentityResourceServiceProxy extends ServiceProxyBase {
}
}
export class NotificationServiceProxy extends ServiceProxyBase {
private instance: AxiosInstance;
private baseUrl: string;
protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;
constructor(baseUrl?: string, instance?: AxiosInstance) {
super();
this.instance = instance ? instance : axios.create();
this.baseUrl = baseUrl !== undefined && baseUrl !== null ? baseUrl : "";
}
/**
*
* @param body (optional)
* @return Success
*/
text(body: PagingNotificationListInput | undefined , cancelToken?: CancelToken | undefined): Promise<PagingNotificationListOutputPagedResultDto> {
let url_ = this.baseUrl + "/Notification/Text";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_ = <AxiosRequestConfig>{
data: content_,
method: "POST",
url: url_,
headers: {
"Content-Type": "application/json",
"Accept": "text/plain"
},
cancelToken
};
return this.transformOptions(options_).then(transformedOptions_ => {
return this.instance.request(transformedOptions_);
}).catch((_error: any) => {
if (isAxiosError(_error) && _error.response) {
return _error.response;
} else {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processText(_response));
});
}
protected processText(response: AxiosResponse): Promise<PagingNotificationListOutputPagedResultDto> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
for (let k in response.headers) {
if (response.headers.hasOwnProperty(k)) {
_headers[k] = response.headers[k];
}
}
}
if (status === 200) {
const _responseText = response.data;
let result200: any = null;
let resultData200 = _responseText;
result200 = PagingNotificationListOutputPagedResultDto.fromJS(resultData200);
return result200;
} else if (status === 403) {
const _responseText = response.data;
let result403: any = null;
let resultData403 = _responseText;
result403 = RemoteServiceErrorResponse.fromJS(resultData403);
return throwException("Forbidden", status, _responseText, _headers, result403);
} else if (status === 401) {
const _responseText = response.data;
let result401: any = null;
let resultData401 = _responseText;
result401 = RemoteServiceErrorResponse.fromJS(resultData401);
return throwException("Unauthorized", status, _responseText, _headers, result401);
} else if (status === 400) {
const _responseText = response.data;
let result400: any = null;
let resultData400 = _responseText;
result400 = RemoteServiceErrorResponse.fromJS(resultData400);
return throwException("Bad Request", status, _responseText, _headers, result400);
} else if (status === 404) {
const _responseText = response.data;
let result404: any = null;
let resultData404 = _responseText;
result404 = RemoteServiceErrorResponse.fromJS(resultData404);
return throwException("Not Found", status, _responseText, _headers, result404);
} else if (status === 501) {
const _responseText = response.data;
let result501: any = null;
let resultData501 = _responseText;
result501 = RemoteServiceErrorResponse.fromJS(resultData501);
return throwException("Server Error", status, _responseText, _headers, result501);
} else if (status === 500) {
const _responseText = response.data;
let result500: any = null;
let resultData500 = _responseText;
result500 = RemoteServiceErrorResponse.fromJS(resultData500);
return throwException("Server Error", status, _responseText, _headers, result500);
} else if (status !== 200 && status !== 204) {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<PagingNotificationListOutputPagedResultDto>(<any>null);
}
/**
* 广
* @param body (optional)
* @return Success
*/
broadCast(body: PagingNotificationListInput | undefined , cancelToken?: CancelToken | undefined): Promise<PagingNotificationListOutputPagedResultDto> {
let url_ = this.baseUrl + "/Notification/BroadCast";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_ = <AxiosRequestConfig>{
data: content_,
method: "POST",
url: url_,
headers: {
"Content-Type": "application/json",
"Accept": "text/plain"
},
cancelToken
};
return this.transformOptions(options_).then(transformedOptions_ => {
return this.instance.request(transformedOptions_);
}).catch((_error: any) => {
if (isAxiosError(_error) && _error.response) {
return _error.response;
} else {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processBroadCast(_response));
});
}
protected processBroadCast(response: AxiosResponse): Promise<PagingNotificationListOutputPagedResultDto> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
for (let k in response.headers) {
if (response.headers.hasOwnProperty(k)) {
_headers[k] = response.headers[k];
}
}
}
if (status === 200) {
const _responseText = response.data;
let result200: any = null;
let resultData200 = _responseText;
result200 = PagingNotificationListOutputPagedResultDto.fromJS(resultData200);
return result200;
} else if (status === 403) {
const _responseText = response.data;
let result403: any = null;
let resultData403 = _responseText;
result403 = RemoteServiceErrorResponse.fromJS(resultData403);
return throwException("Forbidden", status, _responseText, _headers, result403);
} else if (status === 401) {
const _responseText = response.data;
let result401: any = null;
let resultData401 = _responseText;
result401 = RemoteServiceErrorResponse.fromJS(resultData401);
return throwException("Unauthorized", status, _responseText, _headers, result401);
} else if (status === 400) {
const _responseText = response.data;
let result400: any = null;
let resultData400 = _responseText;
result400 = RemoteServiceErrorResponse.fromJS(resultData400);
return throwException("Bad Request", status, _responseText, _headers, result400);
} else if (status === 404) {
const _responseText = response.data;
let result404: any = null;
let resultData404 = _responseText;
result404 = RemoteServiceErrorResponse.fromJS(resultData404);
return throwException("Not Found", status, _responseText, _headers, result404);
} else if (status === 501) {
const _responseText = response.data;
let result501: any = null;
let resultData501 = _responseText;
result501 = RemoteServiceErrorResponse.fromJS(resultData501);
return throwException("Server Error", status, _responseText, _headers, result501);
} else if (status === 500) {
const _responseText = response.data;
let result500: any = null;
let resultData500 = _responseText;
result500 = RemoteServiceErrorResponse.fromJS(resultData500);
return throwException("Server Error", status, _responseText, _headers, result500);
} else if (status !== 200 && status !== 204) {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<PagingNotificationListOutputPagedResultDto>(<any>null);
}
/**
*
* @param body (optional)
* @return Success
*/
read(body: SetReadInput | undefined , cancelToken?: CancelToken | undefined): Promise<void> {
let url_ = this.baseUrl + "/Notification/Read";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_ = <AxiosRequestConfig>{
data: content_,
method: "POST",
url: url_,
headers: {
"Content-Type": "application/json",
},
cancelToken
};
return this.transformOptions(options_).then(transformedOptions_ => {
return this.instance.request(transformedOptions_);
}).catch((_error: any) => {
if (isAxiosError(_error) && _error.response) {
return _error.response;
} else {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processRead(_response));
});
}
protected processRead(response: AxiosResponse): Promise<void> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
for (let k in response.headers) {
if (response.headers.hasOwnProperty(k)) {
_headers[k] = response.headers[k];
}
}
}
if (status === 200) {
const _responseText = response.data;
return Promise.resolve<void>(<any>null);
} else if (status === 403) {
const _responseText = response.data;
let result403: any = null;
let resultData403 = _responseText;
result403 = RemoteServiceErrorResponse.fromJS(resultData403);
return throwException("Forbidden", status, _responseText, _headers, result403);
} else if (status === 401) {
const _responseText = response.data;
let result401: any = null;
let resultData401 = _responseText;
result401 = RemoteServiceErrorResponse.fromJS(resultData401);
return throwException("Unauthorized", status, _responseText, _headers, result401);
} else if (status === 400) {
const _responseText = response.data;
let result400: any = null;
let resultData400 = _responseText;
result400 = RemoteServiceErrorResponse.fromJS(resultData400);
return throwException("Bad Request", status, _responseText, _headers, result400);
} else if (status === 404) {
const _responseText = response.data;
let result404: any = null;
let resultData404 = _responseText;
result404 = RemoteServiceErrorResponse.fromJS(resultData404);
return throwException("Not Found", status, _responseText, _headers, result404);
} else if (status === 501) {
const _responseText = response.data;
let result501: any = null;
let resultData501 = _responseText;
result501 = RemoteServiceErrorResponse.fromJS(resultData501);
return throwException("Server Error", status, _responseText, _headers, result501);
} else if (status === 500) {
const _responseText = response.data;
let result500: any = null;
let resultData500 = _responseText;
result500 = RemoteServiceErrorResponse.fromJS(resultData500);
return throwException("Server Error", status, _responseText, _headers, result500);
} else if (status !== 200 && status !== 204) {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<void>(<any>null);
}
/**
* -使
* @param body (optional)
* @return Success
*/
create(body: CreateNotificationInput | undefined , cancelToken?: CancelToken | undefined): Promise<void> {
let url_ = this.baseUrl + "/Notification/Create";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_ = <AxiosRequestConfig>{
data: content_,
method: "POST",
url: url_,
headers: {
"Content-Type": "application/json",
},
cancelToken
};
return this.transformOptions(options_).then(transformedOptions_ => {
return this.instance.request(transformedOptions_);
}).catch((_error: any) => {
if (isAxiosError(_error) && _error.response) {
return _error.response;
} else {
throw _error;
}
}).then((_response: AxiosResponse) => {
return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processCreate(_response));
});
}
protected processCreate(response: AxiosResponse): Promise<void> {
const status = response.status;
let _headers: any = {};
if (response.headers && typeof response.headers === "object") {
for (let k in response.headers) {
if (response.headers.hasOwnProperty(k)) {
_headers[k] = response.headers[k];
}
}
}
if (status === 200) {
const _responseText = response.data;
return Promise.resolve<void>(<any>null);
} else if (status === 403) {
const _responseText = response.data;
let result403: any = null;
let resultData403 = _responseText;
result403 = RemoteServiceErrorResponse.fromJS(resultData403);
return throwException("Forbidden", status, _responseText, _headers, result403);
} else if (status === 401) {
const _responseText = response.data;
let result401: any = null;
let resultData401 = _responseText;
result401 = RemoteServiceErrorResponse.fromJS(resultData401);
return throwException("Unauthorized", status, _responseText, _headers, result401);
} else if (status === 400) {
const _responseText = response.data;
let result400: any = null;
let resultData400 = _responseText;
result400 = RemoteServiceErrorResponse.fromJS(resultData400);
return throwException("Bad Request", status, _responseText, _headers, result400);
} else if (status === 404) {
const _responseText = response.data;
let result404: any = null;
let resultData404 = _responseText;
result404 = RemoteServiceErrorResponse.fromJS(resultData404);
return throwException("Not Found", status, _responseText, _headers, result404);
} else if (status === 501) {
const _responseText = response.data;
let result501: any = null;
let resultData501 = _responseText;
result501 = RemoteServiceErrorResponse.fromJS(resultData501);
return throwException("Server Error", status, _responseText, _headers, result501);
} else if (status === 500) {
const _responseText = response.data;
let result500: any = null;
let resultData500 = _responseText;
result500 = RemoteServiceErrorResponse.fromJS(resultData500);
return throwException("Server Error", status, _responseText, _headers, result500);
} else if (status !== 200 && status !== 204) {
const _responseText = response.data;
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}
return Promise.resolve<void>(<any>null);
}
}
export class PermissionsServiceProxy extends ServiceProxyBase {
private instance: AxiosInstance;
private baseUrl: string;
@ -6650,6 +7030,62 @@ export interface ICreateIdentityResourceInput {
showInDiscoveryDocument: boolean;
}
export class CreateNotificationInput implements ICreateNotificationInput {
title!: string | undefined;
content!: string | undefined;
messageType!: MessageType;
receiveIds!: string[] | undefined;
constructor(data?: ICreateNotificationInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.title = _data["title"];
this.content = _data["content"];
this.messageType = _data["messageType"];
if (Array.isArray(_data["receiveIds"])) {
this.receiveIds = [] as any;
for (let item of _data["receiveIds"])
this.receiveIds!.push(item);
}
}
}
static fromJS(data: any): CreateNotificationInput {
data = typeof data === 'object' ? data : {};
let result = new CreateNotificationInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["title"] = this.title;
data["content"] = this.content;
data["messageType"] = this.messageType;
if (Array.isArray(this.receiveIds)) {
data["receiveIds"] = [];
for (let item of this.receiveIds)
data["receiveIds"].push(item);
}
return data;
}
}
export interface ICreateNotificationInput {
title: string | undefined;
content: string | undefined;
messageType: MessageType;
receiveIds: string[] | undefined;
}
export class CurrentCultureDto implements ICurrentCultureDto {
displayName!: string | undefined;
englishName!: string | undefined;
@ -9293,6 +9729,11 @@ export enum LoginResultType {
RequiresTwoFactor = 5,
}
export enum MessageType {
BroadCast = 10,
Text = 20,
}
export class MethodParameterApiDescriptionModel implements IMethodParameterApiDescriptionModel {
name!: string | undefined;
typeAsString!: string | undefined;
@ -10769,6 +11210,150 @@ export interface IPagingIdentityResourceListOutputPagedResultDto {
totalCount: number;
}
export class PagingNotificationListInput implements IPagingNotificationListInput {
pageIndex!: number;
pageSize!: number;
readonly skipCount!: number;
constructor(data?: IPagingNotificationListInput) {
if (data) {
for (var property in data) {
if (data.hasOwnProperty(property))
(<any>this)[property] = (<any>data)[property];
}
}
}
init(_data?: any) {
if (_data) {
this.pageIndex = _data["pageIndex"];
this.pageSize = _data["pageSize"];
(<any>this).skipCount = _data["skipCount"];
}
}
static fromJS(data: any): PagingNotificationListInput {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationListInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["pageIndex"] = this.pageIndex;
data["pageSize"] = this.pageSize;
data["skipCount"] = this.skipCount;
return data;
}
}
export interface IPagingNotificationListInput {
pageIndex: number;
pageSize: number;
skipCount: number;
}
export class PagingNotificationListOutput implements IPagingNotificationListOutput {
id!: string;
title!: string | undefined;
content!: string | undefined;
creationTime!: moment.Moment;
read!: boolean;
constructor(data?: IPagingNotificationListOutput) {
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.title = _data["title"];
this.content = _data["content"];
this.creationTime = _data["creationTime"] ? moment(_data["creationTime"].toString()) : <any>undefined;
this.read = _data["read"];
}
}
static fromJS(data: any): PagingNotificationListOutput {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationListOutput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["title"] = this.title;
data["content"] = this.content;
data["creationTime"] = this.creationTime ? this.creationTime.toISOString() : <any>undefined;
data["read"] = this.read;
return data;
}
}
export interface IPagingNotificationListOutput {
id: string;
title: string | undefined;
content: string | undefined;
creationTime: moment.Moment;
read: boolean;
}
export class PagingNotificationListOutputPagedResultDto implements IPagingNotificationListOutputPagedResultDto {
items!: PagingNotificationListOutput[] | undefined;
totalCount!: number;
constructor(data?: IPagingNotificationListOutputPagedResultDto) {
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(PagingNotificationListOutput.fromJS(item));
}
this.totalCount = _data["totalCount"];
}
}
static fromJS(data: any): PagingNotificationListOutputPagedResultDto {
data = typeof data === 'object' ? data : {};
let result = new PagingNotificationListOutputPagedResultDto();
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 IPagingNotificationListOutputPagedResultDto {
items: PagingNotificationListOutput[] | undefined;
totalCount: number;
}
export class PagingRoleListInput implements IPagingRoleListInput {
pageIndex!: number;
pageSize!: number;
@ -11869,6 +12454,46 @@ export interface ISetDataDictinaryDetailInput {
isEnabled: boolean;
}
export class SetReadInput implements ISetReadInput {
id!: string;
receiveId!: string;
constructor(data?: ISetReadInput) {
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.receiveId = _data["receiveId"];
}
}
static fromJS(data: any): SetReadInput {
data = typeof data === 'object' ? data : {};
let result = new SetReadInput();
result.init(data);
return result;
}
toJSON(data?: any) {
data = typeof data === 'object' ? data : {};
data["id"] = this.id;
data["receiveId"] = this.receiveId;
return data;
}
}
export interface ISetReadInput {
id: string;
receiveId: string;
}
export class StringStringFromSelector implements IStringStringFromSelector {
readonly value!: string | undefined;
readonly label!: string | undefined;

4
vben271/src/services/ServiceProxyBase.ts

@ -5,6 +5,7 @@ import { router } from '/@/router';
import { PageEnum } from '/@/enums/pageEnum';
import { useI18n } from '/@/hooks/web/useI18n';
import { Modal } from 'ant-design-vue';
import { useLocale } from '/@/locales/useLocale';
export class ServiceProxyBase {
protected transformOptions(options: AxiosRequestConfig) {
options.baseURL = import.meta.env.VITE_API_URL as string;
@ -56,7 +57,8 @@ export class ServiceProxyBase {
private buildRequestMessage(): any {
const userStore = useUserStoreWithOut();
const token = userStore.getToken;
const language = userStore.getLanguage == undefined ? 'zh-Hans' : userStore.getLanguage;
const { getLocale } = useLocale();
const language = getLocale.value == 'en' ? getLocale.value : 'zh-Hans';
return {
token,
language,

8
vben271/src/views/admin/auditLog/AuditLog.ts

@ -7,14 +7,14 @@ import { AuditLogsServiceProxy, PagingAuditLogListInput } from '/@/services/Serv
export const searchFormSchema: FormSchema[] = [
{
field: 'userName',
label: '用户',
label: t('routes.admin.userManagement_userName'),
component: 'Input',
colProps: { span: 8 },
},
{
field: 'time',
component: 'RangePicker',
label: '执行时间',
label: t('routes.admin.audit_executeTime'),
colProps: {
span: 6,
},
@ -23,12 +23,12 @@ export const searchFormSchema: FormSchema[] = [
export const tableColumns: BasicColumn[] = [
{
title: '租户',
title: t('routes.admin.tenant'),
dataIndex: 'tenantName',
width: 100,
},
{
title: '用户',
title: t('routes.admin.userManagement_userName'),
dataIndex: 'userName',
width: 100,
},

54
vben271/src/views/admin/roles/AbpRole.vue

@ -8,31 +8,62 @@
</template>
<template #toolbar>
<a-button type="primary" @click="openCreateAbpRoleModal">
<a-button
type="primary"
@click="openCreateAbpRoleModal"
v-auth="'AbpIdentity.Roles.Create'"
>
{{ t('common.createText') }}
</a-button>
</template>
<template #action="{ record }">
<a-button type="link" size="small" @click="handlePermission(record)">
<a-button
type="link"
size="small"
@click="handlePermission(record)"
v-auth="'AbpIdentity.Roles.ManagePermissions'"
>
{{ t('routes.admin.roleManagement_permission') }}
</a-button>
<a-button type="link" size="small" @click="handleEdit(record)">
<a-button
type="link"
size="small"
@click="handleEdit(record)"
v-auth="'AbpIdentity.Roles.Update'"
>
{{ t('common.editText') }}
</a-button>
<a-button type="link" size="small" @click="handleDelete(record)">
<a-button
type="link"
size="small"
@click="handleDelete(record)"
v-auth="'AbpIdentity.Roles.Delete'"
>
{{ t('common.delText') }}
</a-button>
</template>
</BasicTable>
<CreateAbpRole @register="registerCreateAbpRoleModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<CreateAbpRole
@register="registerCreateAbpRoleModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
<PermissionAbpRole @register="registerPermissionAbpRoleModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<PermissionAbpRole
@register="registerPermissionAbpRoleModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
<EditAbpRole @register="registerEditAbpRoleModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<EditAbpRole
@register="registerEditAbpRoleModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
</div>
</template>
@ -61,7 +92,8 @@
setup() {
const { createConfirm } = useMessage();
const { t } = useI18n();
const [registerPermissionAbpRoleModal, { openDrawer: openPermissionAbpRoleDrawer }] = useDrawer();
const [registerPermissionAbpRoleModal, { openDrawer: openPermissionAbpRoleDrawer }] =
useDrawer();
const [registerCreateAbpRoleModal, { openModal: openCreateAbpRoleModal }] = useModal();
@ -81,7 +113,7 @@
canResize: true,
showIndexColumn: true,
actionColumn: {
width: 150,
width: 200,
title: t('common.action'),
dataIndex: 'action',
slots: {
@ -107,10 +139,10 @@
//
const handleDelete = async (record: Recordable) => {
let msg = '是否确认删除';
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: '提示',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleleRoleAsync({ roleId: record.id, reload });

32
vben271/src/views/admin/roles/PermissionAbpRole.vue

@ -1,6 +1,16 @@
<template>
<BasicDrawer @register="registerDrawer" :title="t('routes.admin.roleManagement_permission')" width="20%">
<BasicTree :treeData="allPermissionsRef" checkable ref="treeRef" style="margin-bottom: 50px" />
<BasicDrawer
@register="registerDrawer"
:title="t('routes.admin.roleManagement_permission')"
width="20%"
>
<BasicTree
:treeData="allPermissionsRef"
checkable
checkStrictly
ref="treeRef"
style="margin-bottom: 50px"
/>
<div
:style="{
position: 'absolute',
@ -14,7 +24,9 @@
zIndex: 1,
}"
>
<a-button :style="{ marginRight: '8px' }" @click="closeDrawer">{{ t('common.cancelText') }} </a-button>
<a-button :style="{ marginRight: '8px' }" @click="closeDrawer"
>{{ t('common.cancelText') }}
</a-button>
<a-button type="primary" @click="submitRolePermisstionAsync">
{{ t('common.saveText') }}
</a-button>
@ -29,7 +41,11 @@
import { useI18n } from '/@/hooks/web/useI18n';
import { BasicTree, TreeActionType } from '/@/components/Tree/index';
import { useUserStoreWithOut } from '/@/store/modules/user';
import { UpdateRolePermissionsInput, UpdatePermissionDto, UpdatePermissionsDto } from '/@/services/ServiceProxies';
import {
UpdateRolePermissionsInput,
UpdatePermissionDto,
UpdatePermissionsDto,
} from '/@/services/ServiceProxies';
import { message } from 'ant-design-vue';
export default defineComponent({
name: 'PermissionAbpRole',
@ -75,10 +91,10 @@
let permisstions: UpdatePermissionDto[] = [];
request.providerName = 'R';
request.providerKey = roleName;
const keys = toRaw(getTree().getCheckedKeys()) as [];
const { checked } = toRaw(getTree().getCheckedKeys()) as [];
debugger;
const noSelectedPermissions = totalRolePermissionsRef.filter((e) => {
return !(keys.indexOf(e) > -1);
return !(checked.indexOf(e) > -1);
});
noSelectedPermissions.forEach((item: string) => {
if (item.includes('.')) {
@ -88,7 +104,7 @@
permisstions.push(permisstion);
}
});
keys.forEach((item: string) => {
checked.forEach((item: string) => {
if (item.includes('.')) {
let permisstion = new UpdatePermissionDto();
permisstion.name = item;

68
vben271/src/views/admin/users/AbpUser.ts

@ -21,11 +21,11 @@ const [openFullLoading, closeFullLoading] = useLoading({
export const tableColumns: BasicColumn[] = [
{
title: t('routes.admin.userManagement_name'),
title: t('routes.admin.userManagement_userName'),
dataIndex: 'name',
},
{
title: t('routes.admin.userManagement_userName'),
title: t('routes.admin.userManagement_name'),
dataIndex: 'userName',
},
{
@ -63,8 +63,8 @@ export const createFormSchema: FormSchema[] = [
{
field: 'userName',
component: 'Input',
label: '账户',
labelWidth: 70,
label: t('routes.admin.userManagement_userName'),
labelWidth: 85,
required: true,
colProps: {
span: 12,
@ -76,8 +76,8 @@ export const createFormSchema: FormSchema[] = [
{
field: 'name',
component: 'Input',
label: '用户姓名',
labelWidth: 110,
label: t('routes.admin.roleManagement_name'),
labelWidth: 130,
required: true,
colProps: {
span: 12,
@ -91,7 +91,7 @@ export const createFormSchema: FormSchema[] = [
component: 'Input',
label: t('routes.admin.userManagement_email'),
required: true,
labelWidth: 70,
labelWidth: 85,
colProps: {
span: 12,
},
@ -99,9 +99,9 @@ export const createFormSchema: FormSchema[] = [
{
field: 'phoneNumber',
component: 'Input',
label: '手机号码',
label: t('routes.admin.userManagement_phone'),
required: false,
labelWidth: 110,
labelWidth: 130,
colProps: {
span: 12,
},
@ -110,8 +110,8 @@ export const createFormSchema: FormSchema[] = [
field: 'password',
component: 'InputPassword',
label: t('routes.admin.userManagement_password'),
required: false,
labelWidth: 70,
required: true,
labelWidth: 85,
colProps: {
span: 12,
},
@ -125,9 +125,9 @@ export const createFormSchema: FormSchema[] = [
componentProps: {
autocomplete: 'off',
},
label: '密码(再次确认)',
required: false,
labelWidth: 110,
label: t('routes.admin.userManagement_comfirm_password'),
required: true,
labelWidth: 130,
colProps: {
span: 12,
},
@ -138,8 +138,8 @@ export const editFormSchema: FormSchema[] = [
{
field: 'userName',
component: 'Input',
label: '账户',
labelWidth: 70,
label: t('routes.admin.roleManagement_name'),
labelWidth: 85,
required: true,
colProps: {
span: 12,
@ -152,8 +152,8 @@ export const editFormSchema: FormSchema[] = [
{
field: 'name',
component: 'Input',
label: '用户姓名',
labelWidth: 110,
label: t('routes.admin.roleManagement_name'),
labelWidth: 130,
required: true,
colProps: {
span: 12,
@ -164,7 +164,7 @@ export const editFormSchema: FormSchema[] = [
component: 'Input',
label: t('routes.admin.userManagement_email'),
required: true,
labelWidth: 70,
labelWidth: 85,
colProps: {
span: 12,
},
@ -172,9 +172,9 @@ export const editFormSchema: FormSchema[] = [
{
field: 'phoneNumber',
component: 'Input',
label: '手机号码',
label: t('routes.admin.userManagement_phone'),
required: false,
labelWidth: 110,
labelWidth: 130,
colProps: {
span: 12,
},
@ -184,7 +184,7 @@ export const editFormSchema: FormSchema[] = [
component: 'InputPassword',
label: t('routes.admin.userManagement_password'),
required: false,
labelWidth: 70,
labelWidth: 85,
colProps: {
span: 12,
},
@ -192,9 +192,9 @@ export const editFormSchema: FormSchema[] = [
{
field: 'confirmPassword',
component: 'InputPassword',
label: '密码(再次确认)',
label: t('routes.admin.userManagement_comfirm_password'),
required: false,
labelWidth: 110,
labelWidth: 130,
colProps: {
span: 12,
},
@ -206,7 +206,9 @@ export const editFormSchema: FormSchema[] = [
* @param params
* @returns
*/
export async function getTableListAsync(params: PagingUserListInput): Promise<IdentityUserDtoPagedResultDto> {
export async function getTableListAsync(
params: PagingUserListInput
): Promise<IdentityUserDtoPagedResultDto> {
const _userServiceProxy = new UsersServiceProxy();
return _userServiceProxy.page(params);
}
@ -236,7 +238,13 @@ export async function getAllRoleAsync(): Promise<IdentityRoleDtoListResultDto> {
*
* @param param0
*/
export async function createUserAsync({ request, changeOkLoading, validate, closeModal, resetFields }) {
export async function createUserAsync({
request,
changeOkLoading,
validate,
closeModal,
resetFields,
}) {
changeOkLoading(true);
await validate();
if (request.password != request.confirmPassword) {
@ -274,7 +282,13 @@ export async function deleteUserAsync({ userId, reload }) {
*
* @param param0
*/
export async function updateUserAsync({ request, changeOkLoading, validate, closeModal, resetFields }) {
export async function updateUserAsync({
request,
changeOkLoading,
validate,
closeModal,
resetFields,
}) {
changeOkLoading(true);
await validate();

67
vben271/src/views/admin/users/AbpUser.vue

@ -2,31 +2,62 @@
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button type="primary" @click="openCreateAbpUserModal">
<a-button
type="primary"
@click="openCreateAbpUserModal"
v-auth="'AbpIdentity.Users.Create'"
>
{{ t('common.createText') }}
</a-button>
</template>
<template #lockoutEnabled="{ record }">
<Tag :color="record.lockoutEnabled ? 'red' : 'green'">
{{ record.lockoutEnabled ? '已锁定' : '未锁定' }}
{{ record.lockoutEnabled ? t('common.locked') : t('common.unLocked') }}
</Tag>
</template>
<template #action="{ record }">
<a-button type="link" size="small" @click="handleEdit(record)">
<a-button
type="link"
size="small"
@click="handleEdit(record)"
v-auth="'AbpIdentity.Users.Update'"
>
{{ t('common.editText') }}
</a-button>
<a-button type="link" size="small" @click="handleDelete(record)">
<a-button
type="link"
size="small"
@click="handleDelete(record)"
v-auth="'AbpIdentity.Users.Delete'"
>
{{ t('common.delText') }}
</a-button>
<a-button type="link" size="small" @click="handleLock(record)">
{{ record.lockoutEnabled ? '启用' : '禁用' }}
<a-button
type="link"
size="small"
@click="handleLock(record)"
v-auth="'System.Users.Enable'"
>
{{ record.lockoutEnabled ? t('common.enabled') : t('common.disEnabled') }}
</a-button>
</template>
</BasicTable>
<CreateAbpUser @register="registerCreateAbpUserModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<EditAbpUser @register="registerEditAbpUserModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<Warehouse @register="registerWarehosueModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<CreateAbpUser
@register="registerCreateAbpUserModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
<EditAbpUser
@register="registerEditAbpUserModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
<Warehouse
@register="registerWarehosueModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
</div>
</template>
@ -34,7 +65,13 @@
import { defineComponent } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { tableColumns, searchFormSchema, getTableListAsync, deleteUserAsync, lockUserAsync } from './AbpUser';
import {
tableColumns,
searchFormSchema,
getTableListAsync,
deleteUserAsync,
lockUserAsync,
} from './AbpUser';
import { useModal } from '/@/components/Modal';
import CreateAbpUser from './CreateAbpUser.vue';
import EditAbpUser from './EditAbpUser.vue';
@ -99,10 +136,10 @@
message.error('admin not delete');
return;
} else {
let msg = '是否确认删除';
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: '提示',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteUserAsync({ userId: record.id, reload });
@ -115,8 +152,8 @@
if (!record.lockoutEnabled && currentUserId === record.id) {
createConfirm({
iconType: 'warning',
title: '提示',
content: '当前用户本身不能禁用自己',
title: t('common.tip'),
content: t('common.disEnabledSelf'),
});
return;
}
@ -124,7 +161,7 @@
request.userId = record.id;
request.locked = !record.lockoutEnabled;
await lockUserAsync(request);
message.success('操作成功');
message.success(t('common.operationSuccess'));
reload();
};
return {

17
vben271/src/views/admin/users/EditAbpUser.vue

@ -1,6 +1,6 @@
<template>
<BasicModal
title="编辑用户"
:title="t('routes.admin.userManagement_edit_user')"
:width="600"
:canFullscreen="false"
@ok="submit"
@ -13,10 +13,10 @@
>
<div>
<Tabs>
<TabPane tab="用户信息" key="1">
<TabPane :tab="t('routes.admin.userManagement_userInfo')" key="1">
<BasicForm @register="registerUserForm" />
</TabPane>
<TabPane tab="角色" key="2">
<TabPane :tab="t('routes.admin.userManagement_role')" key="2">
<a-checkbox-group v-model:value="defaultRolesRef">
<a-row justify="center">
<a-col :span="24">
@ -54,6 +54,7 @@
IdentityUserUpdateDto,
} from '/@/services/ServiceProxies';
import { message } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: 'EditAbpUser',
components: {
@ -71,6 +72,7 @@
showActionButtonGroup: false,
}
);
const { t } = useI18n();
let currentUserInfo = new IdentityUserDto();
const [registerModal, { changeOkLoading, closeModal }] = useModalInner((data) => {
currentUserInfo = data.record;
@ -103,14 +105,6 @@
}
};
// //
// const onRoleSelectedChange = (value: string[]) => {
// defaultRolesRef.splice(0, defaultRolesRef.length);
// value.forEach((e) => {
// defaultRolesRef.push(e);
// });
// };
const submit = async () => {
try {
let request = getFieldsValue();
@ -159,6 +153,7 @@
visibleChange,
defaultRolesRef,
cancel,
t,
};
},
});

38
vben271/src/views/identityServers/apiResources/ApiResources.ts

@ -13,7 +13,7 @@ import {
export const searchFormSchema: FormSchema[] = [
{
field: 'filter',
label: '关键字',
label: t('common.key'),
component: 'Input',
colProps: { span: 8 },
},
@ -21,24 +21,24 @@ export const searchFormSchema: FormSchema[] = [
export const tableColumns: BasicColumn[] = [
{
title: 'name',
title: 'Name',
dataIndex: 'name',
},
{
title: 'displayName',
title: 'DisplayName',
dataIndex: 'displayName',
},
{
title: '是否启用',
title: t('common.enabled'),
dataIndex: 'enabled',
slots: { customRender: 'enabled' },
},
{
title: 'description',
title: 'Description',
dataIndex: 'description',
},
{
title: 'showInDiscoveryDocument',
title: 'ShowInDiscoveryDocument',
dataIndex: 'showInDiscoveryDocument',
slots: { customRender: 'showInDiscoveryDocument' },
},
@ -47,7 +47,7 @@ export const tableColumns: BasicColumn[] = [
export const createFormSchema: FormSchema[] = [
{
field: 'name',
label: 'name',
label: 'Name',
component: 'Input',
required: true,
labelWidth: 200,
@ -55,7 +55,7 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'displayName',
label: 'displayName',
label: 'DisplayName',
component: 'Input',
required: true,
labelWidth: 200,
@ -63,7 +63,7 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'secret',
label: 'secret',
label: 'Secret',
component: 'Input',
required: true,
labelWidth: 200,
@ -71,21 +71,21 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'description',
label: 'description',
label: 'Description',
component: 'Input',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'showInDiscoveryDocument',
label: 'showInDiscoveryDocument',
label: 'ShowInDiscoveryDocument',
labelWidth: 200,
component: 'Switch',
colProps: { span: 20 },
@ -101,7 +101,7 @@ export const createFormSchema: FormSchema[] = [
export const editFormSchema: FormSchema[] = [
{
field: 'name',
label: 'name',
label: 'Name',
component: 'Input',
required: true,
labelWidth: 200,
@ -109,7 +109,7 @@ export const editFormSchema: FormSchema[] = [
},
{
field: 'displayName',
label: 'displayName',
label: 'DisplayName',
component: 'Input',
required: true,
labelWidth: 200,
@ -117,29 +117,29 @@ export const editFormSchema: FormSchema[] = [
},
{
field: 'secret',
label: 'secret',
label: 'Secret',
component: 'InputPassword',
required: true,
required: false,
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'description',
label: 'description',
label: 'Description',
component: 'Input',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'showInDiscoveryDocument',
label: 'showInDiscoveryDocument',
label: 'ShowInDiscoveryDocument',
labelWidth: 200,
component: 'Switch',
colProps: { span: 20 },

29
vben271/src/views/identityServers/apiResources/ApiResources.vue

@ -2,26 +2,40 @@
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button type="primary" @click="openCreateApiResourceModal">
<a-button
type="primary"
@click="openCreateApiResourceModal"
v-auth="'IdentityServerManagement.ApiResource.Create'"
>
{{ t('common.createText') }}
</a-button>
</template>
<template #enabled="{ record }">
<Tag :color="record.enabled ? 'green' : 'red'">
{{ record.enabled ? '是' : '否' }}
{{ record.enabled ? t('common.enabled') : t('common.disEnabled') }}
</Tag>
</template>
<template #showInDiscoveryDocument="{ record }">
<Tag :color="record.showInDiscoveryDocument ? 'green' : 'red'">
{{ record.showInDiscoveryDocument ? '是' : '否' }}
{{ record.showInDiscoveryDocument ? t('common.enabled') : t('common.disEnabled') }}
</Tag>
</template>
<template #action="{ record }">
<a-button type="link" size="small" @click="handleEdit(record)">
<a-button
type="link"
size="small"
@click="handleEdit(record)"
v-auth="'IdentityServerManagement.ApiResource.Update'"
>
{{ t('common.editText') }}
</a-button>
<a-button type="link" size="small" @click="handleDelete(record)">
<a-button
type="link"
size="small"
@click="handleDelete(record)"
v-auth="'IdentityServerManagement.ApiResource.Delete'"
>
{{ t('common.delText') }}
</a-button>
</template>
@ -91,11 +105,10 @@
useModal();
const [registerEditApiResourceModal, { openModal: openEditApiResourceModal }] = useModal();
const handleDelete = async (record: Recordable) => {
debugger;
let msg = '是否确认删除';
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: '提示',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteApiResourceAsync({ id: record.id, reload });

6
vben271/src/views/identityServers/apiResources/CreateApiResource.vue

@ -1,6 +1,6 @@
<template>
<BasicModal
title="创建ApiResource"
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@ -25,10 +25,6 @@
},
emits: ['reload'],
setup(_, { emit }) {
//
// defineEmit(['reload']);
// const ctx = useContext();
const { t } = useI18n();
const [registerApiResourceForm, { getFieldsValue, validate, resetFields }] = useForm({
labelWidth: 120,

10
vben271/src/views/identityServers/apiResources/EditApiResources.vue

@ -1,6 +1,6 @@
<template>
<BasicModal
title="编辑ApiResources"
:title="t('common.editText')"
:width="700"
:canFullscreen="false"
@ok="submit"
@ -10,7 +10,7 @@
>
<div>
<Tabs>
<TabPane tab="基本信息" key="1">
<TabPane tab="Basic" key="1">
<BasicForm @register="registerBasicInfoForm" />
</TabPane>
<TabPane tab="ApiScopes" key="2">
@ -40,6 +40,7 @@
import { Tabs } from 'ant-design-vue';
import { editFormSchema, getAllApiScopeAsync, updateApiResourceAsync } from './ApiResources';
import { StringStringFromSelector } from '/@/services/ServiceProxies';
import { useI18n } from '/@/hooks/web/useI18n';
export default defineComponent({
name: 'EditApiResources',
components: {
@ -50,6 +51,7 @@
},
emits: ['reload'],
setup(_, { emit }) {
const { t } = useI18n();
const [
registerBasicInfoForm,
{
@ -63,15 +65,12 @@
showActionButtonGroup: false,
});
let currentApiResuource: any;
let apiScopes: StringStringFromSelector[] = [];
const state = reactive({
defaultApiScope: [],
apiScopes,
});
const [registerModal, { changeOkLoading, closeModal }] = useModalInner(async (data) => {
currentApiResuource = data;
setBasicInfoFieldsValue({
name: data.record.name,
displayName: data.record.displayName,
@ -97,6 +96,7 @@
registerModal,
registerBasicInfoForm,
submit,
t,
...toRefs(state),
};
},

47
vben271/src/views/identityServers/apiScopes/ApiScopes.ts

@ -1,11 +1,12 @@
import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import { ApiScopeServiceProxy, PagingApiScopeListInput, IdInput } from '/@/services/ServiceProxies';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export const searchFormSchema: FormSchema[] = [
{
field: 'filter',
label: '关键字',
label: t('common.key'),
component: 'Input',
colProps: { span: 8 },
},
@ -13,34 +14,34 @@ export const searchFormSchema: FormSchema[] = [
export const tableColumns: BasicColumn[] = [
{
title: 'name',
title: 'Name',
dataIndex: 'name',
},
{
title: 'displayName',
title: 'DisplayName',
dataIndex: 'displayName',
},
{
title: '是否启用',
title: t('common.enabled'),
dataIndex: 'enabled',
slots: { customRender: 'enabled' },
},
{
title: 'description',
title: 'Description',
dataIndex: 'description',
},
{
title: 'required',
title: 'Required',
dataIndex: 'required',
slots: { customRender: 'required' },
},
{
title: 'emphasize',
title: 'Emphasize',
dataIndex: 'emphasize',
slots: { customRender: 'emphasize' },
},
{
title: 'showInDiscoveryDocument',
title: 'ShowInDiscoveryDocument',
dataIndex: 'showInDiscoveryDocument',
slots: { customRender: 'showInDiscoveryDocument' },
},
@ -49,7 +50,7 @@ export const tableColumns: BasicColumn[] = [
export const createFormSchema: FormSchema[] = [
{
field: 'name',
label: 'name',
label: 'Name',
component: 'Input',
required: true,
labelWidth: 200,
@ -57,7 +58,7 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'displayName',
label: 'displayName',
label: 'DisplayName',
component: 'Input',
required: true,
labelWidth: 200,
@ -65,35 +66,35 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'description',
label: 'description',
label: 'Description',
component: 'Input',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'required',
label: 'required',
label: 'Required',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'emphasize',
label: 'emphasize',
label: 'Emphasize',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'showInDiscoveryDocument',
label: 'showInDiscoveryDocument',
label: 'ShowInDiscoveryDocument',
labelWidth: 200,
component: 'Switch',
colProps: { span: 20 },
@ -102,7 +103,7 @@ export const createFormSchema: FormSchema[] = [
export const editFormSchema: FormSchema[] = [
{
field: 'name',
label: 'name',
label: 'Name',
component: 'Input',
required: true,
labelWidth: 200,
@ -113,7 +114,7 @@ export const editFormSchema: FormSchema[] = [
},
{
field: 'displayName',
label: 'displayName',
label: 'DisplayName',
component: 'Input',
required: true,
labelWidth: 200,
@ -121,35 +122,35 @@ export const editFormSchema: FormSchema[] = [
},
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'description',
label: 'description',
label: 'Description',
component: 'Input',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'required',
label: 'required',
label: 'Required',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'emphasize',
label: 'emphasize',
label: 'Emphasize',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'showInDiscoveryDocument',
label: 'showInDiscoveryDocument',
label: 'ShowInDiscoveryDocument',
labelWidth: 200,
component: 'Switch',
colProps: { span: 20 },

49
vben271/src/views/identityServers/apiScopes/ApiScopes.vue

@ -2,49 +2,74 @@
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button type="primary" @click="openCreateApiScopeModal">
<a-button
type="primary"
@click="openCreateApiScopeModal"
v-auth="'IdentityServerManagement.ApiScope.Create'"
>
{{ t('common.createText') }}
</a-button>
</template>
<template #enabled="{ record }">
<Tag :color="record.enabled ? 'green' : 'red'">
{{ record.enabled ? '是' : '否' }}
{{ record.enabled ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #required="{ record }">
<Tag :color="record.required ? 'green' : 'red'">
{{ record.required ? '是' : '否' }}
{{ record.required ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #emphasize="{ record }">
<Tag :color="record.emphasize ? 'green' : 'red'">
{{ record.emphasize ? '是' : '否' }}
{{ record.emphasize ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #showInDiscoveryDocument="{ record }">
<Tag :color="record.showInDiscoveryDocument ? 'green' : 'red'">
{{ record.showInDiscoveryDocument ? '是' : '否' }}
{{ record.showInDiscoveryDocument ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #action="{ record }">
<a-button type="link" size="small" @click="handleEdit(record)">
<a-button
type="link"
size="small"
@click="handleEdit(record)"
v-auth="'IdentityServerManagement.ApiScope.Update'"
>
{{ t('common.editText') }}
</a-button>
<a-button type="link" size="small" @click="handleDelete(record)">
<a-button
type="link"
size="small"
@click="handleDelete(record)"
v-auth="'IdentityServerManagement.ApiScope.Delete'"
>
{{ t('common.delText') }}
</a-button>
</template>
</BasicTable>
<CreateApiScope @register="registerCreateApiScopeModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<EditApiScope @register="registerEditApiScopeModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }"
<CreateApiScope
@register="registerCreateApiScopeModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }" />
<EditApiScope
@register="registerEditApiScopeModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/></div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { tableColumns, searchFormSchema, getTableListAsync, deleteApiScopeAsync } from './ApiScopes';
import {
tableColumns,
searchFormSchema,
getTableListAsync,
deleteApiScopeAsync,
} from './ApiScopes';
import { useI18n } from '/@/hooks/web/useI18n';
import { Tag } from 'ant-design-vue';
import CreateApiScope from './CreateApiScope.vue';
@ -92,10 +117,10 @@
openEditApiScopeModal(true, { record: record });
};
const handleDelete = (record: Recordable) => {
let msg = '是否确认删除';
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: '提示',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteApiScopeAsync({ id: record.id, reload });

14
vben271/src/views/identityServers/apiScopes/CreateApiScope.vue

@ -1,11 +1,17 @@
<template>
<BasicModal title="创建ApiScope" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal">
<BasicModal
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerModal"
>
<BasicForm @register="registerApiScopeForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, useContext, defineEmit } from 'vue';
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createFormSchema, createApiScopeAsync } from './ApiScopes';
@ -19,10 +25,6 @@
},
emits: ['reload'],
setup(_, { emit }) {
//
// defineEmit(['reload']);
// const ctx = useContext();
const { t } = useI18n();
const [registerApiScopeForm, { getFieldsValue, validate, resetFields }] = useForm({
labelWidth: 120,

26
vben271/src/views/identityServers/apiScopes/EditApiScope.vue

@ -1,11 +1,17 @@
<template>
<BasicModal title="创建ApiScope" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal">
<BasicModal
:title="t('common.editText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerModal"
>
<BasicForm @register="registerApiScopeForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, useContext, defineEmit } from 'vue';
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { editFormSchema, editApiScopeAsync } from './ApiScopes';
@ -19,19 +25,15 @@
},
emits: ['reload'],
setup(_, { emit }) {
//
// defineEmit(['reload']);
// const ctx = useContext();
const { t } = useI18n();
const [registerApiScopeForm, { getFieldsValue, validate, resetFields, setFieldsValue }] = useForm({
labelWidth: 120,
schemas: editFormSchema,
showActionButtonGroup: false,
});
const [registerApiScopeForm, { getFieldsValue, validate, resetFields, setFieldsValue }] =
useForm({
labelWidth: 120,
schemas: editFormSchema,
showActionButtonGroup: false,
});
const [registerModal, { changeOkLoading, closeModal }] = useModalInner((data) => {
console.log(data.record);
setFieldsValue({
name: data.record.name,
enabled: data.record.enabled,

31
vben271/src/views/identityServers/clients/ClientUri.vue

@ -7,14 +7,14 @@
style="width: 470px"
v-model:value="redirectUriValue"
/>
<a-button type="primary" @click="handleAddRedirectUri" style="margin-bottom: 10px"
>新增</a-button
>
<a-button type="primary" @click="handleAddRedirectUri" style="margin-bottom: 10px">{{
t('common.createText')
}}</a-button>
<div v-for="item in currentClient.redirectUris">
<a-input placeholder="" style="width: 470px" :defaultValue="item.redirectUri" disabled />
<a-button type="primary" @click="handleRemoveRedirectUri(item.redirectUri)" danger
>删除</a-button
>
<a-button type="primary" @click="handleRemoveRedirectUri(item.redirectUri)" danger>{{
t('common.delText')
}}</a-button>
</div>
</TabPane>
<TabPane tab="LogoutRedirectUri" key="2" forceRender>
@ -23,9 +23,9 @@
style="width: 470px"
v-model:value="postLogoutRedirectUriValue"
/>
<a-button type="primary" @click="handleAddLogoutRedirectUri" style="margin-bottom: 10px"
>新增</a-button
>
<a-button type="primary" @click="handleAddLogoutRedirectUri" style="margin-bottom: 10px">{{
t('common.createText')
}}</a-button>
<div v-for="item in currentClient.postLogoutRedirectUris">
<a-input
placeholder=""
@ -37,16 +37,20 @@
type="primary"
@click="handleRemoveLogoutRedirectUri(item.postLogoutRedirectUris)"
danger
>删除</a-button
>{{ t('common.delText') }}</a-button
>
</div>
</TabPane>
<TabPane tab="CORS" key="3" forceRender>
<a-input placeholder="Please Enter Uri" style="width: 470px" v-model:value="originValue" />
<a-button type="primary" @click="handleAddCors" style="margin-bottom: 10px">新增</a-button>
<a-button type="primary" @click="handleAddCors" style="margin-bottom: 10px">{{
t('common.createText')
}}</a-button>
<div v-for="item in currentClient.allowedCorsOrigins">
<a-input placeholder="" style="width: 470px" :defaultValue="item.origin" disabled />
<a-button type="primary" @click="handleRemoveCors(item.origin)" danger>删除</a-button>
<a-button type="primary" @click="handleRemoveCors(item.origin)" danger>{{
t('common.delText')
}}</a-button>
</div>
</TabPane>
</Tabs>
@ -56,6 +60,7 @@
import { defineComponent, reactive, toRefs } from 'vue';
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
import { Tabs } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import {
addRedirectUriAsync,
removeRedirectUriAsync,
@ -70,6 +75,7 @@
components: { BasicDrawer, Tabs, TabPane: Tabs.TabPane },
emits: ['reload'],
setup(_, { emit }) {
const { t } = useI18n();
let currentClient: PagingClientListOutput = new PagingClientListOutput();
const state = reactive({
redirectUriValue: '',
@ -149,6 +155,7 @@
handleAddCors,
handleRemoveCors,
...toRefs(state),
t,
};
},
});

40
vben271/src/views/identityServers/clients/Clients.ts

@ -17,7 +17,7 @@ import {
export const searchFormSchema: FormSchema[] = [
{
field: 'filter',
label: '关键字',
label: t('common.key'),
component: 'Input',
colProps: { span: 8 },
},
@ -33,7 +33,7 @@ export const tableColumns: BasicColumn[] = [
dataIndex: 'clientName',
},
{
title: '是否启用',
title: t('common.enabled'),
dataIndex: 'enabled',
slots: { customRender: 'enabled' },
},
@ -134,28 +134,28 @@ export const editBasicDetailSchema: FormSchema[] = [
export const editBasicOptionSchema: FormSchema[] = [
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
labelWidth: 250,
component: 'Switch',
colProps: { span: 10 },
},
{
field: 'requireClientSecret',
label: 'requireClientSecret',
label: 'RequireClientSecret',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'requireConsent',
label: 'requireConsent',
label: 'RequireConsent',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'allowRememberConsent',
label: 'allowRememberConsent',
label: 'AllowRememberConsent',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
@ -163,42 +163,42 @@ export const editBasicOptionSchema: FormSchema[] = [
{
field: 'requirePkce',
label: 'requirePkce',
label: 'RequirePkce',
labelWidth: 250,
component: 'Switch',
colProps: { span: 10 },
},
{
field: 'allowOfflineAccess',
label: 'allowOfflineAccess',
label: 'AllowOfflineAccess',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'enableLocalLogin',
label: 'enableLocalLogin',
label: 'EnableLocalLogin',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'includeJwtId',
label: 'includeJwtId',
label: 'IncludeJwtId',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'allowAccessTokensViaBrowser',
label: 'allowAccessTokensViaBrowser',
label: 'AllowAccessTokensViaBrowser',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'alwaysIncludeUserClaimsInIdToken',
label: 'alwaysIncludeUserClaimsInIdToken',
label: 'AlwaysIncludeUserClaimsInIdToken',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
@ -206,14 +206,14 @@ export const editBasicOptionSchema: FormSchema[] = [
{
field: 'frontChannelLogoutSessionRequired',
label: 'frontChannelLogoutSessionRequired',
label: 'FrontChannelLogoutSessionRequired',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
},
{
field: 'backChannelLogoutSessionRequired',
label: 'backChannelLogoutSessionRequired',
label: 'BackChannelLogoutSessionRequired',
component: 'Switch',
labelWidth: 250,
colProps: { span: 10 },
@ -223,37 +223,37 @@ export const editBasicOptionSchema: FormSchema[] = [
export const editBasicTokenSchema: FormSchema[] = [
{
field: 'accessTokenLifetime',
label: 'accessTokenLifetime',
label: 'AccessTokenLifetime',
labelWidth: 200,
component: 'Input',
},
{
field: 'authorizationCodeLifetime',
label: 'authorizationCodeLifetime',
label: 'AuthorizationCodeLifetime',
labelWidth: 200,
component: 'Input',
},
{
field: 'absoluteRefreshTokenLifetime',
label: 'absoluteRefreshTokenLifetime',
label: 'AbsoluteRefreshTokenLifetime',
labelWidth: 200,
component: 'Input',
},
{
field: 'slidingRefreshTokenLifetime',
label: 'slidingRefreshTokenLifetime',
label: 'SlidingRefreshTokenLifetime',
labelWidth: 200,
component: 'Input',
},
{
field: 'refreshTokenExpiration',
label: 'refreshTokenExpiration',
label: 'RefreshTokenExpiration',
labelWidth: 200,
component: 'Input',
},
{
field: 'deviceCodeLifetime',
label: 'deviceCodeLifetime',
label: 'DeviceCodeLifetime',
labelWidth: 200,
component: 'Input',
},

44
vben271/src/views/identityServers/clients/Clients.vue

@ -2,26 +2,52 @@
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button type="primary" @click="openCreateClientModal">
<a-button
type="primary"
@click="openCreateClientModal"
v-auth="'IdentityServerManagement.Client.Create'"
>
{{ t('common.createText') }}
</a-button>
</template>
<template #enabled="{ record }">
<Tag :color="record.enabled ? 'green' : 'red'">
{{ record.enabled ? '是' : '否' }}
{{ record.enabled ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #action="{ record }">
<a-button type="link" size="small" @click="handleEdit(record)">
<a-button
type="link"
size="small"
@click="handleEdit(record)"
v-auth="'IdentityServerManagement.Client.Update'"
>
{{ t('common.editText') }}
</a-button>
<a-button type="link" size="small" @click="handleEnabled(record)">
{{ record.enabled ? '禁用' : '启用' }}
<a-button
type="link"
size="small"
@click="handleEnabled(record)"
v-auth="'IdentityServerManagement.Client.Enable'"
>
{{ record.enabled ? t('common.enabled') : t('common.disEnabled') }}
</a-button>
<a-button type="link" size="small" @click="handleUri(record)"> Uri </a-button>
<a-button type="link" size="small" @click="handleDelete(record)">
<a-button
type="link"
size="small"
@click="handleUri(record)"
v-auth="'IdentityServerManagement.Client.Update'"
>
Uri
</a-button>
<a-button
type="link"
size="small"
@click="handleDelete(record)"
v-auth="'IdentityServerManagement.Client.Delete'"
>
{{ t('common.delText') }}
</a-button>
</template>
@ -104,10 +130,10 @@
});
};
const handleDelete = (record: Recordable) => {
let msg = '是否确认删除';
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: '提示',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteClientAsync({ id: record.id, reload });

16
vben271/src/views/identityServers/clients/CreateClient.vue

@ -1,11 +1,17 @@
<template>
<BasicModal title="创建Client" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal">
<BasicModal
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerModal"
>
<BasicForm @register="registerClientForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, useContext, defineEmit } from 'vue';
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createFormSchema, createClientAsync } from './Clients';
@ -17,12 +23,8 @@
BasicModal,
BasicForm,
},
emits: ['reload'],
emits: ['reload'],
setup(_, { emit }) {
//
// defineEmit(['reload']);
// const ctx = useContext();
const { t } = useI18n();
const [registerClientForm, { getFieldsValue, validate, resetFields }] = useForm({
labelWidth: 120,

7
vben271/src/views/identityServers/clients/EditClientBasic.vue

@ -1,6 +1,6 @@
<template>
<BasicModal
title="编辑Client"
:title="t('common.editText')"
:width="700"
:canFullscreen="false"
@ok="submit"
@ -10,7 +10,7 @@
>
<div>
<Tabs>
<TabPane tab="基本信息" key="1">
<TabPane tab="Basic" key="1">
<BasicForm @register="registerDetailForm" />
</TabPane>
<TabPane tab="Options" key="2" forceRender>
@ -32,6 +32,7 @@
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { Tabs } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import {
editBasicDetailSchema,
editBasicOptionSchema,
@ -50,6 +51,7 @@
},
emits: ['reload'],
setup(_, { emit }) {
const { t } = useI18n();
const [
registerDetailForm,
{
@ -163,6 +165,7 @@
registerTokenForm,
registerSecretForm,
submit,
t,
};
},
});

10
vben271/src/views/identityServers/identityResources/CreateIdentityResource.vue

@ -1,11 +1,17 @@
<template>
<BasicModal title="创建IdentityResource" :canFullscreen="false" @ok="submit" @cancel="cancel" @register="registerModal">
<BasicModal
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"
@register="registerModal"
>
<BasicForm @register="registerApiScopeForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, useContext, defineEmit } from 'vue';
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { createFormSchema, createIdentityResourcesAsync } from './IdentityResources';

2
vben271/src/views/identityServers/identityResources/EditIdentityResources.vue

@ -1,6 +1,6 @@
<template>
<BasicModal
title="创建IdentityResource"
:title="t('common.editText')"
:canFullscreen="false"
@ok="submit"
@cancel="cancel"

42
vben271/src/views/identityServers/identityResources/IdentityResources.ts

@ -19,34 +19,34 @@ export const searchFormSchema: FormSchema[] = [
export const tableColumns: BasicColumn[] = [
{
title: 'name',
title: 'Name',
dataIndex: 'name',
},
{
title: 'displayName',
title: 'DisplayName',
dataIndex: 'displayName',
},
{
title: '是否启用',
title: t('common.enabled'),
dataIndex: 'enabled',
slots: { customRender: 'enabled' },
},
{
title: 'description',
title: 'Description',
dataIndex: 'description',
},
{
title: 'required',
title: 'Required',
dataIndex: 'required',
slots: { customRender: 'required' },
},
{
title: 'emphasize',
title: 'Emphasize',
dataIndex: 'emphasize',
slots: { customRender: 'emphasize' },
},
{
title: 'showInDiscoveryDocument',
title: 'ShowInDiscoveryDocument',
dataIndex: 'showInDiscoveryDocument',
slots: { customRender: 'showInDiscoveryDocument' },
},
@ -54,7 +54,7 @@ export const tableColumns: BasicColumn[] = [
export const createFormSchema: FormSchema[] = [
{
field: 'name',
label: 'name',
label: 'Name',
component: 'Input',
required: true,
labelWidth: 200,
@ -62,7 +62,7 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'displayName',
label: 'displayName',
label: 'DisplayName',
component: 'Input',
required: true,
labelWidth: 200,
@ -70,35 +70,35 @@ export const createFormSchema: FormSchema[] = [
},
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'description',
label: 'description',
label: 'Description',
component: 'Input',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'required',
label: 'required',
label: 'Required',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'emphasize',
label: 'emphasize',
label: 'Emphasize',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'showInDiscoveryDocument',
label: 'showInDiscoveryDocument',
label: 'ShowInDiscoveryDocument',
labelWidth: 200,
component: 'Switch',
colProps: { span: 20 },
@ -108,7 +108,7 @@ export const createFormSchema: FormSchema[] = [
export const editFormSchema: FormSchema[] = [
{
field: 'name',
label: 'name',
label: 'Name',
component: 'Input',
required: true,
labelWidth: 200,
@ -119,7 +119,7 @@ export const editFormSchema: FormSchema[] = [
},
{
field: 'displayName',
label: 'displayName',
label: 'DisplayName',
component: 'Input',
required: true,
labelWidth: 200,
@ -127,35 +127,35 @@ export const editFormSchema: FormSchema[] = [
},
{
field: 'enabled',
label: 'enabled',
label: 'Enabled',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'description',
label: 'description',
label: 'Description',
component: 'Input',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'required',
label: 'required',
label: 'Required',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'emphasize',
label: 'emphasize',
label: 'Emphasize',
component: 'Switch',
labelWidth: 200,
colProps: { span: 20 },
},
{
field: 'showInDiscoveryDocument',
label: 'showInDiscoveryDocument',
label: 'ShowInDiscoveryDocument',
labelWidth: 200,
component: 'Switch',
colProps: { span: 20 },

55
vben271/src/views/identityServers/identityResources/IdentityResources.vue

@ -2,49 +2,74 @@
<div>
<BasicTable @register="registerTable" size="small">
<template #toolbar>
<a-button type="primary" @click="openCreateIdentityResourcesModal">
<a-button
type="primary"
@click="openCreateIdentityResourcesModal"
v-auth="'IdentityServerManagement.IdentityResources.Create'"
>
{{ t('common.createText') }}
</a-button>
</template>
<template #enabled="{ record }">
<Tag :color="record.enabled ? 'green' : 'red'">
{{ record.enabled ? '是' : '否' }}
{{ record.enabled ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #required="{ record }">
<Tag :color="record.required ? 'green' : 'red'">
{{ record.required ? '是' : '否' }}
{{ record.required ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #emphasize="{ record }">
<Tag :color="record.emphasize ? 'green' : 'red'">
{{ record.emphasize ? '是' : '否' }}
{{ record.emphasize ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #showInDiscoveryDocument="{ record }">
<Tag :color="record.showInDiscoveryDocument ? 'green' : 'red'">
{{ record.showInDiscoveryDocument ? '是' : '否' }}
{{ record.showInDiscoveryDocument ? t('common.true') : t('common.false') }}
</Tag>
</template>
<template #action="{ record }">
<a-button type="link" size="small" @click="handleEdit(record)">
<a-button
type="link"
size="small"
@click="handleEdit(record)"
v-auth="'IdentityServerManagement.IdentityResources.Update'"
>
{{ t('common.editText') }}
</a-button>
<a-button type="link" size="small" @click="handleDelete(record)">
<a-button
type="link"
size="small"
@click="handleDelete(record)"
v-auth="'IdentityServerManagement.IdentityResources.Delete'"
>
{{ t('common.delText') }}
</a-button>
</template>
</BasicTable>
<CreateIdentityResource @register="registerCreatIdentityResourcesModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<EditIdentityResources @register="registerEditIdentityResourcesModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }"
<CreateIdentityResource
@register="registerCreatIdentityResourcesModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }" />
<EditIdentityResources
@register="registerEditIdentityResourcesModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/></div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { tableColumns, searchFormSchema, getTableListAsync, deleteIdentityResourcesAsync } from './IdentityResources';
import {
tableColumns,
searchFormSchema,
getTableListAsync,
deleteIdentityResourcesAsync,
} from './IdentityResources';
import { useI18n } from '/@/hooks/web/useI18n';
import { Tag } from 'ant-design-vue';
import CreateIdentityResource from './CreateIdentityResource.vue';
@ -86,16 +111,18 @@
fixed: 'right',
},
});
const [registerCreatIdentityResourcesModal, { openModal: openCreateIdentityResourcesModal }] = useModal();
const [registerEditIdentityResourcesModal, { openModal: openEditIdentityResourcesModal }] = useModal();
const [registerCreatIdentityResourcesModal, { openModal: openCreateIdentityResourcesModal }] =
useModal();
const [registerEditIdentityResourcesModal, { openModal: openEditIdentityResourcesModal }] =
useModal();
const handleEdit = (record: Recordable) => {
openEditIdentityResourcesModal(true, { record: record });
};
const handleDelete = (record: Recordable) => {
let msg = '是否确认删除';
let msg = t('common.askDelete');
createConfirm({
iconType: 'warning',
title: '提示',
title: t('common.tip'),
content: msg,
onOk: async () => {
await deleteIdentityResourcesAsync({ id: record.id, reload });

19
vue3/.editorconfig

@ -1,19 +0,0 @@
root = true
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=2
max_line_length = 100
[*.{yml,yaml,json}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab

9
vue3/.env

@ -1,9 +0,0 @@
# port
VITE_PORT = 4200
# spa-title
VITE_GLOB_APP_TITLE = Abp Vnext
# spa shortname
VITE_GLOB_APP_SHORT_NAME = Abp Vnext

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save