using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Linq;
|
using System.Security.Permissions;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace LB_SmartVisionCommon
|
{
|
/// <summary>
|
/// 动态权限对象包装器
|
/// </summary>
|
public class DynamicPermissionObject : ICustomTypeDescriptor
|
{
|
private readonly object _target;
|
private readonly object _currentRole;
|
private readonly Type _roleType;
|
private readonly object[] _roles;
|
|
/// <summary>
|
/// 动态权限对象,可以接受多个角色
|
/// </summary>
|
/// <param name="target">目标</param>
|
/// <param name="roles">角色</param>
|
/// <exception cref="ArgumentException">异常信息</exception>
|
public DynamicPermissionObject(object target, params object[] roles)
|
{
|
_target = target;
|
_roles = roles;
|
|
// 验证所有角色都是枚举类型
|
foreach (var role in _roles)
|
{
|
if (role != null && !role.GetType().IsEnum)
|
throw new ArgumentException("所有角色必须是枚举值", nameof(roles));
|
}
|
}
|
|
/// <summary>
|
/// 在属性过滤时检查所有角色
|
/// </summary>
|
/// <param name="attr">权限属性</param>
|
/// <returns>高是true,低是false</returns>
|
private bool CheckPermissions(PermissionAttribute attr)
|
{
|
foreach (var role in _roles)
|
{
|
if (role != null && role.GetType() == attr.RoleType)
|
{
|
int roleValue = (int)Convert.ChangeType(role, typeof(int));
|
int requiredValue = (int)Convert.ChangeType(attr.MinimumRole, typeof(int));
|
|
if (roleValue >= requiredValue)
|
return true;
|
}
|
}
|
return false;
|
}
|
/// <summary>
|
/// 动态权限对象,单个角色
|
/// </summary>
|
/// <param name="target">目标</param>
|
/// <param name="currentRole">当前角色</param>
|
/// <exception cref="ArgumentException">异常信息</exception>
|
|
public DynamicPermissionObject(object target, object currentRole)
|
{
|
_target = target;
|
_currentRole = currentRole;
|
|
if (currentRole != null)
|
_roleType = currentRole.GetType();
|
|
if (!_roleType.IsEnum)
|
throw new ArgumentException("currentRole 必须是枚举值", nameof(currentRole));
|
}
|
/// <summary>
|
/// 获取属性描述符集合
|
/// </summary>
|
/// <returns>返回属性描述符集合</returns>
|
public PropertyDescriptorCollection GetProperties()
|
{
|
return GetProperties(null);
|
}
|
/// <summary>
|
/// 获取属性描述符集合
|
/// </summary>
|
/// <param name="attributes">自定义属性集合</param>
|
/// <returns>返回属性描述符集合</returns>
|
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
|
{
|
var originalProperties = TypeDescriptor.GetProperties(_target, attributes, true);
|
var filteredProperties = new List<PropertyDescriptor>();
|
foreach (PropertyDescriptor pd in originalProperties)
|
{
|
var attrs = pd.Attributes.OfType<PermissionAttribute>().ToArray();
|
bool hasPermission = true;
|
bool isReadOnly = false;
|
// 检查所有权限特性
|
foreach (var attr in attrs)
|
{
|
// 只处理与当前角色类型匹配的特性
|
if (attr.RoleType == _roleType)
|
{
|
if (!HasPermission(attr.MinimumRole))
|
{
|
hasPermission = false;
|
break;
|
}
|
else
|
{
|
// 有权限但可能只读
|
isReadOnly = !HasPermission(attr.MinimumRole);
|
}
|
}
|
}
|
if (hasPermission)
|
{
|
filteredProperties.Add(new PermissionPropertyDescriptor(pd, isReadOnly));
|
}
|
}
|
return new PropertyDescriptorCollection(filteredProperties.ToArray());
|
}
|
/// <summary>
|
/// 权限检测
|
/// </summary>
|
/// <param name="requiredRole">检测角色</param>
|
/// <returns>是否有权限</returns>
|
private bool HasPermission(object requiredRole)
|
{
|
if (_currentRole == null)
|
{
|
return false;
|
}
|
// 将枚举值转换为整数进行比较
|
int currentRoleValue = (int)Convert.ChangeType(_currentRole, typeof(int));
|
int requiredRoleValue = (int)Convert.ChangeType(requiredRole, typeof(int));
|
return currentRoleValue >= requiredRoleValue;
|
}
|
|
// ICustomTypeDescriptor 的其他方法实现...
|
/// <summary>
|
/// 获取属性
|
/// </summary>
|
/// <returns>返回属性集合</returns>
|
public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(_target);
|
/// <summary>
|
/// 获取类名称
|
/// </summary>
|
/// <returns>返回类名称</returns>
|
public string GetClassName() => TypeDescriptor.GetClassName(_target);
|
/// <summary>
|
/// 获取组件名称
|
/// </summary>
|
/// <returns>返回获取组件名称</returns>
|
public string GetComponentName() => TypeDescriptor.GetComponentName(_target);
|
/// <summary>
|
/// 获取转换
|
/// </summary>
|
/// <returns>返回对应类型的转换</returns>
|
public TypeConverter GetConverter() => TypeDescriptor.GetConverter(_target);
|
/// <summary>
|
/// 获取默认事件
|
/// </summary>
|
/// <returns>返回默认事件</returns>
|
public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(_target);
|
/// <summary>
|
/// 获取默认属性
|
/// </summary>
|
/// <returns>返回默认属性</returns>
|
public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(_target);
|
/// <summary>
|
/// 获取指定组件的具有指定基类型的编辑器
|
/// </summary>
|
/// <param name="editorBaseType">表示要查找的编辑器的基类型的 Type。</param>
|
/// <returns>可转换为指定编辑器类型的编辑器的一个实例,如果找不到请求类型的编辑器,则为 null。</returns>
|
public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(_target, editorBaseType);
|
/// <summary>
|
/// 返回组件或类型的事件的集合。
|
/// </summary>
|
/// <returns>具有此组件的事件的 EventDescriptorCollection。</returns>
|
public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(_target);
|
/// <summary>
|
/// 返回组件或类型的事件的集合。
|
/// </summary>
|
/// <param name="attributes">可以用作筛选器的类型 Attribute 的数组。</param>
|
/// <returns>具有匹配此组件指定属性的事件的 EventDescriptorCollection。</returns>
|
public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(_target, attributes);
|
/// <summary>
|
/// 返回一个对象,该对象包含指定的属性描述符所描述的属性。
|
/// </summary>
|
/// <param name="pd">要检索其所属对象的属性描述符。</param>
|
/// <returns>一个 Object,拥有该类型说明符指定的给定属性。 默认值为 null。</returns>
|
public object GetPropertyOwner(PropertyDescriptor pd) => _target;
|
}
|
}
|