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.
127 lines
5.1 KiB
127 lines
5.1 KiB
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!;
|
|
}
|
|
}
|
|
}
|
|
|