You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

420 lines
15 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)
{
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)
{
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)
{
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>>();
foreach (var item in conditions.Conditions)
{
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>>();
foreach (var group in conditions.Groups)
{
if (group.LogicalOperator == "and")
{
foreach (var item1 in group.Conditions)
{
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)
{
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;
}
}
}