Browse Source

添加组织机构

pull/43/head
王军 4 years ago
parent
commit
99e9c01cda
  1. 20
      aspnet-core/Delete-BIN-OBJ-Folders.bat
  2. 66
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.Staging.json
  3. 3
      aspnet-core/services/host/Lion.AbpPro.HttpApi.Host/appsettings.json
  4. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/AddRoleToOrganizationUnitInput.cs
  5. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/AddUserToOrganizationUnitInput.cs
  6. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/CreateOrganizationUnitInput.cs
  7. 10
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitRoleInput.cs
  8. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitRoleOutput.cs
  9. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitUserInput.cs
  10. 13
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitUserOutput.cs
  11. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddRoleInput.cs
  12. 10
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddRoleOutput.cs
  13. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddUserInput.cs
  14. 12
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddUserOutput.cs
  15. 16
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/OrganizationUnitDto.cs
  16. 10
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/RemoveRoleToOrganizationUnitInput.cs
  17. 10
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/RemoveUserToOrganizationUnitInput.cs
  18. 13
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/TreeOutput.cs
  19. 11
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/UpdateOrganizationUnitInput.cs
  20. 73
      aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/IOrganizationUnitAppService.cs
  21. 6
      aspnet-core/services/src/Lion.AbpPro.Application/AbpProApplicationAutoMapperProfile.cs
  22. 199
      aspnet-core/services/src/Lion.AbpPro.Application/OrganizationUnits/OrganizationUnitAppService.cs
  23. 1
      aspnet-core/services/src/Lion.AbpPro.Application/Users/AccountAppService.cs
  24. 23
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/DbMigratorHostedService.cs
  25. 7
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/Lion.AbpPro.DbMigrator.csproj
  26. 15
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/Program.cs
  27. 5
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.Production.json
  28. 5
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.Staging.json
  29. 0
      aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings1.json
  30. 6
      aspnet-core/services/src/Lion.AbpPro.Domain/AbpProDomainModule.cs
  31. 291
      aspnet-core/services/src/Lion.AbpPro.Domain/Data/AbpProDbMigrationService.cs
  32. 11
      aspnet-core/services/src/Lion.AbpPro.Domain/Data/IAbpProDbSchemaMigrator.cs
  33. 21
      aspnet-core/services/src/Lion.AbpPro.Domain/Data/NullAbpProDbSchemaMigrator.cs
  34. 24
      aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProMigrationsDbContextFactory.cs
  35. 105
      aspnet-core/services/src/Lion.AbpPro.HttpApi/Controllers/Systems/OrganizationUnitController.cs
  36. 4
      aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Swaggers/HiddenAbpDefaultApiFilter.cs
  37. 9
      vben271/src/locales/lang/en/routes/admin.ts
  38. 10
      vben271/src/locales/lang/zh-CN/routes/admin.ts
  39. 2
      vben271/src/router/index.ts
  40. 10
      vben271/src/router/routes/modules/admin.ts
  41. 7529
      vben271/src/services/ServiceProxies.ts
  42. 355
      vben271/src/views/admin/dictionary/AbpDictionary.ts
  43. 84
      vben271/src/views/admin/organizationUnits/AddRoleToOrganizationUnit.vue
  44. 89
      vben271/src/views/admin/organizationUnits/CreateOrganizationUnit.vue
  45. 75
      vben271/src/views/admin/organizationUnits/EditOrganizationUnit.vue
  46. 234
      vben271/src/views/admin/organizationUnits/OrganizationUnit.ts
  47. 344
      vben271/src/views/admin/organizationUnits/OrganizationUnit.vue
  48. 1
      vben271/src/views/sys/login/useLogin.ts

20
aspnet-core/Delete-BIN-OBJ-Folders.bat

@ -0,0 +1,20 @@
@ECHO off
cls
ECHO Deleting all BIN and OBJ folders...
ECHO.
FOR /d /r . %%d in (bin,obj) DO (
IF EXIST "%%d" (
ECHO %%d | FIND /I "\node_modules\" > Nul && (
ECHO.Skipping: %%d
) || (
ECHO.Deleting: %%d
rd /s/q "%%d"
)
)
)
ECHO.
ECHO.BIN and OBJ folders have been successfully deleted. Press any key to exit.
pause > nul

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

@ -0,0 +1,66 @@
{
"App": {
"SelfUrl": "http://localhost:44315",
"CorsOrigins": "https://*.AbpPro.com,http://localhost:4200,http://localhost:3100"
},
"ConnectionStrings": {
"Default": "Data Source=120.24.194.14;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
},
"Redis": {
"Configuration": "localhost,password=mypassword,defaultdatabase=1"
},
"Jwt": {
"Audience": "http://localhost:5010",
"SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=",
"Issuer": "YHWmsOperationApiGateway",
"ExpirationTime": 30
},
"Cap": {
"Enabled": "true",
"RabbitMq": {
"HostName": "localhost",
"UserName": "admin",
"Password": "admin"
}
},
"ElasticSearch": {
"Enabled": "false",
"Url": "http://es.cn",
"IndexFormat": "Lion.AbpPro.development.{0:yyyy.MM.dd}",
"UserName": "elastic",
"Password": "aVVhjQ95RP7nbwNy",
"SearchIndexFormat": "Lion.AbpPro.development*"
},
"HttpClient": {
"Sts": {
"Name": "Sts",
"Url": "http://localhost:44354"
},
"Github": {
"Name": "Github",
"Url": "https://github.com",
"ClientId": "127fc528f611879fba03",
"ClientSecret": "fd0914e9e8e28b51dd5efe381121429279e43973"
},
"GithubApi": {
"Name": "GithubApi",
"Url": "https://api.github.com",
"ClientName": "AbpPro"
}
},
"Consul": {
"Enabled": false,
"Host": "http://localhost:8500",
"Service": "Project-Service"
},
"AliYun": {
"OSS": {
"AccessKeyId": "LTAI5tLkt3vvScGPVZ5qKJDc1S",
"AccessKeySecret": "BixV8vP5uPrbsdwjYzzsEXOPjkxPST2S",
"Endpoint": "oss-cn-shenzhen.aliyuncs.com",
"ContainerName": "lion-abp-pro",
"RegionId": "oss-cn-shenzhen",
"RoleArn": "acs:ram::1846393972471789:role/ramosstestst"
}
}
}

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

@ -1,4 +1,5 @@
{
"Serilog1": "12",
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
@ -33,7 +34,7 @@
"CorsOrigins": "https://*.AbpPro.com,http://localhost:4200,http://localhost:3100"
},
"ConnectionStrings": {
"Default": "Data Source=localhost;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
"Default": "Data Source=120.24.194.14;Database=LionAbpProDB;uid=root;pwd=1q2w3E*;charset=utf8mb4;Allow User Variables=true;AllowLoadLocalInfile=true"
},
"Redis": {
"Configuration": "localhost,password=mypassword,defaultdatabase=1"

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/AddRoleToOrganizationUnitInput.cs

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class AddRoleToOrganizationUnitInput
{
public List<Guid> RoleId { get; set; }
public Guid OrganizationUnitId { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/AddUserToOrganizationUnitInput.cs

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class AddUserToOrganizationUnitInput
{
public List<Guid> UserId { get; set; }
public Guid OrganizationUnitId { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/CreateOrganizationUnitInput.cs

@ -0,0 +1,11 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class CreateOrganizationUnitInput
{
[Required] public string DisplayName { get; set; }
public Guid? ParentId { get; set; }
}

10
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitRoleInput.cs

@ -0,0 +1,10 @@
using System;
using Lion.AbpPro.Extension.Customs.Dtos;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetOrganizationUnitRoleInput : PagingBase
{
public Guid OrganizationUnitId { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitRoleOutput.cs

@ -0,0 +1,11 @@
using System;
using Lion.AbpPro.Extension.Customs.Dtos;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetOrganizationUnitRoleOutput
{
public Guid Id { get; set; }
public string Name { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitUserInput.cs

@ -0,0 +1,11 @@
using System;
using Lion.AbpPro.Extension.Customs.Dtos;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetOrganizationUnitUserInput : PagingBase
{
public Guid OrganizationUnitId { get; set; }
public string Filter { get; set; }
}

13
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetOrganizationUnitUserOutput.cs

@ -0,0 +1,13 @@
using System;
using Lion.AbpPro.Extension.Customs.Dtos;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetOrganizationUnitUserOutput
{
public Guid Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddRoleInput.cs

@ -0,0 +1,11 @@
using System;
using Lion.AbpPro.Extension.Customs.Dtos;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetUnAddRoleInput : PagingBase
{
public Guid OrganizationUnitId { get; set; }
public string Filter { get; set; }
}

10
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddRoleOutput.cs

@ -0,0 +1,10 @@
using System;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetUnAddRoleOutput
{
public Guid Id { get; set; }
public string Name { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddUserInput.cs

@ -0,0 +1,11 @@
using System;
using Lion.AbpPro.Extension.Customs.Dtos;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetUnAddUserInput : PagingBase
{
public Guid OrganizationUnitId { get; set; }
public string Filter { get; set; }
}

12
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/GetUnAddUserOutput.cs

@ -0,0 +1,12 @@
using System;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class GetUnAddUserOutput
{
public Guid Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
}

16
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/OrganizationUnitDto.cs

@ -0,0 +1,16 @@
using System;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class OrganizationUnitDto
{
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public string Code { get; set; }
public string DisplayName { get; set; }
public Guid? ParentId { get; set; }
}

10
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/RemoveRoleToOrganizationUnitInput.cs

@ -0,0 +1,10 @@
using System;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class RemoveRoleToOrganizationUnitInput
{
public Guid RoleId { get; set; }
public Guid OrganizationUnitId { get; set; }
}

10
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/RemoveUserToOrganizationUnitInput.cs

@ -0,0 +1,10 @@
using System;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class RemoveUserToOrganizationUnitInput
{
public Guid UserId { get; set; }
public Guid OrganizationUnitId { get; set; }
}

13
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/TreeOutput.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class TreeOutput
{
public string Title { get; set; }
public Guid Key { get; set; }
public List<TreeOutput> Children { get; set; }
}

11
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/Dto/UpdateOrganizationUnitInput.cs

@ -0,0 +1,11 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace Lion.AbpPro.OrganizationUnits.Dto;
public class UpdateOrganizationUnitInput
{
[Required] public string DisplayName { get; set; }
public Guid Id { get; set; }
}

73
aspnet-core/services/src/Lion.AbpPro.Application.Contracts/OrganizationUnits/IOrganizationUnitAppService.cs

@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Lion.AbpPro.Extension.Customs.Dtos;
using Lion.AbpPro.OrganizationUnits.Dto;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Lion.AbpPro.OrganizationUnits;
public interface IOrganizationUnitAppService : IApplicationService
{
/// <summary>
/// 获取组织机构树结构
/// </summary>
/// <returns></returns>
Task<List<TreeOutput>> GetTreeAsync();
/// <summary>
/// 创建组织机构
/// </summary>
Task CreateAsync(CreateOrganizationUnitInput input);
/// <summary>
/// 删除组织机构
/// </summary>
Task DeleteAsync(IdInput input);
/// <summary>
/// 编辑组织机构
/// </summary>
Task UpdateAsync(UpdateOrganizationUnitInput input);
/// <summary>
/// 向组织机构添加角色
/// </summary>
Task AddRoleToOrganizationUnitAsync(AddRoleToOrganizationUnitInput input);
/// <summary>
/// 向组织机构删除角色
/// </summary>
Task RemoveRoleFromOrganizationUnitAsync(RemoveRoleToOrganizationUnitInput input);
/// <summary>
/// 向组织机构添加用户
/// </summary>
Task AddUserToOrganizationUnitAsync(AddUserToOrganizationUnitInput input);
/// <summary>
/// 向组织机构删除用户
/// </summary>
Task RemoveUserFromOrganizationUnitAsync(RemoveUserToOrganizationUnitInput input);
/// <summary>
/// 分页获取组织机构下用户
/// </summary>
Task<PagedResultDto<GetOrganizationUnitUserOutput>> GetUsersAsync(GetOrganizationUnitUserInput input);
/// <summary>
/// 分页获取组织机构下角色
/// </summary>
Task<PagedResultDto<GetOrganizationUnitRoleOutput>> GetRolesAsync(GetOrganizationUnitRoleInput input);
/// <summary>
/// 获取不在组织机构的用户
/// </summary>
Task<PagedResultDto<GetUnAddUserOutput>> GetUnAddUsersAsync(GetUnAddUserInput input);
/// <summary>
/// 获取不在组织机构的角色
/// </summary>
Task<PagedResultDto<GetUnAddRoleOutput>> GetUnAddRolessAsync(GetUnAddRoleInput input);
}

6
aspnet-core/services/src/Lion.AbpPro.Application/AbpProApplicationAutoMapperProfile.cs

@ -1,4 +1,5 @@
using AutoMapper;
using Lion.AbpPro.OrganizationUnits.Dto;
using Lion.AbpPro.Users.Dtos;
using Volo.Abp.Identity;
@ -14,6 +15,11 @@ namespace Lion.AbpPro
CreateMap<IdentityUser, ExportIdentityUserOutput>()
.ForMember(e => e.CreationTimeFormat, opt => opt.Ignore())
.ForMember(e => e.Status, opt => opt.Ignore());
CreateMap<OrganizationUnit, OrganizationUnitDto>();
CreateMap<IdentityUser, GetOrganizationUnitUserOutput>();
CreateMap<IdentityUser, GetUnAddUserOutput>();
CreateMap<IdentityRole, GetOrganizationUnitRoleOutput>();
CreateMap<IdentityRole, GetUnAddRoleOutput>();
}
}
}

199
aspnet-core/services/src/Lion.AbpPro.Application/OrganizationUnits/OrganizationUnitAppService.cs

@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Lion.AbpPro.Extension.Customs.Dtos;
using Lion.AbpPro.IdentityServers.ApiResources.Dtos;
using Lion.AbpPro.OrganizationUnits.Dto;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;
namespace Lion.AbpPro.OrganizationUnits;
public class OrganizationUnitAppService : AbpProAppService, IOrganizationUnitAppService
{
private readonly OrganizationUnitManager _organizationUnitManager;
private readonly IdentityUserManager _identityUserManager;
private readonly IOrganizationUnitRepository _organizationUnitRepository;
public OrganizationUnitAppService(
OrganizationUnitManager OrganizationUnitManager,
IdentityUserManager identityUserManager,
IOrganizationUnitRepository organizationUnitRepository)
{
_organizationUnitManager = OrganizationUnitManager;
_identityUserManager = identityUserManager;
_organizationUnitRepository = organizationUnitRepository;
}
public async Task<List<TreeOutput>> GetTreeAsync()
{
var organizationUnits = await _organizationUnitRepository.GetListAsync();
var organizationUnitDtos = ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitDto>>(organizationUnits);
return ConvertToTree(organizationUnitDtos);
}
public async Task CreateAsync(CreateOrganizationUnitInput input)
{
var entity = new OrganizationUnit
(
GuidGenerator.Create(),
input.DisplayName,
input.ParentId,
CurrentTenant.Id
);
await _organizationUnitManager.CreateAsync(entity);
}
public Task DeleteAsync(IdInput input)
{
return _organizationUnitManager.DeleteAsync(input.Id);
}
public async Task UpdateAsync(UpdateOrganizationUnitInput input)
{
var entity = await _organizationUnitRepository.FindAsync(input.Id);
if (entity != null)
{
entity.DisplayName = input.DisplayName;
await _organizationUnitManager.UpdateAsync(entity);
}
}
public async Task AddRoleToOrganizationUnitAsync(AddRoleToOrganizationUnitInput input)
{
foreach (var roleId in input.RoleId)
{
await _organizationUnitManager.AddRoleToOrganizationUnitAsync(roleId, input.OrganizationUnitId);
}
}
public async Task RemoveRoleFromOrganizationUnitAsync(RemoveRoleToOrganizationUnitInput input)
{
await _organizationUnitManager.RemoveRoleFromOrganizationUnitAsync(input.RoleId, input.OrganizationUnitId);
}
public async Task AddUserToOrganizationUnitAsync(AddUserToOrganizationUnitInput input)
{
foreach (var userId in input.UserId)
{
await _identityUserManager.AddToOrganizationUnitAsync(userId, input.OrganizationUnitId);
}
}
public async Task RemoveUserFromOrganizationUnitAsync(RemoveUserToOrganizationUnitInput input)
{
await _identityUserManager.RemoveFromOrganizationUnitAsync(input.UserId, input.OrganizationUnitId);
}
public async Task<PagedResultDto<GetOrganizationUnitUserOutput>> GetUsersAsync(GetOrganizationUnitUserInput input)
{
var listResult = new List<GetOrganizationUnitUserOutput>();
var organizationUnit = await _organizationUnitRepository.FindAsync(input.OrganizationUnitId);
if (organizationUnit == null) throw new UserFriendlyException("组织机构不存在");
var count = await _organizationUnitRepository.GetMembersCountAsync(organizationUnit, filter: input.Filter);
if (count > 0)
{
var list = await _organizationUnitRepository.GetMembersAsync
(
organizationUnit,
maxResultCount: input.PageSize,
skipCount: input.SkipCount,
filter: input.Filter
);
listResult = ObjectMapper.Map<List<IdentityUser>, List<GetOrganizationUnitUserOutput>>(list);
}
return new PagedResultDto<GetOrganizationUnitUserOutput>(count, listResult);
}
public async Task<PagedResultDto<GetUnAddUserOutput>> GetUnAddUsersAsync(GetUnAddUserInput input)
{
var listResult = new List<GetUnAddUserOutput>();
var organizationUnit = await _organizationUnitRepository.FindAsync(input.OrganizationUnitId);
if (organizationUnit == null) throw new UserFriendlyException("组织机构不存在");
var count = await _organizationUnitRepository.GetUnaddedUsersCountAsync(organizationUnit, input.Filter);
if (count > 0)
{
var users = await _organizationUnitRepository.GetUnaddedUsersAsync
(
organizationUnit,
maxResultCount: input.PageSize,
skipCount: input.SkipCount,
filter: input.Filter
);
listResult = ObjectMapper.Map<List<IdentityUser>, List<GetUnAddUserOutput>>(users);
}
return new PagedResultDto<GetUnAddUserOutput>(count, listResult);
}
public async Task<PagedResultDto<GetOrganizationUnitRoleOutput>> GetRolesAsync(GetOrganizationUnitRoleInput input)
{
var listResult = new List<GetOrganizationUnitRoleOutput>();
var organizationUnit = await _organizationUnitRepository.FindAsync(input.OrganizationUnitId);
if (organizationUnit == null) throw new UserFriendlyException("组织机构不存在");
var count = await _organizationUnitRepository.GetRolesCountAsync(organizationUnit);
if (count > 0)
{
var list = await _organizationUnitRepository.GetRolesAsync(organizationUnit, maxResultCount: input.PageSize, skipCount: input.SkipCount);
listResult = ObjectMapper.Map<List<IdentityRole>, List<GetOrganizationUnitRoleOutput>>(list);
}
return new PagedResultDto<GetOrganizationUnitRoleOutput>(count, listResult);
}
public async Task<PagedResultDto<GetUnAddRoleOutput>> GetUnAddRolessAsync(GetUnAddRoleInput input)
{
var listResult = new List<GetUnAddRoleOutput>();
var organizationUnit = await _organizationUnitRepository.FindAsync(input.OrganizationUnitId);
if (organizationUnit == null) throw new UserFriendlyException("组织机构不存在");
var count = await _organizationUnitRepository.GetUnaddedRolesCountAsync(organizationUnit, input.Filter);
if (count > 0)
{
var roles = await _organizationUnitRepository.GetUnaddedRolesAsync
(
organizationUnit,
maxResultCount: input.PageSize,
skipCount: input.SkipCount,
filter: input.Filter
);
listResult = ObjectMapper.Map<List<IdentityRole>, List<GetUnAddRoleOutput>>(roles);
}
return new PagedResultDto<GetUnAddRoleOutput>(count, listResult);
}
#region 私有方法
private List<TreeOutput> ConvertToTree(List<OrganizationUnitDto> list,
Guid? Id = null)
{
var result = new List<TreeOutput>();
var childList = Children(list, Id);
foreach (var item in childList)
{
var tree = new TreeOutput
{
Key = item.Id,
Title = item.DisplayName,
Children = ConvertToTree(list, item.Id)
};
result.Add(tree);
}
return result;
}
private List<OrganizationUnitDto> Children(List<OrganizationUnitDto> list,
Guid? Id)
{
var childList = list.Where(x => x.ParentId == Id).ToList();
return childList;
}
#endregion
}

1
aspnet-core/services/src/Lion.AbpPro.Application/Users/AccountAppService.cs

@ -27,7 +27,6 @@ namespace Lion.AbpPro.Users
private readonly Microsoft.AspNetCore.Identity.SignInManager<IdentityUser> _signInManager;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuretion;
private readonly Volo.Abp.Domain.Repositories.IRepository<IdentityRole> _identityRoleRepository;
public AccountAppService(

23
aspnet-core/services/src/Lion.AbpPro.DbMigrator/DbMigratorHostedService.cs

@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Lion.AbpPro.Data;
using Microsoft.Extensions.Configuration;
using Serilog;
using Volo.Abp;
@ -11,28 +12,32 @@ namespace Lion.AbpPro.DbMigrator
public class DbMigratorHostedService : IHostedService
{
private readonly IHostApplicationLifetime _hostApplicationLifetime;
public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime)
private readonly IConfigurationRoot _configurationRoot;
public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime,
IConfigurationRoot configurationRoot)
{
_hostApplicationLifetime = hostApplicationLifetime;
_configurationRoot = configurationRoot;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var application = AbpApplicationFactory.Create<AbpProDbMigratorModule>(options =>
{
options.UseAutofac();
options.Services.AddLogging(c => c.AddSerilog());
}))
using (var application = await AbpApplicationFactory.CreateAsync<AbpProDbMigratorModule>(options =>
{
options.UseAutofac();
options.Services.AddLogging(c => c.AddSerilog());
}))
{
application.Initialize();
var s = _configurationRoot.GetValue<string>("ConnectionStrings:Default");
await application.InitializeAsync();
await application
.ServiceProvider
.GetRequiredService<AbpProDbMigrationService>()
.MigrateAsync();
application.Shutdown();
await application.ShutdownAsync();
_hostApplicationLifetime.StopApplication();
}

7
aspnet-core/services/src/Lion.AbpPro.DbMigrator/Lion.AbpPro.DbMigrator.csproj

@ -12,7 +12,12 @@
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json">
<Content Include="appsettings.Production.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="appsettings.Staging.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

15
aspnet-core/services/src/Lion.AbpPro.DbMigrator/Program.cs

@ -1,5 +1,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@ -32,8 +34,21 @@ namespace Lion.AbpPro.DbMigrator
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging((context, logging) => logging.ClearProviders())
.ConfigureAppConfiguration(otpions =>
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
Console.WriteLine($"ASPNETCORE_ENVIRONMENT:{environment}");
var appSettingFileName = "appsettings.json";
if (!environment.IsNullOrWhiteSpace())
appSettingFileName = $"appsettings.{environment}.json";
Console.WriteLine($"appSettingFileName:{appSettingFileName}");
otpions.AddJsonFile(appSettingFileName,optional:false);
})
.ConfigureServices((hostContext, services) =>
{
var s = hostContext.HostingEnvironment;
var _configurationRoot= services.GetRequiredService<IConfigurationRoot>();
var ss = _configurationRoot.GetValue<string>("ConnectionStrings:Default");
services.AddHostedService<DbMigratorHostedService>();
});
}

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

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

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

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

0
aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings.json → aspnet-core/services/src/Lion.AbpPro.DbMigrator/appsettings1.json

6
aspnet-core/services/src/Lion.AbpPro.Domain/AbpProDomainModule.cs

@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using Lion.AbpPro.MultiTenancy;
using Lion.AbpPro.NotificationManagement;
using Volo.Abp.AuditLogging;
using Volo.Abp.AutoMapper;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Emailing;
using Volo.Abp.FeatureManagement;
@ -43,7 +44,10 @@ namespace Lion.AbpPro
{
options.IsEnabled = MultiTenancyConsts.IsEnabled;
});
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<AbpProDomainModule>();
});
#if DEBUG
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
#endif

291
aspnet-core/services/src/Lion.AbpPro.Domain/Data/AbpProDbMigrationService.cs

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@ -13,208 +13,207 @@ using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.TenantManagement;
namespace Lion.AbpPro.Data
namespace Lion.AbpPro.Data;
public class AbpProDbMigrationService : ITransientDependency
{
public class AbpProDbMigrationService : ITransientDependency
public ILogger<AbpProDbMigrationService> Logger { get; set; }
private readonly IDataSeeder _dataSeeder;
private readonly IEnumerable<IAbpProDbSchemaMigrator> _dbSchemaMigrators;
private readonly ITenantRepository _tenantRepository;
private readonly ICurrentTenant _currentTenant;
public AbpProDbMigrationService(
IDataSeeder dataSeeder,
IEnumerable<IAbpProDbSchemaMigrator> dbSchemaMigrators,
ITenantRepository tenantRepository,
ICurrentTenant currentTenant)
{
public ILogger<AbpProDbMigrationService> Logger { get; set; }
private readonly IDataSeeder _dataSeeder;
private readonly IEnumerable<IAbpProDbSchemaMigrator> _dbSchemaMigrators;
private readonly ITenantRepository _tenantRepository;
private readonly ICurrentTenant _currentTenant;
public AbpProDbMigrationService(
IDataSeeder dataSeeder,
IEnumerable<IAbpProDbSchemaMigrator> dbSchemaMigrators,
ITenantRepository tenantRepository,
ICurrentTenant currentTenant)
{
_dataSeeder = dataSeeder;
_dbSchemaMigrators = dbSchemaMigrators;
_tenantRepository = tenantRepository;
_currentTenant = currentTenant;
_dataSeeder = dataSeeder;
_dbSchemaMigrators = dbSchemaMigrators;
_tenantRepository = tenantRepository;
_currentTenant = currentTenant;
Logger = NullLogger<AbpProDbMigrationService>.Instance;
}
Logger = NullLogger<AbpProDbMigrationService>.Instance;
}
public async Task MigrateAsync()
{
var initialMigrationAdded = AddInitialMigrationIfNotExist();
public async Task MigrateAsync()
{
var initialMigrationAdded = AddInitialMigrationIfNotExist();
if (initialMigrationAdded)
{
return;
}
if (initialMigrationAdded)
{
return;
}
Logger.LogInformation("Started database migrations...");
Logger.LogInformation("Started database migrations...");
await MigrateDatabaseSchemaAsync();
await SeedDataAsync();
await MigrateDatabaseSchemaAsync();
await SeedDataAsync();
Logger.LogInformation($"Successfully completed host database migrations.");
Logger.LogInformation($"Successfully completed host database migrations.");
var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
var migratedDatabaseSchemas = new HashSet<string>();
foreach (var tenant in tenants)
var migratedDatabaseSchemas = new HashSet<string>();
foreach (var tenant in tenants)
{
using (_currentTenant.Change(tenant.Id))
{
using (_currentTenant.Change(tenant.Id))
if (tenant.ConnectionStrings.Any())
{
if (tenant.ConnectionStrings.Any())
{
var tenantConnectionStrings = tenant.ConnectionStrings
.Select(x => x.Value)
.ToList();
var tenantConnectionStrings = tenant.ConnectionStrings
.Select(x => x.Value)
.ToList();
if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
{
await MigrateDatabaseSchemaAsync(tenant);
if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
{
await MigrateDatabaseSchemaAsync(tenant);
migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
}
migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
}
await SeedDataAsync(tenant);
}
Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
await SeedDataAsync(tenant);
}
Logger.LogInformation("Successfully completed all database migrations.");
Logger.LogInformation("You can safely end this process...");
Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
}
private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
{
Logger.LogInformation(
$"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
Logger.LogInformation("Successfully completed all database migrations.");
Logger.LogInformation("You can safely end this process...");
}
foreach (var migrator in _dbSchemaMigrators)
{
await migrator.MigrateAsync();
}
}
private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
{
Logger.LogInformation(
$"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
private async Task SeedDataAsync(Tenant tenant = null)
foreach (var migrator in _dbSchemaMigrators)
{
Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id)
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue)
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue)
);
await migrator.MigrateAsync();
}
}
private async Task SeedDataAsync(Tenant tenant = null)
{
Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
private bool AddInitialMigrationIfNotExist()
await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id)
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue)
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue)
);
}
private bool AddInitialMigrationIfNotExist()
{
try
{
try
{
if (!DbMigrationsProjectExists())
{
return false;
}
}
catch (Exception)
if (!DbMigrationsProjectExists())
{
return false;
}
}
catch (Exception)
{
return false;
}
try
try
{
if (!MigrationsFolderExists())
{
if (!MigrationsFolderExists())
{
AddInitialMigration();
return true;
}
else
{
return false;
}
AddInitialMigration();
return true;
}
catch (Exception e)
else
{
Logger.LogWarning("Couldn't determinate if any migrations exist : " + e.Message);
return false;
}
}
private bool DbMigrationsProjectExists()
catch (Exception e)
{
var dbMigrationsProjectFolder = GetDbMigrationsProjectFolderPath();
return dbMigrationsProjectFolder != null;
Logger.LogWarning("Couldn't determinate if any migrations exist : " + e.Message);
return false;
}
}
private bool MigrationsFolderExists()
{
var dbMigrationsProjectFolder = GetDbMigrationsProjectFolderPath();
private bool DbMigrationsProjectExists()
{
var dbMigrationsProjectFolder = GetEntityFrameworkCoreProjectFolderPath();
return Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "EntityFrameworkCore"));
}
return dbMigrationsProjectFolder != null;
}
private void AddInitialMigration()
{
Logger.LogInformation("Creating initial migration...");
private bool MigrationsFolderExists()
{
var dbMigrationsProjectFolder = GetEntityFrameworkCoreProjectFolderPath();
string argumentPrefix;
string fileName;
return Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "Migrations"));
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
argumentPrefix = "-c";
fileName = "/bin/bash";
}
else
{
argumentPrefix = "/C";
fileName = "cmd.exe";
}
private void AddInitialMigration()
{
Logger.LogInformation("Creating initial migration...");
var procStartInfo = new ProcessStartInfo(fileName,
$"{argumentPrefix} \"abp create-migration-and-run-migrator \"{GetDbMigrationsProjectFolderPath()}\"\""
);
string argumentPrefix;
string fileName;
try
{
Process.Start(procStartInfo);
}
catch (Exception)
{
throw new Exception("Couldn't run ABP CLI...");
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
argumentPrefix = "-c";
fileName = "/bin/bash";
}
private string GetDbMigrationsProjectFolderPath()
else
{
var slnDirectoryPath = GetSolutionDirectoryPath();
argumentPrefix = "/C";
fileName = "cmd.exe";
}
if (slnDirectoryPath == null)
{
throw new Exception("Solution folder not found!");
}
var procStartInfo = new ProcessStartInfo(fileName,
$"{argumentPrefix} \"abp create-migration-and-run-migrator \"{GetEntityFrameworkCoreProjectFolderPath()}\"\""
);
try
{
Process.Start(procStartInfo);
}
catch (Exception)
{
throw new Exception("Couldn't run ABP CLI...");
}
}
var srcDirectoryPath = Path.Combine(slnDirectoryPath, "src");
private string GetEntityFrameworkCoreProjectFolderPath()
{
var slnDirectoryPath = GetSolutionDirectoryPath();
return Directory.GetDirectories(srcDirectoryPath)
.FirstOrDefault(d => d.EndsWith(".DbMigrations"));
if (slnDirectoryPath == null)
{
throw new Exception("Solution folder not found!");
}
private string GetSolutionDirectoryPath()
var srcDirectoryPath = Path.Combine(slnDirectoryPath, "src");
return Directory.GetDirectories(srcDirectoryPath)
.FirstOrDefault(d => d.EndsWith(".EntityFrameworkCore"));
}
private string GetSolutionDirectoryPath()
{
var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
while (Directory.GetParent(currentDirectory.FullName) != null)
{
var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
currentDirectory = Directory.GetParent(currentDirectory.FullName);
while (Directory.GetParent(currentDirectory.FullName) != null)
if (Directory.GetFiles(currentDirectory.FullName).FirstOrDefault(f => f.EndsWith(".sln")) != null)
{
currentDirectory = Directory.GetParent(currentDirectory.FullName);
if (Directory.GetFiles(currentDirectory.FullName).FirstOrDefault(f => f.EndsWith(".sln")) != null)
{
return currentDirectory.FullName;
}
return currentDirectory.FullName;
}
return null;
}
return null;
}
}

11
aspnet-core/services/src/Lion.AbpPro.Domain/Data/IAbpProDbSchemaMigrator.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Lion.AbpPro.Data
namespace Lion.AbpPro.Data;
public interface IAbpProDbSchemaMigrator
{
public interface IAbpProDbSchemaMigrator
{
Task MigrateAsync();
}
Task MigrateAsync();
}

21
aspnet-core/services/src/Lion.AbpPro.Domain/Data/NullAbpProDbSchemaMigrator.cs

@ -1,16 +1,15 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Lion.AbpPro.Data
namespace Lion.AbpPro.Data;
/* This is used if database provider does't define
* IAbpProDbSchemaMigrator implementation.
*/
public class NullAbpProDbSchemaMigrator : IAbpProDbSchemaMigrator, ITransientDependency
{
/* This is used if database provider does't define
* IAbpProDbSchemaMigrator implementation.
*/
public class NullAbpProDbSchemaMigrator : IAbpProDbSchemaMigrator, ITransientDependency
public Task MigrateAsync()
{
public Task MigrateAsync()
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}
}
}

24
aspnet-core/services/src/Lion.AbpPro.EntityFrameworkCore/EntityFrameworkCore/AbpProMigrationsDbContextFactory.cs

@ -1,3 +1,4 @@
using System;
using System.IO;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
@ -23,11 +24,28 @@ namespace Lion.AbpPro.EntityFrameworkCore
private static IConfigurationRoot BuildConfiguration()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var appSettingFileName = "appsettings.json";
if (!environment.IsNullOrWhiteSpace())
appSettingFileName = $"appsettings.{environment}.json";
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../Lion.AbpPro.DbMigrator/"))
.AddJsonFile("appsettings.json", optional: false);
.SetBasePath
(
Path.Combine
(
Directory.GetCurrentDirectory(),
"../Lion.AbpPro.DbMigrator/"
)
)
.AddJsonFile
(
appSettingFileName,
false
);
return builder.Build();
}
}
}
}

105
aspnet-core/services/src/Lion.AbpPro.HttpApi/Controllers/Systems/OrganizationUnitController.cs

@ -0,0 +1,105 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Lion.AbpPro.Extension.Customs.Dtos;
using Lion.AbpPro.OrganizationUnits;
using Lion.AbpPro.OrganizationUnits.Dto;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Volo.Abp.Application.Dtos;
namespace Lion.AbpPro.Controllers.Systems;
[Route("OrganizationUnits")]
public class OrganizationUnitController : AbpProController, IOrganizationUnitAppService
{
private readonly IOrganizationUnitAppService _organizationUnitAppService;
public OrganizationUnitController(IOrganizationUnitAppService organizationUnitAppService)
{
_organizationUnitAppService = organizationUnitAppService;
}
[HttpPost("tree")]
[SwaggerOperation(summary: "获取组织机构树", Tags = new[] { "OrganizationUnits" })]
public Task<List<TreeOutput>> GetTreeAsync()
{
return _organizationUnitAppService.GetTreeAsync();
}
[HttpPost("create")]
[SwaggerOperation(summary: "创建组织机构", Tags = new[] { "OrganizationUnits" })]
public Task CreateAsync(CreateOrganizationUnitInput input)
{
return _organizationUnitAppService.CreateAsync(input);
}
[HttpPost("delete")]
[SwaggerOperation(summary: "删除组织机构", Tags = new[] { "OrganizationUnits" })]
public Task DeleteAsync(IdInput input)
{
return _organizationUnitAppService.DeleteAsync(input);
}
[HttpPost("update")]
[SwaggerOperation(summary: "编辑组织机构", Tags = new[] { "OrganizationUnits" })]
public Task UpdateAsync(UpdateOrganizationUnitInput input)
{
return _organizationUnitAppService.UpdateAsync(input);
}
[HttpPost("addRoleToOrganizationUnitAsync")]
[SwaggerOperation(summary: "向组织机构添加角色", Tags = new[] { "OrganizationUnits" })]
public Task AddRoleToOrganizationUnitAsync(AddRoleToOrganizationUnitInput input)
{
return _organizationUnitAppService.AddRoleToOrganizationUnitAsync(input);
}
[HttpPost("removeRoleFromOrganizationUnitAsync")]
[SwaggerOperation(summary: "向组织机构删除角色", Tags = new[] { "OrganizationUnits" })]
public Task RemoveRoleFromOrganizationUnitAsync(RemoveRoleToOrganizationUnitInput input)
{
return _organizationUnitAppService.RemoveRoleFromOrganizationUnitAsync(input);
}
[HttpPost("addUserToOrganizationUnit")]
[SwaggerOperation(summary: "向组织机构添加用户", Tags = new[] { "OrganizationUnits" })]
public Task AddUserToOrganizationUnitAsync(AddUserToOrganizationUnitInput input)
{
return _organizationUnitAppService.AddUserToOrganizationUnitAsync(input);
}
[HttpPost("removeUserFromOrganizationUnit")]
[SwaggerOperation(summary: "向组织机构删除用户", Tags = new[] { "OrganizationUnits" })]
public Task RemoveUserFromOrganizationUnitAsync(RemoveUserToOrganizationUnitInput input)
{
return _organizationUnitAppService.RemoveUserFromOrganizationUnitAsync(input);
}
[HttpPost("getUsers")]
[SwaggerOperation(summary: "分页获取组织机构下用户", Tags = new[] { "OrganizationUnits" })]
public Task<PagedResultDto<GetOrganizationUnitUserOutput>> GetUsersAsync(GetOrganizationUnitUserInput input)
{
return _organizationUnitAppService.GetUsersAsync(input);
}
[HttpPost("getRoles")]
[SwaggerOperation(summary: "分页获取组织机构下角色", Tags = new[] { "OrganizationUnits" })]
public Task<PagedResultDto<GetOrganizationUnitRoleOutput>> GetRolesAsync(GetOrganizationUnitRoleInput input)
{
return _organizationUnitAppService.GetRolesAsync(input);
}
[HttpPost("getUnAddUsers")]
[SwaggerOperation(summary: "获取不在组织机构的用户", Tags = new[] { "OrganizationUnits" })]
public Task<PagedResultDto<GetUnAddUserOutput>> GetUnAddUsersAsync(GetUnAddUserInput input)
{
return _organizationUnitAppService.GetUnAddUsersAsync(input);
}
[HttpPost("getUnAddRoles")]
[SwaggerOperation(summary: "获取不在组织机构的角色", Tags = new[] { "OrganizationUnits" })]
public Task<PagedResultDto<GetUnAddRoleOutput>> GetUnAddRolessAsync(GetUnAddRoleInput input)
{
return _organizationUnitAppService.GetUnAddRolessAsync(input);
}
}

4
aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Swaggers/HiddenAbpDefaultApiFilter.cs

@ -46,7 +46,9 @@ namespace Lion.AbpPro.Shared.Hosting.Microservices.Swaggers
"/api/identity/my-profile",
"/api/identity",
"/api/multi-tenancy/tenants",
"/api/setting-management/emailing"
"/api/setting-management/emailing",
"/configuration",
"/outputcache"
};
}
}

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

@ -29,7 +29,7 @@ export default {
audit_httpMethod: 'HttpMethod',
audit_httpStatusCode: 'HttpStatusCode',
audit_httpRequest: 'HttpRequest',
audit_ipAdrress: 'IP Address',
audit_ipAddress: 'IP Address',
audit_time: 'Time',
audit_duration: 'Execution Duration(ms)',
audit_url: 'URL',
@ -68,4 +68,11 @@ export default {
editPasswordMessage: 'The passwords entered twice are inconsistent. Procedure',
executionTime: 'ExecutionTime',
executionDuration: 'ExecutionDuration(Millisecond)',
organizationUnitName: 'Name',
parentOrganizationUnitName: 'ParentOrganizationUnit',
organizationUnitManagement: 'OrganizationUnitManagement',
createRootOrganizationUnit: 'CreateRootOrganizationUnit',
organizationUnit: 'OrganizationUnit',
member: 'Member',
role: 'Role',
};

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

@ -26,7 +26,7 @@ export default {
audit_httpMethod: 'Http方法',
audit_httpStatusCode: 'Http状态码',
audit_httpRequest: 'Http请求',
audit_ipAdrress: 'IP地址',
audit_ipAddress: 'IP地址',
audit_time: '时间',
audit_duration: '持续时间(ms)',
audit_url: 'Url地址',
@ -67,5 +67,11 @@ export default {
editPasswordMessage: '输入的2次密码不一致',
executionTime: '执行时间',
executionDuration: '响应时间(毫秒)',
organizationUnitName: '名称',
parentOrganizationUnitName: '上级组织机构',
organizationUnitManagement: '组织机构管理',
createRootOrganizationUnit: '新增根机构',
organizationUnit: '组织机构',
member: '成员',
role: '角色',
};

2
vben271/src/router/index.ts

@ -1,7 +1,7 @@
import { createWebHistory, RouteRecordRaw } from "vue-router";
import type { App } from "vue";
import { createRouter, createWebHashHistory } from "vue-router";
import { createRouter } from "vue-router";
import { basicRoutes } from "./routes";
// 白名单应该包含基本静态路由

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

@ -83,6 +83,16 @@ const admin: AppRouteModule = {
policy: 'System.FileManagement',
},
},
{
path: 'organizationUnit',
name: 'organizationUnit',
component: () => import('/@/views/admin/organizationUnits/OrganizationUnit.vue'),
meta: {
title: t('routes.admin.organizationUnitManagement'),
icon: 'ant-design:snippets-outlined',
policy: 'System.FileManagement',
},
},
],
};

7529
vben271/src/services/ServiceProxies.ts

File diff suppressed because it is too large

355
vben271/src/views/admin/dictionary/AbpDictionary.ts

@ -1,39 +1,39 @@
import { FormSchema } from "/@/components/Table";
import { BasicColumn } from "/@/components/Table";
import { message } from "ant-design-vue";
import { useI18n } from "/@/hooks/web/useI18n";
import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import { message } from 'ant-design-vue';
import { useI18n } from '/@/hooks/web/useI18n';
import {
PagingDataDictionaryInput,
DataDictionaryServiceProxy,
SetDataDictinaryDetailInput,
DeleteDataDictionaryDetailInput,
IdInput
} from "/@/services/ServiceProxies";
import { h } from "vue";
import { Switch } from "ant-design-vue";
IdInput,
} from '/@/services/ServiceProxies';
import { h } from 'vue';
import { Switch } from 'ant-design-vue';
const { t } = useI18n();
export const tableColumns: BasicColumn[] = [
{
title: t("routes.admin.dictionaryCode"),
dataIndex: "code"
title: t('routes.admin.dictionaryCode'),
dataIndex: 'code',
},
{
title: t("routes.admin.dictionaryDisplayText"),
dataIndex: "displayText"
title: t('routes.admin.dictionaryDisplayText'),
dataIndex: 'displayText',
},
{
title: t("routes.admin.dictionaryOrder"),
dataIndex: "order"
title: t('routes.admin.dictionaryOrder'),
dataIndex: 'order',
},
{
title: t("common.status"),
dataIndex: "isEnabled",
title: t('common.status'),
dataIndex: 'isEnabled',
customRender: ({ record }) => {
return h(Switch, {
checked: record.isEnabled,
checkedChildren: "是",
unCheckedChildren: "否",
checkedChildren: '是',
unCheckedChildren: '否',
onChange(checked: boolean) {
const request = new SetDataDictinaryDetailInput();
request.dataDictionaryId = record.dataDictionaryId;
@ -42,103 +42,102 @@ export const tableColumns: BasicColumn[] = [
enableDictionaryAsync(request)
.then(() => {
record.isEnabled = checked;
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
})
.catch(() => {
message.error(t("common.operationFail"));
message.error(t('common.operationFail'));
});
}
},
});
}
},
},
{
dataIndex: "description",
title: t("routes.admin.dictionaryDescription")
}
dataIndex: 'description',
title: t('routes.admin.dictionaryDescription'),
},
];
//字典类型表格
export const dictionaryTypeTableColumns: BasicColumn[] = [
{
title: t("routes.admin.dictionaryCode") + "|" + t("routes.admin.dictionaryDisplayText"),
dataIndex: "text",
align: "left",
title: t('routes.admin.dictionaryCode') + '|' + t('routes.admin.dictionaryDisplayText'),
dataIndex: 'text',
align: 'left',
slots: {
customRender: "text"
}
}
customRender: 'text',
},
},
];
//字典项查询
export const searchFormSchema: FormSchema[] = [
{
field: "filter",
label: "",
component: "Input",
field: 'filter',
label: '',
component: 'Input',
colProps: {
span: 6
}
}
span: 6,
},
},
];
//字典类型查询
export const searchDictionaryFormSchema: FormSchema[] = [
{
field: "filter",
label: "",
component: "Input",
field: 'filter',
label: '',
component: 'Input',
colProps: {
span: 18
}
}
span: 18,
},
},
];
//新增字典项
export const createFormSchema: FormSchema[] = [
{
field: "id",
label: "",
field: 'id',
label: '',
ifShow: false,
component: "Input",
component: 'Input',
colProps: {
span: 18
}
span: 18,
},
},
{
field: "typeDisplayText",
label: t("routes.admin.dictionaryTypeName"),
component: "Input",
field: 'typeDisplayText',
label: t('routes.admin.dictionaryTypeName'),
component: 'Input',
colProps: {
span: 18
span: 18,
},
componentProps: {
disabled: true
}
disabled: true,
},
},
{
field: "code",
label: t("routes.admin.dictionaryCode"),
field: 'code',
label: t('routes.admin.dictionaryCode'),
required: true,
component: "Input",
component: 'Input',
colProps: {
span: 18
}
span: 18,
},
},
{
field: "displayText",
label: t("routes.admin.dictionaryDisplayText"),
component: "Input",
field: 'displayText',
label: t('routes.admin.dictionaryDisplayText'),
component: 'Input',
required: true,
colProps: {
span: 18
}
span: 18,
},
},
{
field: "order",
label: t("routes.admin.dictionaryOrder"),
field: 'order',
label: t('routes.admin.dictionaryOrder'),
required: true,
component: "InputNumber",
component: 'InputNumber',
colProps: {
span: 18
span: 18,
},
dynamicRules: () => {
return [
@ -149,69 +148,69 @@ export const createFormSchema: FormSchema[] = [
if (regNull.test(value)) {
return Promise.resolve();
}
return Promise.reject(t("routes.admin.nonZeroMessage"));
}
}
return Promise.reject(t('routes.admin.nonZeroMessage'));
},
},
];
}
},
},
{
field: "description",
label: t("routes.admin.dictionaryDescription"),
component: "InputTextArea",
field: 'description',
label: t('routes.admin.dictionaryDescription'),
component: 'InputTextArea',
colProps: {
span: 18
}
}
span: 18,
},
},
];
//编辑字典项
export const editFormSchema: FormSchema[] = [
{
field: "dataDictionaryId",
label: "",
field: 'dataDictionaryId',
label: '',
ifShow: false,
component: "Input",
component: 'Input',
colProps: {
span: 18
}
span: 18,
},
},
{
field: "id",
label: "",
field: 'id',
label: '',
ifShow: false,
component: "Input",
component: 'Input',
colProps: {
span: 18
}
span: 18,
},
},
{
field: "code",
label: t("routes.admin.dictionaryCode"),
field: 'code',
label: t('routes.admin.dictionaryCode'),
required: true,
component: "Input",
component: 'Input',
colProps: {
span: 18
span: 18,
},
componentProps: {
disabled: true
}
disabled: true,
},
},
{
field: "displayText",
label: t("routes.admin.dictionaryDisplayText"),
component: "Input",
field: 'displayText',
label: t('routes.admin.dictionaryDisplayText'),
component: 'Input',
required: true,
colProps: {
span: 18
}
span: 18,
},
},
{
field: "order",
label: t("routes.admin.dictionaryOrder"),
field: 'order',
label: t('routes.admin.dictionaryOrder'),
required: true,
component: "InputNumber",
component: 'InputNumber',
colProps: {
span: 18
span: 18,
},
dynamicRules: () => {
return [
@ -222,99 +221,99 @@ export const editFormSchema: FormSchema[] = [
if (regNull.test(value)) {
return Promise.resolve();
}
return Promise.reject(t("routes.admin.nonZeroMessage"));
}
}
return Promise.reject(t('routes.admin.nonZeroMessage'));
},
},
];
}
},
},
{
field: "description",
label: t("routes.admin.dictionaryDescription"),
component: "InputTextArea",
field: 'description',
label: t('routes.admin.dictionaryDescription'),
component: 'InputTextArea',
colProps: {
span: 18
}
}
span: 18,
},
},
];
//新增字典类型
export const createDictionaryTypeFormSchema: FormSchema[] = [
{
field: "code",
label: t("routes.admin.dictionaryCode"),
component: "Input",
field: 'code',
label: t('routes.admin.dictionaryCode'),
component: 'Input',
required: true,
colProps: {
span: 22
}
span: 22,
},
},
{
field: "displayText",
label: t("routes.admin.dictionaryDisplayText"),
component: "Input",
field: 'displayText',
label: t('routes.admin.dictionaryDisplayText'),
component: 'Input',
required: true,
colProps: {
span: 22
}
span: 22,
},
},
{
field: "description",
label: t("routes.admin.dictionaryDescription"),
component: "InputTextArea",
field: 'description',
label: t('routes.admin.dictionaryDescription'),
component: 'InputTextArea',
colProps: {
span: 22
}
}
span: 22,
},
},
];
//编辑字典类型
export const editDictionaryTypeFormSchema: FormSchema[] = [
{
field: "code",
label: t("routes.admin.dictionaryCode"),
component: "Input",
field: 'code',
label: t('routes.admin.dictionaryCode'),
component: 'Input',
required: true,
colProps: {
span: 22
span: 22,
},
componentProps: {
disabled: true
}
disabled: true,
},
},
{
field: "displayText",
label: t("routes.admin.dictionaryDisplayText"),
component: "Input",
field: 'displayText',
label: t('routes.admin.dictionaryDisplayText'),
component: 'Input',
required: true,
colProps: {
span: 22
}
span: 22,
},
},
{
field: "description",
label: t("routes.admin.dictionaryDescription"),
component: "InputTextArea",
field: 'description',
label: t('routes.admin.dictionaryDescription'),
component: 'InputTextArea',
colProps: {
span: 22
}
span: 22,
},
},
{
field: "key",
label: "",
field: 'key',
label: '',
ifShow: false,
component: "Input",
component: 'Input',
colProps: {
span: 18
}
span: 18,
},
},
{
field: "id",
label: "",
field: 'id',
label: '',
ifShow: false,
component: "Input",
component: 'Input',
colProps: {
span: 18
}
}
span: 18,
},
},
];
/**
@ -330,17 +329,17 @@ export async function getDictionaryTypeAsync(params: PagingDataDictionaryInput)
//新建字典类型
export async function createDictionaryTypeAsync({
request,
changeOkLoading,
closeModal,
validate,
resetFields
}) {
request,
changeOkLoading,
closeModal,
validate,
resetFields,
}) {
changeOkLoading(true);
await validate();
const _dataDictionaryServiceProxy = new DataDictionaryServiceProxy();
await _dataDictionaryServiceProxy.create(request);
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
resetFields();
changeOkLoading(false);
closeModal();
@ -352,7 +351,7 @@ export async function editDictionaryTypeAsync({ request, changeOkLoading, valida
await validate();
const _dataDictionaryServiceProxy = new DataDictionaryServiceProxy();
await _dataDictionaryServiceProxy.update(request);
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
changeOkLoading(false);
closeModal();
}
@ -365,17 +364,17 @@ export async function enableDictionaryAsync(input: SetDataDictinaryDetailInput)
//创建数据详情字典
export async function createDetailsDictionaryAsync({
request,
changeOkLoading,
validate,
resetFields,
closeModal
}) {
request,
changeOkLoading,
validate,
resetFields,
closeModal,
}) {
changeOkLoading(true);
await validate();
const _dataDictionaryServiceProxy = new DataDictionaryServiceProxy();
await _dataDictionaryServiceProxy.createDetail(request);
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
resetFields();
changeOkLoading(false);
closeModal();
@ -390,16 +389,16 @@ export async function getDictionaryDetailsAsync({ params }) {
//编辑数据字典
export async function editDetailsDictionaryAsync({
request,
changeOkLoading,
validate,
closeModal
}) {
request,
changeOkLoading,
validate,
closeModal,
}) {
changeOkLoading(true);
await validate();
const _dataDictionaryServiceProxy = new DataDictionaryServiceProxy();
await _dataDictionaryServiceProxy.updateDetail(request);
message.success(t("common.operationSuccess"));
message.success(t('common.operationSuccess'));
changeOkLoading(false);
closeModal();
}

84
vben271/src/views/admin/organizationUnits/AddRoleToOrganizationUnit.vue

@ -0,0 +1,84 @@
<template>
<div>
<BasicModal
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
:maskClosable="false"
@cancel="cancel"
@register="registerModal"
:minHeight="100"
:destroyOnClose="true"
>
<BasicTable @register="registerRoleTable" size="small"/>
</BasicModal>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import { BasicModal, useModalInner } from "/@/components/Modal";
import { BasicForm } from "/@/components/Form/index";
import { useI18n } from "/@/hooks/web/useI18n";
import {
getUnAddRolesAsync, addRoleTableColumns, searchAddRoleFormSchema
} from "/@/views/admin/organizationUnits/OrganizationUnit";
import { AddRoleToOrganizationUnitInput } from "/@/services/ServiceProxies";
import { useTable } from "/@/components/Table";
export default defineComponent({
name: "AddRoleToOrganizationUnit",
components: {
BasicModal,
BasicForm
},
setup(_, { emit }) {
const { t } = useI18n();
const [registerModal, { closeModal, changeOkLoading }] = useModalInner((data) => {
getForm().setFieldsValue({
organizationUnitId: data.organizationUnitId
});
});
const [registerRoleTable, { getForm,getSelectRowKeys }] = useTable({
columns: addRoleTableColumns,
formConfig: {
labelWidth: 70,
schemas: searchAddRoleFormSchema
},
api: getUnAddRolesAsync,
showTableSetting: true,
useSearchForm: false,
bordered: true,
canResize: true,
showIndexColumn: true
});
const submit = async () => {
try {
let selectedRoles = getSelectRowKeys();
console.log(selectedRoles);
let request = new AddRoleToOrganizationUnitInput();
request.organizationUnitId = getForm().getFieldsValue().organizationUnitId;
emit("reload");
} catch (error) {
changeOkLoading(false);
}
};
const cancel = () => {
closeModal();
};
return {
registerModal,
registerRoleTable,
submit,
t,
cancel
};
}
});
</script>
<style lang="less" scoped></style>

89
vben271/src/views/admin/organizationUnits/CreateOrganizationUnit.vue

@ -0,0 +1,89 @@
<template>
<div>
<BasicModal
:title="t('common.createText')"
:canFullscreen="false"
@ok="submit"
:maskClosable="false"
@cancel="cancel"
@register="registerModal"
:minHeight="100"
:destroyOnClose="true"
>
<BasicForm @register="registerOrganizationUnitForm" />
</BasicModal>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { useI18n } from '/@/hooks/web/useI18n';
import {
createOrganizationUnitFormSchema,
createOrganizationUnitAsync,
} from "/@/views/admin/organizationUnits/OrganizationUnit";
export default defineComponent({
name: 'CreateOrganizationUnit',
components: {
BasicModal,
BasicForm,
},
setup(_, { emit }) {
const { t } = useI18n();
const [registerModal, { closeModal, changeOkLoading }] = useModalInner((data) => {
if (data.record.parentId == '') {
updateSchema({ field: 'parentDisplayName', ifShow: false });
} else {
updateSchema({ field: 'parentDisplayName', ifShow: true });
setFieldsValue({
parentDisplayName: data.record.parentDisplayName,
parentId: data.record.parentId,
});
}
});
const [
registerOrganizationUnitForm,
{ resetFields, getFieldsValue, validate, setFieldsValue, updateSchema },
] = useForm({
labelWidth: 120,
schemas: createOrganizationUnitFormSchema,
showActionButtonGroup: false,
});
const submit = async () => {
try {
let request = getFieldsValue();
await createOrganizationUnitAsync({
request,
changeOkLoading,
validate,
resetFields,
closeModal,
});
emit('reload');
} catch (error) {
changeOkLoading(false);
}
};
const cancel = () => {
resetFields();
// emit('clearSelectedRowKeys');
closeModal();
};
return {
registerModal,
registerOrganizationUnitForm,
submit,
t,
cancel,
};
},
});
</script>
<style lang="less" scoped></style>

75
vben271/src/views/admin/organizationUnits/EditOrganizationUnit.vue

@ -0,0 +1,75 @@
<template>
<div>
<BasicModal
:title="t('common.editText')"
:canFullscreen="false"
@ok="submit"
:maskClosable="false"
@cancel="cancel"
@register="registerModal"
:minHeight="100"
:destroyOnClose="true"
>
<BasicForm @register="registerOrganizationUnitForm" />
</BasicModal>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { useI18n } from '/@/hooks/web/useI18n';
import { editOrganizationUnitFormSchema, editOrganizationUnitAsync } from "/@/views/admin/organizationUnits/OrganizationUnit";
export default defineComponent({
name: 'EditOrganizationUnit',
components: {
BasicModal,
BasicForm,
},
setup(_, { emit }) {
const { t } = useI18n();
const [registerModal, { closeModal, changeOkLoading }] = useModalInner((data) => {
setFieldsValue({
displayName: data.record.displayName,
id: data.record.id,
});
});
const [registerOrganizationUnitForm, { getFieldsValue, validate, setFieldsValue }] = useForm({
labelWidth: 120,
schemas: editOrganizationUnitFormSchema,
showActionButtonGroup: false,
});
const submit = async () => {
try {
let request = getFieldsValue();
await editOrganizationUnitAsync({
request,
changeOkLoading,
validate,
closeModal,
});
emit('reload');
} catch (error) {
changeOkLoading(false);
}
};
const cancel = () => {
closeModal();
};
return {
registerModal,
registerOrganizationUnitForm,
submit,
t,
cancel,
};
},
});
</script>
<style lang="less" scoped></style>

234
vben271/src/views/admin/organizationUnits/OrganizationUnit.ts

@ -0,0 +1,234 @@
import {
OrganizationUnitsServiceProxy,
IdInput,
GetOrganizationUnitUserInput,
GetOrganizationUnitRoleInput,
RemoveUserToOrganizationUnitInput,
RemoveRoleToOrganizationUnitInput,
AddRoleToOrganizationUnitInput,
AddUserToOrganizationUnitInput,
GetUnAddRoleInput,
GetUnAddUserInput
} from "/@/services/ServiceProxies";
import { FormSchema } from '/@/components/Table';
import { BasicColumn } from '/@/components/Table';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export const createOrganizationUnitFormSchema: FormSchema[] = [
{
field: 'parentDisplayName',
label: t('routes.admin.parentOrganizationUnitName'),
component: 'Input',
componentProps: {
disabled: true,
},
colProps: {
span: 18,
},
},
{
field: 'displayName',
label: t('routes.admin.organizationUnitName'),
component: 'Input',
colProps: {
span: 18,
},
},
{
field: 'parentId',
label: '',
component: 'Input',
colProps: {
span: 18,
},
ifShow: false,
},
];
export const editOrganizationUnitFormSchema: FormSchema[] = [
{
field: 'displayName',
label: t('routes.admin.organizationUnitName'),
component: 'Input',
colProps: {
span: 18,
},
},
{
field: 'id',
label: '',
component: 'Input',
colProps: {
span: 18,
},
ifShow: false,
},
];
export const addRoleToOrganizationUnitFormSchema: FormSchema[] = [
{
field: 'displayName',
label: t('routes.admin.organizationUnitName'),
component: 'Input',
colProps: {
span: 18,
},
},
{
field: 'organizationUnitId',
label: '',
component: 'Input',
colProps: {
span: 18,
},
ifShow: false,
},
];
export const userTableColumns: BasicColumn[] = [
{
title: t('routes.admin.userManagement_userName'),
dataIndex: 'userName',
},
{
title: t('routes.admin.userManagement_email'),
dataIndex: 'email',
}
];
export const addUserTableColumns: BasicColumn[] = [
{
title: t('routes.admin.userManagement_userName'),
dataIndex: 'userName',
},
{
title: t('routes.admin.userManagement_email'),
dataIndex: 'email',
}
];
export const roleTableColumns: BasicColumn[] = [
{
title: t('routes.admin.userManagement_roleName'),
dataIndex: 'name',
}
];
export const addRoleTableColumns: BasicColumn[] = [
{
title: t('routes.admin.userManagement_roleName'),
dataIndex: 'name',
}
];
export const searchAddRoleFormSchema: FormSchema[] = [
{
field: 'filter',
label: t('routes.admin.userManagement_roleName'),
component: 'Input',
colProps: { span: 8 },
},
{
field: 'organizationUnitId',
label: '',
component: 'Input',
ifShow:false,
colProps: { span: 8 },
}
];
export const searchUserFormSchema: FormSchema[] = [
{
field: 'filter',
label: t('routes.admin.userManagement_userName'),
component: 'Input',
colProps: { span: 8 },
},
{
field: 'organizationUnitId',
label: '',
component: 'Input',
ifShow:false,
colProps: { span: 8 },
}
];
export async function getTreeAsync() {
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return await _organizationUnitsServiceProxy.tree();
}
export async function deleteTreeNodeAsync({ id }) {
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
const request = new IdInput();
request.id = id;
return await _organizationUnitsServiceProxy.delete(request);
}
export async function createOrganizationUnitAsync({
request,
changeOkLoading,
closeModal,
validate,
resetFields,
}) {
changeOkLoading(true);
await validate();
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
await _organizationUnitsServiceProxy.create(request);
resetFields();
changeOkLoading(false);
closeModal();
}
export async function editOrganizationUnitAsync({
request,
changeOkLoading,
closeModal,
validate,
}) {
changeOkLoading(true);
await validate();
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
await _organizationUnitsServiceProxy.update(request);
changeOkLoading(false);
closeModal();
}
export async function getUserTableListAsync(params: GetOrganizationUnitUserInput) {
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.getUsers(params);
}
export async function getRoleTableListAsync(params: GetOrganizationUnitRoleInput) {
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.getRoles(params);
}
export async function removeUserFromOrganizationUnitAsync(params:RemoveUserToOrganizationUnitInput)
{
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.removeUserFromOrganizationUnit(params);
}
export async function removeRoleFromOrganizationUnitAsync(params:RemoveRoleToOrganizationUnitInput)
{
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.removeRoleFromOrganizationUnit(params);
}
export async function addRoleToOrganizationUnitAsync(params:AddRoleToOrganizationUnitInput)
{
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.addRoleToOrganizationUnit(params);
}
export async function addUserToOrganizationUnitAsync(params:AddUserToOrganizationUnitInput)
{
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.addUserToOrganizationUnit(params);
}
export async function GetUnAddUserAsync(params:GetUnAddUserInput)
{
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.getUnAddUsers(params);
}
export async function getUnAddRolesAsync(params:GetUnAddRoleInput)
{
const _organizationUnitsServiceProxy = new OrganizationUnitsServiceProxy();
return _organizationUnitsServiceProxy.getUnAddRoles(params);
}

344
vben271/src/views/admin/organizationUnits/OrganizationUnit.vue

@ -0,0 +1,344 @@
<template>
<div>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<div class="bg-white m-4 mr-0 overflow-hidden">
<BasicTree
toolbar
search
:treeData="treeData"
:beforeRightClick="getRightMenuList"
@select="handleSelect"
>
<template #headerTitle>
<span style="font-weight: 500">组织机构</span>
<a-button
type="primary"
style="margin-left: 20px"
size="small"
@click="createRootOrganizationUnit"
>
添加根机构
</a-button>
</template>
</BasicTree>
</div>
<div class="bg-white m-4 mr-0 w-3/4 xl:w-4/5">
<a-tabs v-model:activeKey="activeKey" @change="activeKeyChange">
<a-tab-pane key="1" tab="成员">
<BasicTable @register="registerUserTable" size="small">
<template #action="{ record }">
<TableAction
:actions="[
{
icon: 'ant-design:delete-outlined',
label: '删除',
onClick: handleUserDelete.bind(null, record),
},
]"
/>
</template>
</BasicTable>
</a-tab-pane>
<a-tab-pane key="2" tab="角色" force-render>
<BasicTable @register="registerRoleTable" size="small">
<template #toolbar>
<a-button
preIcon="ant-design:plus-circle-outlined"
type="primary"
@click="AddRoleToOrganizationUnitModal"
>
{{ t("common.createText") }}
</a-button>
</template>
<template #action="{ record }">
<TableAction
:actions="[
{
icon: 'ant-design:delete-outlined',
label: '删除',
onClick: handleRoleDelete.bind(null, record),
},
]"
/>
</template>
</BasicTable>
</a-tab-pane>
</a-tabs>
</div>
</PageWrapper>
<CreateOrganizationUnit
@register="registerCreateOrganizationUnit"
@reload="initOrganizationUnit"
/>
<EditOrganizationUnit @register="registerEditOrganizationUnit" @reload="initOrganizationUnit" />
<AddRoleToOrganizationUnit @register="registerAddRoleToOrganizationUnit" @reload="initOrganizationUnit" />
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import { PageWrapper } from "/@/components/Page";
import { BasicTree, ContextMenuItem } from "/@/components/Tree";
import { BasicTable, useTable, TableAction } from "/@/components/Table";
import {
getTreeAsync,
deleteTreeNodeAsync,
getUserTableListAsync,
getRoleTableListAsync,
userTableColumns,
roleTableColumns,
searchUserFormSchema,
removeRoleFromOrganizationUnitAsync,
removeUserFromOrganizationUnitAsync
} from "/@/views/admin/organizationUnits/OrganizationUnit";
import {
TreeOutput,
GetOrganizationUnitUserInput,
GetOrganizationUnitRoleInput, RemoveUserToOrganizationUnitInput, RemoveRoleToOrganizationUnitInput
} from "/@/services/ServiceProxies";
import { Tabs } from "ant-design-vue";
import CreateOrganizationUnit from "./CreateOrganizationUnit.vue";
import EditOrganizationUnit from "./EditOrganizationUnit.vue";
import AddRoleToOrganizationUnit from './AddRoleToOrganizationUnit.vue';
import { useModal } from "/@/components/Modal";
import { useMessage } from "/@/hooks/web/useMessage";
import { useI18n } from "/@/hooks/web/useI18n";
export default defineComponent({
name: "OrganizationUnit",
components: {
BasicTree,
PageWrapper,
Tabs,
TabPane: Tabs.TabPane,
CreateOrganizationUnit,
EditOrganizationUnit,
BasicTable,
TableAction,
AddRoleToOrganizationUnit
},
setup() {
const { t } = useI18n();
const { createConfirm } = useMessage();
const treeData = ref<TreeOutput[]>([]);
const activeKey = ref("1");
const [registerCreateOrganizationUnit, { openModal: CreateOrganizationUnitModal }] =
useModal();
const [registerEditOrganizationUnit, { openModal: EditOrganizationUnitModal }] = useModal();
const [registerAddRoleToOrganizationUnit, { openModal: AddRoleToOrganizationUnitModal }] =
useModal();
const initOrganizationUnit = async () => {
treeData.value = await getTreeAsync();
};
onMounted(async () => {
await initOrganizationUnit();
});
//
function createRootOrganizationUnit() {
let record = {
parentId: "",
parentDisplayName: ""
};
CreateOrganizationUnitModal(true, { record });
}
function getRightMenuList(node: any): ContextMenuItem[] {
return [
{
label: t("common.createText"),
handler: () => {
let record = {
parentId: "",
parentDisplayName: ""
};
record.parentId = node.$attrs.node.key;
record.parentDisplayName = node.$attrs.node.title;
CreateOrganizationUnitModal(true, { record });
},
icon: "bi:plus"
},
{
label: t("common.editText"),
handler: () => {
let record = {
id: node.$attrs.node.key,
displayName: node.$attrs.node.title
};
EditOrganizationUnitModal(true, { record });
},
icon: "ant-design:edit-outlined"
},
{
label: t("common.delText"),
handler: () => {
createConfirm({
iconType: "warning",
title: t("common.tip"),
content: t("common.askDelete"),
onOk: async () => {
await deleteTreeNodeAsync({ id: node.eventKey });
await initOrganizationUnit();
}
});
},
icon: "ant-design:delete-outlined"
}
];
}
let organizationUnitId: string = "";
async function handleSelect(keys) {
console.log(keys);
if (keys.length > 0) {
organizationUnitId = keys[0];
if (activeKey.value == "1") {
await reloadUser();
} else {
await reloadRole();
}
} else {
organizationUnitId = "";
}
}
const getUserAsync = async () => {
if (organizationUnitId) {
let request = new GetOrganizationUnitUserInput();
request.filter = getUserForm().getFieldsValue().filter;
request.organizationUnitId = organizationUnitId;
return await getUserTableListAsync(request);
}
};
const getRoleAsync = async () => {
if (organizationUnitId) {
let request = new GetOrganizationUnitRoleInput();
request.organizationUnitId = organizationUnitId;
return await getRoleTableListAsync(request);
}
};
const [registerUserTable, { reload: reloadUser, getForm: getUserForm }] = useTable({
columns: userTableColumns,
formConfig: {
labelWidth: 70,
schemas: searchUserFormSchema
},
api: getUserAsync,
showTableSetting: true,
useSearchForm: true,
bordered: true,
canResize: true,
showIndexColumn: true,
actionColumn: {
width: 120,
title: t("common.action"),
dataIndex: "action",
slots: {
customRender: "action"
},
fixed: "right"
}
});
const [registerRoleTable, { reload: reloadRole }] = useTable({
columns: roleTableColumns,
api: getRoleAsync,
showTableSetting: true,
useSearchForm: false,
bordered: true,
canResize: true,
showIndexColumn: true,
actionColumn: {
width: 120,
title: t("common.action"),
dataIndex: "action",
slots: {
customRender: "action"
},
fixed: "right"
}
});
const activeKeyChange = async (activeKey) => {
console.log(activeKey);
if (organizationUnitId) {
if (activeKey == 1) {
await reloadUser();
} else {
await reloadRole();
}
}
};
//
const handleUserDelete = async (record: Recordable) => {
let msg = t("common.askDelete");
createConfirm({
iconType: "warning",
title: t("common.tip"),
content: msg,
onOk: async () => {
let request = new RemoveUserToOrganizationUnitInput();
request.userId = record.id;
request.organizationUnitId = organizationUnitId;
await removeUserFromOrganizationUnitAsync(request);
await reloadUser();
}
});
};
//
const handleRoleDelete = async (record: Recordable) => {
let msg = t("common.askDelete");
createConfirm({
iconType: "warning",
title: t("common.tip"),
content: msg,
onOk: async () => {
let request = new RemoveRoleToOrganizationUnitInput();
request.roleId = record.id;
request.organizationUnitId = organizationUnitId;
await removeRoleFromOrganizationUnitAsync(request);
await reloadRole();
}
});
};
return {
treeData,
getRightMenuList,
createRootOrganizationUnit,
activeKey,
registerCreateOrganizationUnit,
initOrganizationUnit,
handleSelect,
registerEditOrganizationUnit,
registerUserTable,
registerRoleTable,
activeKeyChange,
handleUserDelete,
handleRoleDelete,
t,
registerAddRoleToOrganizationUnit,
AddRoleToOrganizationUnitModal
};
}
});
</script>
<style scoped>
/*.ant-tabs-tabpane {*/
/* background: #F0F2F5;*/
/*}*/
</style>

1
vben271/src/views/sys/login/useLogin.ts

@ -135,6 +135,7 @@ function getOidcSettings() {
export function useOidcLogin() {
const settings = getOidcSettings();
mgr.getUser()
const mgr = new Oidc.UserManager(settings);
mgr.signinRedirect();
}

Loading…
Cancel
Save