using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using ZhonTai.Admin.Core.Attributes; using ZhonTai.Common.Helpers; using ZhonTai.Admin.Core.Dto; using ZhonTai.Admin.Domain.Role; using ZhonTai.Admin.Domain.RolePermission; using ZhonTai.Admin.Domain.Tenant; using ZhonTai.Admin.Domain.User; using ZhonTai.Admin.Domain.UserRole; using ZhonTai.Admin.Services.Tenant.Dto; using ZhonTai.Admin.Domain.Tenant.Dto; using ZhonTai.DynamicApi; using ZhonTai.DynamicApi.Attributes; using ZhonTai.Admin.Core.Consts; using ZhonTai.Admin.Core.Configs; using ZhonTai.Admin.Domain.Org; using ZhonTai.Admin.Domain.UserStaff; using ZhonTai.Admin.Domain.UserOrg; using Microsoft.AspNetCore.Identity; using System.Linq.Expressions; using System; using System.Collections.Generic; using Yitter.IdGenerator; using ZhonTai.Admin.Domain.Pkg; using ZhonTai.Admin.Domain.TenantPkg; using ZhonTai.Admin.Services.Pkg; using ZhonTai.Admin.Domain.Platform; using ZhonTai.Admin.Repositories.Platform; using ZhonTai.Admin.Core.Auth; namespace ZhonTai.Admin.Services.Tenant; /// /// 租户服务 /// [Order(50)] [DynamicApi(Area = AdminConsts.AreaName)] public class TenantService : BaseService, ITenantService, IDynamicApi { private AppConfig _appConfig => LazyGetRequiredService(); private ITenantRepository _tenantRepository => LazyGetRequiredService(); private IRoleRepository _roleRepository => LazyGetRequiredService(); private IUserRepository _userRepository => LazyGetRequiredService(); private IOrgRepository _orgRepository => LazyGetRequiredService(); private IUserRoleRepository _userRoleRepository => LazyGetRequiredService(); private IRolePermissionRepository _rolePermissionRepository => LazyGetRequiredService(); private IUserStaffRepository _userStaffRepository => LazyGetRequiredService(); private IUserOrgRepository _userOrgRepository => LazyGetRequiredService(); private IPasswordHasher _passwordHasher => LazyGetRequiredService>(); private ITenantPkgRepository _tenantPkgRepository => LazyGetRequiredService(); private IPlatformUserRepository _platformUserRepository => LazyGetRequiredService(); public TenantService() { } /// /// 查询 /// /// /// public async Task GetAsync(long id) { using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant)) { var tenant = await _tenantRepository.Select .WhereDynamic(id) .IncludeMany(a => a.Pkgs.Select(b => new PkgEntity { Id = b.Id, Name = b.Name })) .FirstAsync(a => new TenantGetOutput { Name = a.Org.Name, Code = a.Org.Code, Pkgs = a.Pkgs, UserName = a.User.UserName, RealName = a.User.Name, Phone = a.User.Mobile, Email = a.User.Email, }); return tenant; } } /// /// 查询分页 /// /// /// [HttpPost] public async Task> GetPageAsync(PageInput input) { using var _ = _tenantRepository.DataFilter.Disable(FilterNames.Tenant); var key = input.Filter?.Name; var list = await _tenantRepository.Select .WhereDynamicFilter(input.DynamicFilter) .WhereIf(key.NotNull(), a => a.Org.Name.Contains(key)) .Count(out var total) .OrderByDescending(true, a => a.Id) .IncludeMany(a => a.Pkgs.Select(b => new PkgEntity { Name = b.Name })) .Page(input.CurrentPage, input.PageSize) .ToListAsync(a => new TenantListOutput { Name = a.Org.Name, Code = a.Org.Code, UserName = a.User.UserName, RealName = a.User.Name, Phone = a.User.Mobile, Email = a.User.Email, Pkgs = a.Pkgs, }); var data = new PageOutput() { List = Mapper.Map>(list), Total = total }; return data; } /// /// 新增 /// /// /// [AdminTransaction] public virtual async Task AddAsync(TenantAddInput input) { using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant)) { var existsOrg = await _orgRepository.Select .Where(a => (a.Name == input.Name || a.Code == input.Code) && a.ParentId == 0) .FirstAsync(a => new { a.Name, a.Code }); if (existsOrg != null) { if (existsOrg.Name == input.Name) { throw ResultOutput.Exception($"企业名称已存在"); } if (existsOrg.Code == input.Code) { throw ResultOutput.Exception($"企业编码已存在"); } } Expression> where = (a => a.UserName == input.UserName); where = where.Or(input.Phone.NotNull(), a => a.Mobile == input.Phone) .Or(input.Email.NotNull(), a => a.Email == input.Email); var existsUser = await _userRepository.Select.Where(where) .FirstAsync(a => new { a.UserName, a.Mobile, a.Email }); if (existsUser != null) { if (existsUser.UserName == input.UserName) { throw ResultOutput.Exception($"企业账号已存在"); } if (input.Phone.NotNull() && existsUser.Mobile == input.Phone) { throw ResultOutput.Exception($"企业手机号已存在"); } if (input.Email.NotNull() && existsUser.Email == input.Email) { throw ResultOutput.Exception($"企业邮箱已存在"); } } //添加租户 TenantEntity entity = Mapper.Map(input); TenantEntity tenant = await _tenantRepository.InsertAsync(entity); long tenantId = tenant.Id; //添加租户套餐 if (input.PkgIds != null && input.PkgIds.Any()) { var pkgs = input.PkgIds.Select(pkgId => new TenantPkgEntity { TenantId = tenantId, PkgId = pkgId }).ToList(); await _tenantPkgRepository.InsertAsync(pkgs); } //添加部门 var org = new OrgEntity { TenantId = tenantId, Name = input.Name, Code = input.Code, ParentId = 0, MemberCount = 1, Sort = 1, Enabled = true }; await _orgRepository.InsertAsync(org); //添加用户 if (input.Password.IsNull()) { input.Password = _appConfig.DefaultPassword; } var user = new UserEntity { TenantId = tenantId, UserName = input.UserName, Name = input.RealName, Mobile = input.Phone, Email = input.Email, Type = UserType.TenantAdmin, OrgId = org.Id, Enabled = true }; if (_appConfig.PasswordHasher) { user.Password = _passwordHasher.HashPassword(user, input.Password); user.PasswordEncryptType = PasswordEncryptType.PasswordHasher; } else { user.Password = MD5Encrypt.Encrypt32(input.Password); user.PasswordEncryptType = PasswordEncryptType.MD5Encrypt32; } await _userRepository.InsertAsync(user); long userId = user.Id; //添加用户员工 var emp = new UserStaffEntity { Id = userId, TenantId = tenantId }; await _userStaffRepository.InsertAsync(emp); //添加用户部门 var userOrg = new UserOrgEntity { UserId = userId, OrgId = org.Id }; await _userOrgRepository.InsertAsync(userOrg); //添加角色分组和角色 var roleGroupId = YitIdHelper.NextId(); var roleId = YitIdHelper.NextId(); var jobGroupId = YitIdHelper.NextId(); var roles = new List{ new RoleEntity { Id = roleGroupId, ParentId = 0, TenantId = tenantId, Type = RoleType.Group, Name = "系统默认", Sort = 1 }, new RoleEntity { Id = roleId, TenantId = tenantId, Type = RoleType.Role, Name = "主管理员", Code = "main-admin", ParentId = roleGroupId, DataScope = DataScope.All, Sort = 1 }, new RoleEntity { Id= jobGroupId, ParentId = 0, TenantId = tenantId, Type = RoleType.Group, Name = "岗位", Sort = 2 }, new RoleEntity { TenantId = tenantId, Type = RoleType.Role, Name = "普通员工", Code = "emp", ParentId = jobGroupId, DataScope = DataScope.Self, Sort = 2 } }; await _roleRepository.InsertAsync(roles); //添加用户角色 var userRole = new UserRoleEntity() { UserId = userId, RoleId = roleId }; await _userRoleRepository.InsertAsync(userRole); //新增平台用户 string invite = await CreateInviteCode(); var platfromUser = new PlatformUserEntity() { TenantId = tenantId, Name = user.UserName, Phone = user.Mobile, Password = user.Password, Role = "1", ParentId = "0_", InviteCode = invite }; await _platformUserRepository.InsertAsync(platfromUser); long platfromUserId = platfromUser.Id; //更新租户的用户和部门 tenant.UserId = userId; tenant.OrgId = org.Id; tenant.PlatfromUserId = platfromUserId; await _tenantRepository.UpdateAsync(tenant); return tenant.Id; } } /// /// 修改 /// /// /// public async Task UpdateAsync(TenantUpdateInput input) { using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant)) { var tenant = await _tenantRepository.GetAsync(input.Id); if (!(tenant?.Id > 0)) { throw ResultOutput.Exception("租户不存在"); } var existsOrg = await _orgRepository.Select .Where(a => a.Id != tenant.OrgId && (a.Name == input.Name || a.Code == input.Code)) .FirstAsync(a => new { a.Name, a.Code }); if (existsOrg != null) { if (existsOrg.Name == input.Name) { throw ResultOutput.Exception($"企业名称已存在"); } if (existsOrg.Code == input.Code) { throw ResultOutput.Exception($"企业编码已存在"); } } Expression> where = (a => a.UserName == input.UserName); where = where.Or(input.Phone.NotNull(), a => a.Mobile == input.Phone) .Or(input.Email.NotNull(), a => a.Email == input.Email); var existsUser = await _userRepository.Select.Where(a => a.Id != tenant.UserId).Where(where) .FirstAsync(a => new { a.Id, a.Name, a.UserName, a.Mobile, a.Email }); if (existsUser != null) { if (existsUser.UserName == input.UserName) { throw ResultOutput.Exception($"企业账号已存在"); } if (input.Phone.NotNull() && existsUser.Mobile == input.Phone) { throw ResultOutput.Exception($"企业手机号已存在"); } if (input.Email.NotNull() && existsUser.Email == input.Email) { throw ResultOutput.Exception($"企业邮箱已存在"); } } //更新用户 await _userRepository.UpdateDiy.DisableGlobalFilter(FilterNames.Tenant).SetSource( new UserEntity() { Id = tenant.UserId, Name = input.RealName, UserName = input.UserName, Mobile = input.Phone, Email = input.Email }) .UpdateColumns(a => new { a.Name, a.UserName, a.Mobile, a.Email, a.ModifiedTime }).ExecuteAffrowsAsync(); //更新部门 await _orgRepository.UpdateDiy.DisableGlobalFilter(FilterNames.Tenant).SetSource( new OrgEntity() { Id = tenant.OrgId, Name = input.Name, Code = input.Code }) .UpdateColumns(a => new { a.Name, a.Code, a.ModifiedTime }).ExecuteAffrowsAsync(); //更新租户 await _tenantRepository.UpdateDiy.DisableGlobalFilter(FilterNames.Tenant).SetSource( new TenantEntity() { Id = tenant.Id, Description = input.Description, }) .UpdateColumns(a => new { a.Description, a.ModifiedTime }).ExecuteAffrowsAsync(); //更新租户套餐 await _tenantPkgRepository.DeleteAsync(a => a.TenantId == tenant.Id); if (input.PkgIds != null && input.PkgIds.Any()) { var pkgs = input.PkgIds.Select(pkgId => new TenantPkgEntity { TenantId = tenant.Id, PkgId = pkgId }).ToList(); await _tenantPkgRepository.InsertAsync(pkgs); //清除租户下所有用户权限缓存 await LazyGetRequiredService().ClearUserPermissionsAsync(new List { tenant.Id }); } //更新平台用户 await _platformUserRepository.UpdateDiy.SetSource(new PlatformUserEntity() { Id=tenant.PlatfromUserId, Name = input.RealName, Phone = input.Phone, }).UpdateColumns(m => new { m.Name, m.Phone }).ExecuteAffrowsAsync(); ; } } /// /// 彻底删除 /// /// /// [AdminTransaction] public virtual async Task DeleteAsync(long id) { using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant)) { var tenantType = await _tenantRepository.Select.WhereDynamic(id).ToOneAsync(a => a.TenantType); if (tenantType == TenantType.Platform) { throw ResultOutput.Exception("平台租户禁止删除"); } //删除角色权限 await _rolePermissionRepository.Where(a => a.Role.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除用户角色 await _userRoleRepository.Where(a => a.User.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除员工 await _userStaffRepository.Where(a => a.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除用户部门 await _userOrgRepository.Where(a => a.User.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除部门 await _orgRepository.Where(a => a.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除用户 await _userRepository.Where(a => a.TenantId == id && a.Type != UserType.Member).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除角色 await _roleRepository.Where(a => a.TenantId == id).DisableGlobalFilter(FilterNames.Tenant).ToDelete().ExecuteAffrowsAsync(); //删除租户套餐 await _tenantPkgRepository.DeleteAsync(a => a.TenantId == id); //删除租户 await _tenantRepository.DeleteAsync(id); //清除租户下所有用户权限缓存 await LazyGetRequiredService().ClearUserPermissionsAsync(new List { id }); } } /// /// 删除 /// /// /// [AdminTransaction] public virtual async Task SoftDeleteAsync(long id) { using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant)) { var tenantType = await _tenantRepository.Select.WhereDynamic(id).ToOneAsync(a => a.TenantType); if (tenantType == TenantType.Platform) { throw ResultOutput.Exception("平台租户禁止删除"); } //删除部门 await _orgRepository.SoftDeleteAsync(a => a.TenantId == id, FilterNames.Tenant); //删除用户 await _userRepository.SoftDeleteAsync(a => a.TenantId == id && a.Type != UserType.Member, FilterNames.Tenant); //删除角色 await _roleRepository.SoftDeleteAsync(a => a.TenantId == id, FilterNames.Tenant); //删除租户 var result = await _tenantRepository.SoftDeleteAsync(id); //清除租户下所有用户权限缓存 await LazyGetRequiredService().ClearUserPermissionsAsync(new List { id }); } } /// /// 批量删除 /// /// /// [AdminTransaction] public virtual async Task BatchSoftDeleteAsync(long[] ids) { using (_tenantRepository.DataFilter.Disable(FilterNames.Tenant)) { var tenantType = await _tenantRepository.Select.WhereDynamic(ids).ToOneAsync(a => a.TenantType); if (tenantType == TenantType.Platform) { throw ResultOutput.Exception("平台租户禁止删除"); } //删除部门 await _orgRepository.SoftDeleteAsync(a => ids.Contains(a.TenantId.Value), FilterNames.Tenant); //删除用户 await _userRepository.SoftDeleteAsync(a => ids.Contains(a.TenantId.Value) && a.Type != UserType.Member, FilterNames.Tenant); //删除角色 await _roleRepository.SoftDeleteAsync(a => ids.Contains(a.TenantId.Value), FilterNames.Tenant); //删除租户 var result = await _tenantRepository.SoftDeleteAsync(ids); //清除租户下所有用户权限缓存 await LazyGetRequiredService().ClearUserPermissionsAsync(ids.ToList()); } } /// /// 设置启用 /// /// /// public async Task SetEnableAsync(TenantSetEnableInput input) { var entity = await _tenantRepository.GetAsync(input.TenantId); if (entity.TenantType == TenantType.Platform) { throw ResultOutput.Exception("平台租户禁止禁用"); } entity.Enabled = input.Enabled; await _tenantRepository.UpdateAsync(entity); } private async Task CreateInviteCode() { string invite = StringHelper.GenerateRandomNumber(); var count = await _platformUserRepository.Select.Where(m => m.InviteCode == invite).CountAsync(); if (count > 0) { invite = await CreateInviteCode(); } return invite; } }