using System.Globalization;
using System.Reflection;
namespace YLErp.Modules.SuperviseReportModule.SAC.Common
{
#region CheckAttrbute
///
/// 检查字段属性基类
///
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public abstract class BaseCheckAttribute : Attribute
{
///
/// 是否必填
/// 默认为true
///
public bool Required { get; set; } = true;
///
/// 处理逻辑名称
/// 该值主要为的派生类提供指定处理逻辑时的绑定名称,如果不需要指定,则该字段不应填写
/// 该值不为Null时,则应在的派生类中字段中指定,否则永远不会被执行
///
public string CheckHandleName { get; set; }
///
/// 是否需要修改值
///
public bool UseChangeValue { get; protected set; }
///
/// 修改后的值
///
public object ChangedValue { get; protected set; }
///
/// 错误提示
///
public abstract string ErrMsg { get; set; }
public abstract bool Execute(object value);
}
///
/// 检查字符串字段属性基类
///
public abstract class BaseCheckStringAttribute : BaseCheckAttribute
{
///
/// Null或空白字符是否通过检查
/// 仅Required=true时有效
/// 默认为和Required一致
///
public bool IgnoreNullOrEmpty { get; set; } = false;
public override bool Execute(object value)
{
var state = false;
var text = (value?.ToString()) ?? "";
if (text.Length == 0)
{
state = !Required || IgnoreNullOrEmpty;
}
else
{
state = Execute(value?.ToString());
}
if (!state)
{
ErrMsg = GenerateErrMsg(value?.ToString());
}
return state;
}
protected abstract string GenerateErrMsg(string value);
protected abstract bool Execute(string value);
}
///
/// 检查字符串长度
/// 字符串长度是否等于预设值
///
public sealed class CheckStringLengthAttribute : BaseCheckStringAttribute
{
///
/// 字符串长度
///
public int Length { get; set; }
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,长度应为{Length}
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且长度应为{Length}";
_errMsg = "值不应为空,且长度应为{Length}";
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
return (value ?? "").Length == Length;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg.Replace("{fieldValue}", value).Replace("{Length}", Length.ToString());
}
}
///
/// 检查字符串最大长度
/// 字符串长度是否超过预设值
///
public sealed class CheckStringMaxLengthAttribute : BaseCheckStringAttribute
{
///
/// 字符串最大长度
///
public int MaxLength { get; set; }
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,最大长度不应超过{MaxLength}
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且最大长度不应超过{MaxLength}";
_errMsg = "值不应为空,且最大长度不应超过{MaxLength}";
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
return (value ?? "").Length <= MaxLength;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg.Replace("{fieldValue}", value).Replace("{MaxLength}", MaxLength.ToString());
}
}
///
/// 检查字符串最小长度
/// 字符串长度是否低于预设值
///
public sealed class CheckStringMinLengthAttribute : BaseCheckStringAttribute
{
///
/// 字符串最小长度
///
public int MinLength { get; set; }
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,长度不应小于{MinLength}
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且长度不应小于{MinLength}";
_errMsg = "值不应为空,且长度不应小于{MinLength}";
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
return (value ?? "").Length >= MinLength;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg.Replace("{fieldValue}", value).Replace("{MinLength}", MinLength.ToString());
}
}
///
/// 检查字符串结尾
/// 检查字符串是否以预设值结尾
///
public sealed class CheckStringEndsWithAttribute : BaseCheckStringAttribute
{
///
/// 指定字符串结尾部分
///
public string EndsWithString { get; set; }
///
/// 多选模式
/// 该字段为true时,将使用对分割后,进行匹配
///
public bool Multiple { get; set; }
///
/// 多条件分隔符
///
public string SplitStr { get; set; } = "|";
///
/// 如字符串为英文字母,是否忽略大小写
/// 默认为:true
///
public bool IgnoreCase { get; set; } = true;
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,内容应以{EndsWithString}结尾
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值不应为空,且内容应以{EndsWithString}结尾";
_errMsg = "值不应为空,且内容应以{EndsWithString}结尾";
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
var match = false;
if (Multiple)
{
var split = EndsWithString.Split(SplitStr.ToCharArray());
foreach (var item in split)
{
match = (value ?? "").EndsWith(item, IgnoreCase, CultureInfo.CurrentCulture);
if (match) { break; }
}
}
else
{
match = (value ?? "").EndsWith(EndsWithString, IgnoreCase, CultureInfo.CurrentCulture);
}
return match;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg.Replace("{fieldValue}", value).Replace("{EndsWithString}", EndsWithString);
}
}
///
/// 检查字符串是否为指定格式的DateTime字符串
///
public sealed class CheckStringIsDateTimeFormatAttribute : BaseCheckStringAttribute
{
///
/// DateTime类型支持的格式化字符
/// 默认为:yyyy-MM-dd
///
public string FormatString { get; set; } = "yyyy-MM-dd";
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,不匹配{FormatString}格式
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,不匹配{FormatString}格式";
_errMsg = "不匹配{FormatString}格式";
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
var result = true;
try
{
result = DateTime.TryParseExact(value ?? "", FormatString, CultureInfo.CurrentCulture, DateTimeStyles.None, out _);
if (!result)
{
result = DateTime.TryParse(value ?? "", out var temp);
if (result)
{
UseChangeValue = true;
ChangedValue = temp.ToString(FormatString);
}
}
}
catch
{
result = false;
}
return result;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg.Replace("{fieldValue}", value).Replace("{FormatString}", FormatString);
}
}
///
/// 检查字符串是否为数字或百分数,长度在指定范围内,可选是否检查值的合法区间
///
public sealed class CheckStringIntOrPercentRangeAttribute : BaseCheckStringAttribute
{
///
/// 值为数字时小数点前最大长度
///
public int BeforePointMaxLength_Number { get; set; }
///
/// 值为数字时小数点后最大长度
///
public int AfterPointMaxLength_Number { get; set; }
///
/// 值为数字时最大值
/// 可选,不设置则不检查
///
public double MaxValue_Number { get; set; } = double.NaN;
///
/// 值为数字时最小值
/// 可选,不设置则不检查
///
public double MinValue_Number { get; set; } = double.NaN;
///
/// 值为百分数时小数点前最大长度
///
public int BeforePointMaxLength_Percent { get; set; }
///
/// 值为百分数时小数点后最大长度
///
public int AfterPointMaxLength_Percent { get; set; }
///
/// 值为百分数时最大值
/// 可选,不设置则不检查
///
public double MaxValue_Percent { get; set; } = double.NaN;
///
/// 值为百分数时最小值
/// 可选,不设置则不检查
///
public double MinValue_Percent { get; set; } = double.NaN;
private string _errMsg;
///
/// 错误提示
/// 默认为:
/// {fieldName}={fieldValue}不合法,保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}],取值区间为[>{MinValue},<{MaxValue}]
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]";
_errMsg = "值应为数字,且保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]";
double minValue, maxValue;
if (isPercent)
{
minValue = MinValue_Percent;
maxValue = MaxValue_Percent;
}
else
{
minValue = MinValue_Number;
maxValue = MaxValue_Number;
}
var msgArr = new List();
if (!double.IsNaN(minValue))
{
msgArr.Add(">={MinValue}");
}
if (!double.IsNaN(maxValue))
{
msgArr.Add("<={MaxValue}");
}
if (msgArr.Count > 0)
{
_errMsg += $",取值范围为[{string.Join(",", msgArr)}]";
}
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
private bool isPercent;
protected override bool Execute(string value)
{
int beforePointMaxLength, afterPointMaxLength;
double maxValue, minValue;
isPercent = isPercent = value != null && value.EndsWith("%");
if (isPercent)
{
value = value.Remove(value.Length - 1);
beforePointMaxLength = BeforePointMaxLength_Percent;
afterPointMaxLength = AfterPointMaxLength_Percent;
maxValue = MaxValue_Percent;
minValue = MinValue_Percent;
}
else
{
beforePointMaxLength = BeforePointMaxLength_Number;
afterPointMaxLength = AfterPointMaxLength_Number;
maxValue = MaxValue_Number;
minValue = MinValue_Number;
}
if (!double.TryParse(value, out var temp))
{
return false;
}
var part = (value ?? "").Split('.');
if (part.Length > 2)
{
return false;
}
if (part[0].Length > beforePointMaxLength)
{
return false;
}
if (!double.IsNaN(maxValue) && temp > maxValue)
{
return false;
}
if (!double.IsNaN(minValue) && temp < minValue)
{
return false;
}
if (part.Length > 1 && part[1].Length > afterPointMaxLength)
{
UseChangeValue = true;
string sufix = "0.".PadRight(afterPointMaxLength + 2, '0');
UseChangeValue = true;
ChangedValue = temp.ToString(sufix) + (isPercent ? "%" : "");
return true;
}
return true;
}
protected override string GenerateErrMsg(string value)
{
int beforePointMaxLength, afterPointMaxLength;
double maxValue, minValue;
isPercent = isPercent = value != null && value.EndsWith("%");
if (isPercent)
{
value = value.Remove(value.Length - 2);
beforePointMaxLength = BeforePointMaxLength_Percent;
afterPointMaxLength = AfterPointMaxLength_Percent;
maxValue = MaxValue_Percent;
minValue = MinValue_Percent;
}
else
{
beforePointMaxLength = BeforePointMaxLength_Number;
afterPointMaxLength = AfterPointMaxLength_Number;
maxValue = MaxValue_Number;
minValue = MinValue_Number;
}
return ErrMsg
.Replace("{fieldValue}", value)
.Replace("{BeforePointMaxLength}", beforePointMaxLength.ToString())
.Replace("{AfterPointMaxLength}", afterPointMaxLength.ToString())
.Replace("{MinValue}", minValue.ToString())
.Replace("{MaxValue}", maxValue.ToString());
}
}
///
/// 检查字符串是否为数字,长度在指定范围内,可选是否检查值的合法区间
///
public sealed class CheckStringIntMaxLengthAttribute : BaseCheckStringAttribute
{
///
/// 小数点前最大长度
///
public int BeforePointMaxLength { get; set; }
///
/// 小数点后最大长度
///
public int AfterPointMaxLength { get; set; }
///
/// 最大值
/// 可选,不设置则不检查
///
public double MaxValue { get; set; } = double.NaN;
///
/// 最小值
/// 可选,不设置则不检查
///
public double MinValue { get; set; } = double.NaN;
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}],取值范围为[>{MinValue},<{MaxValue}]
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]";
_errMsg = "值应为数字,且最大保留位数为[{BeforePointMaxLength},{AfterPointMaxLength}]";
var msgArr = new List();
if (!double.IsNaN(MinValue))
{
msgArr.Add(">={MinValue}");
}
if (!double.IsNaN(MaxValue))
{
msgArr.Add("<={MaxValue}");
}
if (msgArr.Count > 0)
{
_errMsg += $",取值范围为[{string.Join(",", msgArr)}]";
}
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
if (!double.TryParse(value, out var temp))
{
return false;
}
var part = (value ?? "").Split('.');
if (part.Length > 2)
{
return false;
}
if (part[0].Length > BeforePointMaxLength)
{
return false;
}
var state = true;
if (part.Length == 1 || (part.Length > 1 && part[1].Length != AfterPointMaxLength))
{
UseChangeValue = true;
var sufix = "0.".PadRight(AfterPointMaxLength + 2, '0');
UseChangeValue = true;
ChangedValue = temp.ToString(sufix);
state = true;
}
if (!double.IsNaN(MinValue) && temp < MinValue)
{
state = false;
}
if (!double.IsNaN(MaxValue) && temp > MaxValue)
{
state = false;
}
return state;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg
.Replace("{fieldValue}", value)
.Replace("{BeforePointMaxLength}", BeforePointMaxLength.ToString())
.Replace("{AfterPointMaxLength}", AfterPointMaxLength.ToString())
.Replace("{MinValue}", MinValue.ToString())
.Replace("{MaxValue}", MaxValue.ToString());
}
}
///
/// 检查字符串是否为数字,长度在指定范围内(小数长度必须和预设值相等),可选是否检查值的合法区间
///
public sealed class CheckStringIntLengthAttribute : BaseCheckStringAttribute
{
///
/// 小数点前最大长度
///
public int BeforePointMaxLength { get; set; }
///
/// 小数点后长度
/// 小数位必须与该值相等,否则应使用
///
public int AfterPointLength { get; set; }
///
/// 最大值
/// 可选,不设置则不检查
///
public double MaxValue { get; set; } = double.NaN;
///
/// 最小值
/// 可选,不设置则不检查
///
public double MinValue { get; set; } = double.NaN;
private string _errMsg;
///
/// 错误提示
/// 默认为:{fieldName}={fieldValue}不合法,保留位数必须为{BeforePointMaxLength},{AfterPointLength},取值范围为[>{MinValue},<{MaxValue}]
///
public override string ErrMsg
{
get
{
if (string.IsNullOrWhiteSpace(_errMsg))
{
//_errMsg = "{fieldName}={fieldValue}不合法,值应为数字,且保留位数必须为[{BeforePointMaxLength},{AfterPointLength}]";
_errMsg = "值应为数字,且保留位数必须为[{BeforePointMaxLength},{AfterPointLength}]";
var msgArr = new List();
if (!double.IsNaN(MinValue))
{
msgArr.Add(">={MinValue}");
}
if (!double.IsNaN(MaxValue))
{
msgArr.Add("<={MaxValue}");
}
if (msgArr.Count > 0)
{
_errMsg += $",取值范围为[{string.Join(",", msgArr)}]";
}
}
return _errMsg;
}
set
{
_errMsg = value;
}
}
protected override bool Execute(string value)
{
if (!double.TryParse(value, out var temp))
{
return false;
}
if (!double.IsNaN(MinValue) && temp < MinValue)
{
return false;
}
if (!double.IsNaN(MaxValue) && temp > MaxValue)
{
return false;
}
var part = (value ?? "").Split('.');
if (part[0].Length > BeforePointMaxLength)
{
return false;
}
if (part.Length == 1 || (part.Length > 1 && part[1].Length != AfterPointLength))
{
var sufix = "0.".PadRight(AfterPointLength + 2, '0');
UseChangeValue = true;
ChangedValue = temp.ToString(sufix);
return true;
}
return true;
}
protected override string GenerateErrMsg(string value)
{
return ErrMsg
.Replace("{fieldValue}", value)
.Replace("{BeforePointMaxLength}", BeforePointMaxLength.ToString())
.Replace("{AfterPointLength}", AfterPointLength.ToString())
.Replace("{MinValue}", MinValue.ToString())
.Replace("{MaxValue}", MaxValue.ToString());
}
}
///
/// 检查IEnumerable基类属性基类
///
public abstract class BaseCheckIEnumerableTAttribute : BaseCheckAttribute
{
public override bool Execute(object value)
{
var state = false;
var objs = value as IEnumerable