You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
5.1 KiB

3 weeks ago
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Wood.Util;
namespace WoodWood.Util.Validations
{
/// <summary>
/// 数据库中 唯一值验证
/// null 和 "" 不会进行验证
/// </summary>
public class UniqueValueAttribute : ValidationAttribute
{
/// <summary>
/// 字段名称,留空取当前
/// </summary>
public string? PropertyName { get; set; }
/// <summary>
/// 实体,留空取当前
/// </summary>
public Type? EntityType { get; set; }
/// <summary>
///
/// </summary>
/// <param name="value"></param>
/// <param name="validationContext"></param>
/// <returns></returns>
protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
{
if (value == null|| string.IsNullOrEmpty(value.ToString()))
return ValidationResult.Success!;
var serviceProvider = validationContext.GetService(typeof(IServiceProvider)) as IServiceProvider;
if (serviceProvider == null)
return new ValidationResult($"[{validationContext.MemberName}]无法获取服务提供者!");
// 获取 ISqlSugarClient 实例
var sqlClient = serviceProvider!.GetRequiredService<ISqlSugarClient>();
if (sqlClient == null)
return new ValidationResult($"[{validationContext.MemberName}]无法获取 ISqlSugarClient!");
string sqlTable = "";
bool hasTenantFilter = false;
bool hasDeletedFilter = false;
string sqlProperty = "";
Type sqlPropertyType;
//字段名
if (string.IsNullOrEmpty(PropertyName))
// 获取成员名称(属性名)
sqlProperty = validationContext.MemberName ?? "";
else
sqlProperty = PropertyName;
Type sqlType;
//表明
if (EntityType == null)
sqlType = validationContext.ObjectType;
else
sqlType = EntityType;
// 获取类上的所有自定义特性,包括继承的特性
var classAttributes = sqlType.GetCustomAttributes(true);
// 如果你知道具体要查找的特性类型,可以直接获取它
var sugarTable = Attribute.GetCustomAttribute(sqlType, typeof(SugarTable)) as SugarTable;
if (sugarTable == null)
return new ValidationResult($"[{validationContext.MemberName}]无法识别SugarTable表信息!");
sqlTable = sugarTable.TableName;
// 假设我们要检查 实体是否有 租户过滤特性
hasTenantFilter = sqlType.GetInterfaces().Any(it => it.Name == "ITenantIdFilter");
// 假设我们要检查 实体是否有 软删除过滤特性
hasDeletedFilter = sqlType.GetInterfaces().Any(it => it.Name == "IDeletedFilter");
//字段类型
sqlPropertyType = sqlType.GetProperty(sqlProperty)!.PropertyType;
// 获取当前对象实例及其主键值
var propertyInfo = validationContext.ObjectType.GetProperty("Id");
var primaryKeyValue = propertyInfo?.GetValue(validationContext.ObjectInstance);
long idVal = 0;
if (primaryKeyValue == null)
return new ValidationResult($"[{validationContext.MemberName}]无法识别主键信息!");
else
idVal = primaryKeyValue.ToString()!.ToLong();
string sql = $"select count(id) from {sqlTable} where ";
if (sqlPropertyType == typeof(string))
sql += $"{sqlProperty}='{value.ToString()}'";
else if (sqlPropertyType == typeof(int))
sql += $"{sqlProperty}={value}";
else if (sqlPropertyType == typeof(long))
sql += $"{sqlProperty}={value}";
else
return new ValidationResult($"[{validationContext.MemberName}]不支持的字段类型,只支持【string,int,long】!");
if (idVal > 0)
sql += $" and Id != {idVal}";
var userInfo = GlobalContext.UserInfo;
if (hasTenantFilter)
if (userInfo == null)
return new ValidationResult($"[{validationContext.MemberName}]没有找到租户信息!");
else
if(!userInfo.IsSuperAdmin)
sql += $" and Tenantid={userInfo.TenantId}";
if (hasDeletedFilter)
sql += $" and IsDelete=0";
var res = sqlClient.Ado.SqlQuerySingle<int>(sql);
if (res > 0)
return new ValidationResult(!string.IsNullOrEmpty(ErrorMessage) ? ErrorMessage : $"该{validationContext.MemberName}已存在,请输入其他值。");
// 执行同步验证逻辑
return ValidationResult.Success!;
}
}
}