using Microsoft.EntityFrameworkCore; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using VolPro.Core.Configuration; using VolPro.Core.DBManager; using VolPro.Core.Enums; using VolPro.Core.Extensions; using VolPro.Core.ManageUser; using VolPro.Core.UserManager; using VolPro.Entity.DomainModels; namespace VolPro.Core.Tenancy { public static class TenancySqlExpression { /// /// 注意:数据库表中必须包括appsettings.json配置文件UserIdField的字段才会进行数据隔离。如果表没有这些字段,请在上面单独写过滤逻辑 /// /// /// /// 是否对管理员帐号也做验证 /// public static string CreateTenancySqlFilter(this string tableName, string selectSql, List filters, List parameters, string leftQuote = "", string rightQuote = "") { filters ??= new List(); // 统一到菜单表名,避免传入真实表名(TableTrueName)时权限匹配失败 string permissionTableName = ResolvePermissionTableName(tableName); bool isUserTable = permissionTableName.Equals(nameof(Sys_User), StringComparison.OrdinalIgnoreCase); string filterCreateId = isUserTable ? "User_Id" : AppSetting.CreateMember?.UserIdField; if (string.IsNullOrWhiteSpace(filterCreateId)) { filterCreateId = "CreateId"; } if (AppSetting.UserAuth) { int[] userIds = UserContext.Current.GetCurrentUserAuthUserIds(permissionTableName); if (userIds?.Length > 0) { // 对应 QueryTenancyDynamicShareDBFilter:直接写入 filters 供 BuildWhere 生成 IN AddInFilter(filters, filterCreateId, userIds); return selectSql; } } var roleIds = UserContext.Current.RoleIds ?? Array.Empty(); var permission = UserContext.Current.GetPermissions(permissionTableName.ToLower()) ?? new Permissions(); // 自定义数据权限:对应 QueryCustom,转换成 SearchParameters 直接放入 filters if (permission.CustomAuth != null) { AddCustomFilters(filters, permission.CustomAuth); return selectSql; } List authDataTypes; if (!string.IsNullOrEmpty(permission.AuthMenuData)) { authDataTypes = new List { permission.AuthMenuData.GetInt() }; } else { authDataTypes = RoleContext.GetRoles(x => roleIds.Contains(x.Id)) .Where(x => x.AuthData > 0) .Select(s => s.AuthData) .ToList(); } if (!isUserTable && authDataTypes.Count == 0) { return selectSql; } if (!isUserTable && (authDataTypes.Contains((int)AuthData.本组织及下数据) || authDataTypes.Contains((int)AuthData.本组织数据))) { var deptIds = UserContext.Current.DeptIds; var userDeptQuery = DBServerProvider.DbContext.Set().Where(x => x.Enable == 1); if (authDataTypes.Contains((int)AuthData.本组织及下数据)) { var childDeptIds = DepartmentContext.GetAllChildrenIds(deptIds); userDeptQuery = userDeptQuery.Where(x => childDeptIds.Contains(x.DepartmentId)); } else { userDeptQuery = userDeptQuery.Where(x => deptIds.Contains(x.DepartmentId)); } var deptUserIds = userDeptQuery.Select(s => s.UserId).Distinct().Take(5000).ToArray(); AddInFilter(filters, filterCreateId, deptUserIds); return selectSql; } if (isUserTable || authDataTypes.Contains((int)AuthData.本角色以及下数据) || authDataTypes.Contains((int)AuthData.本角色数据)) { var userRoleQuery = DBServerProvider.DbContext.Set() .Where(x => x.Enable == 1 && x.RoleId > 1); if (isUserTable || authDataTypes.Contains((int)AuthData.本角色以及下数据)) { var childRoleIds = RoleContext.GetAllChildrenIds(roleIds); userRoleQuery = userRoleQuery.Where(x => childRoleIds.Contains(x.RoleId)); } else { userRoleQuery = userRoleQuery.Where(x => roleIds.Contains(x.RoleId)); } var roleUserIds = userRoleQuery.Select(s => s.UserId).Distinct().Take(5000).ToArray(); AddInFilter(filters, filterCreateId, roleUserIds); return selectSql; } if (authDataTypes.Contains((int)AuthData.仅自己数据)) { filters.Add(new SearchParameters { Name = filterCreateId, Value = UserContext.Current.UserId.ToString(), DisplayType = "=" }); } return selectSql; } private static string ResolvePermissionTableName(string tableName) { //var tableInfo = TableColumnContext.TableInfo.FirstOrDefault(x => // string.Equals(x.TableName, tableName, StringComparison.OrdinalIgnoreCase) // || string.Equals(x.TableTrueName, tableName, StringComparison.OrdinalIgnoreCase)); //return tableInfo?.TableName ?? tableName; return tableName; } private static void AddInFilter(List filters, string fieldName, IEnumerable userIds) { if (string.IsNullOrWhiteSpace(fieldName) || userIds == null) { return; } var ids = userIds.Distinct().ToArray(); if (ids.Length == 0) { return; } filters.Add(new SearchParameters { Name = fieldName, Value = string.Join(",", ids), DisplayType = "in" }); } private static void AddCustomFilters(List filters, List> list) { if (list == null || list.Count == 0) { return; } foreach (var item in list) { if (!item.TryGetValue("field", out var field) || string.IsNullOrWhiteSpace(field)) { continue; } if (!item.TryGetValue("value", out var value) || string.IsNullOrWhiteSpace(value)) { continue; } value = value.Trim(); item.TryGetValue("filterType", out var filterType); item.TryGetValue("valueType", out var valueType); // valueType=1: 当前用户上下文字段替换 if (valueType == "1") { switch (value) { case "User_Id": filters.Add(new SearchParameters { Name = field, Value = UserContext.Current.UserId.ToString(), DisplayType = "eq" }); break; case "RoleIds": AddInStringFilter(filters, field, UserContext.Current.RoleIds.Select(s => s.ToString())); break; case "DeptIds": AddInStringFilter(filters, field, UserContext.Current.DeptIds.Select(s => s.ToString())); break; default: var property = typeof(UserInfo).GetProperty(value); var userInfoVal = property?.GetValue(UserContext.Current.UserInfo); if (userInfoVal != null) { filters.Add(new SearchParameters { Name = field, Value = userInfoVal.ToString(), DisplayType = MapDisplayType(filterType, false) }); } break; } continue; } bool isListValue = value.Contains(","); bool isIn = string.Equals(filterType, "in", StringComparison.OrdinalIgnoreCase); bool isNotEqual = string.Equals(filterType, "!=", StringComparison.OrdinalIgnoreCase); if (isIn || isNotEqual || isListValue) { var vals = value.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray(); if (vals.Length == 0) { continue; } filters.Add(new SearchParameters { Name = field, Value = string.Join(",", vals), DisplayType = isIn ? "in" : "notin" }); continue; } filters.Add(new SearchParameters { Name = field, Value = value, DisplayType = MapDisplayType(filterType, false) }); } } private static void AddInStringFilter(List filters, string field, IEnumerable values) { if (string.IsNullOrWhiteSpace(field) || values == null) { return; } var list = values.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToArray(); if (list.Length == 0) { return; } filters.Add(new SearchParameters { Name = field, Value = string.Join(",", list), DisplayType = "in" }); } private static string MapDisplayType(string filterType, bool defaultLike) { switch (filterType) { case "小于": filterType = "<"; break; default: break; } return filterType; } } }