274 lines
11 KiB
C#
274 lines
11 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// 注意:数据库表中必须包括appsettings.json配置文件UserIdField的字段才会进行数据隔离。如果表没有这些字段,请在上面单独写过滤逻辑
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="query"></param>
|
|
/// <param name="checkAdmin">是否对管理员帐号也做验证</param>
|
|
/// <returns></returns>
|
|
public static string CreateTenancySqlFilter(this string tableName, string selectSql,
|
|
List<SearchParameters> filters, List<SugarParameter> parameters, string leftQuote = "", string rightQuote = "")
|
|
{
|
|
filters ??= new List<SearchParameters>();
|
|
|
|
// 统一到菜单表名,避免传入真实表名(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<int>();
|
|
var permission = UserContext.Current.GetPermissions(permissionTableName.ToLower()) ?? new Permissions();
|
|
|
|
// 自定义数据权限:对应 QueryCustom,转换成 SearchParameters 直接放入 filters
|
|
if (permission.CustomAuth != null)
|
|
{
|
|
AddCustomFilters(filters, permission.CustomAuth);
|
|
return selectSql;
|
|
}
|
|
|
|
List<int> authDataTypes;
|
|
if (!string.IsNullOrEmpty(permission.AuthMenuData))
|
|
{
|
|
authDataTypes = new List<int> { 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<Sys_UserDepartment>().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<Sys_UserRole>()
|
|
.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<SearchParameters> filters, string fieldName, IEnumerable<int> 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<SearchParameters> filters, List<Dictionary<string, string>> 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<SearchParameters> filters, string field, IEnumerable<string> 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;
|
|
}
|
|
}
|
|
}
|