移动系统liao
2025-03-19 16b063870156db78148440971ab46c649e3e6018
cylsg/cylsg.utility/CommonHelper.cs
@@ -1,15 +1,22 @@
using System;
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
{
@@ -818,12 +825,165 @@
        #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>
    /// 枚举项属性
@@ -847,4 +1007,9 @@
        [Description("枚举项属性")]
        public string? Description { get; set; }
    }
}