using JNPF.Common.Const; using JNPF.Common.Core.Manager; using JNPF.Common.Enums; using JNPF.Common.Extension; using JNPF.Common.Filter; using JNPF.Common.Manager; using JNPF.Common.Security; using JNPF.DatabaseAccessor; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.Systems.Entitys.Dto.Role; using JNPF.Systems.Entitys.Permission; using JNPF.Systems.Interfaces.Permission; using Mapster; using Microsoft.AspNetCore.Mvc; using SqlSugar; namespace JNPF.Systems; /// /// 业务实现:角色信息. /// [ApiDescriptionSettings(Tag = "Permission", Name = "Role", Order = 167)] [Route("api/permission/[controller]")] public class RoleService : IRoleService, IDynamicApiController, ITransient { /// /// 基础仓储. /// private readonly ISqlSugarRepository _repository; /// /// 操作权限服务. /// private readonly IAuthorizeService _authorizeService; /// /// 缓存管理器. /// private readonly ICacheManager _cacheManager; /// /// 用户管理. /// private readonly IUserManager _userManager; /// /// 机构表服务. /// private readonly IOrganizeService _organizeService; /// /// 初始化一个类型的新实例. /// public RoleService( ISqlSugarRepository repository, IAuthorizeService authorizeService, ICacheManager cacheManager, IOrganizeService organizeService, IUserManager userManager) { _repository = repository; _authorizeService = authorizeService; _cacheManager = cacheManager; _organizeService = organizeService; _userManager = userManager; } #region GET /// /// 获取列表. /// /// 参数. /// [HttpGet("")] public async Task GetList([FromQuery] RoleListInput input) { // 获取分级管理组织 var dataScope = _userManager.DataScope.Where(x => x.Select).Select(x => x.organizeId).Distinct().ToList(); PageInputBase? pageInput = input.Adapt(); // 处理组织树 名称 List? orgTreeNameList = _organizeService.GetOrgListTreeName(); #region 获取组织层级 List? childOrgIds = new List(); if (input.organizeId.IsNotEmptyOrNull() && input.organizeId != "0") { childOrgIds.Add(input.organizeId); // 根据组织Id 获取所有子组织Id集合 childOrgIds.AddRange(_repository.AsSugarClient().Queryable().ToChildList(x => x.ParentId, input.organizeId).Select(x => x.Id).ToList()); childOrgIds = childOrgIds.Distinct().ToList(); } #endregion SqlSugarPagedList? data = new SqlSugarPagedList(); if (childOrgIds.Any()) { // 拼接查询 List>? listQuery = new List>(); foreach (string item in childOrgIds) { var quer = _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.ObjectId)) .Where((a, b) => item == a.OrganizeId) .WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => b.FullName.Contains(pageInput.keyword) || b.EnCode.Contains(pageInput.keyword)) .WhereIF(!_userManager.IsAdministrator, a => dataScope.Contains(a.ObjectId)) .Where((a, b) => b.DeleteMark == null) .Select((a, b) => new RoleListOutput { id = b.Id, parentId = b.Type, type = SqlFunc.IIF(b.GlobalMark == 1, "全局", "组织"), enCode = b.EnCode, fullName = b.FullName, enabledMark = b.EnabledMark, creatorTime = b.CreatorTime, sortCode = b.SortCode }); listQuery.Add(quer); } var sql = _repository.AsSugarClient().UnionAll(listQuery).Where(a => !SqlFunc.IsNullOrEmpty(a.id)).ToSqlString(); data = await _repository.AsSugarClient().UnionAll(listQuery).Where(a => !SqlFunc.IsNullOrEmpty(a.id)) .GroupBy(a => new { a.id, a.parentId, a.type, a.creatorTime, a.enCode, a.fullName, a.sortCode, a.enabledMark }) .Select(a => new RoleListOutput { id = a.id, parentId = a.parentId, type = a.type, creatorTime = a.creatorTime, enCode = a.enCode, fullName = a.fullName, sortCode = a.sortCode }).ToPagedListAsync(input.currentPage, input.pageSize); } else { data = await _repository.AsSugarClient().Queryable() .WhereIF(input.organizeId == "0", a => a.GlobalMark == 1) .WhereIF(!_userManager.IsAdministrator, a => a.GlobalMark == 0) .WhereIF(!_userManager.IsAdministrator, a => a.GlobalMark == 1) .WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword)) .Where(a => a.DeleteMark == null) .Select((a) => new RoleListOutput { id = a.Id, parentId = a.Type, type = SqlFunc.IIF(a.GlobalMark == 1, "全局", "组织"), enCode = a.EnCode, fullName = a.FullName, description = a.Description, enabledMark = a.EnabledMark, creatorTime = a.CreatorTime, sortCode = a.SortCode }).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize); } #region 处理 多组织 List? orgUserIdAll = await _repository.AsSugarClient().Queryable() .Where(x => data.list.Select(u => u.id).Contains(x.ObjectId)).ToListAsync(); foreach (RoleListOutput? item in data.list) { // 获取组织集合 var organizeList = orgUserIdAll.Where(x => x.ObjectId == item.id).Select(x => x.OrganizeId).ToList(); item.organizeInfo = string.Join(" ; ", orgTreeNameList.Where(x => organizeList.Contains(x.Id)).Select(x => x.Description)); item.sortCode = 999; if (organizeList.Contains(input.organizeId)) item.sortCode = 0; } data.list = data.list.OrderBy(x => x.sortCode).ToList(); #endregion return PageResult.SqlSugarPageResult(data); } /// /// 获取下拉框(类型+角色). /// /// [HttpGet("Selector")] public async Task GetSelector() { var orgInfoList = _organizeService.GetOrgListTreeName(); // 获取所有组织 对应 的 角色id集合 var ridList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role") .Select(x => new { x.ObjectId, x.OrganizeId }).ToListAsync(); // 获取 全局角色 和 组织角色 List? roleList = await _repository.AsQueryable().Where(a => a.DeleteMark == null && a.EnabledMark.Equals(1)) .Where(a => a.GlobalMark == 1 || ridList.Select(x => x.ObjectId).Contains(a.Id)) .Select(a => new RoleListOutput { id = a.Id, parentId = a.GlobalMark.ToString(), fullName = a.FullName, enabledMark = a.EnabledMark, creatorTime = a.CreatorTime, type = "role", //organize = SqlFunc.IIF(a.GlobalMark == 1, "全局角色", "组织角色"), icon = "icon-ym icon-ym-generator-role", sortCode = 0 }).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToListAsync(); for (int i = 0; i < roleList.Count; i++) roleList[i].onlyId = "role_" + i; // 处理 组织角色 roleList.Where(x => ridList.Select(x => x.ObjectId).Contains(x.id)).ToList().ForEach(item => { var oolist = ridList.Where(x => x.ObjectId == item.id).ToList(); item.organize = string.Join(",", orgInfoList.Where(x => oolist.Select(x => x.OrganizeId).Contains(x.Id)).Select(x => x.Description)); for (int i = 0; i < oolist.Count; i++) { if (i == 0) { item.parentId = oolist.FirstOrDefault().OrganizeId; } else { // 该角色属于多个组织 RoleListOutput? newItem = item.ToObject(); newItem.parentId = oolist[i].OrganizeId; roleList.Add(newItem); } } }); // 设置 全局 根目录 List? treeList = new List() { new RoleListOutput() { id = "1", type = string.Empty, parentId = "-1", enCode = string.Empty, fullName = "全局", num = roleList.Count(x => x.parentId == "1") } }; List? organizeList = orgInfoList.Select(x => new RoleListOutput() { id = x.Id, type = x.Category, parentId = x.ParentId, organize = x.Description, organizeInfo = x.OrganizeIdTree, icon = x.Category == "company" ? "icon-ym icon-ym-tree-organization3" : "icon-ym icon-ym-tree-department1", fullName = x.FullName, sortCode = 1 }).ToList(); treeList.AddRange(organizeList); for (int i = 0; i < treeList.Count; i++) { treeList[i].onlyId = "organizeList_" + i; treeList[i].num = roleList.Count(x => x.parentId == treeList[i].id); } treeList.Where(x => x.num > 0).ToList().ForEach(item => { if (item.organizeInfo.IsNotEmptyOrNull()) { treeList.Where(x => !x.id.Equals("1") && x.organizeInfo.IsNotEmptyOrNull()).Where(x => item.organizeInfo.Contains(x.id)).ToList().ForEach(it => { if (it != null && it.num < 1) it.num = item.num; }); } }); var res = treeList.Where(x => x.num > 0).Union(roleList).OrderBy(x => x.sortCode).ToList().ToTree("-1"); return new { list = OrderbyTree(res) }; } /// /// 获取下拉框,有分级管理查看权限(类型+角色). /// /// [HttpGet("SelectorByPermission")] public async Task GetSelectorByPermission() { // 获取分级管理组织 var dataScope = _userManager.DataScope.Where(x => x.Edit).Select(x => x.organizeId).Distinct().ToList(); var ridList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role") .WhereIF(!_userManager.IsAdministrator, x => dataScope.Contains(x.OrganizeId)) .Select(x => new { x.ObjectId, x.OrganizeId }).ToListAsync(); // 获取 全局角色 和 组织角色 List? roleList = await _repository.AsQueryable().Where(a => a.DeleteMark == null && a.EnabledMark.Equals(1)) .WhereIF(!_userManager.IsAdministrator, a => a.GlobalMark == 0 && ridList.Select(x => x.ObjectId).Contains(a.Id)) .WhereIF(_userManager.IsAdministrator, a => a.GlobalMark == 1 || ridList.Select(x => x.ObjectId).Contains(a.Id)) .Select(a => new RoleListOutput { id = a.Id, parentId = a.GlobalMark.ToString(), fullName = a.FullName, enabledMark = a.EnabledMark, creatorTime = a.CreatorTime, type = "role", icon = "icon-ym icon-ym-global-role", sortCode = 0 }).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToListAsync(); for (int i = 0; i < roleList.Count; i++) roleList[i].onlyId = "role_" + i; // 处理 组织角色 roleList.Where(x => ridList.Select(x => x.ObjectId).Contains(x.id)).ToList().ForEach(item => { var oolist = ridList.Where(x => x.ObjectId == item.id).ToList(); for (int i = 0; i < oolist.Count; i++) { if (i == 0) { item.parentId = oolist.FirstOrDefault().OrganizeId; } else { // 该角色属于多个组织 RoleListOutput? newItem = item.ToObject(); newItem.parentId = oolist[i].OrganizeId; roleList.Add(newItem); } } }); // 设置 全局 根目录 List? treeList = new List(); if (_userManager.IsAdministrator) treeList.Add(new RoleListOutput() { id = "1", sortCode = 9999, type = string.Empty, parentId = "-1", enCode = string.Empty, fullName = "全局", num = roleList.Count(x => x.parentId == "1") }); // 获取所有组织 List? allOrgList = await _repository.AsSugarClient().Queryable().Where(x => x.DeleteMark == null).ToListAsync(); if (!_userManager.IsAdministrator) { var orgIdList = new List(); allOrgList.Where(x => dataScope.Contains(x.Id)).ToList().ForEach(item => { orgIdList.AddRange(item.OrganizeIdTree.Split(",")); }); allOrgList = allOrgList.Where(x => orgIdList.Contains(x.Id)).ToList(); } List? organizeList = allOrgList.Select(x => new RoleListOutput() { id = x.Id, type = x.Category, parentId = x.ParentId, organizeInfo = x.OrganizeIdTree, sortCode = 11, icon = x.Category == "company" ? "icon-ym icon-ym-tree-organization3" : "icon-ym icon-ym-tree-department1", fullName = x.FullName }).ToList(); treeList.AddRange(organizeList); for (int i = 0; i < treeList.Count; i++) { treeList[i].onlyId = "organizeList_" + i; treeList[i].num = roleList.Count(x => x.parentId == treeList[i].id); } treeList.Where(x => x.num > 0).ToList().ForEach(item => { if (item.organizeInfo.IsNotEmptyOrNull()) { treeList.Where(x => !x.id.Equals("1") && x.organizeInfo.IsNotEmptyOrNull()).Where(x => item.organizeInfo.Contains(x.id)).ToList().ForEach(it => { if (it != null && it.num < 1) it.num = item.num; }); } }); var res = treeList.Where(x => x.num > 0).Union(roleList).OrderBy(x => x.sortCode).ToList().ToTree("-1"); return new { list = OrderbyTree(res) }; } /// /// 获取信息. /// /// 主键. /// [HttpGet("{id}")] public async Task GetInfo(string id) { RoleEntity? entity = await _repository.GetFirstAsync(r => r.Id == id); RoleInfoOutput? output = entity.Adapt(); output.organizeIdsTree = new List>(); List? oIds = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectId == id).ToListAsync(); List? oList = await _repository.AsSugarClient().Queryable().Where(x => oIds.Select(o => o.OrganizeId).Contains(x.Id)).ToListAsync(); oList.ForEach(item => { if (item.OrganizeIdTree.IsNullOrEmpty()) item.OrganizeIdTree = item.Id; List? idList = item.OrganizeIdTree?.Split(",").ToList(); output.organizeIdsTree.Add(idList); }); return output; } #endregion #region POST /// /// 获取角色列表 根据组织Id集合. /// /// 参数. /// [HttpPost("getListByOrgIds")] public async Task GetListByOrgIds([FromBody] RoleListInput input) { // 获取所有组织 对应 的 角色id集合 var ridList = await _repository.AsSugarClient().Queryable() .Where(x => x.ObjectType == "Role" && input.organizeIds.Contains(x.OrganizeId)) .Select(x => new { x.ObjectId, x.OrganizeId }).ToListAsync(); // 获取 全局角色 和 组织角色 List? roleList = await _repository.AsSugarClient().Queryable() .Where(a => a.DeleteMark == null && a.EnabledMark == 1).Where(a => a.GlobalMark == 1 || ridList.Select(x => x.ObjectId).Contains(a.Id)) .Select(a => new RoleListOutput { id = a.Id, type = "role", parentId = a.GlobalMark.ToString(), fullName = a.FullName, enabledMark = a.EnabledMark, creatorTime = a.CreatorTime, sortCode = a.SortCode }).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToListAsync(); for (int i = 0; i < roleList.Count; i++) roleList[i].onlyId = "role_" + i; // 处理 组织角色 roleList.Where(x => ridList.Select(x => x.ObjectId).Contains(x.id)).ToList().ForEach(item => { var oolist = ridList.Where(x => x.ObjectId == item.id).ToList(); for (int i = 0; i < oolist.Count; i++) { if (i == 0) { item.parentId = oolist.FirstOrDefault().OrganizeId; } else { // 该角色属于多个组织 RoleListOutput? newItem = item.ToObject(); newItem.parentId = oolist[i].OrganizeId; roleList.Add(newItem); } } }); List? treeList = new List(); // 获取所有组织 List? allOrgList = await _repository.AsSugarClient().Queryable().OrderBy(x => x.CreatorTime, OrderByType.Asc).ToListAsync(); allOrgList.ForEach(item => { if (item.OrganizeIdTree == null || item.OrganizeIdTree == string.Empty) item.OrganizeIdTree = item.Id; }); List? organizeList = allOrgList.Where(x => input.organizeIds.Contains(x.Id)).Select(x => new RoleListOutput() { id = x.Id, type = x.Category, parentId = "0", enCode = string.Empty, fullName = string.Join("/", allOrgList.Where(all => x.OrganizeIdTree.Split(",").Contains(all.Id)).Select(x => x.FullName)), num = roleList.Count(x => x.parentId == x.id) }).ToList(); treeList.AddRange(organizeList); treeList.Add(new RoleListOutput() { id = "1", type = string.Empty, parentId = "0", enCode = string.Empty, fullName = "全局", num = roleList.Count(x => x.parentId == "1") }); for (int i = 0; i < treeList.Count; i++) treeList[i].onlyId = "organizeList_" + i; return new { list = treeList.Union(roleList).OrderBy(x => x.sortCode).ToList().ToTree("0") }; } /// /// 新建. /// /// 参数. /// [HttpPost("")] [UnitOfWork] public async Task Create([FromBody] RoleCrInput input) { // 全局角色 只能超管才能变更 if (input.globalMark == 1 && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1612); #region 分级权限验证 List? orgIdList = input.organizeIdsTree.Select(x => x.LastOrDefault()).ToList(); if (!_userManager.DataScope.Any(it => orgIdList.Contains(it.organizeId) && it.Add) && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1013); #endregion if (await _repository.IsAnyAsync(r => r.EnCode == input.enCode && r.DeleteMark == null)) throw Oops.Oh(ErrorCode.D1600); if (await _repository.IsAnyAsync(r => r.FullName == input.fullName && r.GlobalMark == input.globalMark && r.DeleteMark == null)) throw Oops.Oh(ErrorCode.D1601); RoleEntity? entity = input.Adapt(); // 删除除了门户外的相关权限 await _repository.AsSugarClient().Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync(); #region 组织角色关系 if (input.globalMark == 0) { List? oreList = new List(); input.organizeIdsTree.ForEach(item => { string? id = item.LastOrDefault(); if (id.IsNotEmptyOrNull()) { OrganizeRelationEntity? oreEntity = new OrganizeRelationEntity(); oreEntity.ObjectType = "Role"; oreEntity.CreatorUserId = _userManager.UserId; oreEntity.ObjectId = entity.Id; oreEntity.OrganizeId = id; oreList.Add(oreEntity); } }); await _repository.AsSugarClient().Insertable(oreList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync(); // 插入关系数据 } #endregion await DelRole(string.Format("{0}_{1}", _userManager.TenantId, _userManager.UserId)); } /// /// 删除. /// /// 主键. /// [HttpDelete("{id}")] [UnitOfWork] public async Task Delete(string id) { RoleEntity? entity = await _repository.GetFirstAsync(r => r.Id == id && r.DeleteMark == null); _ = entity ?? throw Oops.Oh(ErrorCode.D1608); // 全局角色 只能超管才能变更 if (entity.GlobalMark == 1 && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1612); #region 分级权限验证 // 旧数据 List? orgIdList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectId == id && x.ObjectType == "Role").Select(x => x.OrganizeId).ToListAsync(); if (!_userManager.DataScope.Any(it => orgIdList.Contains(it.organizeId) && it.Delete) && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1013); #endregion // 角色下有数据权限不能删 List? items = await _authorizeService.GetAuthorizeItemIds(entity.Id, "resource"); if (items.Count > 0) throw Oops.Oh(ErrorCode.D1603); // 角色下有表单不能删 items = await _authorizeService.GetAuthorizeItemIds(entity.Id, "form"); if (items.Count > 0) throw Oops.Oh(ErrorCode.D1606); // 角色下有列不能删除 items = await _authorizeService.GetAuthorizeItemIds(entity.Id, "column"); if (items.Count > 0) throw Oops.Oh(ErrorCode.D1605); // 角色下有按钮不能删除 items = await _authorizeService.GetAuthorizeItemIds(entity.Id, "button"); if (items.Count > 0) throw Oops.Oh(ErrorCode.D1604); // 角色下有菜单不能删 items = await _authorizeService.GetAuthorizeItemIds(entity.Id, "module"); if (items.Count > 0) throw Oops.Oh(ErrorCode.D1606); // 角色下有用户不能删 if (await _repository.AsSugarClient().Queryable().AnyAsync(u => u.ObjectType == "Role" && u.ObjectId == id)) throw Oops.Oh(ErrorCode.D1607); await _repository.AsSugarClient().Updateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandAsync(); //// 删除角色和组织关联数据 //await ForcedOffline(id); await _repository.AsSugarClient().Deleteable().Where(x => x.ObjectType == "Role" && x.ObjectId == id).ExecuteCommandAsync(); await DelRole(string.Format("{0}_{1}", _userManager.TenantId, _userManager.UserId)); } /// /// 更新. /// /// 主键. /// 参数. /// [HttpPut("{id}")] [UnitOfWork] public async Task Update(string id, [FromBody] RoleUpInput input) { RoleEntity? oldRole = await _repository.AsQueryable().InSingleAsync(input.id); // 全局角色 只能超管才能变更 if (oldRole.GlobalMark == 1 && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1612); #region 分级权限验证 // 旧数据 List? orgIdList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectId == id && x.ObjectType == "Role").Select(x => x.OrganizeId).ToListAsync(); if (!_userManager.DataScope.Any(it => orgIdList.Contains(it.organizeId) && it.Edit) && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1013); // 新数据 orgIdList = input.organizeIdsTree.Select(x => x.LastOrDefault()).ToList(); if (!_userManager.DataScope.Any(it => orgIdList.Contains(it.organizeId) && it.Edit) && !_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1013); #endregion if (await _repository.IsAnyAsync(r => r.EnCode == input.enCode && r.DeleteMark == null && r.Id != id)) throw Oops.Oh(ErrorCode.D1600); if (await _repository.IsAnyAsync(r => r.FullName == input.fullName && r.GlobalMark == input.globalMark && r.DeleteMark == null && r.Id != id)) throw Oops.Oh(ErrorCode.D1601); #region 如果变更组织,该角色下已存在成员,则不允许修改 if (oldRole.GlobalMark == 0) { // 查找该角色下的所有所属组织id List? orgRoleList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ObjectId == id).Select(x => x.OrganizeId).ToListAsync(); // 查找该角色下的所有成员id List? roleUserList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ObjectId == id).Select(x => x.UserId).ToListAsync(); // 获取带有角色成员的组织集合 var orgUserCountList = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Organize" && roleUserList.Contains(x.UserId)) .GroupBy(it => new { it.ObjectId }) .Having(x => SqlFunc.AggregateCount(x.UserId) > 0) .Select(x => new { x.ObjectId, UCount = SqlFunc.AggregateCount(x.UserId) }) .ToListAsync(); List? oldList = orgRoleList.Intersect(orgUserCountList.Select(x => x.ObjectId)).ToList(); // 将两个组织List交集 List? newList = input.organizeIdsTree.Select(x => x.LastOrDefault()).ToList(); if (oldList.Except(newList).Any()) throw Oops.Oh(ErrorCode.D1613); } // 全局改成组织 if (oldRole.GlobalMark == 1 && input.globalMark == 0 && _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ObjectId == id).Any()) { throw Oops.Oh(ErrorCode.D1615); } #endregion if (oldRole.EnabledMark == 1 && input.enabledMark != 1) { // 角色下有用户则无法停用 if (await _repository.AsSugarClient().Queryable().AnyAsync(u => u.ObjectType == "Role" && u.ObjectId == id)) throw Oops.Oh(ErrorCode.D1607); } RoleEntity? entity = input.Adapt(); await _repository.AsSugarClient().Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync(); #region 组织角色关系 //await ForcedOffline(id); await _repository.AsSugarClient().Deleteable().Where(x => x.ObjectType == "Role" && x.ObjectId == entity.Id).ExecuteCommandAsync(); // 删除原数据 if (input.globalMark == 0) { List? oreList = new List(); input.organizeIdsTree.ForEach(item => { string? id = item.LastOrDefault(); if (id.IsNotEmptyOrNull()) { OrganizeRelationEntity? oreEntity = new OrganizeRelationEntity(); oreEntity.ObjectType = "Role"; oreEntity.CreatorUserId = _userManager.UserId; oreEntity.ObjectId = entity.Id; oreEntity.OrganizeId = id; oreList.Add(oreEntity); } }); await _repository.AsSugarClient().Insertable(oreList).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync(); // 插入关系数据 } #endregion await DelRole(string.Format("{0}_{1}", _userManager.TenantId, _userManager.UserId)); } /// /// 更新状态. /// /// 主键. /// [HttpPut("{id}/Actions/State")] public async Task UpdateState(string id) { if (!await _repository.IsAnyAsync(r => r.Id == id && r.DeleteMark == null)) throw Oops.Oh(ErrorCode.D1608); // 只能超管才能变更 if (!_userManager.IsAdministrator) throw Oops.Oh(ErrorCode.D1612); int isOk = await _repository.AsSugarClient().Updateable().SetColumns(it => new RoleEntity() { EnabledMark = SqlFunc.IIF(it.EnabledMark == 1, 0, 1), LastModifyUserId = _userManager.UserId, LastModifyTime = SqlFunc.GetDate() }).Where(it => it.Id == id).ExecuteCommandAsync(); if (!(isOk > 0)) throw Oops.Oh(ErrorCode.D1610); await DelRole(string.Format("{0}_{1}", _userManager.TenantId, _userManager.UserId)); } #endregion #region PrivateMethod /// /// 删除角色缓存. /// /// 适配多租户模式(userId:tenantId_userId). /// private async Task DelRole(string userId) { string? cacheKey = string.Format("{0}{1}", CommonConst.CACHEKEYROLE, userId); await _cacheManager.DelAsync(cacheKey); return await Task.FromResult(true); } /// /// 递归排序 树形 List. /// /// . /// private List OrderbyTree(List list) { list.ForEach(item => { var cList = item.children.ToObject>(); if (cList != null) { cList = cList.OrderBy(x => x.sortCode).ToList(); item.children = cList.ToObject>(); if (cList.Any()) OrderbyTree(cList); } }); return list; } /// /// 强制角色下的所有用户下线. /// /// 角色Id. /// public async Task ForcedOffline(string roleId) { // 查找该角色下的所有成员id var roleUserIds = await _repository.AsSugarClient().Queryable().Where(x => x.ObjectType == "Role" && x.ObjectId == roleId).Select(x => x.UserId).ToListAsync(); Scoped.Create((_, scope) => { roleUserIds.ForEach(id => { var services = scope.ServiceProvider; var _onlineuser = App.GetService(services); _onlineuser.ForcedOffline(id); }); }); } #endregion }