diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN.Abp.Identity.Application.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN.Abp.Identity.Application.csproj
new file mode 100644
index 000000000..fbb9fc057
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN.Abp.Identity.Application.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModule.cs
new file mode 100644
index 000000000..3da3d702e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModule.cs
@@ -0,0 +1,22 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Identity
+{
+ [DependsOn(
+ typeof(Volo.Abp.Identity.AbpIdentityApplicationModule),
+ typeof(AbpIdentityApplicationContractsModule))]
+ public class AbpIdentityApplicationModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddAutoMapperObjectMapper();
+
+ Configure(options =>
+ {
+ options.AddProfile(validate: true);
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModuleAutoMapperProfile.cs b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModuleAutoMapperProfile.cs
new file mode 100644
index 000000000..c206508f8
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/AbpIdentityApplicationModuleAutoMapperProfile.cs
@@ -0,0 +1,23 @@
+using AutoMapper;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class AbpIdentityApplicationModuleAutoMapperProfile : Profile
+ {
+ public AbpIdentityApplicationModuleAutoMapperProfile()
+ {
+ CreateMap()
+ .MapExtraProperties();
+
+ CreateMap()
+ .MapExtraProperties();
+
+ CreateMap()
+ .MapExtraProperties();
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/OrganizationUnitAppService.cs b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/OrganizationUnitAppService.cs
new file mode 100644
index 000000000..1ad5300d3
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.Application/LINGYUN/Abp/Identity/OrganizationUnitAppService.cs
@@ -0,0 +1,183 @@
+using Microsoft.AspNetCore.Authorization;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectExtending;
+
+namespace LINGYUN.Abp.Identity
+{
+ [Authorize(IdentityPermissions.OrganizationUnits.Default)]
+ public class OrganizationUnitAppService : IdentityAppServiceBase, IOrganizationUnitAppService
+ {
+ protected OrganizationUnitManager OrganizationUnitManager { get; }
+ protected IOrganizationUnitRepository OrganizationUnitRepository { get; }
+
+ protected IdentityUserManager UserManager { get; }
+ protected IIdentityUserRepository UserRepository { get; }
+
+ public OrganizationUnitAppService(
+ IdentityUserManager userManager,
+ IIdentityUserRepository userRepository,
+ OrganizationUnitManager organizationUnitManager,
+ IOrganizationUnitRepository organizationUnitRepository)
+ {
+ UserManager = userManager;
+ UserRepository = userRepository;
+ OrganizationUnitManager = organizationUnitManager;
+ OrganizationUnitRepository = organizationUnitRepository;
+
+ ObjectMapperContext = typeof(AbpIdentityApplicationModule);
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.Create)]
+ public virtual async Task CreateAsync(OrganizationUnitCreateDto input)
+ {
+ var origanizationUnit = new OrganizationUnit(
+ GuidGenerator.Create(), input.DisplayName, input.ParentId, CurrentTenant.Id)
+ {
+ CreationTime = Clock.Now
+ };
+ input.MapExtraPropertiesTo(origanizationUnit);
+
+ await OrganizationUnitManager.CreateAsync(origanizationUnit);
+ await CurrentUnitOfWork.SaveChangesAsync();
+
+ return ObjectMapper.Map(origanizationUnit);
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.Delete)]
+ public virtual async Task DeleteAsync(Guid id)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.FindAsync(id);
+ if (origanizationUnit == null)
+ {
+ return;
+ }
+ await OrganizationUnitManager.DeleteAsync(id);
+ }
+
+ public virtual async Task> FindChildrenAsync(OrganizationUnitGetChildrenDto input)
+ {
+ var origanizationUnitChildren = await OrganizationUnitManager.FindChildrenAsync(input.Id, input.Recursive);
+
+ return new ListResultDto(
+ ObjectMapper.Map, List>(origanizationUnitChildren));
+ }
+
+ public virtual async Task GetAsync(Guid id)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.FindAsync(id);
+
+ return ObjectMapper.Map(origanizationUnit);
+ }
+
+ public virtual async Task GetLastChildOrNullAsync(Guid parentId)
+ {
+ var origanizationUnitLastChildren = await OrganizationUnitManager.GetLastChildOrNullAsync(parentId);
+
+ return ObjectMapper.Map(origanizationUnitLastChildren);
+ }
+
+ public virtual async Task> GetListAsync(OrganizationUnitGetByPagedDto input)
+ {
+ var origanizationUnitCount = await OrganizationUnitRepository.GetCountAsync();
+ var origanizationUnits = await OrganizationUnitRepository
+ .GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount, false);
+
+ return new PagedResultDto(origanizationUnitCount,
+ ObjectMapper.Map, List>(origanizationUnits));
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.ManageRoles)]
+ public virtual async Task> GetRolesAsync(OrganizationUnitGetRoleByPagedDto input)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(input.Id);
+ var origanizationUnitRoleCount = await OrganizationUnitRepository.GetRolesCountAsync(origanizationUnit);
+ var origanizationUnitRoles = await OrganizationUnitRepository.GetRolesAsync(origanizationUnit,
+ input.Sorting, input.MaxResultCount, input.SkipCount, false);
+
+ return new PagedResultDto(origanizationUnitRoleCount,
+ ObjectMapper.Map, List>(origanizationUnitRoles));
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.ManageUsers)]
+ public virtual async Task> GetUsersAsync(OrganizationUnitGetUserDto input)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(input.Id);
+ // TODO: 官方库没有定义分页查询API,有可能是企业付费版本,需要自行实现
+ var origanizationUnitUsers = await UserRepository.GetUsersInOrganizationUnitAsync(origanizationUnit.Id);
+
+ return new ListResultDto(
+ ObjectMapper.Map, List>(origanizationUnitUsers));
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.Update)]
+ public virtual async Task MoveAsync(OrganizationUnitMoveDto input)
+ {
+ await OrganizationUnitManager.MoveAsync(input.Id, input.ParentId);
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.Update)]
+ public virtual async Task UpdateAsync(Guid id, OrganizationUnitUpdateDto input)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(id);
+ origanizationUnit.DisplayName = input.DisplayName;
+ input.MapExtraPropertiesTo(origanizationUnit);
+
+ await OrganizationUnitManager.UpdateAsync(origanizationUnit);
+ await CurrentUnitOfWork.SaveChangesAsync();
+
+ return ObjectMapper.Map(origanizationUnit);
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.ManageRoles)]
+ public virtual async Task AddRoleAsync(OrganizationUnitDtoAddOrRemoveRoleDto input)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(input.Id);
+ if (!origanizationUnit.IsInRole(input.RoleId))
+ {
+ origanizationUnit.AddRole(input.RoleId);
+ await OrganizationUnitManager.UpdateAsync(origanizationUnit);
+ await CurrentUnitOfWork.SaveChangesAsync();
+ }
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.ManageRoles)]
+ public virtual async Task RemoveRoleAsync(OrganizationUnitDtoAddOrRemoveRoleDto input)
+ {
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(input.Id);
+ if (origanizationUnit.IsInRole(input.RoleId))
+ {
+ origanizationUnit.RemoveRole(input.RoleId);
+ await OrganizationUnitManager.UpdateAsync(origanizationUnit);
+ await CurrentUnitOfWork.SaveChangesAsync();
+ }
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.ManageUsers)]
+ public virtual async Task AddUserAsync(OrganizationUnitDtoAddOrRemoveUserDto input)
+ {
+ var identityUser = await UserRepository.GetAsync(input.UserId);
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(input.Id);
+ if (!identityUser.IsInOrganizationUnit(input.Id))
+ {
+ await UserManager.AddToOrganizationUnitAsync(identityUser, origanizationUnit);
+ await CurrentUnitOfWork.SaveChangesAsync();
+ }
+ }
+
+ [Authorize(IdentityPermissions.OrganizationUnits.ManageUsers)]
+ public virtual async Task RemoveUserAsync(OrganizationUnitDtoAddOrRemoveUserDto input)
+ {
+ var identityUser = await UserRepository.GetAsync(input.UserId);
+ var origanizationUnit = await OrganizationUnitRepository.GetAsync(input.Id);
+ if (identityUser.IsInOrganizationUnit(input.Id))
+ {
+ await UserManager.RemoveFromOrganizationUnitAsync(identityUser, origanizationUnit);
+ await CurrentUnitOfWork.SaveChangesAsync();
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi.Client/LINGYUN.Abp.Identity.HttpApi.Client.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi.Client/LINGYUN.Abp.Identity.HttpApi.Client.csproj
new file mode 100644
index 000000000..dc5757263
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi.Client/LINGYUN.Abp.Identity.HttpApi.Client.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi.Client/LINGYUN/Abp/Identity/AbpIdentityHttpApiClientModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi.Client/LINGYUN/Abp/Identity/AbpIdentityHttpApiClientModule.cs
new file mode 100644
index 000000000..bf5590325
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi.Client/LINGYUN/Abp/Identity/AbpIdentityHttpApiClientModule.cs
@@ -0,0 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Identity;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Identity.HttpApi.Client
+{
+ [DependsOn(
+ typeof(Volo.Abp.Identity.AbpIdentityHttpApiClientModule),
+ typeof(AbpIdentityApplicationContractsModule))]
+ public class AbpIdentityHttpApiClientModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddHttpClientProxies(
+ typeof(AbpIdentityApplicationContractsModule).Assembly,
+ IdentityRemoteServiceConsts.RemoteServiceName
+ );
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN.Abp.Identity.HttpApi.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN.Abp.Identity.HttpApi.csproj
new file mode 100644
index 000000000..789c960f8
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN.Abp.Identity.HttpApi.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/AbpIdentityHttpApiModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/AbpIdentityHttpApiModule.cs
new file mode 100644
index 000000000..60f4e524c
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/AbpIdentityHttpApiModule.cs
@@ -0,0 +1,19 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Identity
+{
+ [DependsOn(
+ typeof(Volo.Abp.Identity.AbpIdentityHttpApiModule),
+ typeof(AbpIdentityApplicationContractsModule))]
+ public class AbpIdentityHttpApiModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(mvcBuilder =>
+ {
+ mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpIdentityHttpApiModule).Assembly);
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/IOrganizationUnitController.cs b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/IOrganizationUnitController.cs
new file mode 100644
index 000000000..eb851923d
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Identity.HttpApi/LINGYUN/Abp/Identity/IOrganizationUnitController.cs
@@ -0,0 +1,124 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.AspNetCore.Mvc;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Identity
+{
+ [RemoteService(Name = IdentityRemoteServiceConsts.RemoteServiceName)]
+ [Area("organization-unit")]
+ [ControllerName("organization-unit")]
+ [Route("api/identity/organization-unit")]
+ public class IOrganizationUnitController : AbpController, IOrganizationUnitAppService
+ {
+ protected IOrganizationUnitAppService OrganizationUnitAppService { get; }
+
+ public IOrganizationUnitController(
+ IOrganizationUnitAppService organizationUnitAppService)
+ {
+ OrganizationUnitAppService = organizationUnitAppService;
+ }
+
+ [HttpPost]
+ [Route("management-roles")]
+ public virtual async Task AddRoleAsync(OrganizationUnitDtoAddOrRemoveRoleDto input)
+ {
+ await OrganizationUnitAppService.AddRoleAsync(input);
+ }
+
+ [HttpPost]
+ [Route("management-users")]
+ public virtual async Task AddUserAsync(OrganizationUnitDtoAddOrRemoveUserDto input)
+ {
+ await OrganizationUnitAppService.AddUserAsync(input);
+ }
+
+ [HttpPost]
+ public virtual async Task CreateAsync(OrganizationUnitCreateDto input)
+ {
+ return await OrganizationUnitAppService.CreateAsync(input);
+ }
+
+ [HttpDelete]
+ [Route("{id}")]
+ public virtual async Task DeleteAsync(Guid id)
+ {
+ await OrganizationUnitAppService.DeleteAsync(id);
+ }
+
+ [HttpGet]
+ [Route("find-children")]
+ public virtual async Task> FindChildrenAsync(OrganizationUnitGetChildrenDto input)
+ {
+ return await OrganizationUnitAppService.FindChildrenAsync(input);
+ }
+
+ [HttpGet]
+ [Route("{id}")]
+ public virtual async Task GetAsync(Guid id)
+ {
+ return await OrganizationUnitAppService.GetAsync(id);
+ }
+
+ [HttpGet]
+ [Route("last-children")]
+ public virtual async Task GetLastChildOrNullAsync([Required] Guid parentId)
+ {
+ return await OrganizationUnitAppService.GetLastChildOrNullAsync(parentId);
+ }
+
+ [HttpGet]
+ public virtual async Task> GetListAsync(OrganizationUnitGetByPagedDto input)
+ {
+ return await OrganizationUnitAppService.GetListAsync(input);
+ }
+
+ [HttpGet]
+ [Route("management-roles")]
+ public virtual async Task> GetRolesAsync(OrganizationUnitGetRoleByPagedDto input)
+ {
+ return await OrganizationUnitAppService.GetRolesAsync(input);
+ }
+
+ [HttpGet]
+ [Route("management-users")]
+ public virtual async Task> GetUsersAsync(OrganizationUnitGetUserDto input)
+ {
+ return await OrganizationUnitAppService.GetUsersAsync(input);
+ }
+
+ [HttpPut]
+ [Route("{id}/move")]
+ public virtual async Task MoveAsync(OrganizationUnitMoveDto input)
+ {
+ await OrganizationUnitAppService.MoveAsync(input);
+ }
+
+ [HttpDelete]
+ [Route("management-roles")]
+ public virtual async Task RemoveRoleAsync(OrganizationUnitDtoAddOrRemoveRoleDto input)
+ {
+ await OrganizationUnitAppService.RemoveRoleAsync(input);
+ }
+
+ [HttpDelete]
+ [Route("management-users")]
+ public virtual async Task RemoveUserAsync(OrganizationUnitDtoAddOrRemoveUserDto input)
+ {
+ await OrganizationUnitAppService.RemoveUserAsync(input);
+ }
+
+ [HttpPut]
+ [Route("{id}")]
+ public virtual async Task UpdateAsync(Guid id, OrganizationUnitUpdateDto input)
+ {
+ return await OrganizationUnitAppService.UpdateAsync(id, input);
+ }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN.Abp.Identity.Application.Contracts.csproj b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN.Abp.Identity.Application.Contracts.csproj
new file mode 100644
index 000000000..c4f751730
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN.Abp.Identity.Application.Contracts.csproj
@@ -0,0 +1,22 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/AbpIdentityApplicationContractsModule.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/AbpIdentityApplicationContractsModule.cs
new file mode 100644
index 000000000..d249bc291
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/AbpIdentityApplicationContractsModule.cs
@@ -0,0 +1,32 @@
+using Volo.Abp.Application;
+using Volo.Abp.Authorization;
+using Volo.Abp.Identity.Localization;
+using Volo.Abp.Localization;
+using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
+
+namespace LINGYUN.Abp.Identity
+{
+ [DependsOn(
+ typeof(Volo.Abp.Identity.AbpIdentityApplicationContractsModule),
+ typeof(AbpAuthorizationModule),
+ typeof(AbpDddApplicationModule)
+ )]
+ public class AbpIdentityApplicationContractsModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/Identity/Localization");
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitCreateDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitCreateDto.cs
new file mode 100644
index 000000000..a67e088f3
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitCreateDto.cs
@@ -0,0 +1,17 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.Validation;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitCreateDto : ExtensibleObject
+ {
+ [Required]
+ [DynamicStringLength(typeof(OrganizationUnitConsts), nameof(OrganizationUnitConsts.MaxDisplayNameLength))]
+ public string DisplayName { get; set; }
+
+ public Guid? ParentId { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDto.cs
new file mode 100644
index 000000000..8ee2a8fb4
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDto.cs
@@ -0,0 +1,12 @@
+using System;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitDto : ExtensibleAuditedEntityDto
+ {
+ public Guid? ParentId { get; set; }
+ public string Code { get; set; }
+ public string DisplayName { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDtoAddOrRemoveRoleDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDtoAddOrRemoveRoleDto.cs
new file mode 100644
index 000000000..a7e681927
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDtoAddOrRemoveRoleDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitDtoAddOrRemoveRoleDto : IEntityDto
+ {
+ [Required]
+ public Guid Id { get; set; }
+
+ [Required]
+ public Guid RoleId { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDtoAddOrRemoveUserDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDtoAddOrRemoveUserDto.cs
new file mode 100644
index 000000000..c51d6df78
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitDtoAddOrRemoveUserDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitDtoAddOrRemoveUserDto : IEntityDto
+ {
+ [Required]
+ public Guid Id { get; set; }
+
+ [Required]
+ public Guid UserId { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetByPagedDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetByPagedDto.cs
new file mode 100644
index 000000000..ebe951dd3
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetByPagedDto.cs
@@ -0,0 +1,9 @@
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitGetByPagedDto : PagedAndSortedResultRequestDto
+ {
+ public string Filter { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetChildrenDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetChildrenDto.cs
new file mode 100644
index 000000000..36c68a5cc
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetChildrenDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitGetChildrenDto : IEntityDto
+ {
+ [Required]
+ public Guid Id { get; set; }
+ public bool Recursive { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetRoleByPagedDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetRoleByPagedDto.cs
new file mode 100644
index 000000000..2b70f0800
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetRoleByPagedDto.cs
@@ -0,0 +1,14 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitGetRoleByPagedDto : PagedAndSortedResultRequestDto, IEntityDto
+ {
+ [Required]
+ public Guid Id { get; set; }
+
+ public string Filter { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetUserDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetUserDto.cs
new file mode 100644
index 000000000..be2548091
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitGetUserDto.cs
@@ -0,0 +1,14 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitGetUserDto : IEntityDto
+ {
+ [Required]
+ public Guid Id { get; set; }
+
+ public string Filter { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitMoveDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitMoveDto.cs
new file mode 100644
index 000000000..7b63634e6
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitMoveDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Application.Dtos;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitMoveDto : IEntityDto
+ {
+ [Required]
+ public Guid Id { get; set; }
+ public Guid? ParentId { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitUpdateDto.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitUpdateDto.cs
new file mode 100644
index 000000000..1c48b6191
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Dto/OrganizationUnitUpdateDto.cs
@@ -0,0 +1,9 @@
+using Volo.Abp.ObjectExtending;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class OrganizationUnitUpdateDto : ExtensibleObject
+ {
+ public string DisplayName { get; set; }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IOrganizationUnitAppService.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IOrganizationUnitAppService.cs
new file mode 100644
index 000000000..ae17cb285
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IOrganizationUnitAppService.cs
@@ -0,0 +1,35 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Identity;
+
+namespace LINGYUN.Abp.Identity
+{
+ public interface IOrganizationUnitAppService :
+ ICrudAppService
+ {
+ Task GetLastChildOrNullAsync([Required] Guid parentId);
+
+ Task MoveAsync(OrganizationUnitMoveDto input);
+
+ Task> FindChildrenAsync(OrganizationUnitGetChildrenDto input);
+
+ Task> GetRolesAsync(OrganizationUnitGetRoleByPagedDto input);
+
+ Task> GetUsersAsync(OrganizationUnitGetUserDto input);
+
+ Task AddRoleAsync(OrganizationUnitDtoAddOrRemoveRoleDto input);
+
+ Task RemoveRoleAsync(OrganizationUnitDtoAddOrRemoveRoleDto input);
+
+ Task AddUserAsync(OrganizationUnitDtoAddOrRemoveUserDto input);
+
+ Task RemoveUserAsync(OrganizationUnitDtoAddOrRemoveUserDto input);
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityPermissionDefinitionProvider.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityPermissionDefinitionProvider.cs
new file mode 100644
index 000000000..501df66e9
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityPermissionDefinitionProvider.cs
@@ -0,0 +1,26 @@
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Identity.Localization;
+using Volo.Abp.Localization;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class IdentityPermissionDefinitionProvider : PermissionDefinitionProvider
+ {
+ public override void Define(IPermissionDefinitionContext context)
+ {
+ var identityGroup = context.GetGroupOrNull(Volo.Abp.Identity.IdentityPermissions.GroupName);
+
+ var origanizationUnitPermission = identityGroup.AddPermission(IdentityPermissions.OrganizationUnits.Default, L("Permission:OrganizationUnitManagement"));
+ origanizationUnitPermission.AddChild(IdentityPermissions.OrganizationUnits.Create, L("Permission:Create"));
+ origanizationUnitPermission.AddChild(IdentityPermissions.OrganizationUnits.Update, L("Permission:Edit"));
+ origanizationUnitPermission.AddChild(IdentityPermissions.OrganizationUnits.Delete, L("Permission:Delete"));
+ origanizationUnitPermission.AddChild(IdentityPermissions.OrganizationUnits.ManageRoles, L("Permission:ChangeRoles"));
+ origanizationUnitPermission.AddChild(IdentityPermissions.OrganizationUnits.ManageUsers, L("Permission:ChangeUsers"));
+ }
+
+ private static LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityPermissions.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityPermissions.cs
new file mode 100644
index 000000000..1200ce27a
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/IdentityPermissions.cs
@@ -0,0 +1,22 @@
+using Volo.Abp.Reflection;
+
+namespace LINGYUN.Abp.Identity
+{
+ public class IdentityPermissions
+ {
+ public static class OrganizationUnits
+ {
+ public const string Default = Volo.Abp.Identity.IdentityPermissions.GroupName + ".OrganizationUnits";
+ public const string Create = Default + ".Create";
+ public const string Update = Default + ".Update";
+ public const string Delete = Default + ".Delete";
+ public const string ManageUsers = Default + ".ManageUsers";
+ public const string ManageRoles = Default + ".ManageRoles";
+ }
+
+ public static string[] GetAll()
+ {
+ return ReflectionHelper.GetPublicConstantsRecursively(typeof(IdentityPermissions));
+ }
+ }
+}
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/en.json b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/en.json
new file mode 100644
index 000000000..f1c21169c
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/en.json
@@ -0,0 +1,8 @@
+{
+ "culture": "en",
+ "texts": {
+ "Permission:OrganizationUnitManagement": "Organization unit management",
+ "Permission:ChangeRoles": "Change roles",
+ "Permission:ChangeUsers": "Change users"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/zh-Hans.json b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/zh-Hans.json
new file mode 100644
index 000000000..69bbbb26b
--- /dev/null
+++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Application.Contracts/LINGYUN/Abp/Identity/Localization/zh-Hans.json
@@ -0,0 +1,8 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "Permission:OrganizationUnitManagement": "组织机构管理",
+ "Permission:ChangeRoles": "更改角色",
+ "Permission:ChangeUsers": "更改用户"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
index d6f0a2214..0048e3e7f 100644
--- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
+++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs
@@ -3,7 +3,6 @@ using IdentityModel;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
-using LINGYUN.Abp.IdentityServer;
using LINGYUN.Abp.Location.Tencent;
using LINGYUN.Abp.MessageService;
using LINGYUN.Abp.SettingManagement;
@@ -33,7 +32,6 @@ using Volo.Abp.Autofac;
using Volo.Abp.Caching;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
-using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.Identity.Localization;
using Volo.Abp.IdentityServer.EntityFrameworkCore;
@@ -50,6 +48,7 @@ using Volo.Abp.Security.Encryption;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using Volo.Abp.VirtualFileSystem;
+
namespace LINGYUN.BackendAdmin
{
[DependsOn(
@@ -59,14 +58,14 @@ namespace LINGYUN.BackendAdmin
typeof(AppPlatformApplicationContractModule),
typeof(ApiGatewayApplicationContractsModule),
typeof(AbpMessageServiceApplicationContractsModule),
- typeof(AbpIdentityHttpApiModule),
- typeof(AbpIdentityApplicationModule),
- typeof(Abp.Account.AbpAccountApplicationModule),
- typeof(Abp.Account.AbpAccountHttpApiModule),
+ typeof(LINGYUN.Abp.Identity.AbpIdentityHttpApiModule),
+ typeof(LINGYUN.Abp.Identity.AbpIdentityApplicationModule),
+ typeof(LINGYUN.Abp.Account.AbpAccountApplicationModule),
+ typeof(LINGYUN.Abp.Account.AbpAccountHttpApiModule),
+ typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerApplicationModule),
+ typeof(LINGYUN.Abp.IdentityServer.AbpIdentityServerHttpApiModule),
typeof(AbpAccountApplicationModule),
typeof(AbpAccountHttpApiModule),
- typeof(AbpIdentityServerApplicationModule),
- typeof(AbpIdentityServerHttpApiModule),
typeof(AbpSettingManagementApplicationModule),
typeof(AbpSettingManagementHttpApiModule),
typeof(AbpPermissionManagementApplicationModule),
@@ -131,7 +130,8 @@ namespace LINGYUN.BackendAdmin
{
// Rename IdentityServer.Client.ManagePermissions
// See https://github.com/abpframework/abp/blob/dev/modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer/Volo/Abp/PermissionManagement/IdentityServer/AbpPermissionManagementDomainIdentityServerModule.cs
- options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = AbpIdentityServerPermissions.Clients.ManagePermissions;
+ options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] =
+ LINGYUN.Abp.IdentityServer.AbpIdentityServerPermissions.Clients.ManagePermissions;
});
// 自定义需要处理的异常
diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
index 7c5d91527..6295369b7 100644
--- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
+++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj
@@ -44,8 +44,6 @@
-
-
@@ -64,6 +62,8 @@
+
+
@@ -81,4 +81,6 @@
+
+