using cylsg.utility.Extend;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Linq;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.ComponentModel.DataAnnotations;
|
using System.Globalization;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Net.Http.Json;
|
using System.Reflection;
|
using System.Runtime.Loader;
|
using System.Security.Cryptography;
|
using System.Text;
|
using System.Text.Json.Serialization;
|
using System.Text.RegularExpressions;
|
using System.Threading.Tasks;
|
using static cylsg.utility.untilityModels;
|
|
namespace cylsg.utility
|
{
|
/// <summary>
|
/// 通用帮助类
|
/// </summary>
|
public static class CommonHelper
|
{
|
|
#region 判断字符串是否为手机号码
|
/// <summary>
|
/// 判断字符串是否为手机号码
|
/// </summary>
|
/// <param name="mobilePhoneNumber"></param>
|
/// <returns></returns>
|
public static bool IsMobile(string mobilePhoneNumber)
|
{
|
if (mobilePhoneNumber.Length < 11)
|
{
|
return false;
|
}
|
|
//电信手机号码正则
|
string dianxin = @"^1[345789][01379]\d{8}$";
|
Regex regexDx = new Regex(dianxin);
|
//联通手机号码正则
|
string liantong = @"^1[345678][01256]\d{8}$";
|
Regex regexLt = new Regex(liantong);
|
//移动手机号码正则
|
string yidong = @"^1[345789][0123456789]\d{8}$";
|
Regex regexYd = new Regex(yidong);
|
if (regexDx.IsMatch(mobilePhoneNumber) || regexLt.IsMatch(mobilePhoneNumber) || regexYd.IsMatch(mobilePhoneNumber))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
#endregion
|
|
#region 检测是否符合email格式
|
|
/// <summary>
|
/// 检测是否符合email格式
|
/// </summary>
|
/// <param name="strEmail">要判断的email字符串</param>
|
/// <returns>判断结果</returns>
|
public static bool IsValidEmail(string strEmail)
|
{
|
return Regex.IsMatch(strEmail, @"^[\w\.]+([-]\w+)*@[A-Za-z0-9-_]+[\.][A-Za-z0-9-_]");
|
}
|
|
public static bool IsValidDoEmail(string strEmail)
|
{
|
return Regex.IsMatch(strEmail,
|
@"^@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
|
}
|
#endregion
|
|
#region 检测是否是正确的Url
|
/// <summary>
|
/// 检测是否是正确的Url
|
/// </summary>
|
/// <param name="strUrl">要验证的Url</param>
|
/// <returns>判断结果</returns>
|
public static bool IsUrl(string strUrl)
|
{
|
return Regex.IsMatch(strUrl,
|
@"^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{1,10}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$");
|
}
|
|
|
#endregion
|
|
#region string 转int数组
|
|
public static int[] StringToIntArray(string str)
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(str)) return new int[0];
|
if (str.EndsWith(","))
|
{
|
str = str.Remove(str.Length - 1, 1);
|
}
|
var idstrarr = str.Split(',');
|
var idintarr = new int[idstrarr.Length];
|
|
for (int i = 0; i < idstrarr.Length; i++)
|
{
|
idintarr[i] = Convert.ToInt32(idstrarr[i]);
|
}
|
return idintarr;
|
}
|
catch
|
{
|
return new int[0];
|
}
|
}
|
#endregion
|
|
#region String转数组
|
public static string[] StringToStringArray(string str)
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(str)) return new string[0];
|
if (str.EndsWith(",")) str = str.Remove(str.Length - 1, 1);
|
return str.Split(',');
|
}
|
catch
|
{
|
return new string[0];
|
}
|
}
|
#endregion
|
|
#region String数组转Int数组
|
public static int[] StringArrAyToIntArray(string[] str)
|
{
|
try
|
{
|
int[] iNums = Array.ConvertAll(str, s => int.Parse(s));
|
return iNums;
|
}
|
catch
|
{
|
return new int[0];
|
}
|
}
|
#endregion
|
|
#region string转Guid数组
|
|
public static Guid[] StringToGuidArray(string str)
|
{
|
try
|
{
|
if (string.IsNullOrEmpty(str)) return new Guid[0];
|
if (str.EndsWith(",")) str = str.Remove(str.Length - 1, 1);
|
var strarr = str.Split(',');
|
Guid[] guids = new Guid[strarr.Length];
|
for (int index = 0; index < strarr.Length; index++)
|
{
|
guids[index] = Guid.Parse(strarr[index]);
|
}
|
return guids;
|
}
|
catch
|
{
|
return new Guid[0];
|
}
|
}
|
#endregion
|
|
#region 转MD5
|
/// <summary>
|
/// 转MD5
|
/// </summary>
|
/// <param name="str"></param>
|
/// <returns></returns>
|
public static string ToMd5(string str)
|
{
|
MD5 md5 = MD5.Create();
|
// 将字符串转换成字节数组
|
byte[] byteOld = Encoding.UTF8.GetBytes(str);
|
// 调用加密方法
|
byte[] byteNew = md5.ComputeHash(byteOld);
|
// 将加密结果转换为字符串
|
StringBuilder sb = new StringBuilder();
|
foreach (byte b in byteNew)
|
{
|
// 将字节转换成16进制表示的字符串,
|
sb.Append(b.ToString("x2"));
|
}
|
// 返回加密的字符串
|
return sb.ToString();
|
}
|
#endregion
|
|
#region 获取32位md5加密
|
/// <summary>
|
/// 通过创建哈希字符串适用于任何 MD5 哈希函数 (在任何平台) 上创建 32 个字符的十六进制格式哈希字符串
|
/// </summary>
|
/// <param name="source"></param>
|
/// <returns>32位md5加密字符串</returns>
|
public static string Md5For32(string source)
|
{
|
using (MD5 md5Hash = MD5.Create())
|
{
|
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source));
|
StringBuilder sBuilder = new StringBuilder();
|
for (int i = 0; i < data.Length; i++)
|
{
|
sBuilder.Append(data[i].ToString("x2"));
|
}
|
|
string hash = sBuilder.ToString();
|
return hash.ToUpper();
|
}
|
}
|
#endregion
|
|
#region 获取16位md5加密
|
/// <summary>
|
/// 获取16位md5加密
|
/// </summary>
|
/// <param name="source"></param>
|
/// <returns>16位md5加密字符串</returns>
|
public static string Md5For16(string source)
|
{
|
using (MD5 md5Hash = MD5.Create())
|
{
|
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source));
|
//转换成字符串,并取9到25位
|
string sBuilder = BitConverter.ToString(data, 4, 8);
|
//BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉
|
sBuilder = sBuilder.Replace("-", "");
|
return sBuilder.ToUpper();
|
}
|
}
|
|
#endregion
|
|
#region 返回当前的毫秒时间戳
|
|
/// <summary>
|
/// 返回当前的毫秒时间戳
|
/// </summary>
|
public static string Msectime()
|
{
|
long timeTicks = (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000;
|
return timeTicks.ToString();
|
}
|
|
|
#endregion
|
|
|
|
#region 剩余多久时间文字描述
|
/// <summary>
|
/// 剩余多久时间
|
/// </summary>
|
/// <param name="remainingTime"></param>
|
/// <returns>文字描述</returns>
|
public static string GetRemainingTime(DateTime remainingTime)
|
{
|
TimeSpan timeSpan = remainingTime - DateTime.Now;
|
var day = timeSpan.Days;
|
var hours = timeSpan.Hours;
|
var minute = timeSpan.Minutes;
|
var seconds = timeSpan.Seconds;
|
if (day > 0)
|
{
|
return day + "天" + hours + "小时" + minute + "分" + seconds + "秒";
|
}
|
else
|
{
|
if (hours > 0)
|
{
|
return hours + "小时" + minute + "分" + seconds + "秒";
|
}
|
else
|
{
|
return minute + "分" + seconds + "秒";
|
}
|
}
|
}
|
|
#endregion
|
|
#region 剩余多久时间返回时间类型
|
/// <summary>
|
/// 剩余多久时间
|
/// </summary>
|
/// <param name="remainingTime"></param>
|
/// <returns>返回时间类型</returns>
|
public static void GetBackTime(DateTime remainingTime, out int day, out int hours, out int minute, out int seconds)
|
{
|
TimeSpan timeSpan = remainingTime - DateTime.Now;
|
day = timeSpan.Days;
|
hours = timeSpan.Hours;
|
minute = timeSpan.Minutes;
|
seconds = timeSpan.Seconds;
|
}
|
|
#endregion
|
|
#region 计算时间戳剩余多久时间
|
|
/// <summary>
|
/// 计算时间戳剩余多久时间
|
/// </summary>
|
/// <param name="postTime">提交时间(要是以前的时间)</param>
|
/// <returns></returns>
|
public static string TimeAgo(DateTime postTime)
|
{
|
//当前时间的时间戳
|
var nowtimes = ConvertTicks(DateTime.Now);
|
//提交的时间戳
|
var posttimes = ConvertTicks(postTime);
|
//相差时间戳
|
var counttime = nowtimes - posttimes;
|
|
//进行时间转换
|
if (counttime <= 60)
|
{
|
return "刚刚";
|
}
|
else if (counttime > 60 && counttime <= 120)
|
{
|
return "1分钟前";
|
}
|
else if (counttime > 120 && counttime <= 180)
|
{
|
return "2分钟前";
|
}
|
else if (counttime > 180 && counttime < 3600)
|
{
|
return Convert.ToInt32(counttime / 60) + "分钟前";
|
}
|
else if (counttime >= 3600 && counttime < 3600 * 24)
|
{
|
return Convert.ToInt32(counttime / 3600) + "小时前";
|
}
|
else if (counttime >= 3600 * 24 && counttime < 3600 * 24 * 2)
|
{
|
return "昨天";
|
}
|
else if (counttime >= 3600 * 24 * 2 && counttime < 3600 * 24 * 3)
|
{
|
return "前天";
|
}
|
else if (counttime >= 3600 * 24 * 3 && counttime <= 3600 * 24 * 7)
|
{
|
return Convert.ToInt32(counttime / (3600 * 24)) + "天前";
|
}
|
else if (counttime >= 3600 * 24 * 7 && counttime <= 3600 * 24 * 30)
|
{
|
return Convert.ToInt32(counttime / (3600 * 24 * 7)) + "周前";
|
}
|
else if (counttime >= 3600 * 24 * 30 && counttime <= 3600 * 24 * 365)
|
{
|
return Convert.ToInt32(counttime / (3600 * 24 * 30)) + "个月前";
|
}
|
else if (counttime >= 3600 * 24 * 365)
|
{
|
return Convert.ToInt32(counttime / (3600 * 24 * 365)) + "年前";
|
}
|
else
|
{
|
return "";
|
}
|
}
|
|
/// <summary>
|
/// 时间转换为秒的时间戳
|
/// </summary>
|
/// <param name="time"></param>
|
/// <returns></returns>
|
private static long ConvertTicks(DateTime time)
|
{
|
long currentTicks = time.Ticks;
|
DateTime dtFrom = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
long currentMillis = (currentTicks - dtFrom.Ticks) / 10000000; //转换为秒为Ticks/10000000,转换为毫秒Ticks/10000
|
return currentMillis;
|
}
|
|
#endregion
|
|
#region 清除HTML中指定样式
|
/// <summary>
|
/// 清除HTML中指定样式
|
/// </summary>
|
/// <param name="content"></param>
|
/// <param name="rule"></param>
|
/// <returns></returns>
|
public static string ClearHtml(string content, string[] rule)
|
{
|
if (!rule.Any())
|
{
|
return content;
|
}
|
|
foreach (var item in rule)
|
{
|
content = Regex.Replace(content, "/" + item + @"\s*=\s*\d+\s*/i", "");
|
content = Regex.Replace(content, "/" + item + @"\s*=\s*.+?[""]/i", "");
|
content = Regex.Replace(content, "/" + item + @"\s*:\s*\d+\s*px\s*;?/i", "");
|
}
|
return content;
|
}
|
#endregion
|
|
#region list随机排序方法
|
/// <summary>
|
/// list随机排序方法
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <param name="ListT"></param>
|
/// <returns></returns>
|
public static List<T> RandomSortList<T>(List<T> ListT)
|
{
|
Random random = new Random();
|
List<T> newList = new List<T>();
|
foreach (T item in ListT)
|
{
|
newList.Insert(random.Next(newList.Count + 1), item);
|
}
|
return newList;
|
}
|
#endregion
|
|
|
|
#region 截前后字符(串)
|
///<summary>
|
/// 截前后字符(串)
|
///</summary>
|
///<param name="val">原字符串</param>
|
///<param name="str">要截掉的字符串</param>
|
///<param name="all">是否贪婪</param>
|
///<returns></returns>
|
public static string GetCaptureInterceptedText(string val, string str, bool all = false)
|
{
|
return Regex.Replace(val, @"(^(" + str + ")" + (all ? "*" : "") + "|(" + str + ")" + (all ? "*" : "") + "$)", "");
|
}
|
#endregion
|
|
#region 密码加密方法
|
/// <summary>
|
/// 密码加密方法
|
/// </summary>
|
/// <param name="password">要加密的字符串</param>
|
/// <param name="createTime">时间组合</param>
|
/// <returns></returns>
|
public static string EnPassword(string password, DateTime createTime)
|
{
|
var dtStr = createTime.ToString("yyyyMMddHHmmss");
|
var md5 = Md5For32(password);
|
var enPwd = Md5For32(md5 + dtStr);
|
return enPwd;
|
}
|
#endregion
|
|
#region 获取现在是星期几
|
/// <summary>
|
/// 获取现在是星期几
|
/// </summary>
|
/// <returns></returns>
|
public static string GetWeek()
|
{
|
string week = string.Empty;
|
switch (DateTime.Now.DayOfWeek)
|
{
|
case DayOfWeek.Monday:
|
week = "周一";
|
break;
|
case DayOfWeek.Tuesday:
|
week = "周二";
|
break;
|
case DayOfWeek.Wednesday:
|
week = "周三";
|
break;
|
case DayOfWeek.Thursday:
|
week = "周四";
|
break;
|
case DayOfWeek.Friday:
|
week = "周五";
|
break;
|
case DayOfWeek.Saturday:
|
week = "周六";
|
break;
|
case DayOfWeek.Sunday:
|
week = "周日";
|
break;
|
default:
|
week = "N/A";
|
break;
|
}
|
return week;
|
}
|
|
#endregion
|
|
#region UrlEncode (URL编码)
|
/// <summary>
|
/// UrlEncode (URL编码)
|
/// </summary>
|
/// <param name="str"></param>
|
/// <returns></returns>
|
public static string UrlEncode(string str)
|
{
|
StringBuilder sb = new StringBuilder();
|
byte[] byStr = Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
|
for (int i = 0; i < byStr.Length; i++)
|
{
|
sb.Append(@"%" + Convert.ToString(byStr[i], 16));
|
}
|
|
return sb.ToString();
|
}
|
|
#endregion
|
|
#region 获取10位时间戳
|
/// <summary>
|
/// 获取10位时间戳
|
/// </summary>
|
/// <returns></returns>
|
public static long GetTimeStampByTotalSeconds()
|
{
|
TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
return Convert.ToInt64(ts.TotalSeconds);
|
}
|
#endregion
|
|
#region 获取13位时间戳
|
/// <summary>
|
/// 获取13位时间戳
|
/// </summary>
|
/// <returns></returns>
|
public static long GetTimeStampByTotalMilliseconds()
|
{
|
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
return Convert.ToInt64(ts.TotalMilliseconds);
|
}
|
|
/// <summary>
|
/// 获取时间戳
|
/// </summary>
|
/// <param name="dt"></param>
|
/// <returns></returns>
|
public static int GetDateTimeStamp(DateTime dt)
|
{
|
DateTime dateStart = new DateTime(1970, 1, 1, 0, 0, 0);
|
int timeStamp = Convert.ToInt32((dt.ToUniversalTime() - dateStart).TotalSeconds);
|
return timeStamp;
|
}
|
|
#endregion
|
|
#region 获取随机字符串
|
/// <summary>
|
/// 获取随机字符串
|
/// </summary>
|
/// <returns></returns>
|
public static string GetSerialNumber()
|
{
|
var str = string.Empty;
|
Random rand = new Random();
|
var charsStr2 = new[] { 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
|
var charsLen2 = charsStr2.Length - 1;
|
// shuffle($chars);
|
str = "";
|
for (int i = 0; i < 16; i++)
|
{
|
str += charsStr2[rand.Next(0, charsLen2)];
|
}
|
return str;
|
}
|
|
#endregion
|
|
#region Sha1签名
|
/// <summary>
|
/// Sha1签名
|
/// </summary>
|
/// <param name="str">内容</param>
|
/// <param name="encoding">编码</param>
|
/// <returns></returns>
|
public static string Sha1Signature(string str, Encoding encoding = null)
|
{
|
if (encoding == null) encoding = Encoding.UTF8;
|
var buffer = encoding.GetBytes(str);
|
var data = SHA1.Create().ComputeHash(buffer);
|
StringBuilder sub = new StringBuilder();
|
foreach (var t in data)
|
{
|
sub.Append(t.ToString("x2"));
|
}
|
|
return sub.ToString();
|
}
|
#endregion
|
|
/// <summary>
|
/// 精确计算base64字符串文件大小(单位:B)
|
/// param base64String
|
/// return double 字节大小
|
/// </summary>
|
/// <param name="base64String"></param>
|
/// <returns></returns>
|
public static double Base64FileSize(string base64String)
|
{
|
//检测是否含有base64,文件头)
|
if (base64String.LastIndexOf(",", StringComparison.Ordinal) > -1)
|
{
|
base64String = base64String[(base64String.LastIndexOf(",", StringComparison.Ordinal) + 1)..];
|
}
|
//获取base64字符串长度(不含data:audio/wav;base64,文件头)
|
var size0 = base64String.Length;
|
if (size0 <= 10) return size0 - (double)size0 / 8 * 2;
|
//获取字符串的尾巴的最后10个字符,用于判断尾巴是否有等号,正常生成的base64文件'等号'不会超过4个
|
var tail = base64String[(size0 - 10)..];
|
//找到等号,把等号也去掉,(等号其实是空的意思,不能算在文件大小里面)
|
int equalIndex = tail.IndexOf("=", StringComparison.Ordinal);
|
if (equalIndex > 0)
|
{
|
size0 = size0 - (10 - equalIndex);
|
}
|
//计算后得到的文件流大小,单位为字节
|
return size0 - (double)size0 / 8 * 2;
|
}
|
|
/// <summary>
|
/// 判断文件大小
|
/// </summary>
|
/// <param name="base64"></param>
|
/// <param name="size"></param>
|
/// <param name="unit"></param>
|
/// <returns></returns>
|
public static bool CheckBase64Size(string base64, int size, string unit = "M")
|
{
|
// 上传文件的大小, 单位为字节.
|
var len = Base64FileSize(base64);
|
// 准备接收换算后文件大小的容器
|
double fileSize = unit.ToUpperInvariant() switch
|
{
|
"B" => len,
|
"K" => (double)len / 1024,
|
"M" => (double)len / 1048576,
|
"G" => (double)len / 1073741824,
|
_ => 0
|
};
|
// 如果上传文件大于限定的容量
|
return !(fileSize > size);
|
}
|
|
/// <summary>
|
/// 10位时间戳 转化
|
/// </summary>
|
/// <param name="time"></param>
|
/// <returns></returns>
|
public static long ConvertDateTimeToInt(DateTime time)
|
{
|
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0, 0));
|
long t = (time.Ticks - startTime.Ticks) / 10000000; //除10000000调整为10位
|
return t;
|
}
|
|
#region 反射相关
|
private static List<Assembly>? _allAssemblies = null;
|
/// <summary>
|
/// 获取所有程序目录下和常用的程序集 包括一些系统引用程序集
|
/// </summary>
|
/// <returns> 当前工程下的程序集</returns>
|
public static List<Assembly> GetAllAssembly()
|
{
|
|
|
if (_allAssemblies == null)
|
{
|
_allAssemblies = new List<Assembly>();
|
string? path = null;
|
string singlefile = null;
|
try
|
{
|
path = Assembly.GetEntryAssembly()?.Location;
|
}
|
catch { }
|
if (string.IsNullOrEmpty(path))
|
{
|
singlefile = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
|
path = Path.GetDirectoryName(singlefile);
|
}
|
if (string.IsNullOrEmpty(path))
|
|
throw new Exception("获取程序目录出错");
|
var dir = new DirectoryInfo(Path.GetDirectoryName(path) ?? "");
|
|
var dlls = dir.GetFiles("*.dll", SearchOption.TopDirectoryOnly);
|
string[] systemdll = new string[]
|
{
|
"Microsoft.",
|
"System.",
|
"Swashbuckle.",
|
"ICSharpCode",
|
"Newtonsoft.",
|
"Oracle.",
|
"Pomelo.",
|
"SQLitePCLRaw.",
|
"Aliyun.OSS",
|
"BouncyCastle.",
|
"FreeSql.",
|
"Google.Protobuf.dll",
|
"Humanizer.dll",
|
"IdleBus.dll",
|
"K4os.",
|
"MySql.Data.",
|
"Npgsql.",
|
"NPOI.",
|
"netstandard",
|
"MySqlConnector",
|
"VueCliMiddleware"
|
};
|
|
var filtered = dlls.Where(x => systemdll.Any(y => x.Name.StartsWith(y)) == false);
|
foreach (var dll in filtered)
|
{
|
try
|
{
|
AssemblyLoadContext.Default.LoadFromAssemblyPath(dll.FullName);
|
}
|
catch
|
{
|
}
|
}
|
var dlllist = AssemblyLoadContext.Default.Assemblies.Where(x => systemdll.Any(y => x.FullName.StartsWith(y)) == false).ToList();
|
_allAssemblies.AddRange(dlllist);
|
}
|
return _allAssemblies;
|
}
|
#endregion
|
|
#region 枚举获取所有项
|
/// <summary>
|
/// 获取枚举的所有项
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <returns></returns>
|
public static List<MenmItem> GetEnumItemsWithAttributes<T>() where T : Enum
|
{
|
var result = new List<MenmItem>();
|
|
foreach (var value in Enum.GetValues(typeof(T)))
|
{
|
var member = typeof(T).GetMember(value.ToString())[0];
|
var descriptionAttribute = member.GetCustomAttribute<DescriptionAttribute>();
|
|
var item = new MenmItem
|
{
|
Key = value.ToString(),
|
Value = (int)value, // 或者直接使用 value.ToString() 如果不需要转换为整数字符串
|
Description = descriptionAttribute?.Description ?? string.Empty
|
};
|
|
result.Add(item);
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 获取枚举所有的项,返回名称 值 和Description 描述
|
/// </summary>
|
/// <param name="enumType"></param>
|
/// <returns></returns>
|
/// <exception cref="ArgumentException"></exception>
|
public static List<MenmItem> EnumerateWithDescriptions(Type enumType)
|
{
|
if (!enumType.IsEnum)
|
{
|
throw new ArgumentException(" 这不是枚举");
|
}
|
|
var result = new List<MenmItem>();
|
|
foreach (var value in Enum.GetValues(enumType))
|
{
|
var member = enumType.GetMember(value.ToString())[0];
|
var descriptionAttribute = member.GetCustomAttribute<DescriptionAttribute>();
|
|
var item = new MenmItem
|
{
|
Key = value.ToString(),
|
Value = (int)value, // 或者直接使用 value.ToString() 如果不需要转换为整数字符串
|
Description = descriptionAttribute?.Description ?? string.Empty
|
};
|
|
result.Add(item);
|
}
|
|
return result;
|
}
|
/// <summary>
|
/// 是否是系统类型
|
/// </summary>
|
/// <param name="type"></param>
|
/// <returns></returns>
|
public static bool IsCustomType(Type type)
|
{
|
// 定义一个或多个基础命名空间列表,这些命名空间下的类型通常认为是系统类型
|
string[] frameworkNamespaces = { "System", "Microsoft", "mscorlib", "netstandard", "System.Private.CoreLib" };
|
|
// 获取类型所在的命名空间
|
string typeNameSpace = type.Namespace;
|
|
// 检查该命名空间是否在基础命名空间列表中,如果不在,则认为是自定义类型
|
return frameworkNamespaces.Any(n => typeNameSpace.StartsWith(n, StringComparison.OrdinalIgnoreCase));
|
}
|
|
|
#endregion
|
|
/// <summary>
|
/// 根据json字符穿处理
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <param name="jsonString"></param>
|
/// <param name="parameter"></param>
|
/// <returns></returns>
|
private static Expression<Func<T, bool>> CreateWhereExpressionRecursive<T>(string jsonString, ParameterExpression parameter)
|
{
|
var conditions = new List<Expression>();
|
|
JObject jsonObject = JObject.Parse(jsonString);
|
|
foreach (var property in jsonObject.Properties())
|
{
|
var propertyName = property.Name;
|
var propertyValue = property.Value.ToString();
|
if (propertyValue == "") //空值不处理
|
continue;
|
var propertyInfo = typeof(T).GetProperty(propertyName);
|
|
if (propertyInfo == null)
|
{
|
propertyInfo = typeof(T).GetProperty(propertyName.FirstToCapitalize());
|
if (propertyInfo == null)
|
continue; // 如果属性不存在,跳过
|
}
|
|
var propertyType = propertyInfo.PropertyType;
|
var TypeName = propertyType.GenericTypeArguments.Length > 0 ? propertyType.GenericTypeArguments[0].Name + "?" : propertyType.Name;
|
if (propertyType.IsClass && TypeName != "String")
|
{
|
// 递归处理嵌套模型
|
var nestedParameter = Expression.Parameter(propertyType, propertyName);
|
var nestedJsonString = property.Value.ToString();
|
|
// 使用 MakeGenericType 动态创建泛型方法
|
var genericMethod = typeof(CommonHelper).GetMethod("CreateWhereExpressionRecursive", BindingFlags.Static | BindingFlags.NonPublic)
|
.MakeGenericMethod(propertyType);
|
|
// 调用泛型方法并获取返回的表达式
|
var nestedConditions = (Expression<Func<object, bool>>)genericMethod.Invoke(null, new object[] { nestedJsonString, nestedParameter });
|
|
var propExpr = Expression.Property(parameter, propertyName);
|
var lambda = Expression.Lambda(nestedConditions.Body, nestedParameter);
|
var invoke = Expression.Invoke(lambda, propExpr);
|
conditions.Add(invoke);
|
}
|
else if (propertyType == typeof(string))
|
{
|
var propExpr = Expression.Property(parameter, propertyName);
|
var constant = Expression.Constant(propertyValue);
|
|
var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
|
var containsExpression = Expression.Call(propExpr, containsMethod, constant);
|
conditions.Add(containsExpression);
|
}
|
else if (TypeName.Contains( "DateTime")) //兼容DateTime?
|
{
|
var dateRange = propertyValue.Split('~');
|
if (dateRange.Length == 2)
|
{
|
var startDate = DateTime.Parse(dateRange[0]);
|
var endDate = DateTime.Parse(dateRange[1]);
|
|
var propExpr = Expression.Property(parameter, propertyName);
|
var startConstant = Expression.Constant(startDate);
|
var endConstant = Expression.Constant(endDate);
|
if (TypeName == "DateTime?")
|
// 将常量表达式转换为 Nullable<DateTime>
|
{
|
var startNullableConstant = Expression.Convert(startConstant, typeof(DateTime?));
|
var endNullableConstant = Expression.Convert(endConstant, typeof(DateTime?));
|
|
|
var greaterThanOrEqual = Expression.GreaterThanOrEqual(propExpr, startNullableConstant);
|
var lessThanOrEqual = Expression.LessThanOrEqual(propExpr, endNullableConstant);
|
|
|
var andExpression = Expression.AndAlso(greaterThanOrEqual, lessThanOrEqual);
|
conditions.Add(andExpression);
|
}
|
else
|
{
|
|
var greaterThanOrEqual = Expression.GreaterThanOrEqual(propExpr, startConstant);
|
var lessThanOrEqual = Expression.LessThanOrEqual(propExpr, endConstant);
|
|
|
var andExpression = Expression.AndAlso(greaterThanOrEqual, lessThanOrEqual);
|
conditions.Add(andExpression);
|
|
}
|
}
|
else if (DateTime.TryParse(propertyValue, out var dateTime))
|
{
|
var propExpr = Expression.Property(parameter, propertyName);
|
var constant = Expression.Constant(dateTime);
|
var equalExpression = Expression.Equal(propExpr, constant);
|
conditions.Add(equalExpression);
|
}
|
}
|
else
|
{
|
var propExpr = Expression.Property(parameter, propertyName);
|
var constant = Expression.Constant(Convert.ChangeType(propertyValue, propertyType));
|
var equalExpression = Expression.Equal(propExpr, constant);
|
conditions.Add(equalExpression);
|
}
|
}
|
|
var body = conditions.Count > 1 ? conditions.Aggregate(Expression.AndAlso) : conditions.FirstOrDefault();
|
return Expression.Lambda<Func<T, bool>>(body ?? Expression.Constant(true), parameter);
|
}
|
|
/// <summary>
|
/// json格式化为表达式树
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <param name="jsonString"></param>
|
/// <returns></returns>
|
public static Expression<Func<T, bool>> FormatWhereExpression<T>(string jsonString)
|
{
|
var parameter = Expression.Parameter(typeof(T), "x");
|
return CreateWhereExpressionRecursive<T>(jsonString, parameter);
|
}
|
|
/// <summary>
|
/// 更具属性名称生成表达式树,如x.id
|
/// </summary>
|
/// <typeparam name="T"></typeparam>
|
/// <param name="propertyName"></param>
|
/// <returns></returns>
|
public static Expression<Func<T, object>> FormatPropertyExpression<T>(string propertyName)
|
{
|
// 获取参数表达式
|
var parameter = Expression.Parameter(typeof(T), "x");
|
|
// 获取属性表达式
|
var propertyAccess = Expression.PropertyOrField(parameter, propertyName);
|
if (propertyAccess == null)
|
{
|
///首字母转大写
|
propertyAccess = Expression.PropertyOrField(parameter, propertyName.FirstToCapitalize());
|
}
|
|
|
// 创建 Lambda 表达式,并在返回值中进行类型转换
|
return Expression.Lambda<Func<T, object>>(
|
Expression.Convert(propertyAccess, typeof(object)),
|
parameter);
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
/// 枚举项属性
|
/// </summary>
|
[Description("枚举项属性")]
|
public class MenmItem
|
{
|
/// <summary>
|
/// 枚举key
|
/// </summary>
|
[Description("枚举key")]
|
public string? Key { get; set; }
|
/// <summary>
|
/// 枚举值
|
/// </summary>
|
[Description("枚举值")]
|
public int Value { get; set; }
|
/// <summary>
|
/// 枚举描述
|
/// </summary>
|
[Description("枚举项属性")]
|
public string? Description { get; set; }
|
}
|
|
|
|
|
|
}
|