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;
}
}
}