init commit

This commit is contained in:
路 范
2022-03-30 17:54:33 +08:00
parent df01841625
commit 904bdd16cd
500 changed files with 217251 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Core.Extension.DataFilter.Entity
{
public class FilterInfo
{
/// <summary>
/// 查询信息集合
/// </summary>
private List<SearchInfo> _SearchInfos;
/// <summary>
/// 高级查询信息集合
/// </summary>
public List<SearchInfo> SearchInfos
{
get { return _SearchInfos; }
}
public FilterInfo()
{
_SearchInfos = new List<SearchInfo>();
}
/// <summary>
/// 设置查询信息
/// </summary>
/// <param name="filterFields"></param>
public void SetSearchInfo(SearchInfo[] searchInfo, IEnumerable<string> filterFields)
{
if (searchInfo == null) return;
try
{
foreach (var elem in searchInfo)
{
var fieldName = elem.Field;
if (filterFields.FirstOrDefault(m => m.Equals(fieldName, StringComparison.OrdinalIgnoreCase)) == null) continue;
var searchStrs = elem.Value;
if (searchStrs == null) continue;
if (searchStrs.Count == 0) continue;
var searchInfoEntity = new SearchInfo();
searchInfoEntity.Field = fieldName;
searchInfoEntity.Type = elem.Type;
var searchStrsNode = elem.Value;
if (searchStrsNode != null)
{
foreach (var node in searchStrsNode)
{
searchInfoEntity.Value.Add(node);
}
}
_SearchInfos.Add(searchInfoEntity);
}
}
catch
{
}
}
}
}

View File

@@ -0,0 +1,54 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Core
{
public class SearchInfo
{
/// <summary>
/// 字段名
/// </summary>
public string Field { get; set; }
/// <summary>
/// 查询多个条件
/// </summary>
public List<string> Value { get; set; }
/// <summary>
/// 查询运算符
/// </summary>
public string Type { get; set; }
public QueryTypeEnum QueryType
{
get
{
return Type.ToLower() switch
{
"=" or "equal" => QueryTypeEnum.Equal,
"<" or "lessthan" => QueryTypeEnum.LessThan,
"<=" or "lessthanorequal" => QueryTypeEnum.LessThanOrEqual,
">" or "greaterthan" => QueryTypeEnum.GreaterThan,
">=" or "greaterthanorequal" => QueryTypeEnum.GreaterThanOrEqual,
"start" => QueryTypeEnum.StartWith,
"end" => QueryTypeEnum.EndWith,
_ => QueryTypeEnum.Like,
};
}
}
/// <summary>
/// 构造函数
/// </summary>
public SearchInfo()
{
Value = new List<string>();
}
}
}

View File

@@ -0,0 +1,14 @@
using Ewide.Core.Extension.DataFilter.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Core.Extension.DataFilter
{
public interface IFitlerInfoGetService
{
FilterInfo GetFilterInfo();
}
}

View File

@@ -0,0 +1,110 @@
using Dapper;
using Ewide.Core.Extension.DataFilter.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ewide.Core.Extension.DataFilter.WebPage
{
public class SearchJsonFitlerInfoGetService : IFitlerInfoGetService
{
protected PageInputBase Input;
protected IEnumerable<string> FilterFields;
public DynamicParameters sqlParameters = new DynamicParameters();
public SearchJsonFitlerInfoGetService(PageInputBase input, IEnumerable<string> filterFields, object param = null)
{
Input = input;
FilterFields = filterFields;
sqlParameters = new DynamicParameters(param);
}
public FilterInfo GetFilterInfo()
{
var result = new FilterInfo();
result.SetSearchInfo(Input.SearchInfo, FilterFields);
return result;
}
public string GetWhereSql(string baseSql)
{
var filterInfo = GetFilterInfo();
baseSql = String.Format("SELECT * FROM ({0}) T ", baseSql);
var searchInfoList = filterInfo.SearchInfos;
if (searchInfoList.Count == 0)
return baseSql;
List<string> whereSqls = new List<string>();
foreach (var elem in searchInfoList.Where(m => m != null))
{
var r = GetWhereSqlBuild(elem);
if (String.IsNullOrWhiteSpace(r)) continue;
whereSqls.Add(r);
}
StringBuilder result = new StringBuilder();
if (whereSqls.Count > 0)
{
result.Append(" WHERE ");
result.Append(String.Join(" AND ", whereSqls));
}
return baseSql + result.ToString();
}
#region
private string GetWhereSqlBuild(SearchInfo searchInfo)
{
string sqlT = "`{0}` {1} {2}";
List<string> whereList = new List<string>();
foreach (var elem in searchInfo.Value)
{
if (String.IsNullOrWhiteSpace(elem)) continue;
var parameterName = "@" + searchInfo.Field + Guid.NewGuid().ToString();
//AddParameter(parameterName, elem);
sqlParameters.Add(parameterName, QueryTypeEnum.Like == searchInfo.QueryType ? "%" + elem + "%" : QueryTypeEnum.StartWith == searchInfo.QueryType ? elem + "%" : QueryTypeEnum.EndWith == searchInfo.QueryType ? "%" + elem : elem);
whereList.Add(String.Format(sqlT, searchInfo.Field, GetSearchOperatorStr(searchInfo.QueryType), parameterName));
}
if (whereList.Count == 0) return String.Empty;
var resultT = "({0})";
var result = String.Format(resultT, String.Join(" OR ", whereList));
return result;
}
private string GetSearchOperatorStr(QueryTypeEnum searchOperator)
{
switch (searchOperator)
{
case QueryTypeEnum.GreaterThan:
return ">";
case QueryTypeEnum.GreaterThanOrEqual:
return ">=";
case QueryTypeEnum.LessThan:
return "<";
case QueryTypeEnum.LessThanOrEqual:
return "<=";
case QueryTypeEnum.Equal:
return "=";
default:
return "LIKE";
}
}
private void AddParameter(string key, object value)
{
//var parameter = _SqlParameters.ParameterNames.FirstOrDefault(m => m == key);
//if (parameter != null)
//{
// _SqlParameters.
//}
//else
//{
// _SqlParameters.Add(key, value);
//}
}
#endregion
}
}

View File

@@ -0,0 +1,49 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ewide.Core
{
/// <summary>
/// 字典扩展
/// </summary>
public static class DictionaryExtensions
{
/// <summary>
/// 将一个字典转化为 QueryString
/// </summary>
/// <param name="dict"></param>
/// <param name="urlEncode"></param>
/// <returns></returns>
public static string ToQueryString(this Dictionary<string, string> dict, bool urlEncode = true)
{
return string.Join("&", dict.Select(p => $"{(urlEncode ? p.Key?.UrlEncode() : "")}={(urlEncode ? p.Value?.UrlEncode() : "")}"));
}
/// <summary>
/// 将一个字符串 URL 编码
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string UrlEncode(this string str)
{
if (string.IsNullOrEmpty(str))
{
return "";
}
return System.Web.HttpUtility.UrlEncode(str, Encoding.UTF8);
}
/// <summary>
/// 移除空值项
/// </summary>
/// <param name="dict"></param>
public static void RemoveEmptyValueItems(this Dictionary<string, string> dict)
{
dict.Where(item => string.IsNullOrEmpty(item.Value)).Select(item => item.Key).ToList().ForEach(key =>
{
dict.Remove(key);
});
}
}
}

View File

@@ -0,0 +1,86 @@
using System.Collections.Generic;
namespace Ewide.Core
{
/// <summary>
/// 通用输入扩展参数(带权限)
/// </summary>
public class InputBase : PageInputBase
{
/// <summary>
/// 授权菜单
/// </summary>
public List<string> GrantMenuIdList { get; set; } = new List<string>();
/// <summary>
/// 授权角色
/// </summary>
public virtual List<string> GrantRoleIdList { get; set; } = new List<string>();
/// <summary>
/// 授权数据
/// </summary>
public virtual List<string> GrantOrgIdList { get; set; } = new List<string>();
/// <summary>
/// 授权区域
/// </summary>
public virtual List<string> GrantAreaCodeList { get; set; } = new List<string>();
}
/// <summary>
/// 通用分页输入参数
/// </summary>
public class PageInputBase
{
/// <summary>
/// 搜索值
/// </summary>
public virtual string SearchValue { get; set; }
/// <summary>
/// 当前页码
/// </summary>
public virtual int PageIndex { get; set; } = 1;
/// <summary>
/// 页码容量
/// </summary>
public virtual int PageSize { get; set; } = 20;
/// <summary>
/// 搜索开始时间
/// </summary>
public virtual string SearchBeginTime { get; set; }
/// <summary>
/// 搜索结束时间
/// </summary>
public virtual string SearchEndTime { get; set; }
/// <summary>
/// 排序字段
/// </summary>
public virtual string SortField { get; set; }
/// <summary>
/// 排序方法,默认升序,否则降序(配合antd前端,约定参数为 Ascend,Dscend)
/// </summary>
public virtual string SortOrder { get; set; }
/// <summary>
/// 降序排序(不要问我为什么是descend不是desc前端约定参数就是这样)
/// </summary>
public virtual string DescStr => "descend";
/// <summary>
/// 查询条件
/// </summary>
public virtual SearchInfo[] SearchInfo { get; set; }
/// <summary>
/// 树节点数据范围 1"只看本级" 2"查看本级及以下"
/// </summary>
public virtual int? TreeNodeDataScope { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
namespace Ewide.Core
{
/// <summary>
/// 小诺分页列表结果
/// </summary>
/// <typeparam name="T"></typeparam>
public static class PageDataResult<T> where T : new()
{
public static dynamic PageResult(PagedList<T> page)
{
return new
{
PageIndex = page.PageIndex,
PageSize = page.PageSize,
TotalPage = page.TotalPages,
TotalCount = page.TotalCount,
Items = page.Items
};
}
}
public static class PageDataResult
{
public static dynamic PageResult(PagedList page)
{
return new
{
PageIndex = page.PageIndex,
PageSize = page.PageSize,
TotalPage = page.TotalPages,
TotalCount = page.TotalCount,
Items = page.Items
};
}
}
}

View File

@@ -0,0 +1,227 @@
using Dapper;
using Ewide.Core.Extension.DataFilter.WebPage;
using Furion.DatabaseAccessor;
using Furion.LinqBuilder;
using Mapster;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
namespace Ewide.Core.Extension
{
public static class PageExtensions
{
private static string OrderBuilder(PageInputBase pageInput)
{
var orderStr = string.Empty;
if (!string.IsNullOrEmpty(pageInput.SortField))
{
orderStr = $"{pageInput.SortField} {(pageInput.SortOrder == pageInput.DescStr ? "Desc" : "Asc")}";
}
return orderStr;
}
private static string OrderBuilder<T>(PageInputBase pageInput, bool descSort = false)
{
var type = typeof(T);
var hasId = type.GetProperty("Id") != null;
var hasSort = type.GetProperty("Sort") != null;
var hasCreatedTime = type.GetProperty("CreatedTime") != null;
var defaultField = hasSort ? "Sort" : hasCreatedTime ? "CreatedTime" : hasId ? "Id" : "";
// 排序优先级 创建时间->序号->ID
var orderStr = string.IsNullOrEmpty(defaultField) ? "" : defaultField + (descSort ? " Desc" : " Asc");
// 排序是否可用-排序字段和排序顺序都为非空才启用排序
if (!string.IsNullOrEmpty(pageInput.SortField))
{
orderStr = OrderBuilder(pageInput);
}
return orderStr;
}
//public static IQueryable<T> GetFilterInfo<T>(this IQueryable<T> source, PageInputBase input, IEnumerable<string> equalsFields = null, IEnumerable<string> likeFields = null, IEnumerable<string> dateTimeRangeFields = null, IEnumerable<string> otherRangeFields = null) where T : new()
//{
// var _searchStr = input._Search;
// var searchInfoObj = Newtonsoft.Json.JsonConvert.DeserializeObject<DataFilter.Entity.SearchInfo[]>(_searchStr);
// foreach(var elem in searchInfoObj)
// {
// ParameterExpression param = Expression.Parameter(typeof(T), "p");
// var field = typeof(T).GetProperty(elem.Field, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
// Expression left = Expression.Property(param, field);
// Expression<Func<T, bool>> finalExpression = null;
// foreach(var value in elem.Value)
// {
// Expression right = Expression.Constant(Convert.ChangeType(value, Nullable.GetUnderlyingType(left.Type) ?? left.Type));
// right = Expression.Convert(right, left.Type);
// Expression filter = null;
// filter = filter.Filter(left, right, elem.QueryType);
// if (finalExpression == null)
// {
// finalExpression = Expression.Lambda<Func<T, bool>>(filter, param);
// }
// else
// {
// finalExpression = finalExpression.Or(Expression.Lambda<Func<T, bool>>(filter, param));
// }
// }
// source.Where(finalExpression);
// }
// return source;
//}
private static Expression Filter(this Expression filter, Expression left, Expression right, Ewide.Core.QueryTypeEnum queryType)
{
switch (queryType)
{
//case "=":
// filter = Expression.Equal(left, right);
// break;
//case "<>":
//case "!=":
// filter = Expression.NotEqual(left, right);
// break;
case QueryTypeEnum.GreaterThan:
filter = Expression.GreaterThan(left, right);
break;
case QueryTypeEnum.GreaterThanOrEqual:
filter = Expression.GreaterThanOrEqual(left, right);
break;
case QueryTypeEnum.LessThan:
filter = Expression.LessThan(left, right);
break;
case QueryTypeEnum.LessThanOrEqual:
filter = Expression.LessThanOrEqual(left, right);
break;
case QueryTypeEnum.Like:
filter = Expression.Call(left, typeof(string).GetMethod("Contains"), right);
break;
//case "NOT LIKE":
// filter = Expression.Not(Expression.Call(left, typeof(string).GetMethod("Contains"), right));
// break;
default:
filter = Expression.Equal(left, right);
break;
}
return filter;
}
public static Task<PagedList<T>> ToPageData<T>(this IQueryable<T> source, PageInputBase input) where T : new()
{
return source.OrderBy(OrderBuilder<T>(input)).ToPagedListAsync(input.PageIndex, input.PageSize);
}
public static Task<PagedList<O>> ToPageData<T, O>(this IQueryable<T> source, PageInputBase input) where O : new()
{
return source.OrderBy(OrderBuilder<T>(input)).Select(u => u.Adapt<O>()).ToPagedListAsync(input.PageIndex, input.PageSize);
}
public static Task<PagedList<O>> ToPageData<T, O>(this IQueryable<T> source, PageInputBase input, TypeAdapterConfig config) where O : new()
{
return source.OrderBy(OrderBuilder<T>(input)).Select(u => u.Adapt<O>(config)).ToPagedListAsync(input.PageIndex, input.PageSize);
}
#region DAPPER
public async static Task<PagedList> QueryPageDataDynamic(this IDapperRepository source, string baseSql, PageInputBase input, object param = null, IEnumerable<string> filterFields = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
SearchJsonFitlerInfoGetService searchJsonFitlerInfoGetService = new SearchJsonFitlerInfoGetService(input, filterFields, param);
var sql = searchJsonFitlerInfoGetService.GetWhereSql(baseSql);
var sqlParam = searchJsonFitlerInfoGetService.sqlParameters;
return await QueryPageData(source, sql, input, sqlParam, transaction, commandTimeout, commandType);
}
public async static Task<PagedList> QueryPageData(this IDapperRepository source, string sql, PageInputBase input, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
var count = await source.PageTotalCount(
sql,
param: param,
transaction: transaction,
commandTimeout: commandTimeout,
commandType: commandType
);
var data = await source.QueryAsync(
PageSqlBuilder(sql, input),
param: param,
transaction: transaction,
commandTimeout: commandTimeout,
commandType: commandType
);
var page = new PagedList
{
PageIndex = input.PageIndex,
PageSize = input.PageSize,
Items = data,
TotalCount = count,
TotalPages = input.PageSize.Equals(0) ? 1 : (int)Math.Ceiling((decimal)count / (decimal)input.PageSize)
};
return page;
}
public async static Task<PagedList<T>> QueryPageData<T>(this IDapperRepository source, string sql, PageInputBase input, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) where T : new()
{
var count = await source.PageTotalCount(
sql,
param: param,
transaction: transaction,
commandTimeout: commandTimeout,
commandType: commandType
);
var data = await source.QueryAsync<T>(
PageSqlBuilder(sql, input),
param: param,
transaction: transaction,
commandTimeout: commandTimeout,
commandType: commandType
);
var page = new PagedList<T>
{
PageIndex = input.PageIndex,
PageSize = input.PageSize,
Items = data,
TotalCount = count,
TotalPages = input.PageSize.Equals(0) ? 1 : (int)Math.Ceiling((decimal)count / (decimal)input.PageSize)
};
return page;
}
private async static Task<int> PageTotalCount(this IDapperRepository source, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
var countSql = String.Format("SELECT COUNT(0) FROM ({0}) T", sql);
var countAsync = await source.QueryAsync<int>(
countSql,
param: param,
transaction: transaction,
commandTimeout: commandTimeout,
commandType: commandType);
var count = countAsync.SingleOrDefault();
return count;
}
private static string PageSqlBuilder(string sql , PageInputBase input)
{
var sqlStrList = new List<string>();
var orderStr = OrderBuilder(input);
if (!string.IsNullOrEmpty(orderStr)) sqlStrList.Add(" ORDER BY " + orderStr);
// input.PageSize = 0表示不分页
if (input.PageSize != 0) sqlStrList.Add(" LIMIT " + ((input.PageIndex - 1) * input.PageSize).ToString() + "," + input.PageSize.ToString());
sql += String.Join("", sqlStrList);
return sql;
}
#endregion
}
}

View File

@@ -0,0 +1,197 @@
using Furion.DataValidation;
using Furion.DependencyInjection;
using Furion.UnifyResult;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Furion.UnifyResult.Internal;
namespace Ewide.Core
{
/// <summary>
/// 规范化RESTful风格返回值
/// </summary>
[SuppressSniffer, UnifyModel(typeof(RestfulResult<>))]
public class RestfulResultProvider : IUnifyResultProvider
{
private IActionResult DisplayJson(object data)
{
return new ContentResult
{
Content = JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings
{
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(),
DateFormatString = "yyyy-MM-dd HH:mm:ss"
}),
ContentType = "application/json"
};
}
/// <summary>
/// 异常返回值
/// </summary>
/// <param name="context"></param>
/// <param name="metadata"></param>
/// <returns></returns>
public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
{
// 解析异常信息
//var (StatusCode, ErrorCode, Errors) = UnifyContext.GetExceptionMetadata(context);
// 如果是代码自行抛出的异常,视为接口调用成功,返回结果失败
if (context.Exception.GetType() == typeof(Furion.FriendlyException.AppFriendlyException))
{
return DisplayJson(new RestfulResult<object>
{
BizCode = metadata.ErrorCode,
Code = StatusCodes.Status200OK,
Success = false,
Data = null,
Message = metadata.Errors,
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
return DisplayJson(new RestfulResult<object>
{
Code = metadata.StatusCode,
BizCode = metadata.ErrorCode,
Success = false,
Data = null,
Message = metadata.Errors,
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
/// <summary>
/// 处理输出状态码
/// </summary>
/// <param name="context"></param>
/// <param name="statusCode"></param>
/// <param name="options"></param>
/// <returns></returns>
public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings = default)
{
switch (statusCode)
{
// 处理 401 状态码
case StatusCodes.Status401Unauthorized:
await context.Response.WriteAsJsonAsync(new RestfulResult<object>
{
Code = StatusCodes.Status401Unauthorized,
Success = false,
Data = null,
Message = "401 未经授权",
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
break;
// 处理 403 状态码
case StatusCodes.Status403Forbidden:
await context.Response.WriteAsJsonAsync(new RestfulResult<object>
{
Code = StatusCodes.Status403Forbidden,
Success = false,
Data = null,
Message = "403 禁止访问",
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
break;
default:
break;
}
}
/// <summary>
/// 成功返回值
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public IActionResult OnSucceeded(ActionExecutedContext context, object data)
{
//object data;
// 处理内容结果
if (context.Result is ContentResult contentResult) data = contentResult.Content;
// 处理对象结果
else if (context.Result is ObjectResult objectResult) data = objectResult.Value;
else if (context.Result is EmptyResult) data = null;
else return null;
return DisplayJson(new RestfulResult<object>
{
Code = context.Result is EmptyResult ? StatusCodes.Status204NoContent : StatusCodes.Status200OK, // 处理没有返回值情况 204
Success = true,
Data = data,
Message = "请求成功",
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
/// <summary>
/// 验证失败返回值
/// </summary>
/// <param name="context"></param>
/// <param name="metadata"></param>
/// <returns></returns>
public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
{
return DisplayJson(new RestfulResult<object>
{
Code = StatusCodes.Status400BadRequest,
Success = false,
Data = null,
Message = metadata.ValidationResult,// validationResults,
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
}
/// <summary>
/// RESTful风格---XIAONUO返回格式
/// </summary>
/// <typeparam name="T"></typeparam>
[SuppressSniffer]
public class RestfulResult<T>
{
/// <summary>
/// 执行成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 状态码
/// </summary>
public int? Code { get; set; }
//业务码
public object BizCode { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public object Message { get; set; }
/// <summary>
/// 数据
/// </summary>
public T Data { get; set; }
/// <summary>
/// 附加数据
/// </summary>
public object Extras { get; set; }
/// <summary>
/// 时间戳
/// </summary>
public long Timestamp { get; set; }
}
}