using Tiobon.Core.AuthHelper; using Tiobon.Core.AuthHelper.OverWrite; using Newtonsoft.Json.Linq; using System.Security.Claims; namespace Tiobon.Core.Controllers { /// /// 菜单管理 /// [Route("api/[controller]/[action]")] [ApiController] [Authorize(Permissions.Name), ApiExplorerSettings(GroupName = Grouping.GroupName_System)] public class PermissionController : BaseApiController { readonly IUnitOfWorkManage _unitOfWorkManage; readonly IPermissionServices _permissionServices; readonly IModuleServices _moduleServices; readonly IRoleModulePermissionServices _roleModulePermissionServices; readonly IUserRoleServices _userRoleServices; private readonly IHttpClientFactory _httpClientFactory; readonly IHttpContextAccessor _httpContext; readonly IUser _user; private readonly PermissionRequirement _requirement; /// /// 构造函数 /// /// /// /// /// /// /// /// /// /// public PermissionController(IPermissionServices permissionServices, IModuleServices moduleServices, IRoleModulePermissionServices roleModulePermissionServices, IUserRoleServices userRoleServices, IUnitOfWorkManage unitOfWorkManage, IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContext, IUser user, PermissionRequirement requirement) { _permissionServices = permissionServices; _unitOfWorkManage = unitOfWorkManage; _moduleServices = moduleServices; _roleModulePermissionServices = roleModulePermissionServices; _userRoleServices = userRoleServices; this._httpClientFactory = httpClientFactory; _httpContext = httpContext; _user = user; _requirement = requirement; } /// /// 获取菜单 /// /// /// /// /// // GET: api/User [HttpGet] public async Task>> Get(int page = 1, string key = "", int pageSize = 50) { PageModel permissions = new PageModel(); if (string.IsNullOrEmpty(key) || string.IsNullOrWhiteSpace(key)) { key = ""; } permissions = await _permissionServices.QueryPage(a => a.IsDeleted != true && (a.Name != null && a.Name.Contains(key)), page, pageSize, " Id desc "); #region 单独处理 var apis = await _moduleServices.Query(d => d.IsDeleted == false); var permissionsView = permissions.data; var permissionAll = await _permissionServices.Query(d => d.IsDeleted != true); foreach (var item in permissionsView) { List pidarr = new() { item.Pid }; if (item.Pid > 0) { pidarr.Add(0); } var parent = permissionAll.FirstOrDefault(d => d.Id == item.Pid); while (parent != null) { pidarr.Add(parent.Id); parent = permissionAll.FirstOrDefault(d => d.Id == parent.Pid); } item.PidArr = pidarr.OrderBy(d => d).Distinct().ToList(); foreach (var pid in item.PidArr) { var per = permissionAll.FirstOrDefault(d => d.Id == pid); item.PnameArr.Add((per != null ? per.Name : "根节点") + "/"); //var par = Permissions.Where(d => d.Pid == item.Id ).ToList(); //item.PCodeArr.Add((per != null ? $"/{per.Code}/{item.Code}" : "")); //if (par.Count == 0 && item.Pid == 0) //{ // item.PCodeArr.Add($"/{item.Code}"); //} } item.MName = apis.FirstOrDefault(d => d.Id == item.Mid)?.LinkUrl; } permissions.data = permissionsView; #endregion //return new ServiceResult>() //{ // msg = "获取成功", // success = permissions.dataCount >= 0, // response = permissions //}; return permissions.dataCount >= 0 ? Success(permissions, "获取成功") : Failed>("获取失败"); } /// /// 查询树形 Table /// /// 父节点 /// 关键字 /// [HttpGet] [AllowAnonymous] public async Task>> GetTreeTable(long f = 0, string key = "") { List permissions = new List(); var apiList = await _moduleServices.Query(d => d.IsDeleted == false); var permissionsList = await _permissionServices.Query(d => d.IsDeleted == false); if (string.IsNullOrEmpty(key) || string.IsNullOrWhiteSpace(key)) { key = ""; } if (key != "") { permissions = permissionsList.Where(a => a.Name.Contains(key)).OrderBy(a => a.OrderSort).ToList(); } else { permissions = permissionsList.Where(a => a.Pid == f).OrderBy(a => a.OrderSort).ToList(); } foreach (var item in permissions) { List pidarr = new() { }; var parent = permissionsList.FirstOrDefault(d => d.Id == item.Pid); while (parent != null) { pidarr.Add(parent.Id); parent = permissionsList.FirstOrDefault(d => d.Id == parent.Pid); } //item.PidArr = pidarr.OrderBy(d => d).Distinct().ToList(); pidarr.Reverse(); pidarr.Insert(0, 0); item.PidArr = pidarr; item.MName = apiList.FirstOrDefault(d => d.Id == item.Mid)?.LinkUrl; item.hasChildren = permissionsList.Where(d => d.Pid == item.Id).Any(); } //return new ServiceResult>() //{ // msg = "获取成功", // success = true, // response = permissions //}; return Success(permissions, "获取成功"); } /// /// 添加一个菜单 /// /// /// // POST: api/User [HttpPost] public async Task> Post([FromBody] Permission permission) { //var data = new ServiceResult(); permission.CreateId = _user.ID; permission.CreateBy = _user.Name; var id = (await _permissionServices.Add(permission)); //data.success = id > 0; //if (data.success) //{ // data.response = id.ObjToString(); // data.msg = "添加成功"; //} return id > 0 ? Success(id.ObjToString(), "添加成功") : Failed("添加失败"); } /// /// 保存菜单权限分配 /// /// /// [HttpPost] public async Task> Assign([FromBody] AssignView assignView) { if (assignView.rid > 0) { //开启事务 try { var old_rmps = await _roleModulePermissionServices.Query(d => d.RoleId == assignView.rid); _unitOfWorkManage.BeginTran(); await _permissionServices.Db.Deleteable(t => t.RoleId == assignView.rid).ExecuteCommandAsync(); var permissions = await _permissionServices.Query(d => d.IsDeleted == false); List new_rmps = new List(); var nowTime = _permissionServices.Db.GetDate(); foreach (var item in assignView.pids) { var moduleid = permissions.Find(p => p.Id == item)?.Mid; var find_old_rmps = old_rmps.Find(p => p.PermissionId == item); RoleModulePermission roleModulePermission = new RoleModulePermission() { IsDeleted = false, RoleId = assignView.rid, ModuleId = moduleid.ObjToLong(), PermissionId = item, CreateId = find_old_rmps == null ? _user.ID : find_old_rmps.CreateId, CreateBy = find_old_rmps == null ? _user.Name : find_old_rmps.CreateBy, CreateTime = find_old_rmps == null ? nowTime : find_old_rmps.CreateTime, ModifyId = _user.ID, ModifyBy = _user.Name, ModifyTime = nowTime }; new_rmps.Add(roleModulePermission); } if (new_rmps.Count > 0) await _roleModulePermissionServices.Add(new_rmps); _unitOfWorkManage.CommitTran(); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } _requirement.Permissions.Clear(); return Success("保存成功"); } else { return Failed("请选择要操作的角色"); } } /// /// 获取菜单树 /// /// /// /// [HttpGet] public async Task> GetPermissionTree(long pid = 0, bool needbtn = false) { //var data = new ServiceResult(); var permissions = await _permissionServices.Query(d => d.IsDeleted == false); var permissionTrees = (from child in permissions where child.IsDeleted == false orderby child.Id select new PermissionTree { value = child.Id, label = child.Name, Pid = child.Pid, isbtn = child.IsButton, order = child.OrderSort, }).ToList(); PermissionTree rootRoot = new PermissionTree { value = 0, Pid = 0, label = "根节点" }; permissionTrees = permissionTrees.OrderBy(d => d.order).ToList(); RecursionHelper.LoopToAppendChildren(permissionTrees, rootRoot, pid, needbtn); //data.success = true; //if (data.success) //{ // data.response = rootRoot; // data.msg = "获取成功"; //} return Success(rootRoot, "获取成功"); //return data; } /// /// 获取路由树 /// /// /// [HttpGet] public async Task> GetNavigationBar(long uid) { var data = new ServiceResult(); long uidInHttpcontext1 = 0; var roleIds = new List(); // ids4和jwt切换 if (Permissions.IsUseIds4) { // ids4 uidInHttpcontext1 = (from item in _httpContext.HttpContext.User.Claims where item.Type == ClaimTypes.NameIdentifier select item.Value).FirstOrDefault().ObjToLong(); if (!(uidInHttpcontext1 > 0)) { uidInHttpcontext1 = (from item in _httpContext.HttpContext.User.Claims where item.Type == "sub" select item.Value).FirstOrDefault().ObjToLong(); } roleIds = (from item in _httpContext.HttpContext.User.Claims where item.Type == ClaimTypes.Role select item.Value.ObjToLong()).ToList(); if (!roleIds.Any()) { roleIds = (from item in _httpContext.HttpContext.User.Claims where item.Type == "role" select item.Value.ObjToLong()).ToList(); } } else { // jwt uidInHttpcontext1 = ((JwtHelper.SerializeJwt(_httpContext.HttpContext.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", "")))?.Uid).ObjToLong(); roleIds = (await _userRoleServices.Query(d => d.IsDeleted == false && d.UserId == uid)).Select(d => d.RoleId.ObjToLong()).Distinct().ToList(); } if (uid > 0 && uid == uidInHttpcontext1) { if (roleIds.Any()) { var pids = (await _roleModulePermissionServices.Query(d => d.IsDeleted == false && roleIds.Contains(d.RoleId))).Select(d => d.PermissionId.ObjToLong()).Distinct(); if (pids.Any()) { var rolePermissionMoudles = (await _permissionServices.Query(d => pids.Contains(d.Id))).OrderBy(c => c.OrderSort); var temp = rolePermissionMoudles.ToList().Find(t => t.Id == 87); var permissionTrees = (from child in rolePermissionMoudles where child.IsDeleted == false orderby child.Id select new NavigationBar { id = child.Id, name = child.Name, pid = child.Pid, order = child.OrderSort, path = child.Code, iconCls = child.Icon, Func = child.Func, IsHide = child.IsHide.ObjToBool(), IsButton = child.IsButton.ObjToBool(), meta = new NavigationBarMeta { requireAuth = true, title = child.Name, NoTabPage = child.IsHide.ObjToBool(), keepAlive = child.IskeepAlive.ObjToBool() } }).ToList(); NavigationBar rootRoot = new NavigationBar() { id = 0, pid = 0, order = 0, name = "根节点", path = "", iconCls = "", meta = new NavigationBarMeta(), }; permissionTrees = permissionTrees.OrderBy(d => d.order).ToList(); RecursionHelper.LoopNaviBarAppendChildren(permissionTrees, rootRoot); data.Success = true; if (data.Success) { data.Data = rootRoot; data.Message = "获取成功"; } } } } return data; } /// /// 获取路由树 /// /// /// [HttpGet] public async Task>> GetNavigationBarPro(long uid) { var data = new ServiceResult>(); long uidInHttpcontext1 = 0; var roleIds = new List(); // ids4和jwt切换 if (Permissions.IsUseIds4) { // ids4 uidInHttpcontext1 = (from item in _httpContext.HttpContext.User.Claims where item.Type == ClaimTypes.NameIdentifier select item.Value).FirstOrDefault().ObjToLong(); if (!(uidInHttpcontext1 > 0)) { uidInHttpcontext1 = (from item in _httpContext.HttpContext.User.Claims where item.Type == "sub" select item.Value).FirstOrDefault().ObjToLong(); } roleIds = (from item in _httpContext.HttpContext.User.Claims where item.Type == ClaimTypes.Role select item.Value.ObjToLong()).ToList(); if (!roleIds.Any()) { roleIds = (from item in _httpContext.HttpContext.User.Claims where item.Type == "role" select item.Value.ObjToLong()).ToList(); } } else { // jwt uidInHttpcontext1 = ((JwtHelper.SerializeJwt(_httpContext.HttpContext.Request.Headers["Authorization"].ObjToString().Replace("Bearer ", "")))?.Uid).ObjToLong(); roleIds = (await _userRoleServices.Query(d => d.IsDeleted == false && d.UserId == uid)).Select(d => d.RoleId.ObjToLong()).Distinct().ToList(); } if (uid > 0 && uid == uidInHttpcontext1) { if (roleIds.Any()) { var pids = (await _roleModulePermissionServices.Query(d => d.IsDeleted == false && roleIds.Contains(d.RoleId))) .Select(d => d.PermissionId.ObjToLong()).Distinct(); if (pids.Any()) { var rolePermissionMoudles = (await _permissionServices.Query(d => pids.Contains(d.Id) && d.IsButton == false)).OrderBy(c => c.OrderSort); var permissionTrees = (from item in rolePermissionMoudles where item.IsDeleted == false orderby item.Id select new NavigationBarPro { id = item.Id, name = item.Name, parentId = item.Pid, order = item.OrderSort, path = item.Code == "-" ? item.Name.GetTotalPingYin().FirstOrDefault() : (item.Code == "/" ? "/dashboard/workplace" : item.Code), component = item.Pid == 0 ? (item.Code == "/" ? "dashboard/Workplace" : "RouteView") : item.Code?.TrimStart('/'), iconCls = item.Icon, Func = item.Func, IsHide = item.IsHide.ObjToBool(), IsButton = item.IsButton.ObjToBool(), meta = new NavigationBarMetaPro { show = true, title = item.Name, icon = "user"//item.Icon } }).ToList(); permissionTrees = permissionTrees.OrderBy(d => d.order).ToList(); data.Success = true; if (data.Success) { data.Data = permissionTrees; data.Message = "获取成功"; } } } } return data; } /// /// 通过角色获取菜单 /// /// /// [HttpGet] [AllowAnonymous] public async Task> GetPermissionIdByRoleId(long rid = 0) { //var data = new ServiceResult(); var rmps = await _roleModulePermissionServices.Query(d => d.IsDeleted == false && d.RoleId == rid); var permissionTrees = (from child in rmps orderby child.Id select child.PermissionId.ObjToLong()).ToList(); var permissions = await _permissionServices.Query(d => d.IsDeleted == false); List assignbtns = new List(); foreach (var item in permissionTrees) { var pername = permissions.FirstOrDefault(d => d.IsButton && d.Id == item)?.Name; if (!string.IsNullOrEmpty(pername)) { //assignbtns.Add(pername + "_" + item); assignbtns.Add(item.ObjToString()); } } //data.success = true; //if (data.success) //{ // data.response = new AssignShow() // { // permissionids = permissionTrees, // assignbtns = assignbtns, // }; // data.msg = "获取成功"; //} return Success(new AssignShow() { permissionids = permissionTrees, assignbtns = assignbtns, }, "获取成功"); //return data; } /// /// 更新菜单 /// /// /// // PUT: api/User/5 [HttpPut] public async Task> Put([FromBody] Permission permission) { var data = new ServiceResult(); if (permission != null && permission.Id > 0) { data.Success = await _permissionServices.Update(permission); await _roleModulePermissionServices.UpdateModuleId(permission.Id, permission.Mid); if (data.Success) { data.Message = "更新成功"; data.Data = permission?.Id.ObjToString(); } } return data; } /// /// 删除菜单 /// /// /// // DELETE: api/ApiWithActions/5 [HttpDelete] public async Task> Delete(long id) { var data = new ServiceResult(); if (id > 0) { var userDetail = await _permissionServices.QueryById(id); userDetail.IsDeleted = true; data.Success = await _permissionServices.Update(userDetail); if (data.Success) { data.Message = "删除成功"; data.Data = userDetail?.Id.ObjToString(); } } return data; } /// /// 导入多条菜单信息 /// /// /// // POST: api/User [HttpPost] public async Task> BatchPost([FromBody] List permissions) { var data = new ServiceResult(); string ids = string.Empty; int sucCount = 0; for (int i = 0; i < permissions.Count; i++) { var permission = permissions[i]; if (permission != null) { permission.CreateId = _user.ID; permission.CreateBy = _user.Name; ids += (await _permissionServices.Add(permission)); sucCount++; } } data.Success = ids.IsNotEmptyOrNull(); if (data.Success) { data.Data = ids; data.Message = $"{sucCount}条数据添加成功"; } return data; } /// /// 系统接口菜单同步接口 /// /// [HttpGet] public async Task>> MigratePermission(string action = "", string token = "", string gatewayPrefix = "", string swaggerDomain = "", string controllerName = "", long pid = 0, bool isAction = false) { var data = new ServiceResult>(); if (controllerName.IsNullOrEmpty()) { data.Message = "必须填写要迁移的所属接口的控制器名称"; return data; } controllerName = controllerName.TrimEnd('/').ToLower(); gatewayPrefix = gatewayPrefix.Trim(); swaggerDomain = swaggerDomain.Trim(); controllerName = controllerName.Trim(); using var client = _httpClientFactory.CreateClient(); var Configuration = swaggerDomain.IsNotEmptyOrNull() ? swaggerDomain : AppSettings.GetValue("SystemCfg:Domain"); var url = $"{Configuration}/swagger/V2/swagger.json"; if (Configuration.IsNullOrEmpty()) { data.Message = "Swagger.json在线文件域名不能为空"; return data; } if (token.IsNullOrEmpty()) token = Request.Headers.Authorization; token = token.Trim(); client.DefaultRequestHeaders.Add("Authorization", $"{token}"); var response = await client.GetAsync(url); var body = await response.Content.ReadAsStringAsync(); var resultJObj = (JObject)JsonConvert.DeserializeObject(body); var paths = resultJObj["paths"].ObjToString(); var pathsJObj = (JObject)JsonConvert.DeserializeObject(paths); List permissions = new List(); foreach (JProperty jProperty in pathsJObj.Properties()) { var apiPath = gatewayPrefix + jProperty.Name.ToLower(); if (action.IsNotEmptyOrNull()) { action = action.Trim(); if (!apiPath.Contains(action.ToLower())) { continue; } } string httpmethod = ""; if (jProperty.Value.ToString().ToLower().Contains("get")) { httpmethod = "get"; } else if (jProperty.Value.ToString().ToLower().Contains("post")) { httpmethod = "post"; } else if (jProperty.Value.ToString().ToLower().Contains("put")) { httpmethod = "put"; } else if (jProperty.Value.ToString().ToLower().Contains("delete")) { httpmethod = "delete"; } var summary = jProperty.Value?.SelectToken($"{httpmethod}.summary")?.ObjToString() ?? ""; var subIx = summary.IndexOf("(Auth"); if (subIx >= 0) { summary = summary.Substring(0, subIx); } permissions.Add(new Permission() { Code = " ", Name = summary, IsButton = true, IsHide = false, Enabled = true, CreateTime = DateTime.Now, IsDeleted = false, Pid = pid, Module = new Modules() { LinkUrl = apiPath ?? "", Name = summary, Enabled = true, CreateTime = DateTime.Now, ModifyTime = DateTime.Now, IsDeleted = false, } }); } var modulesList = (await _moduleServices.Query(d => d.IsDeleted == false && d.LinkUrl != null)).Select(d => d.LinkUrl.ToLower()).ToList(); permissions = permissions.Where(d => !modulesList.Contains(d.Module.LinkUrl.ToLower()) && d.Module.LinkUrl.Contains($"/{controllerName}/")).ToList(); if (isAction) { foreach (var item in permissions) { List modules = await _moduleServices.Query(d => d.LinkUrl != null && d.LinkUrl.ToLower() == item.Module.LinkUrl); if (!modules.Any()) { var mid = await _moduleServices.Add(item.Module); if (mid > 0) { item.Mid = mid; var permissionid = await _permissionServices.Add(item); } } } data.Message = "同步完成"; } data.Data = permissions; data.Status = 200; data.Success = isAction; return data; } } public class AssignView { public List pids { get; set; } public long rid { get; set; } } public class AssignShow { public List permissionids { get; set; } public List assignbtns { get; set; } } }