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);
if (isExist) throw Oops.Oh(ErrorCodeEnum.D1300);
isExist = await _userRep.AsQueryable().Filter(null, true).AnyAsync(u => u.Account == input.AdminName);
if (isExist) throw Oops.Oh(ErrorCodeEnum.D1301);
var tenant = input.Adapt();
await _tenantRep.InsertAsync(tenant);
await UpdateTenantCache();
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);
// 默认租户管理员角色菜单集合
var menuIdList = new List { 252885263002100,252885263002110,252885263002111,
252885263005200,252885263005210,252885263005211,252885263005212,252885263005213,252885263005214,252885263005215,252885263005216,252885263005217,252885263005218,252885263005219,252885263015220,
252885263005220,252885263005221,252885263005222,252885263005223,252885263005224,252885263005225,252885263005226,252885263005227,
252885263005230,252885263005231,
252885263005240,252885263005241,252885263005242,252885263005243,252885263005244,
252885263005250,252885263005251,252885263005252,252885263005253,252885263005254,
252885263005260,252885263005261,252885263005262,252885263005263,
252885263005270,252885263005271,252885263005272,252885263005273,252885263005274,252885263005275,252885263005276
};
await _sysRoleMenuService.GrantRoleMenu(new RoleMenuInput() { Id = newRole.Id, MenuIdList = menuIdList });
}
///
/// 删除租户
///
///
///
[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 config = new DbConnectionConfig
{
EnableInitDb = true,
EnableDiffLog = false,
DbType = tenant.DbType,
ConfigId = tenant.Id.ToString(),
ConnectionString = tenant.Connection,
IsAutoCloseConnection = true,
};
SqlSugarSetup.InitTenantDatabase(App.GetRequiredService().AsTenant(), config);
}
}