using JNPF.Common.Const;
using JNPF.Common.Enums;
using JNPF.Common.Extension;
using JNPF.Common.Manager;
using JNPF.Common.Models.Authorize;
using JNPF.Common.Models.User;
using JNPF.Common.Net;
using JNPF.Common.Security;
using JNPF.DataEncryption;
using JNPF.DependencyInjection;
using JNPF.Systems.Entitys.Entity.Permission;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using System.Security.Claims;
namespace JNPF.Common.Core.Manager;
///
/// 用户管理 .
///
public class UserManager : IUserManager, IScoped
{
///
/// 用户表仓储.
///
private readonly ISqlSugarRepository _repository;
///
/// 缓存管理.
///
private readonly ICacheManager _cacheManager;
///
/// 当前Http请求.
///
private readonly HttpContext _httpContext;
///
/// 用户Claim主体.
///
private readonly ClaimsPrincipal _user;
///
/// 初始化一个类型的新实例.
///
/// 用户仓储.
/// 缓存管理.
public UserManager(
ISqlSugarRepository repository,
ICacheManager cacheManager)
{
_repository = repository;
_cacheManager = cacheManager;
_httpContext = App.HttpContext;
_user = _httpContext?.User;
if (!string.IsNullOrEmpty(_httpContext?.Request.Query["token"].ToString()))
{
var token = _httpContext.Request.Query["token"].ToString();
var claims = JWTEncryption.ReadJwtToken(token.Replace("Bearer ", string.Empty).Replace("bearer ", string.Empty))?.Claims;
ClaimsIdentity toKen = new ClaimsIdentity();
foreach (Claim item in claims)
{
toKen.AddClaim(item);
}
_user = new ClaimsPrincipal(toKen);
}
}
///
/// 用户信息.
///
public UserEntity User
{
get => _repository.GetSingle(u => u.Id == UserId);
}
///
/// 用户ID.
///
public string UserId
{
get => _user.FindFirst(ClaimConst.CLAINMUSERID)?.Value;
}
///
/// 获取用户角色.
///
public List Roles
{
get
{
var user = _repository.GetSingle(u => u.Id == UserId);
return GetUserRoleIds(user.RoleId, user.OrganizeId);
}
}
///
/// 用户账号.
///
public string Account
{
get => _user.FindFirst(ClaimConst.CLAINMACCOUNT)?.Value;
}
///
/// 用户昵称.
///
public string RealName
{
get => _user.FindFirst(ClaimConst.CLAINMREALNAME)?.Value;
}
///
/// 当前用户 token.
///
public string ToKen
{
get => String.IsNullOrEmpty(App.HttpContext?.Request.Headers["Authorization"]) ? App.HttpContext?.Request.Query["token"] : App.HttpContext?.Request.Headers["Authorization"];
}
///
/// 数据库连接.
///
public ConnectionConfigOptions ConnectionConfig
{
get => _user.FindFirst(ClaimConst.CONNECTIONCONFIG)?.Value.ToObject();
}
///
/// 租户ID.
///
public string TenantId
{
get => ConnectionConfig.ConfigId;
}
///
/// 租户数据库名称.
///
public string TenantDbName
{
get => ConnectionConfig.ConfigList.Find(it => it.IsMaster.Equals(true)).ServiceName;
}
///
/// 是否是管理员.
///
public bool IsAdministrator
{
get => _user.FindFirst(ClaimConst.CLAINMADMINISTRATOR)?.Value == ((int)AccountType.Administrator).ToString();
}
///
/// 获取用户的数据范围.
///
public List DataScope
{
get
{
return GetUserDataScope(UserId);
}
}
///
/// 用户当前组织及子组织.
///
public List Subsidiary
{
get
{
List list = new List();
list.AddRange(GetSubsidiary(User.OrganizeId, IsAdministrator).ToObject>());
return list;
}
}
///
/// 当前用户下属.
///
public List Subordinates
{
get
{
return this.GetSubordinates(UserId).ToList();
}
}
///
/// 获取请求端类型 pc 、 app.
///
public string UserOrigin
{
get => _httpContext?.Request.Headers["jnpf-origin"];
}
///
/// 获取用户登录信息.
///
///
public async Task GetUserInfo()
{
UserAgent userAgent = new UserAgent(_httpContext);
var data = new UserInfoModel();
var ipAddress = NetHelper.Ip;
//var ipAddressName = await NetHelper.GetLocation(ipAddress);
var userDataScope = await GetUserDataScopeAsync(UserId);
var sysConfigInfo = await _repository.AsSugarClient().Queryable().FirstAsync(s => s.Category.Equals("SysConfig") && s.Key.ToLower().Equals("tokentimeout"));
data = await _repository.AsQueryable().Where(it => it.Id == UserId)
.Select(a => new UserInfoModel
{
userId = a.Id,
headIcon = SqlFunc.MergeString("/api/File/Image/userAvatar/", a.HeadIcon),
userAccount = a.Account,
userName = a.RealName,
gender = a.Gender,
organizeId = a.OrganizeId,
departmentId = a.OrganizeId,
departmentName = SqlFunc.Subqueryable().Where(o => o.Id == SqlFunc.ToString(a.OrganizeId) && o.Category.Equals("department")).Select(o => o.FullName),
organizeName = SqlFunc.Subqueryable().Where(o => o.Id == SqlFunc.ToString(a.OrganizeId)).Select(o => o.OrganizeIdTree),
managerId = a.ManagerId,
isAdministrator = SqlFunc.IIF(a.IsAdministrator == 1, true, false),
portalId = a.PortalId,
positionId = a.PositionId,
roleId = a.RoleId,
prevLoginTime = a.PrevLogTime,
prevLoginIPAddress = a.PrevLogIP,
landline = a.Landline,
telePhone = a.TelePhone,
manager = SqlFunc.Subqueryable().Where(u => u.Id == a.ManagerId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
mobilePhone = a.MobilePhone,
email = a.Email,
birthday = a.Birthday,
systemId = a.SystemId,
signImg = SqlFunc.Subqueryable().Where(a => a.CreatorUserId == UserId && a.IsDefault == 1).Select(a => a.SignImg),
}).FirstAsync();
if (data.portalId.IsNullOrWhiteSpace()) data.portalId = string.Empty;
if (data != null && data.organizeName.IsNotEmptyOrNull())
{
var orgIdTree = data?.organizeName?.Split(',');
var organizeName = await _repository.AsSugarClient().Queryable().Where(x => orgIdTree.Contains(x.Id)).OrderBy(x => x.SortCode).OrderBy(x => x.CreatorTime).Select(x => x.FullName).ToListAsync();
data.organizeName = string.Join("/", organizeName);
}
else
{
data.organizeName = data.departmentName;
}
data.loginTime = DateTime.Now;
data.prevLogin = (await _repository.AsSugarClient().Queryable().FirstAsync(x => x.Category.Equals("SysConfig") && x.Key.ToLower().Equals("lastlogintimeswitch"))).Value.ParseToInt();
data.loginIPAddress = ipAddress;
//data.loginIPAddressName = ipAddressName;
//data.prevLoginIPAddressName = await NetHelper.GetLocation(data.prevLoginIPAddress);
data.loginPlatForm = userAgent.RawValue;
data.subsidiary = await GetSubsidiaryAsync(data.organizeId, data.isAdministrator);
data.subordinates = await this.GetSubordinatesAsync(UserId);
data.positionIds = data.positionId == null ? null : await GetPosition(data.positionId);
data.positionName = data.positionIds == null ? null : string.Join(",", data.positionIds.Select(it => it.name));
var roleList = await GetUserOrgRoleIds(data.roleId, data.organizeId);
data.roleName = await GetRoleNameByIds(string.Join(",", roleList));
data.roleIds = roleList.ToArray();
if (!data.isAdministrator && data.roleIds.Any())
{
var portalIds = await _repository.AsSugarClient().Queryable().In(a => a.ObjectId, data.roleIds).Where(a => a.ItemType == "portal").GroupBy(it => new { it.ItemId }).Select(it => it.ItemId).ToListAsync();
if (portalIds.Any())
{
if (!portalIds.Any(x => x == data.portalId)) data.portalId = portalIds.FirstOrDefault()?.ToString();
}
else data.portalId = string.Empty;
}
data.overdueTime = TimeSpan.FromMinutes(sysConfigInfo.Value.ParseToDouble());
data.dataScope = userDataScope;
data.tenantId = TenantId;
data.tenantDbName = TenantDbName;
// 根据系统配置过期时间自动过期
await SetUserInfo(string.Format("{0}{1}_{2}", CommonConst.CACHEKEYUSER, TenantId, UserId), data, TimeSpan.FromMinutes(sysConfigInfo.Value.ParseToDouble()));
return data;
}
///
/// 获取用户数据范围.
///
/// 用户ID.
///
private async Task> GetUserDataScopeAsync(string userId)
{
List data = new List();
List subData = new List();
List inteList = new List();
var list = await _repository.AsSugarClient().Queryable().Where(it => SqlFunc.ToString(it.UserId) == userId && it.DeleteMark == null).ToListAsync();
// 填充数据
foreach (var item in list)
{
if (item.SubLayerAdd.ParseToBool() || item.SubLayerEdit.ParseToBool() || item.SubLayerDelete.ParseToBool())
{
var subsidiary = (await GetSubsidiaryAsync(item.OrganizeId, false)).ToList();
subsidiary.Remove(item.OrganizeId);
subsidiary.ToList().ForEach(it =>
{
subData.Add(new UserDataScopeModel()
{
organizeId = it,
Add = item.SubLayerAdd.ParseToBool(),
Edit = item.SubLayerEdit.ParseToBool(),
Delete = item.SubLayerDelete.ParseToBool()
});
});
}
if (item.ThisLayerAdd.ParseToBool() || item.ThisLayerEdit.ParseToBool() || item.ThisLayerDelete.ParseToBool())
{
data.Add(new UserDataScopeModel()
{
organizeId = item.OrganizeId,
Add = item.ThisLayerAdd.ParseToBool(),
Edit = item.ThisLayerEdit.ParseToBool(),
Delete = item.ThisLayerDelete.ParseToBool()
});
}
}
/* 比较数据
所有分级数据权限以本级权限为主 子级为辅
将本级数据与子级数据对比 对比出子级数据内组织ID存在本级数据的组织ID*/
var intersection = data.Select(it => it.organizeId).Intersect(subData.Select(it => it.organizeId)).ToList();
intersection.ForEach(it =>
{
var parent = data.Find(item => item.organizeId == it);
var child = subData.Find(item => item.organizeId == it);
var add = false;
var edit = false;
var delete = false;
if (parent.Add || child.Add)
add = true;
if (parent.Edit || child.Edit)
edit = true;
if (parent.Delete || child.Delete)
delete = true;
inteList.Add(new UserDataScopeModel()
{
organizeId = it,
Add = add,
Edit = edit,
Delete = delete
});
data.Remove(parent);
subData.Remove(child);
});
return data.Union(subData).Union(inteList).ToList();
}
///
/// 获取用户数据范围.
///
/// 用户ID.
///
private List GetUserDataScope(string userId)
{
List data = new List();
List subData = new List();
List inteList = new List();
// 填充数据
foreach (var item in _repository.AsSugarClient().Queryable()
.Where(it => SqlFunc.ToString(it.UserId) == userId && it.DeleteMark == null).ToList())
{
if (item.SubLayerSelect.ParseToBool() || item.SubLayerAdd.ParseToBool() || item.SubLayerEdit.ParseToBool() || item.SubLayerDelete.ParseToBool())
{
var subsidiary = GetSubsidiary(item.OrganizeId, false).ToList();
subsidiary.Remove(item.OrganizeId);
subsidiary.ToList().ForEach(it =>
{
subData.Add(new UserDataScopeModel()
{
organizeId = it,
Add = item.SubLayerAdd.ParseToBool(),
Edit = item.SubLayerEdit.ParseToBool(),
Delete = item.SubLayerDelete.ParseToBool(),
Select = item.SubLayerSelect.ParseToBool()
});
});
}
if (item.ThisLayerSelect.ParseToBool() || item.ThisLayerAdd.ParseToBool() || item.ThisLayerEdit.ParseToBool() || item.ThisLayerDelete.ParseToBool())
{
data.Add(new UserDataScopeModel()
{
organizeId = item.OrganizeId,
Add = item.ThisLayerAdd.ParseToBool(),
Edit = item.ThisLayerEdit.ParseToBool(),
Delete = item.ThisLayerDelete.ParseToBool(),
Select = item.ThisLayerSelect.ParseToBool()
});
}
}
/* 比较数据
所有分级数据权限以本级权限为主 子级为辅
将本级数据与子级数据对比 对比出子级数据内组织ID存在本级数据的组织ID*/
var intersection = data.Select(it => it.organizeId).Intersect(subData.Select(it => it.organizeId)).ToList();
intersection.ForEach(it =>
{
var parent = data.Find(item => item.organizeId == it);
var child = subData.Find(item => item.organizeId == it);
var add = false;
var edit = false;
var delete = false;
var select = false;
if (parent.Add || child.Add) add = true;
if (parent.Edit || child.Edit) edit = true;
if (parent.Delete || child.Delete) delete = true;
if (parent.Select || child.Select) select = true;
inteList.Add(new UserDataScopeModel()
{
organizeId = it,
Add = add,
Edit = edit,
Delete = delete,
Select = select
});
data.Remove(parent);
subData.Remove(child);
});
return data.Union(subData).Union(inteList).ToList();
}
///
/// 获取数据条件.
///
/// 实体.
/// 模块ID.
/// 表主键.
/// 是否开启数据权限.
/// 联表编号.
///
public async Task> GetConditionAsync(string moduleId, string primaryKey = "F_Id", bool isDataPermissions = true, string tableNumber = "")
where T : new()
{
var userInfo = await GetUserInfo();
var conModels = new List();
if (IsAdministrator) return conModels;
var items = await _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.ObjectId && b.EnabledMark == 1 && b.DeleteMark == null))
.In((a, b) => b.Id, userInfo.roleIds)
.Where(a => a.ItemType == "resource")
.GroupBy(a => new { a.ItemId }).Select(a => a.ItemId).ToListAsync();
if (!isDataPermissions)
{
conModels.Add(new ConditionalCollections()
{
ConditionalList = new List>()
{
new KeyValuePair(WhereType.And, new ConditionalModel() { FieldName = string.Format("{0}{1}", tableNumber, primaryKey), ConditionalType = ConditionalType.NoEqual, FieldValue = "0", FieldValueConvertFunc = it => SqlSugar.UtilMethods.ChangeType2(it, typeof(string)) })
}
});
return conModels;
}
else if (items.Count == 0 && isDataPermissions)
{
conModels.Add(new ConditionalCollections()
{
ConditionalList = new List>()
{
new KeyValuePair(WhereType.And, new ConditionalModel() { FieldName = string.Format("{0}{1}", tableNumber, primaryKey), ConditionalType = ConditionalType.Equal, FieldValue = "0", FieldValueConvertFunc = it => SqlSugar.UtilMethods.ChangeType2(it, typeof(string)) })
}
});
return conModels;
}
var resourceList = _repository.AsSugarClient().Queryable().In(it => it.Id, items).Where(it => it.ModuleId == moduleId && it.DeleteMark == null).ToList();
if (resourceList.Any(x => x.AllData == 1 || "jnpf_alldata".Equals(x.EnCode)))
{
conModels.Add(new ConditionalCollections()
{
ConditionalList = new List>() {
new KeyValuePair(WhereType.And, new ConditionalModel() { FieldName = string.Format("{0}{1}", tableNumber, primaryKey), ConditionalType = ConditionalType.NoEqual, FieldValue = "0", FieldValueConvertFunc = it => SqlSugar.UtilMethods.ChangeType2(it, typeof(string)) })
}
});
}
else
{
var allList = new List