using Microsoft.EntityFrameworkCore; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using VOL.Core.CacheManager; using VOL.Core.DBManager; using VOL.Core.Enums; using VOL.Core.Extensions; using VOL.Core.Extensions.AutofacManager; using VOL.Entity; using VOL.Entity.DomainModels; using ConvertHelper; using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace VOL.Core.ManageUser { public class UserContext { /// /// 为了尽量减少redis或Memory读取,保证执行效率,将UserContext注入到DI, /// 每个UserContext的属性至多读取一次redis或Memory缓存从而提高查询效率 /// public static UserContext Current { get { return Context.RequestServices.GetService(typeof(UserContext)) as UserContext; } } private static Microsoft.AspNetCore.Http.HttpContext Context { get { return Utilities.HttpContext.Current; } } private static ICacheService CacheService { get { return GetService(); } } private static T GetService() where T : class { return AutofacContainerModule.GetService(); } public UserInfo UserInfo { get { if (_userInfo != null) { return _userInfo; } return GetUserInfo(UserId); } } private UserInfo _userInfo { get; set; } private const string AdministratorId= "1BEC90E1-9780-472F-90C2-0C6390C044A4"; /// /// 角色ID为1的默认为超级管理员 /// public bool IsSuperAdmin { get { return IsRoleIdSuperAdmin(this.RoleId); } } /// /// 角色ID为1的默认为超级管理员 /// public static bool IsRoleIdSuperAdmin(string roleId) { return roleId == "1"; } public UserInfo GetUserInfo(Guid userId) { if (_userInfo != null) return _userInfo; if (userId.isNullorEmpty()) { _userInfo = new UserInfo(); return _userInfo; } string key = userId.GetUserIdKey(); _userInfo = CacheService.Get(key); if (_userInfo != null && !_userInfo.User_Id.isNullorEmpty() ) return _userInfo; _userInfo = DBServerProvider.DbContext.Set() .Where(x => (x.User_Id== userId)).Select(s => new UserInfo() { User_Id = userId, Role_Id = s.Role_Id,//.GetInt() RoleName = s.RoleName, Token = s.Token, UserName = s.UserName, UserTrueName = s.UserTrueName, Enable = s.Enable, CompanyId=s.CompanyId, Dept_Id=s.Dept_Id, CompanyName=s.CompanyName }).FirstOrDefault(); var currrole = DBServerProvider.DbContext.Set().First(x => x.Role_Id == _userInfo.Role_Id); _userInfo.LimitInCompany = currrole.LimitCompanyRange==null?true:(bool)currrole.LimitCompanyRange; _userInfo.LimitBySTORAGE = currrole.LimitBySTORAGE == null ? true : (bool)currrole.LimitBySTORAGE; _userInfo.LimitByUser = currrole.LimitByUser == null ? true : (bool)currrole.LimitByUser; //如果 _userInfo.LimitBySTORAGE == true //从VW_OP_WMS_STOREHOUSE_USERLIMIT中查出这个用户userid的所有记录 //据此查出所有他可以看的仓库id 然后转换为四位编码 if (_userInfo.LimitBySTORAGE) { var userStorehouseLimitList = DBServerProvider.DbContext.Set().Where(x => x.USERID == _userInfo.User_Id).Select(s=>s.Pid).ToList(); var storehouseList = DBServerProvider.DbContext.Set().Where(x => userStorehouseLimitList.Contains( x.Id )).ToList(); _userInfo.STOREHOUSEList = new List(); foreach (var item in storehouseList) { _userInfo.STOREHOUSEList.Add(item.AREACODE); } } if (_userInfo != null && !_userInfo.User_Id.isNullorEmpty()) { CacheService.AddObject(key, _userInfo); } return _userInfo ?? new UserInfo(); } /// /// 获取角色权限时通过安全字典锁定的角色id /// private static ConcurrentDictionary objKeyValue = new ConcurrentDictionary(); /// /// 角色权限的版本号 /// private static readonly Dictionary rolePermissionsVersion = new Dictionary(); /// /// 每个角色ID对应的菜单权限(已做静态化处理) /// 每次获取权限时用当前服务器的版本号与redis/memory缓存的版本比较,如果不同会重新刷新缓存 /// private static readonly Dictionary> rolePermissions = new Dictionary>(); /// /// 获取用户所有的菜单权限 /// public List Permissions { get { return GetPermissionsByRoleId(RoleId); } } /// /// 获取单个表的权限 /// /// /// public Permissions GetPermissions(string tableName) { return GetPermissionsByRoleId(RoleId).Where(x => x.TableName == tableName).FirstOrDefault(); } /// /// 自定条件查询权限 /// /// /// public Permissions GetPermissions(Func func) { return GetPermissionsByRoleId(RoleId).Where(func).FirstOrDefault(); } private List ActionToArray(List permissions) { permissions.ForEach(x => { try { x.UserAuthArr = string.IsNullOrEmpty(x.UserAuth) ? new string[0] : x.UserAuth.Split(","); } catch { } finally { if (x.UserAuthArr == null) { x.UserAuthArr = new string[0]; } } }); return permissions; } private List MenuActionToArray(List permissions) { permissions.ForEach(x => { try { x.UserAuthArr = string.IsNullOrEmpty(x.UserAuth) ? new string[0] : x.UserAuth.DeserializeObject>().Select(s => s.Value).ToArray(); } catch { } finally { if (x.UserAuthArr == null) { x.UserAuthArr = new string[0]; } } }); return permissions; } public List GetPermissionsByRoleId(string roleId) { if (IsRoleIdSuperAdmin(roleId)) { var permissions_I = DBServerProvider.DbContext.Set().Where(x => x.Enable == 1).Select(a => new Permissions { Menu_Id = a.Menu_Id, ParentId = a.ParentId, //2020.05.06增加默认将表名转换成小写,权限验证时不再转换 TableName = (a.TableName ?? "").ToLower(), //MenuAuth = a.Auth, UserAuth = a.Auth, }); var permissions= permissions_I.ToList(); //var menutablename = new List(); //foreach (var item in permissions) { // menutablename.Add(item.TableName); //} //var alltable = DBServerProvider.DbContext.Set().Where(x => !menutablename.Contains(x.TableName)).ToList(); //foreach (var item in alltable) { // permissions.Add(new Permissions { Menu_Id = 9999, ParentId=9999,TableName= item.TableName.ToLower(), }) //} return MenuActionToArray(permissions); } ICacheService cacheService = CacheService; string roleKey = roleId.GetRoleIdKey(); //角色有缓存,并且当前服务器的角色版本号与redis/memory缓存角色的版本号相同直接返回静态对象角色权限 string currnetVeriosn = ""; if (rolePermissionsVersion.TryGetValue(roleId, out currnetVeriosn) && currnetVeriosn == cacheService.Get(roleKey)) { return rolePermissions.ContainsKey(roleId) ? rolePermissions[roleId] : new List(); } //锁定每个角色,通过安全字典减少锁粒度,否则多个同时角色获取缓存会导致阻塞 object objId = objKeyValue.GetOrAdd(roleId.ToString(), new object()); //锁定每个角色 lock (objId) { if (rolePermissionsVersion.TryGetValue(roleId, out currnetVeriosn) && currnetVeriosn == cacheService.Get(roleKey)) { return rolePermissions.ContainsKey(roleId) ? rolePermissions[roleId] : new List(); } //没有redis/memory缓存角色的版本号或与当前服务器的角色版本号不同时,刷新缓存 var dbContext = DBServerProvider.DbContext; List _permissions = (from a in dbContext.Set() join b in dbContext.Set() on a.Menu_Id equals b.Menu_Id where b.Role_Id == roleId //&& a.ParentId > 0 && b.AuthValue != "" orderby a.ParentId select new Permissions { Menu_Id = a.Menu_Id, ParentId = a.ParentId, //2020.05.06增加默认将表名转换成小写,权限验证时不再转换 TableName = (a.TableName ?? "").ToLower(), MenuAuth = a.Auth, UserAuth = b.AuthValue ?? "" }).ToList(); var menutablename = new List(); foreach (var item in _permissions) { menutablename.Add(item.TableName); } var alltable = DBServerProvider.DbContext.Set().Where(x => !menutablename.Contains(x.TableName)).ToList(); foreach (var item in alltable) { _permissions.Add(new Permissions { Menu_Id = 9999, ParentId = 9999, TableName = item.TableName.ToLower(),UserAuth= "Search,Add,Delete,Update,Import,Export,Upload,Audit" }); } ActionToArray(_permissions); string _version = cacheService.Get(roleKey); //生成一个唯一版本号标识 if (_version == null) { _version = DateTime.Now.ToString("yyyyMMddHHMMssfff"); //将版本号写入缓存 cacheService.Add(roleKey, _version); } //刷新当前服务器角色的权限 rolePermissions[roleId] = _permissions; //写入当前服务器的角色最新版本号 rolePermissionsVersion[roleId] = _version; return _permissions; } } /// /// 判断是否有权限 /// /// /// /// /// public bool ExistsPermissions(string tableName, string authName, string roleId = "") { if (string.IsNullOrWhiteSpace( roleId)) roleId = RoleId; tableName = tableName.ToLower(); authName = authName.ToLower(); return GetPermissionsByRoleId(roleId).Any(x => x.TableName == tableName && x.UserAuthArr.Contains(authName)); } /// /// 判断是否有权限 /// /// /// /// /// public bool ExistsPermissions(string tableName, ActionPermissionOptions actionPermission, string roleId ="") { return ExistsPermissions(tableName, actionPermission.ToString(),roleId); } public Guid UserId { get { Guid result = Guid.Empty; try { //var _r=(Context.User.FindFirstValue(JwtRegisteredClaimNames.Jti) //?? Context.User.FindFirstValue(ClaimTypes.NameIdentifier)).GetInt(); var r1 = Context.User.FindFirstValue(JwtRegisteredClaimNames.Jti); var r2 = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); if (r1 == null && r2 == null) result = Guid.Empty; else { var _r = (r1 ?? r2).ToString(); result = new Guid(_r); } //result = (Context.User.FindFirstValue(JwtRegisteredClaimNames.Jti) //?? Context.User.FindFirstValue(ClaimTypes.NameIdentifier)).ToString(); return result; } catch (Exception e) { return result; } } } public string UserName { get { return UserInfo.UserName; } } public string UserTrueName { get { return UserInfo.UserTrueName; } } public string Token { get { return UserInfo.Token; } } public string RoleId { get { return UserInfo.Role_Id; } } public void LogOut(Guid userId) { CacheService.Remove(userId.GetUserIdKey()); } public bool HaveLogin(Guid userId) { var uid = userId.GetUserIdKey(); var _r = CacheService.Get(uid); if (_r != null) { return true; } else{ return false; } } } }