|
|
using System.Collections.Concurrent;
|
|
|
using System.ComponentModel;
|
|
|
using System.Reflection;
|
|
|
using DS.Module.Core.Data;
|
|
|
using Newtonsoft.Json;
|
|
|
using SqlSugar;
|
|
|
|
|
|
namespace DS.Module.Core.Extensions;
|
|
|
|
|
|
public static partial class Extensions
|
|
|
{
|
|
|
static readonly ConcurrentDictionary<Type, string[]> OrderFieldCache = [];
|
|
|
|
|
|
internal static List<OrderByModel> GetOrderFields<T>(OrderByType orderByType = OrderByType.Desc)
|
|
|
{
|
|
|
Type type = typeof(T);
|
|
|
if (!OrderFieldCache.TryGetValue(type, out string[]? fields))
|
|
|
{
|
|
|
List<string> list = new List<string>(2);
|
|
|
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
|
|
|
|
|
//查找ID或创建时间,暂时只设置一个默认排序字段
|
|
|
var propId = Array.Find(properties, x => x.Name == "Id");
|
|
|
if (propId != null)
|
|
|
{
|
|
|
list.Add(propId.Name);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var propCT = Array.Find(properties, x => x.Name == "CreateTime");
|
|
|
if (propCT != null)
|
|
|
list.Add(propCT.Name);
|
|
|
}
|
|
|
|
|
|
fields = [.. list];
|
|
|
OrderFieldCache.AddOrUpdate(type, fields, (k, v) => v = fields);
|
|
|
}
|
|
|
|
|
|
return fields.Select(x => new OrderByModel { FieldName = x, OrderByType = orderByType }).ToList();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 多排序方法
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TEntity">要排序实体</typeparam>
|
|
|
/// <param name="source">源</param>
|
|
|
/// <param name="orderConditions">排序条件</param>
|
|
|
/// <returns></returns>
|
|
|
public static ISugarQueryable<TEntity> OrderBy<TEntity>(this ISugarQueryable<TEntity> source,
|
|
|
SortCondition[] orderConditions)
|
|
|
{
|
|
|
orderConditions.NotNull(nameof(orderConditions));
|
|
|
string orderStr = string.Empty;
|
|
|
|
|
|
foreach (SortCondition orderCondition in orderConditions)
|
|
|
{
|
|
|
orderStr = orderStr +
|
|
|
$"{orderCondition.SortField} {(orderCondition.ListSortDirection == ListSortDirection.Ascending ? "asc" : "desc")}, ";
|
|
|
}
|
|
|
|
|
|
orderStr = orderStr.TrimEnd(", ".ToCharArray());
|
|
|
return source.OrderBy(orderStr);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="page"></param>
|
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
|
/// <returns></returns>
|
|
|
public static DataResult<List<TEntity>> ToQueryPage<TEntity>(this ISugarQueryable<TEntity> source,
|
|
|
PageCondition page)
|
|
|
{
|
|
|
page.NotNull(nameof(page));
|
|
|
var result = page.IsExport ? source.WhereNoPage(page.SortConditions) : source.Where(page.PageIndex, page.PageSize, page.SortConditions);
|
|
|
var list = result.data;
|
|
|
var total = result.totalNumber;
|
|
|
return DataResult<List<TEntity>>.PageList(total, list, MultiLanguageConst.DataQuerySuccess);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将查询转换为分页结果
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
|
/// <param name="source">数据源</param>
|
|
|
/// <param name="page">分页设置</param>
|
|
|
/// <returns></returns>
|
|
|
public static async Task<DataResult<List<TEntity>>> ToQueryPageAsync<TEntity>(this ISugarQueryable<TEntity> source,
|
|
|
PageCondition? page)
|
|
|
{
|
|
|
page.NotNull(nameof(page));
|
|
|
var result = page.IsExport ? await source.WhereNoPageAsync(page.SortConditions) : await source.WhereAsync(page.PageIndex, page.PageSize, page.SortConditions);
|
|
|
var list = result.Item1;
|
|
|
var total = result.Item2;
|
|
|
return DataResult<List<TEntity>>.PageList(total, list, MultiLanguageConst.DataQuerySuccess);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 过滤操作权限
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="conditionalModels"></param>
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static ISugarQueryable<TEntity> WhereFilterOperationRule<TEntity>(this ISugarQueryable<TEntity> source, List<IConditionalModel> conditionalModels)
|
|
|
{
|
|
|
source = source.Where(conditionalModels);
|
|
|
if (source.Count() == 0)
|
|
|
{
|
|
|
//return new Exception("没有数据操作权限!");
|
|
|
Check.ExceptionEasy("NO Operation", "没有数据操作权限!");
|
|
|
}
|
|
|
return source;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="pageIndex"></param>
|
|
|
/// <param name="pageSize"></param>
|
|
|
/// <param name="orderConditions"></param>
|
|
|
/// <typeparam name="TEntity"></typeparam>
|
|
|
/// <returns></returns>
|
|
|
private static (List<TEntity> data, int totalNumber) Where<TEntity>(this ISugarQueryable<TEntity> source,
|
|
|
int pageIndex,
|
|
|
int pageSize, SortCondition[] orderConditions)
|
|
|
{
|
|
|
var total = source.Count();
|
|
|
|
|
|
ISugarQueryable<TEntity> orderSource;
|
|
|
if (orderConditions == null || orderConditions.Length == 0)
|
|
|
{
|
|
|
orderSource = source;
|
|
|
|
|
|
var orderFields = GetOrderFields<TEntity>();
|
|
|
if (orderFields?.Count > 0)
|
|
|
orderSource = source.OrderBy(orderFields);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
orderSource = source.OrderBy(orderConditions);
|
|
|
}
|
|
|
|
|
|
source = orderSource;
|
|
|
|
|
|
return (
|
|
|
source.Count() != 0
|
|
|
? source.ToPageList(pageIndex, pageSize, ref total)
|
|
|
: Enumerable.Empty<TEntity>().ToList(), total);
|
|
|
}
|
|
|
private static (List<TEntity> data, int totalNumber) WhereNoPage<TEntity>(this ISugarQueryable<TEntity> source, SortCondition[] orderConditions)
|
|
|
{
|
|
|
var total = source.Count();
|
|
|
|
|
|
ISugarQueryable<TEntity> orderSource;
|
|
|
if (orderConditions == null || orderConditions.Length == 0)
|
|
|
{
|
|
|
orderSource = source;
|
|
|
|
|
|
var orderFields = GetOrderFields<TEntity>();
|
|
|
if (orderFields?.Count > 0)
|
|
|
orderSource = source.OrderBy(orderFields);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
orderSource = source.OrderBy(orderConditions);
|
|
|
}
|
|
|
|
|
|
source = orderSource;
|
|
|
|
|
|
return (
|
|
|
source.Count() != 0
|
|
|
? source.ToList()
|
|
|
: Enumerable.Empty<TEntity>().ToList(), total);
|
|
|
}
|
|
|
private static async Task<Tuple<List<TEntity>, int>> WhereAsync<TEntity>(this ISugarQueryable<TEntity> source,
|
|
|
int pageIndex, int pageSize, SortCondition[] orderConditions)
|
|
|
{
|
|
|
ISugarQueryable<TEntity> orderSource;
|
|
|
if (orderConditions == null || orderConditions.Length == 0)
|
|
|
{
|
|
|
orderSource = source;
|
|
|
|
|
|
var orderFields = GetOrderFields<TEntity>();
|
|
|
if (orderFields?.Count > 0)
|
|
|
orderSource = source.OrderBy(orderFields);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
orderSource = source.OrderBy(orderConditions);
|
|
|
}
|
|
|
|
|
|
source = orderSource;
|
|
|
|
|
|
var total = new RefAsync<int>();
|
|
|
var list = await source.ToPageListAsync(pageIndex, pageSize, total);
|
|
|
|
|
|
return new Tuple<List<TEntity>, int>(list, total.Value);
|
|
|
}
|
|
|
private static async Task<Tuple<List<TEntity>, int>> WhereNoPageAsync<TEntity>(this ISugarQueryable<TEntity> source, SortCondition[] orderConditions)
|
|
|
{
|
|
|
ISugarQueryable<TEntity> orderSource;
|
|
|
if (orderConditions == null || orderConditions.Length == 0)
|
|
|
{
|
|
|
orderSource = source;
|
|
|
|
|
|
var orderFields = GetOrderFields<TEntity>();
|
|
|
if (orderFields?.Count > 0)
|
|
|
orderSource = source.OrderBy(orderFields);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
orderSource = source.OrderBy(orderConditions);
|
|
|
}
|
|
|
|
|
|
source = orderSource;
|
|
|
|
|
|
var total = new RefAsync<int>();
|
|
|
var list = await source.ToListAsync();
|
|
|
total = list.Count;
|
|
|
|
|
|
return new Tuple<List<TEntity>, int>(list, total.Value);
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 转换SqlSugar条件查询表达式
|
|
|
/// </summary>
|
|
|
/// <param name="ruleStr"></param>
|
|
|
/// <returns></returns>
|
|
|
public static List<ConditionalCollections> ConvertSqlSugarExpression(this string ruleStr)
|
|
|
{
|
|
|
var conditions = JsonConvert.DeserializeObject<DataGroupConditions>(ruleStr);
|
|
|
var conditionalCollections = new List<ConditionalCollections>();
|
|
|
if (conditions.LogicalOperator == "and")
|
|
|
{
|
|
|
var conditionList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
foreach (var item in conditions.Conditions)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item.Field))
|
|
|
{
|
|
|
conditionList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
(WhereType.And,
|
|
|
new ConditionalModel
|
|
|
{
|
|
|
FieldName = item.Field,
|
|
|
ConditionalType = GetConditionalType(item.Operator),
|
|
|
FieldValue = item.Value
|
|
|
})
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (conditionList.Count > 0)
|
|
|
{
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
{
|
|
|
ConditionalList = conditionList
|
|
|
}
|
|
|
)
|
|
|
;
|
|
|
}
|
|
|
|
|
|
var groupList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
foreach (var group in conditions.Groups)
|
|
|
{
|
|
|
if (group.LogicalOperator == "and")
|
|
|
{
|
|
|
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item1.Field))
|
|
|
{
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
(WhereType.And,
|
|
|
new ConditionalModel
|
|
|
{
|
|
|
FieldName = item1.Field,
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
FieldValue = item1.Value
|
|
|
})
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item1.Field))
|
|
|
{
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
(WhereType.Or,
|
|
|
new ConditionalModel
|
|
|
{
|
|
|
FieldName = item1.Field,
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
FieldValue = item1.Value
|
|
|
})
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (groupList.Count > 0)
|
|
|
{
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
{
|
|
|
ConditionalList = groupList
|
|
|
}
|
|
|
)
|
|
|
;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
var conditionList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
if (conditions.Conditions.IsNotNull() && conditions.Conditions.Count > 0)
|
|
|
{
|
|
|
foreach (var item in conditions.Conditions)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item.Field))
|
|
|
{
|
|
|
conditionList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
(WhereType.Or,
|
|
|
new ConditionalModel
|
|
|
{
|
|
|
FieldName = item.Field,
|
|
|
ConditionalType = GetConditionalType(item.Operator),
|
|
|
FieldValue = item.Value
|
|
|
})
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
if (conditionList.Count > 0)
|
|
|
{
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
{
|
|
|
ConditionalList = conditionList
|
|
|
}
|
|
|
)
|
|
|
;
|
|
|
}
|
|
|
|
|
|
var groupList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
if (conditions.Groups.IsNotNull() && conditions.Groups.Count > 0)
|
|
|
{
|
|
|
foreach (var group in conditions.Groups)
|
|
|
{
|
|
|
if (group.LogicalOperator == "and")
|
|
|
{
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item1.Field))
|
|
|
{
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
(WhereType.And,
|
|
|
new ConditionalModel
|
|
|
{
|
|
|
FieldName = item1.Field,
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
FieldValue = item1.Value
|
|
|
})
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item1.Field))
|
|
|
{
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
(WhereType.Or,
|
|
|
new ConditionalModel
|
|
|
{
|
|
|
FieldName = item1.Field,
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
FieldValue = item1.Value
|
|
|
})
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (groupList.Count > 0)
|
|
|
{
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
{
|
|
|
ConditionalList = groupList
|
|
|
}
|
|
|
)
|
|
|
;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return conditionalCollections;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 转换SqlSugar 条件操作符
|
|
|
/// </summary>
|
|
|
/// <param name="conditionalType"></param>
|
|
|
/// <returns></returns>
|
|
|
private static ConditionalType GetConditionalType(string conditionalType)
|
|
|
{
|
|
|
switch (conditionalType)
|
|
|
{
|
|
|
//等于
|
|
|
case "equal":
|
|
|
return ConditionalType.Equal;
|
|
|
//不等于
|
|
|
case "not_equal":
|
|
|
return ConditionalType.NoEqual;
|
|
|
//大于
|
|
|
case "GreaterThan":
|
|
|
return ConditionalType.GreaterThan;
|
|
|
//大于等于
|
|
|
case "GreaterThanOrEqual":
|
|
|
return ConditionalType.GreaterThanOrEqual;
|
|
|
//小于
|
|
|
case "LessThan":
|
|
|
return ConditionalType.LessThan;
|
|
|
//小于等于
|
|
|
case "LessThanOrEqual":
|
|
|
return ConditionalType.GreaterThanOrEqual;
|
|
|
//包含
|
|
|
case "contains":
|
|
|
return ConditionalType.In;
|
|
|
//不包含
|
|
|
case "not_contain":
|
|
|
return ConditionalType.NotIn;
|
|
|
//默认
|
|
|
default:
|
|
|
return ConditionalType.Equal;
|
|
|
}
|
|
|
}
|
|
|
} |