namespace Admin.NET.Core.Service; /// /// 系统租户管理服务 /// [ApiDescriptionSettings(Order = 140)] public class SysTenantService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _tenantRep; private readonly SqlSugarRepository _orgRep; private readonly SqlSugarRepository _roleRep; private readonly SqlSugarRepository _posRep; private readonly SqlSugarRepository _userRep; private readonly SqlSugarRepository _sysUserExtOrgRep; private readonly SqlSugarRepository _sysRoleMenuRep; private readonly SqlSugarRepository _userRoleRep; private readonly SysUserRoleService _sysUserRoleService; private readonly SysRoleMenuService _sysRoleMenuService; private readonly SysConfigService _sysConfigService; private readonly SysCacheService _sysCacheService; public SysTenantService(SqlSugarRepository tenantRep, SqlSugarRepository orgRep, SqlSugarRepository roleRep, SqlSugarRepository posRep, SqlSugarRepository userRep, SqlSugarRepository sysUserExtOrgRep, SqlSugarRepository sysRoleMenuRep, SqlSugarRepository userRoleRep, SysUserRoleService sysUserRoleService, SysRoleMenuService sysRoleMenuService, SysConfigService sysConfigService, SysCacheService sysCacheService) { _tenantRep = tenantRep; _orgRep = orgRep; _roleRep = roleRep; _posRep = posRep; _userRep = userRep; _sysUserExtOrgRep = sysUserExtOrgRep; _sysRoleMenuRep = sysRoleMenuRep; _userRoleRep = userRoleRep; _sysUserRoleService = sysUserRoleService; _sysRoleMenuService = sysRoleMenuService; _sysConfigService = sysConfigService; _sysCacheService = sysCacheService; } /// /// 获取租户分页列表 /// /// /// [HttpGet("/sysTenant/page")] public async Task> GetTenantPage([FromQuery] PageTenantInput input) { return await _tenantRep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Phone), u => u.Phone.Contains(input.Phone.Trim())) .ToPagedListAsync(input.Page, input.PageSize); } /// /// 获取库隔离的租户列表 /// /// [NonAction] public async Task> GetTenantDbList() { return await _tenantRep.GetListAsync(u => u.TenantType == TenantTypeEnum.Db && u.Status == StatusEnum.Enable); } /// /// 增加租户 /// /// /// [HttpPost("/sysTenant/add")] public async Task AddTenant(AddTenantInput input) { var isExist = await _tenantRep.IsAnyAsync(u => u.Name == input.Name || (u.AdminName == input.AdminName && input.TenantType == TenantTypeEnum.Id)); if (isExist) throw Oops.Oh(ErrorCodeEnum.D1300); var tenant = input.Adapt(); await _tenantRep.InsertAsync(tenant); await UpdateTenantCache(); if (tenant.TenantType == TenantTypeEnum.Db) return; await InitNewTenant(tenant); } /// /// 设置租户状态 /// /// /// [HttpPost("/sysTenant/setStatus")] public async Task SetTenantStatus(TenantInput input) { var tenant = await _tenantRep.GetFirstAsync(u => u.Id == input.Id); if (tenant.ConfigId == SqlSugarConst.ConfigId) throw Oops.Oh(ErrorCodeEnum.Z1001); if (!Enum.IsDefined(typeof(StatusEnum), input.Status)) throw Oops.Oh(ErrorCodeEnum.D3005); tenant.Status = input.Status; return await _tenantRep.AsUpdateable(tenant).UpdateColumns(u => new { u.Status }).ExecuteCommandAsync(); } /// /// 新增租户初始化(Id隔离) /// /// private async Task InitNewTenant(SysTenant newTenant) { long tenantId = newTenant.Id; string admin = newTenant.AdminName; string companyName = newTenant.Name; // 初始化租户(组织结构) var newOrg = new SysOrg { TenantId = tenantId, Pid = 0, Name = companyName, Code = companyName, Remark = companyName, }; await _orgRep.InsertAsync(newOrg); // 初始化角色 var newRole = new SysRole { TenantId = tenantId, Code = CommonConst.SysAdminRole, Name = "租户管理员-" + companyName, DataScope = DataScopeEnum.All, Remark = companyName }; await _roleRep.InsertAsync(newRole); var newPos = new SysPos { Name = "租户管理员", Code = "adminTenant", TenantId = tenantId, Remark = companyName, }; await _posRep.InsertAsync(newPos); // 初始化租户管理员 var password = await _sysConfigService.GetConfigValue(CommonConst.SysPassword); var newUser = new SysUser { TenantId = tenantId, Account = admin, Password = MD5Encryption.Encrypt(password), NickName = newTenant.AdminName, Email = newTenant.Email, Phone = newTenant.Phone, AccountType = AccountTypeEnum.Admin, OrgId = newOrg.Id, PosId = newPos.Id, Birthday = DateTime.Parse("1986-06-28"), RealName = "租户管理员", Remark = "租户管理员" + companyName, }; await _userRep.InsertAsync(newUser); var newUserRole = new SysUserRole { RoleId = newRole.Id, UserId = newUser.Id }; await _userRoleRep.InsertAsync(newUserRole); } /// /// 删除租户 /// /// /// [HttpPost("/sysTenant/delete")] public async Task DeleteTenant(DeleteTenantInput input) { var users = await _userRep.AsQueryable().Filter(null, true).Where(u => u.TenantId == input.Id).ToListAsync(); // 超级管理员所在租户为默认租户 if (users.Any(u => u.AccountType == AccountTypeEnum.SuperAdmin)) throw Oops.Oh(ErrorCodeEnum.D1023); var entity = await _tenantRep.GetFirstAsync(u => u.Id == input.Id); await _tenantRep.DeleteAsync(entity); await UpdateTenantCache(); // 删除与租户相关的表数据 var userIds = users.Select(u => u.Id).ToList(); await _userRep.AsDeleteable().Where(u => userIds.Contains(u.Id)).ExecuteCommandAsync(); await _userRoleRep.AsDeleteable().Where(u => userIds.Contains(u.UserId)).ExecuteCommandAsync(); await _sysUserExtOrgRep.AsDeleteable().Where(u => userIds.Contains(u.UserId)).ExecuteCommandAsync(); await _roleRep.AsDeleteable().Where(u => u.TenantId == input.Id).ExecuteCommandAsync(); var roleIds = await _roleRep.AsQueryable().Filter(null, true) .Where(u => u.TenantId == input.Id).Select(u => u.Id).ToListAsync(); await _sysRoleMenuRep.AsDeleteable().Where(u => roleIds.Contains(u.RoleId)).ExecuteCommandAsync(); await _orgRep.AsDeleteable().Where(u => u.TenantId == input.Id).ExecuteCommandAsync(); await _posRep.AsDeleteable().Where(u => u.TenantId == input.Id).ExecuteCommandAsync(); } /// /// 更新租户 /// /// /// [HttpPost("/sysTenant/update")] public async Task UpdateTenant(UpdateTenantInput input) { var entity = input.Adapt(); await _tenantRep.Context.Updateable(entity).IgnoreColumns(true).ExecuteCommandAsync(); var tenantAdminUser = await GetTenantAdminUser(input.Id); if (tenantAdminUser == null) return; tenantAdminUser.Account = entity.AdminName; await _userRep.Context.Updateable(tenantAdminUser).UpdateColumns(u => new { u.Account }).ExecuteCommandAsync(); await UpdateTenantCache(); } /// /// 授权租户管理员角色菜单 /// /// /// [HttpPost("/sysTenant/grantMenu")] public async Task GrantMenu(RoleMenuInput input) { var tenantAdminUser = await GetTenantAdminUser(input.Id); if (tenantAdminUser == null) return; var roleIds = await _sysUserRoleService.GetUserRoleIdList(tenantAdminUser.Id); input.Id = roleIds[0]; // 重置租户管理员角色Id await _sysRoleMenuService.GrantRoleMenu(input); } /// /// 获取租户管理员角色拥有菜单树 /// /// /// [HttpGet("/sysTenant/ownMenuTree")] public async Task> OwnMenuTree([FromQuery] TenantInput input) { var tenantAdminUser = await GetTenantAdminUser(input.Id); if (tenantAdminUser == null) return new List(); var roleIds = await _sysUserRoleService.GetUserRoleIdList(tenantAdminUser.Id); return await _sysRoleMenuService.GetRoleMenuTree(new List { roleIds[0] }); } /// /// 获取租户管理员角色拥有菜单树 /// /// /// [HttpGet("/sysTenant/ownMenuList")] public async Task> OwnMenuList([FromQuery] TenantInput input) { var tenantAdminUser = await GetTenantAdminUser(input.Id); if (tenantAdminUser == null) return new List(); var roleIds = await _sysUserRoleService.GetUserRoleIdList(tenantAdminUser.Id); return await _sysRoleMenuService.GetRoleMenuList(new List { roleIds[0] }); } /// /// 重置租户管理员密码 /// /// /// [HttpPost("/sysTenant/resetPwd")] public async Task ResetTenantPwd(TenantInput input) { var password = await _sysConfigService.GetConfigValue(CommonConst.SysPassword); var tenantAdminUser = await GetTenantAdminUser(input.Id); tenantAdminUser.Password = MD5Encryption.Encrypt(password); await _userRep.UpdateAsync(tenantAdminUser); } /// /// 获取租户 /// /// /// [NonAction] public async Task GetTenant(long tenantId) { return await _tenantRep.GetFirstAsync(u => u.Id == tenantId); } /// /// 获取租户管理员用户 /// /// /// private async Task GetTenantAdminUser(long tenantId) { return await _userRep.GetFirstAsync(u => u.TenantId == tenantId && u.AccountType == AccountTypeEnum.Admin); } /// /// 缓存所有租户 /// /// [NonAction] public async Task UpdateTenantCache() { _sysCacheService.Remove(CacheConst.KeyTenant); var tenantList = await _tenantRep.GetListAsync(); _sysCacheService.Set(CacheConst.KeyTenant, tenantList); } /// /// 创建租户数据库(根据默认库结构) /// /// /// [HttpPost("/sysTenant/createDb")] public async Task CreateTenantDb(TenantInput input) { var tenant = await _tenantRep.GetFirstAsync(u => u.Id == input.Id); if (tenant == null) return; if (tenant.DbType == SqlSugar.DbType.Oracle) throw Oops.Oh(ErrorCodeEnum.Z1002); var dbConnection = new DbConnectionConfig { EnableInitDb = true, DbType = tenant.DbType, ConfigId = tenant.ConfigId, ConnectionString = tenant.Connection, IsAutoCloseConnection = true, }; SqlSugarSetup.SetDbConfig(dbConnection); var db = App.GetRequiredService(); db.AsTenant().AddConnection(dbConnection); db.DbMaintenance.CreateDatabase(); SqlSugarSetup.InitDataBase(db.AsTenant(), dbConnection, tenant.Id); } }