|
|
using Microsoft.EntityFrameworkCore;
|
|
|
using Newtonsoft.Json;
|
|
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Linq.Expressions;
|
|
|
using System.Reflection;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
using VOL.Core.CacheManager;
|
|
|
using VOL.Core.Configuration;
|
|
|
using VOL.Core.Const;
|
|
|
using VOL.Core.Enums;
|
|
|
using VOL.Core.Extensions;
|
|
|
using VOL.Core.Extensions.AutofacManager;
|
|
|
using VOL.Core.Filters;
|
|
|
using VOL.Core.ManageUser;
|
|
|
using VOL.Core.Services;
|
|
|
using VOL.Core.Utilities;
|
|
|
using VOL.Entity;
|
|
|
using VOL.Entity.DomainModels;
|
|
|
using VOL.Entity.SystemModels;
|
|
|
using System.Drawing.Text;
|
|
|
//using System.Data.SqlClient;
|
|
|
using Microsoft.Data.SqlClient;
|
|
|
using AutoMapper;
|
|
|
using VOL.Core.DBManager;
|
|
|
using VOL.Core.Infrastructure;
|
|
|
using System.Collections.ObjectModel;
|
|
|
using System.Data;
|
|
|
using ConvertHelper;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
|
|
|
|
|
namespace VOL.Core.BaseProvider
|
|
|
{
|
|
|
public abstract class ServiceBase<T, TRepository> : ServiceFunFilter<T>
|
|
|
where T : BaseEntity
|
|
|
where TRepository : IRepository<T>
|
|
|
{
|
|
|
public ICacheService CacheContext
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
return AutofacContainerModule.GetService<ICacheService>();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public Microsoft.AspNetCore.Http.HttpContext Context
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
return HttpContext.Current;
|
|
|
}
|
|
|
}
|
|
|
private WebResponseContent Response { get; set; }
|
|
|
|
|
|
protected IRepository<T> repository;
|
|
|
|
|
|
private PropertyInfo[] _propertyInfo { get; set; } = null;
|
|
|
private PropertyInfo[] TProperties
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (_propertyInfo != null)
|
|
|
{
|
|
|
return _propertyInfo;
|
|
|
}
|
|
|
_propertyInfo = typeof(T).GetProperties();
|
|
|
return _propertyInfo;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//用于标记正在执行的业务 防止重复执行
|
|
|
private static List<string> LockKeyList;
|
|
|
|
|
|
public class LockKeyHelper
|
|
|
{
|
|
|
|
|
|
private static readonly Lazy<LockKeyHelper> lazy = new Lazy<LockKeyHelper>(() => new LockKeyHelper());
|
|
|
public static LockKeyHelper Instance { get { return lazy.Value; } }
|
|
|
private LockKeyHelper() { }
|
|
|
|
|
|
public static int newno { get; set; } = 0;
|
|
|
public bool addLockKey(object key)
|
|
|
{
|
|
|
|
|
|
|
|
|
try
|
|
|
{
|
|
|
//logger.Debug("获取编号");
|
|
|
if (LockKeyList == null)
|
|
|
LockKeyList = new List<string>();
|
|
|
if (LockKeyList.Contains(key.ToString())) return false;
|
|
|
LockKeyList.Add(key.ToString());
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
//logger.Debug("获取编号错误");
|
|
|
return false;
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 原锁定key方法 由于线程不安全 改为调用lazy单例的模式
|
|
|
/// </summary>
|
|
|
/// <param name="key"></param>
|
|
|
/// <returns></returns>
|
|
|
public bool addLockKey(object key) {
|
|
|
//if (LockKeyList == null)
|
|
|
// LockKeyList = new List<string>();
|
|
|
//if (LockKeyList.Contains(key.ToString())) return false;
|
|
|
//LockKeyList.Add(key.ToString());
|
|
|
//return true;
|
|
|
return LockKeyHelper.Instance.addLockKey(key);
|
|
|
}
|
|
|
|
|
|
public void delLockKey(object key) {
|
|
|
if (LockKeyList == null)
|
|
|
LockKeyList = new List<string>();
|
|
|
|
|
|
if (LockKeyList.Contains(key.ToString())) {
|
|
|
for (var _i = LockKeyList.Count - 1; _i >= 0; _i--) {
|
|
|
if (LockKeyList[_i] == key.ToString()) {
|
|
|
LockKeyList.RemoveAt(_i);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public ServiceBase()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
public ServiceBase(TRepository repository)
|
|
|
{
|
|
|
Response = new WebResponseContent(true);
|
|
|
this.repository = repository;
|
|
|
}
|
|
|
|
|
|
protected virtual void Init(IRepository<T> repository)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 2020.08.15添加自定义原生查询sql或多租户(查询、导出)
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private IQueryable<T> GetSearchQueryable()
|
|
|
{
|
|
|
//UserContext.Current.IsSuperAdmin超级管理员不限制数据
|
|
|
//自定sql,没有使用多租户,直接执行自定义sql
|
|
|
if (QuerySql != null && (!IsMultiTenancy || UserContext.Current.IsSuperAdmin))
|
|
|
{
|
|
|
//将
|
|
|
|
|
|
return repository.DbContext.Set<T>().FromSqlRaw(QuerySql);
|
|
|
}
|
|
|
//没有自定sql与多租户执行默认查询
|
|
|
if ((QuerySql == null && !IsMultiTenancy) )
|
|
|
{
|
|
|
return repository.DbContext.Set<T>();
|
|
|
}
|
|
|
|
|
|
string multiTenancyString;
|
|
|
|
|
|
//多租户
|
|
|
if (QuerySql != null && IsMultiTenancy)
|
|
|
{
|
|
|
//自定sql+多租户
|
|
|
multiTenancyString = $"select * from ({QuerySql}) as mt ";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//如果是pgsql数据库,请修改select * from 为pgsql的语法
|
|
|
multiTenancyString = $"select * from {typeof(T).GetEntityTableName()} ";
|
|
|
}
|
|
|
|
|
|
//多租户请继续完善下面sql,
|
|
|
//例如sql只显示自己创建的数据:
|
|
|
//multiTenancyString = multiTenancyString + " where createid=" + UserContext.Current.UserId;
|
|
|
|
|
|
return repository.DbContext.Set<T>().FromSqlRaw(multiTenancyString);
|
|
|
}
|
|
|
|
|
|
protected void SetQuerySqlCondition(PageDataOptions options, Dictionary<string, string> SearchName)
|
|
|
{
|
|
|
options = options ?? new PageDataOptions();
|
|
|
|
|
|
List<SearchParameters> searchParametersList = new List<SearchParameters>();
|
|
|
if (!string.IsNullOrEmpty(options.Wheres))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
|
|
|
}
|
|
|
catch { }
|
|
|
}
|
|
|
QueryRelativeList?.Invoke(searchParametersList);
|
|
|
|
|
|
foreach (var item in searchParametersList)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(item.Name))
|
|
|
{
|
|
|
|
|
|
var searchname = item.Name;
|
|
|
try
|
|
|
{
|
|
|
searchname = (SearchName == null || string.IsNullOrWhiteSpace(SearchName[item.Name])) ? item.Name : SearchName[item.Name];
|
|
|
}
|
|
|
catch (Exception e) { }
|
|
|
|
|
|
var searchparam = item.DisplayType.GetDBCondition();
|
|
|
|
|
|
|
|
|
|
|
|
if (searchparam == HtmlElementType.like)
|
|
|
{
|
|
|
item.Value = $"%{item.Value}%";
|
|
|
QuerySql += $" and {searchname} {searchparam} '{item.Value}' ";
|
|
|
}
|
|
|
else
|
|
|
if (searchparam == HtmlElementType.StartWith)
|
|
|
{
|
|
|
searchparam = HtmlElementType.like;
|
|
|
item.Value = $"{item.Value}%";
|
|
|
QuerySql += $" and {searchname} {searchparam} '{item.Value}' ";
|
|
|
}
|
|
|
else
|
|
|
if (searchparam == "in")
|
|
|
{
|
|
|
//searchparam = HtmlElementType.like;
|
|
|
//item.Value = $"{item.Value}%";
|
|
|
var _str = item.Value.Replace(",", "','");
|
|
|
QuerySql += $" and {searchname} in ('{_str}') ";
|
|
|
}
|
|
|
else
|
|
|
QuerySql += $" and {searchname} {searchparam} '{item.Value}' ";
|
|
|
|
|
|
|
|
|
}
|
|
|
else {
|
|
|
var searchparam = item.DisplayType.GetDBCondition();
|
|
|
if (searchparam == HtmlElementType.Exists)
|
|
|
{
|
|
|
QuerySql += $" and {item.Value} ";
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 2020.08.15添加获取多租户数据过滤sql(删除、编辑)
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private string GetMultiTenancySql(string ids, string tableKey)
|
|
|
{
|
|
|
string sql = $"select count(*) FROM {typeof(T).GetEntityTableName() } where {tableKey} in ({ids}) ";
|
|
|
if (DBType.Name == DbCurrentType.PgSql.ToString())
|
|
|
{
|
|
|
sql = $"select count(*) FROM \"public\".\"{typeof(T).GetEntityTableName()}\" where \"{tableKey}\" in ({ids}) ";
|
|
|
}
|
|
|
return sql;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 2020.08.15添加多租户数据过滤(编辑)
|
|
|
/// </summary>
|
|
|
private void CheckUpdateMultiTenancy(string ids, string tableKey)
|
|
|
{
|
|
|
string sql = GetMultiTenancySql(ids, tableKey);
|
|
|
|
|
|
//请接着过滤条件
|
|
|
//例如sql,只能(编辑)自己创建的数据:判断数据是不是当前用户创建的
|
|
|
//sql = $" {sql} and createid!={UserContext.Current.UserId}";
|
|
|
object obj = repository.DapperContext.ExecuteScalar(sql, null);
|
|
|
if (obj == null || obj.GetInt() > 0)
|
|
|
{
|
|
|
Response.Error("不能编辑此数据");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 2020.08.15添加多租户数据过滤(删除)
|
|
|
/// </summary>
|
|
|
private void CheckDelMultiTenancy(string ids, string tableKey)
|
|
|
{
|
|
|
string sql = GetMultiTenancySql(ids, tableKey);
|
|
|
|
|
|
//请接着过滤条件
|
|
|
//例如sql,只能(删除)自己创建的数据:找出不是自己创建的数据
|
|
|
//sql = $" {sql} and createid!={UserContext.Current.UserId}";
|
|
|
object obj = repository.DapperContext.ExecuteScalar(sql, null);
|
|
|
if (obj == null || obj.GetInt() > 0)
|
|
|
{
|
|
|
Response.Error("不能删除此数据");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//private const string _desc = "desc";
|
|
|
private const string _asc = "asc";
|
|
|
/// <summary>
|
|
|
/// 生成排序字段
|
|
|
/// </summary>
|
|
|
/// <param name="pageData"></param>
|
|
|
/// <param name="propertyInfo"></param>
|
|
|
private Dictionary<string, QueryOrderBy> GetPageDataSort(PageDataOptions pageData, PropertyInfo[] propertyInfo)
|
|
|
{
|
|
|
if (base.OrderByExpression != null)
|
|
|
{
|
|
|
return base.OrderByExpression.GetExpressionToDic();
|
|
|
}
|
|
|
|
|
|
//排序字段不存在直接移除
|
|
|
if (!string.IsNullOrEmpty(pageData.Sort) && !propertyInfo.Any(x => x.Name.ToLower() == pageData.Sort.ToLower()))
|
|
|
{
|
|
|
pageData.Sort = null;
|
|
|
}
|
|
|
|
|
|
//如果没有排序字段,则使用主键作为排序字段
|
|
|
if (string.IsNullOrEmpty(pageData.Sort))
|
|
|
{
|
|
|
PropertyInfo property = propertyInfo.GetKeyProperty();
|
|
|
//如果主键不是自增类型则使用appsettings.json中CreateMember->DateField配置的创建时间作为排序
|
|
|
if (property.PropertyType == typeof(int) || property.PropertyType == typeof(long))
|
|
|
{
|
|
|
if (!propertyInfo.Any(x => x.Name.ToLower() == pageData.Sort))
|
|
|
{
|
|
|
pageData.Sort = propertyInfo.GetKeyName();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(AppSetting.CreateMember.DateField)
|
|
|
&& propertyInfo.Any(x => x.Name == AppSetting.CreateMember.DateField))
|
|
|
{
|
|
|
pageData.Sort = AppSetting.CreateMember.DateField;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pageData.Sort = propertyInfo.GetKeyName();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var result = new Dictionary<string, QueryOrderBy>();
|
|
|
return new Dictionary<string, QueryOrderBy>() { {
|
|
|
pageData.Sort, pageData.Order?.ToLower() == _asc? QueryOrderBy.Asc: QueryOrderBy.Desc
|
|
|
} };
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 验证排序与查询字段合法性
|
|
|
/// </summary>
|
|
|
/// <param name="options"></param>
|
|
|
/// <param name="queryable"></param>
|
|
|
/// <returns></returns>
|
|
|
public PageDataOptions ValidatePageOptions(PageDataOptions options, out IQueryable<T> queryable)
|
|
|
{
|
|
|
options = options ?? new PageDataOptions();
|
|
|
|
|
|
List<SearchParameters> searchParametersList = new List<SearchParameters>();
|
|
|
if (!string.IsNullOrEmpty(options.Wheres))
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
|
|
|
}
|
|
|
catch { }
|
|
|
}
|
|
|
QueryRelativeList?.Invoke(searchParametersList);
|
|
|
// Connection
|
|
|
// queryable = repository.DbContext.Set<T>();
|
|
|
//2020.08.15添加自定义原生查询sql或多租户
|
|
|
queryable = GetSearchQueryable();
|
|
|
//判断列的数据类型数字,日期的需要判断值的格式是否正确
|
|
|
for (int i = 0; i < searchParametersList.Count; i++)
|
|
|
{
|
|
|
SearchParameters x = searchParametersList[i];
|
|
|
|
|
|
if(string.IsNullOrWhiteSpace(x.SearchType))
|
|
|
x.SearchType = x.DisplayType.GetDBCondition();
|
|
|
//else
|
|
|
//x.DisplayType = x.DisplayType.GetDBCondition();
|
|
|
if (string.IsNullOrEmpty(x.Value) )
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
|
|
|
PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault();
|
|
|
//2020.06.25增加字段null处理
|
|
|
if (property == null)
|
|
|
continue;
|
|
|
// property
|
|
|
|
|
|
|
|
|
//移除查询的值与数据库类型不匹配的数据
|
|
|
object[] values = property.ValidationValueForDbType(x.Value.Split(',')).Where(q => q.Item1).Select(s => s.Item3).ToArray();
|
|
|
if (values == null || values.Length == 0)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (x.SearchType == HtmlElementType.Contains)
|
|
|
x.Value = string.Join(",", values);
|
|
|
LinqExpressionType expressionType = x.SearchType.GetLinqCondition();
|
|
|
queryable = LinqExpressionType.In == expressionType
|
|
|
? queryable.Where(x.Name.CreateExpression<T>(values, expressionType))
|
|
|
: queryable.Where(x.Name.CreateExpression<T>(x.Value, expressionType));
|
|
|
|
|
|
|
|
|
}
|
|
|
options.TableName = base.TableName ?? typeof(T).Name;
|
|
|
return options;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 加载页面数据 通用查询 基类
|
|
|
/// </summary>
|
|
|
/// <param name="loadSingleParameters"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual PageGridData<T> GetPageData(PageDataOptions options)
|
|
|
{
|
|
|
|
|
|
options = ValidatePageOptions(options, out IQueryable<T> queryable);
|
|
|
//获取排序字段
|
|
|
//Dictionary<string, QueryOrderBy> orderbyDic = GetPageDataSort(options, TProperties);
|
|
|
|
|
|
//PageGridData<T> pageGridData = new PageGridData<T>();
|
|
|
//if (QueryRelativeExpression != null)
|
|
|
//{
|
|
|
// queryable = QueryRelativeExpression.Invoke(queryable);
|
|
|
//}
|
|
|
//if (options.Export)
|
|
|
//{
|
|
|
// pageGridData.rows = queryable.GetIQueryableOrderBy(orderbyDic).Take(Limit).ToList();
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
// pageGridData.rows = repository.IQueryablePage(queryable,
|
|
|
// options.Page,
|
|
|
// options.Rows,
|
|
|
// out int rowCount,
|
|
|
// orderbyDic).ToList();
|
|
|
// pageGridData.total = rowCount;
|
|
|
// //查询界面统计求等字段
|
|
|
// if (SummaryExpress != null)
|
|
|
// {
|
|
|
// pageGridData.summary = SummaryExpress.Invoke(queryable);
|
|
|
// //Func<T, T> groupExpress = x =>x;
|
|
|
// //pageGridData.summary = queryable.GroupBy(groupExpress).Select(SummaryExpress).FirstOrDefault();
|
|
|
// }
|
|
|
//}
|
|
|
//GetPageDataOnExecuted?.Invoke(pageGridData);
|
|
|
//return pageGridData;
|
|
|
return Do_GetPageData(options, queryable);
|
|
|
}
|
|
|
|
|
|
|
|
|
public PageGridData<T> Do_GetPageData(PageDataOptions options, IQueryable<T> queryable)
|
|
|
{
|
|
|
|
|
|
Dictionary<string, QueryOrderBy> orderbyDic = GetPageDataSort(options, TProperties);
|
|
|
|
|
|
PageGridData<T> pageGridData = new PageGridData<T>();
|
|
|
if (QueryRelativeExpression != null)
|
|
|
{
|
|
|
queryable = QueryRelativeExpression.Invoke(queryable);
|
|
|
}
|
|
|
if (options.Export)
|
|
|
{
|
|
|
pageGridData.rows = queryable.GetIQueryableOrderBy(orderbyDic).Take(Limit).ToList();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pageGridData.rows = repository.IQueryablePage(queryable,
|
|
|
options.Page,
|
|
|
options.Rows,
|
|
|
out int rowCount,
|
|
|
orderbyDic).ToList();
|
|
|
pageGridData.total = rowCount;
|
|
|
//查询界面统计求等字段
|
|
|
if (SummaryExpress != null)
|
|
|
{
|
|
|
pageGridData.summary = SummaryExpress.Invoke(queryable);
|
|
|
//Func<T, T> groupExpress = x =>x;
|
|
|
//pageGridData.summary = queryable.GroupBy(groupExpress).Select(SummaryExpress).FirstOrDefault();
|
|
|
}
|
|
|
}
|
|
|
GetPageDataOnExecuted?.Invoke(pageGridData);
|
|
|
return pageGridData;
|
|
|
|
|
|
}
|
|
|
|
|
|
public virtual object GetDetailPage(PageDataOptions pageData)
|
|
|
{
|
|
|
Type detailType = typeof(T).GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
|
|
|
if (detailType == null)
|
|
|
{
|
|
|
return null;
|
|
|
}
|
|
|
object obj = typeof(ServiceBase<T, TRepository>)
|
|
|
.GetMethod("GetDetailPage", BindingFlags.Instance | BindingFlags.NonPublic)
|
|
|
.MakeGenericMethod(new Type[] { detailType }).Invoke(this, new object[] { pageData });
|
|
|
return obj;
|
|
|
}
|
|
|
protected override object GetDetailSummary<Detail>(IQueryable<Detail> queryeable)
|
|
|
{
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
private PageGridData<Detail> GetDetailPage<Detail>(PageDataOptions options) where Detail : class
|
|
|
{
|
|
|
//校验查询值,排序字段,分页大小规则待完
|
|
|
PageGridData<Detail> gridData = new PageGridData<Detail>();
|
|
|
if (options.Value == null) return gridData;
|
|
|
//主表主键字段
|
|
|
string keyName = typeof(T).GetKeyName();
|
|
|
|
|
|
//生成查询条件
|
|
|
Expression<Func<Detail, bool>> whereExpression = keyName.CreateExpression<Detail>(options.Value, LinqExpressionType.Equal);
|
|
|
|
|
|
var queryeable = repository.DbContext.Set<Detail>().Where(whereExpression);
|
|
|
|
|
|
gridData.total = queryeable.Count();
|
|
|
|
|
|
string sortName = options.Sort ?? typeof(Detail).GetKeyName();
|
|
|
Dictionary<string, QueryOrderBy> orderBy = new Dictionary<string, QueryOrderBy>() { {
|
|
|
sortName,
|
|
|
options.Order == "asc" ?
|
|
|
QueryOrderBy.Asc :
|
|
|
QueryOrderBy.Desc } };
|
|
|
gridData.rows = queryeable
|
|
|
.GetIQueryableOrderBy(orderBy)
|
|
|
.Skip((options.Page - 1) * options.Rows)
|
|
|
.Take(options.Rows)
|
|
|
.ToList();
|
|
|
gridData.summary = GetDetailSummary<Detail>(queryeable);
|
|
|
return gridData;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 上传文件
|
|
|
/// </summary>
|
|
|
/// <param name="files"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Upload(List<Microsoft.AspNetCore.Http.IFormFile> files)
|
|
|
{
|
|
|
if (files == null || files.Count == 0) return Response.Error("请上传文件");
|
|
|
|
|
|
var limitFiles = files.Where(x => x.Length > LimitUpFileSizee * 1024 * 1024).Select(s => s.FileName);
|
|
|
if (limitFiles.Count() > 0)
|
|
|
{
|
|
|
return Response.Error($"文件大小不能超过:{ LimitUpFileSizee}M,{string.Join(",", limitFiles)}");
|
|
|
}
|
|
|
string filePath = $"Upload/Tables/{typeof(T).GetEntityTableName()}/{DateTime.Now.ToString("yyyMMddHHmmsss") + new Random().Next(1000, 9999)}/";
|
|
|
string fullPath = filePath.MapPath(true);
|
|
|
int i = 0;
|
|
|
// List<string> fileNames = new List<string>();
|
|
|
try
|
|
|
{
|
|
|
if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath);
|
|
|
for (i = 0; i < files.Count; i++)
|
|
|
{
|
|
|
string fileName = files[i].FileName;
|
|
|
|
|
|
//20230830 增加处理 如果文件名称中带有+ - % & < > / # 则将其替换为_
|
|
|
|
|
|
fileName = BasicDALRef.FileNameDeal(fileName);
|
|
|
|
|
|
//if (fileNames.Contains(fileName))
|
|
|
//{
|
|
|
// fileName += $"({i}){fileName}";
|
|
|
//}
|
|
|
//fileNames.Add(fileName);
|
|
|
using (var stream = new FileStream(fullPath + fileName, FileMode.Create))
|
|
|
{
|
|
|
files[i].CopyTo(stream);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Logger.Error($"上传文件失败:{typeof(T).GetEntityTableCnName()},路径:{filePath},失败文件:{files[i]},{ex.Message + ex.StackTrace}");
|
|
|
return Response.Error("文件上传失败");
|
|
|
}
|
|
|
return Response.OK("文件上传成功", filePath);
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 上传文件-董家镇
|
|
|
/// </summary>
|
|
|
/// <param name="files"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent UploadDJZ(List<Microsoft.AspNetCore.Http.IFormFile> files)
|
|
|
{
|
|
|
if (files == null || files.Count == 0) return Response.Error("请上传文件");
|
|
|
|
|
|
var limitFiles = files.Where(x => x.Length > LimitUpFileSizee * 1024 * 1024).Select(s => s.FileName);
|
|
|
if (limitFiles.Count() > 0)
|
|
|
{
|
|
|
return Response.Error($"文件大小不能超过:{ LimitUpFileSizee}M,{string.Join(",", limitFiles)}");
|
|
|
}
|
|
|
string filePath = $"Upload/Tables/{typeof(T).GetEntityTableName()}/{DateTime.Now.ToString("yyyMMddHHmmsss") + new Random().Next(1000, 9999)}/";
|
|
|
string fullPath = filePath.MapPath(true);
|
|
|
int i = 0;
|
|
|
// List<string> fileNames = new List<string>();
|
|
|
try
|
|
|
{
|
|
|
if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath);
|
|
|
for (i = 0; i < files.Count; i++)
|
|
|
{
|
|
|
string fileName = files[i].FileName;
|
|
|
//if (fileNames.Contains(fileName))
|
|
|
//{
|
|
|
// fileName += $"({i}){fileName}";
|
|
|
//}
|
|
|
//fileNames.Add(fileName);
|
|
|
using (var stream = new FileStream(fullPath + fileName, FileMode.Create))
|
|
|
{
|
|
|
files[i].CopyTo(stream);
|
|
|
}
|
|
|
}
|
|
|
return Response.OK("文件上传成功", filePath);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Logger.Error($"上传文件失败:{typeof(T).GetEntityTableCnName()},路径:{filePath},失败文件:{files[i]},{ex.Message + ex.StackTrace}");
|
|
|
return Response.Error("文件上传失败");
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private List<string> GetIgnoreTemplate()
|
|
|
{
|
|
|
//忽略创建人、修改人、审核等字段
|
|
|
List<string> ignoreTemplate = UserIgnoreFields.ToList();
|
|
|
ignoreTemplate.AddRange(auditFields.ToList());
|
|
|
return ignoreTemplate;
|
|
|
}
|
|
|
|
|
|
public virtual WebResponseContent DownLoadTemplate()
|
|
|
{
|
|
|
string tableName = typeof(T).GetEntityTableCnName();
|
|
|
|
|
|
string dicPath = $"Download/{DateTime.Now.ToString("yyyMMdd")}/Template/".MapPath();
|
|
|
if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath);
|
|
|
string fileName = tableName + DateTime.Now.ToString("yyyyMMddHHssmm") + ".xlsx";
|
|
|
//DownLoadTemplateColumns 2020.05.07增加扩展指定导出模板的列
|
|
|
EPPlusHelper.ExportTemplate<T>(DownLoadTemplateColumns, GetIgnoreTemplate(), dicPath, fileName);
|
|
|
return Response.OK(null, dicPath + fileName);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 导入表数据Excel文件夹
|
|
|
/// </summary>
|
|
|
/// <param name="files"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Import(List<Microsoft.AspNetCore.Http.IFormFile> files)
|
|
|
{
|
|
|
|
|
|
if (files == null || files.Count == 0)
|
|
|
return new WebResponseContent { Status = true, Message = "请选择上传的文件" };
|
|
|
Microsoft.AspNetCore.Http.IFormFile formFile = files[0];
|
|
|
string dicPath = $"Upload/{DateTime.Now.ToString("yyyMMdd")}/{typeof(T).Name}/".MapPath();
|
|
|
if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath);
|
|
|
dicPath = $"{dicPath}{Guid.NewGuid().ToString()}_{formFile.FileName}";
|
|
|
|
|
|
using (var stream = new FileStream(dicPath, FileMode.Create))
|
|
|
{
|
|
|
formFile.CopyTo(stream);
|
|
|
}
|
|
|
try
|
|
|
{
|
|
|
Response = EPPlusHelper.ReadToDataTable<T>(dicPath, DownLoadTemplateColumns, GetIgnoreTemplate());
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Response.Error("未能处理导入的文件,请检查导入的文件是否正确");
|
|
|
Logger.Error($"表{typeof(T).GetEntityTableCnName()}导入失败{ex.Message + ex.InnerException?.Message}");
|
|
|
}
|
|
|
if (!Response.Status) return Response;
|
|
|
List<T> list = Response.Data as List<T>;
|
|
|
if (ImportOnExecuting != null)
|
|
|
{
|
|
|
Response = ImportOnExecuting.Invoke(list);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
repository.AddRange(list, true);
|
|
|
if (ImportOnExecuted != null)
|
|
|
{
|
|
|
Response = ImportOnExecuted.Invoke(list);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
return new WebResponseContent { Status = true, Message = "文件上传成功" };
|
|
|
}
|
|
|
|
|
|
public virtual List<T> GetListByExcel(List<Microsoft.AspNetCore.Http.IFormFile> files,out WebResponseContent _webResponseContent)
|
|
|
{
|
|
|
|
|
|
if (files == null || files.Count == 0)
|
|
|
{
|
|
|
_webResponseContent = new WebResponseContent().Error("没有找到文件");
|
|
|
return new List<T>();
|
|
|
|
|
|
}
|
|
|
Microsoft.AspNetCore.Http.IFormFile formFile = files[0];
|
|
|
string dicPath = $"Upload/{DateTime.Now.ToString("yyyMMdd")}/{typeof(T).Name}/".MapPath();
|
|
|
if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath);
|
|
|
dicPath = $"{dicPath}{Guid.NewGuid().ToString()}_{formFile.FileName}";
|
|
|
|
|
|
using (var stream = new FileStream(dicPath, FileMode.Create))
|
|
|
{
|
|
|
formFile.CopyTo(stream);
|
|
|
}
|
|
|
try
|
|
|
{
|
|
|
Response = EPPlusHelper.ReadToDataTable<T>(dicPath, DownLoadTemplateColumns, GetIgnoreTemplate());
|
|
|
_webResponseContent = Response;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Response.Error("未能处理导入的文件,请检查导入的文件是否正确");
|
|
|
Logger.Error($"表{typeof(T).GetEntityTableCnName()}导入失败{ex.Message + ex.InnerException?.Message}");
|
|
|
_webResponseContent = Response;
|
|
|
}
|
|
|
if (!Response.Status) return new List<T>();
|
|
|
List<T> list = Response.Data as List<T>;
|
|
|
|
|
|
File.Delete(dicPath);
|
|
|
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 导出
|
|
|
/// </summary>
|
|
|
/// <param name="pageData"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Export(PageDataOptions pageData)
|
|
|
{
|
|
|
pageData.Export = true;
|
|
|
List<T> list = GetPageData(pageData).rows;
|
|
|
string tableName = typeof(T).GetEntityTableCnName();
|
|
|
string fileName = tableName + DateTime.Now.ToString("yyyyMMddHHssmm") + ".xlsx";
|
|
|
string folder = DateTime.Now.ToString("yyyyMMdd");
|
|
|
string savePath = $"Download/ExcelExport/{folder}/".MapPath();
|
|
|
List<string> ignoreColumn = new List<string>();
|
|
|
if (ExportOnExecuting != null)
|
|
|
{
|
|
|
Response = ExportOnExecuting(list, ignoreColumn);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
//ExportColumns 2020.05.07增加扩展指定导出模板的列
|
|
|
if (ExportColumns != null)
|
|
|
{
|
|
|
EPPlusHelper.Export(list, ExportColumns?.GetExpressionToArray(), ignoreColumn, savePath, fileName);
|
|
|
}
|
|
|
else
|
|
|
if (ExportColumnsList != null && ExportColumnsList.Count > 0)
|
|
|
{
|
|
|
EPPlusHelper.Export(list, ExportColumnsList.ToArray(), ignoreColumn, savePath, fileName);
|
|
|
}
|
|
|
else {
|
|
|
EPPlusHelper.Export(list, ExportColumns?.GetExpressionToArray(), ignoreColumn, savePath, fileName);
|
|
|
}
|
|
|
return Response.OK(null, (savePath + "/" + fileName).EncryptDES(AppSetting.Secret.ExportFile));
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 新建 新建方法
|
|
|
/// </summary>
|
|
|
/// <param name="saveDataModel"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Add(SaveModel saveDataModel)
|
|
|
{
|
|
|
if (AddOnExecute != null)
|
|
|
{
|
|
|
Response = AddOnExecute(saveDataModel);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
if (saveDataModel == null
|
|
|
|| saveDataModel.MainData == null
|
|
|
|| saveDataModel.MainData.Count == 0)
|
|
|
return Response.Set(ResponseType.ParametersLack, false);
|
|
|
|
|
|
saveDataModel.DetailData = saveDataModel.DetailData?.Where(x => x.Count > 0).ToList();
|
|
|
Type type = typeof(T);
|
|
|
|
|
|
string validReslut = type.ValidateDicInEntity(saveDataModel.MainData, true, UserIgnoreFields);
|
|
|
|
|
|
if (!string.IsNullOrEmpty(validReslut)) return Response.Error(validReslut);
|
|
|
|
|
|
if (saveDataModel.MainData.Count == 0)
|
|
|
return Response.Error("保存的数据为空,请检查model是否配置正确!");
|
|
|
|
|
|
UserInfo userInfo = UserContext.Current.UserInfo;
|
|
|
saveDataModel.SetDefaultVal(AppSetting.CreateMember, userInfo);
|
|
|
|
|
|
PropertyInfo keyPro = type.GetKeyProperty();
|
|
|
if (keyPro.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
saveDataModel.MainData.Add(keyPro.Name, Guid.NewGuid());
|
|
|
}
|
|
|
else if (keyPro.PropertyType.Name == "String") {
|
|
|
//string型的主键也使用guid填充
|
|
|
//如果需要使用命名规则 需要在这里实现
|
|
|
saveDataModel.MainData.Add(keyPro.Name, Guid.NewGuid().ToString());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
saveDataModel.MainData.Remove(keyPro.Name);
|
|
|
}
|
|
|
//没有明细直接保存返回
|
|
|
if (saveDataModel.DetailData == null || saveDataModel.DetailData.Count == 0)
|
|
|
{
|
|
|
//20200922 首先把editable=false的都去掉
|
|
|
//var editfalse = type.GetEditableFalse();
|
|
|
//foreach (var editfalsefield in editfalse) {
|
|
|
// saveDataModel.MainData.Remove(editfalsefield.Name);
|
|
|
//}
|
|
|
|
|
|
T mainEntity = saveDataModel.MainData.DicToEntity<T>();
|
|
|
if (base.AddOnExecuting != null)
|
|
|
{
|
|
|
Response = base.AddOnExecuting(mainEntity, null);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.Add(mainEntity,true);
|
|
|
saveDataModel.MainData[keyPro.Name] = keyPro.GetValue(mainEntity);
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
if (base.AddOnExecuted != null)
|
|
|
{
|
|
|
Response = base.AddOnExecuted(mainEntity, null);
|
|
|
}
|
|
|
return Response;
|
|
|
});
|
|
|
if (Response.Status)
|
|
|
{
|
|
|
Response.Data = new { data = saveDataModel.MainData, message = "保存成功" };
|
|
|
}
|
|
|
if (Response.Status && string.IsNullOrEmpty(Response.Message))
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
Type detailType = typeof(T).GetCustomAttribute<EntityAttribute>().DetailTable[0];
|
|
|
|
|
|
return typeof(ServiceBase<T, TRepository>)
|
|
|
.GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic)
|
|
|
.MakeGenericMethod(new Type[] { detailType })
|
|
|
.Invoke(this, new object[] { saveDataModel })
|
|
|
as WebResponseContent;
|
|
|
}
|
|
|
|
|
|
public virtual WebResponseContent AddEntity(T entity, bool validationEntity = true)
|
|
|
{
|
|
|
return Add<T>(entity, null, validationEntity);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 保存主、明细数据
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TDetail"></typeparam>
|
|
|
/// <param name="entity"></param>
|
|
|
/// <param name="list"></param>
|
|
|
/// <param name="validationEntity">是否进行实体验证</param>
|
|
|
/// <returns></returns>
|
|
|
public WebResponseContent Add<TDetail>(T entity, List<TDetail> list = null, bool validationEntity = true) where TDetail : class
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
entity.SetCreateDefaultVal();
|
|
|
if (validationEntity)
|
|
|
{
|
|
|
Response = entity.ValidationEntity();
|
|
|
if (!Response.Status) return Response;
|
|
|
if (list != null && list.Count > 0)
|
|
|
{
|
|
|
Response = list.ValidationEntity();
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
}
|
|
|
if (this.AddOnExecuting != null)
|
|
|
{
|
|
|
Response = AddOnExecuting(entity, list);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.Add(entity);
|
|
|
repository.DbContext.SaveChanges();
|
|
|
//保存明细
|
|
|
if (list != null && list.Count > 0)
|
|
|
{
|
|
|
//获取保存后的主键值
|
|
|
PropertyInfo mainKey = typeof(T).GetKeyProperty();
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetProperties()
|
|
|
.Where(q => q.Name.ToLower() == mainKey.Name.ToLower()).FirstOrDefault();
|
|
|
object keyValue = mainKey.GetValue(entity);
|
|
|
list.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
if (AddOnExecuted != null)
|
|
|
Response = AddOnExecuted(entity, list);
|
|
|
return Response;
|
|
|
});
|
|
|
if (Response.Status && string.IsNullOrEmpty(Response.Message))
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
public WebResponseContent Add<TDetail>(T entity, List<TDetail> list1=null, List<TDetail> list2=null, List<TDetail> list3 = null, List<TDetail> list4 = null, List<TDetail> list5 = null, List<TDetail> list6 = null,bool validationEntity = true) where TDetail : class
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
entity.SetCreateDefaultVal();
|
|
|
if (validationEntity)
|
|
|
{
|
|
|
Response = entity.ValidationEntity();
|
|
|
if (!Response.Status) return Response;
|
|
|
if (BodyListValidation(list1)) {
|
|
|
return Response;
|
|
|
}
|
|
|
if (BodyListValidation(list2))
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
if (BodyListValidation(list3))
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
if (BodyListValidation(list4))
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
if (BodyListValidation(list5))
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
if (BodyListValidation(list6))
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
}
|
|
|
if (this.AddOnExecuting != null)
|
|
|
{
|
|
|
if (!list1.isNullorEmpty())
|
|
|
Response = AddOnExecuting(entity, list1);
|
|
|
if (!list2.isNullorEmpty())
|
|
|
Response = AddOnExecuting(entity, list2);
|
|
|
if (!list3.isNullorEmpty())
|
|
|
Response = AddOnExecuting(entity, list3);
|
|
|
if (!list4.isNullorEmpty())
|
|
|
Response = AddOnExecuting(entity, list4);
|
|
|
if (!list5.isNullorEmpty())
|
|
|
Response = AddOnExecuting(entity, list5);
|
|
|
if (!list6.isNullorEmpty())
|
|
|
Response = AddOnExecuting(entity, list6);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.Add(entity);
|
|
|
repository.DbContext.SaveChanges();
|
|
|
//获取保存后的主键值
|
|
|
PropertyInfo mainKey = typeof(T).GetKeyProperty();
|
|
|
object keyValue = mainKey.GetValue(entity);
|
|
|
//保存明细
|
|
|
if (!list1.isNullorEmpty())
|
|
|
{
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
|
|
|
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
list1.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
if (BodyPK.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
}
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
if (!list2.isNullorEmpty())
|
|
|
{
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
list2.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
if (BodyPK.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
}
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
if (!list3.isNullorEmpty())
|
|
|
{
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
list3.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
if (BodyPK.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
}
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
if (!list4.isNullorEmpty())
|
|
|
{
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
list4.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
if (BodyPK.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
}
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
if (!list5.isNullorEmpty())
|
|
|
{
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
list5.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
if (BodyPK.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
}
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
if (!list6.isNullorEmpty())
|
|
|
{
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(typeof(T).GetEntityTableName());
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
list6.ForEach(x =>
|
|
|
{
|
|
|
//设置用户默认值
|
|
|
x.SetCreateDefaultVal();
|
|
|
detailMainKey.SetValue(x, keyValue);
|
|
|
if (BodyPK.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
}
|
|
|
repository.DbContext.Entry<TDetail>(x).State = EntityState.Added;
|
|
|
});
|
|
|
repository.DbContext.SaveChanges();
|
|
|
}
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
if (AddOnExecuted != null)
|
|
|
{
|
|
|
if (!list1.isNullorEmpty())
|
|
|
Response = AddOnExecuted(entity, list1);
|
|
|
if (!list2.isNullorEmpty())
|
|
|
Response = AddOnExecuted(entity, list2);
|
|
|
if (!list3.isNullorEmpty())
|
|
|
Response = AddOnExecuted(entity, list3);
|
|
|
if (!list4.isNullorEmpty())
|
|
|
Response = AddOnExecuted(entity, list4);
|
|
|
if (!list5.isNullorEmpty())
|
|
|
Response = AddOnExecuted(entity, list5);
|
|
|
if (!list6.isNullorEmpty())
|
|
|
Response = AddOnExecuted(entity, list6);
|
|
|
}
|
|
|
|
|
|
return Response;
|
|
|
});
|
|
|
if (Response.Status && string.IsNullOrEmpty(Response.Message))
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
private Boolean BodyListValidation<TDetail>(List<TDetail> list) {
|
|
|
if (list != null && list.Count > 0)
|
|
|
{
|
|
|
Response = list.ValidationEntity();
|
|
|
return (!Response.Status) ;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
public void AddDetailToDBSet<TDetail>() where TDetail : class
|
|
|
{
|
|
|
List<PropertyInfo> listChilds = TProperties.Where(x => x.PropertyType.Name == "List`1").ToList();
|
|
|
// repository.DbContext.Set<TDetail>().AddRange();
|
|
|
}
|
|
|
|
|
|
private WebResponseContent Add<TDetail>(SaveModel saveDataModel) where TDetail : class
|
|
|
{
|
|
|
T mainEntity = saveDataModel.MainData.DicToEntity<T>();
|
|
|
//验证明细
|
|
|
string reslut = typeof(TDetail).ValidateDicInEntity(saveDataModel.DetailData, true, false, new string[] { TProperties.GetKeyName() });
|
|
|
if (reslut != string.Empty)
|
|
|
return Response.Error(reslut);
|
|
|
|
|
|
List<TDetail> list = saveDataModel.DetailData.DicToList<TDetail>();
|
|
|
Response = Add<TDetail>(mainEntity, list, false);
|
|
|
|
|
|
//保存失败
|
|
|
if (!Response.Status)
|
|
|
{
|
|
|
Logger.Error(LoggerType.Add, saveDataModel.Serialize() + Response.Message);
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
PropertyInfo propertyKey = typeof(T).GetKeyProperty();
|
|
|
saveDataModel.MainData[propertyKey.Name] = propertyKey.GetValue(mainEntity);
|
|
|
Response.Data = new { data = saveDataModel.MainData, list };
|
|
|
return Response.Set(ResponseType.SaveSuccess);
|
|
|
}
|
|
|
|
|
|
#region 编辑
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取编辑明细主键
|
|
|
/// </summary>
|
|
|
/// <typeparam name="DetailT"></typeparam>
|
|
|
/// <typeparam name="Tkey"></typeparam>
|
|
|
/// <param name="detailKeyName"></param>
|
|
|
/// <param name="mainKeyName"></param>
|
|
|
/// <param name="mainKeyValue"></param>
|
|
|
/// <returns></returns>
|
|
|
public List<Tkey> GetUpdateDetailSelectKeys<DetailT, Tkey>(string detailKeyName, string mainKeyName, string mainKeyValue) where DetailT : class
|
|
|
{
|
|
|
IQueryable<DetailT> queryable = repository.DbContext.Set<DetailT>();
|
|
|
Expression<Func<DetailT, Tkey>> selectExpression = detailKeyName.GetExpression<DetailT, Tkey>();
|
|
|
Expression<Func<DetailT, bool>> whereExpression = mainKeyName.CreateExpression<DetailT>(mainKeyValue, LinqExpressionType.Equal);
|
|
|
List<Tkey> detailKeys = queryable.Where(whereExpression).Select(selectExpression).ToList();
|
|
|
return detailKeys;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将数据转换成对象后最终保存
|
|
|
/// </summary>
|
|
|
/// <typeparam name="DetailT"></typeparam>
|
|
|
/// <param name="saveModel"></param>
|
|
|
/// <param name="mainKeyProperty"></param>
|
|
|
/// <param name="detailKeyInfo"></param>
|
|
|
/// <param name="keyDefaultVal"></param>
|
|
|
/// <returns></returns>
|
|
|
public WebResponseContent UpdateToEntity<DetailT>(SaveModel saveModel, PropertyInfo mainKeyProperty, PropertyInfo detailKeyInfo, object keyDefaultVal) where DetailT : class
|
|
|
{
|
|
|
T mainEnity = saveModel.MainData.DicToEntity<T>();
|
|
|
List<DetailT> detailList = saveModel.DetailData.DicToList<DetailT>();
|
|
|
//删除的主键
|
|
|
|
|
|
//查出所有明细表数据的ID
|
|
|
System.Collections.IList detailKeys = this.GetType().GetMethod("GetUpdateDetailSelectKeys")
|
|
|
.MakeGenericMethod(new Type[] { typeof(DetailT), detailKeyInfo.PropertyType })
|
|
|
.Invoke(this, new object[] {
|
|
|
detailKeyInfo.Name, mainKeyProperty.Name,
|
|
|
saveModel.MainData[mainKeyProperty.Name].ToString()
|
|
|
}) as System.Collections.IList;
|
|
|
|
|
|
//新增对象
|
|
|
List<DetailT> addList = new List<DetailT>();
|
|
|
// List<object> containsKeys = new List<object>();
|
|
|
//编辑对象
|
|
|
List<DetailT> editList = new List<DetailT>();
|
|
|
//删除的主键
|
|
|
List<object> delKeys = new List<object>();
|
|
|
mainKeyProperty = typeof(DetailT).GetProperties().Where(x => x.Name == mainKeyProperty.Name).FirstOrDefault();
|
|
|
//获取新增与修改的对象
|
|
|
foreach (DetailT item in detailList)
|
|
|
{
|
|
|
object value = detailKeyInfo.GetValue(item);
|
|
|
if (keyDefaultVal.Equals(value))//主键为默认值的,新增数据
|
|
|
{
|
|
|
//设置新增的主表的值
|
|
|
mainKeyProperty.SetValue(item,
|
|
|
saveModel.MainData[mainKeyProperty.Name]
|
|
|
.ChangeType(mainKeyProperty.PropertyType));
|
|
|
|
|
|
if (detailKeyInfo.PropertyType == typeof(Guid))
|
|
|
{
|
|
|
detailKeyInfo.SetValue(item, Guid.NewGuid());
|
|
|
}
|
|
|
addList.Add(item);
|
|
|
}
|
|
|
else if (detailKeys.Contains(value))
|
|
|
{
|
|
|
//containsKeys.Add(value);
|
|
|
editList.Add(item);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//获取需要删除的对象的主键
|
|
|
if (saveModel.DelKeys != null && saveModel.DelKeys.Count > 0)
|
|
|
{
|
|
|
delKeys = saveModel.DelKeys
|
|
|
.Where(x => detailKeys.Contains(x.ChangeType(detailKeyInfo.PropertyType)))
|
|
|
.Select(q => q.ChangeType(detailKeyInfo.PropertyType)).ToList();
|
|
|
}
|
|
|
|
|
|
if (UpdateOnExecuting != null)
|
|
|
{
|
|
|
Response = UpdateOnExecuting(mainEnity, addList, editList, delKeys);
|
|
|
if (!Response.Status)
|
|
|
return Response;
|
|
|
}
|
|
|
mainEnity.SetModifyDefaultVal();
|
|
|
//主表修改
|
|
|
//不修改!CreateFields.Contains创建人信息
|
|
|
repository.Update(mainEnity, typeof(T).GetEditField()
|
|
|
.Where(c => saveModel.MainData.Keys.Contains(c) && !CreateFields.Contains(c))
|
|
|
.ToArray());
|
|
|
foreach (var item in saveModel.DetailData)
|
|
|
{
|
|
|
item.SetModifyDefaultVal();
|
|
|
}
|
|
|
//明细修改
|
|
|
editList.ForEach(x =>
|
|
|
{
|
|
|
//获取编辑的字段
|
|
|
string[] updateField = saveModel.DetailData
|
|
|
.Where(c => c[detailKeyInfo.Name].ChangeType(detailKeyInfo.PropertyType)
|
|
|
.Equal(detailKeyInfo.GetValue(x)))
|
|
|
.FirstOrDefault()
|
|
|
.Keys.Where(k => k != detailKeyInfo.Name)
|
|
|
.Where(r => !CreateFields.Contains(r))
|
|
|
.ToArray();
|
|
|
//設置默認值
|
|
|
x.SetModifyDefaultVal();
|
|
|
//添加修改字段
|
|
|
repository.Update<DetailT>(x, updateField);
|
|
|
});
|
|
|
|
|
|
//明细新增
|
|
|
addList.ForEach(x =>
|
|
|
{
|
|
|
x.SetCreateDefaultVal();
|
|
|
repository.DbContext.Entry<DetailT>(x).State = EntityState.Added;
|
|
|
});
|
|
|
//明细删除
|
|
|
delKeys.ForEach(x =>
|
|
|
{
|
|
|
DetailT delT = Activator.CreateInstance<DetailT>();
|
|
|
detailKeyInfo.SetValue(delT, x);
|
|
|
repository.DbContext.Entry<DetailT>(delT).State = EntityState.Deleted;
|
|
|
});
|
|
|
|
|
|
if (UpdateOnExecuted == null)
|
|
|
{
|
|
|
repository.DbContext.SaveChanges();
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.DbContext.SaveChanges();
|
|
|
Response = UpdateOnExecuted(mainEnity, addList, editList, delKeys);
|
|
|
return Response;
|
|
|
});
|
|
|
}
|
|
|
if (Response.Status)
|
|
|
{
|
|
|
addList.AddRange(editList);
|
|
|
Response.Data = new { data = mainEnity, list = addList };
|
|
|
if (string.IsNullOrEmpty(Response.Message))
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
}
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取配置的创建人ID创建时间创建人,修改人ID修改时间、修改人与数据相同的字段
|
|
|
/// </summary>
|
|
|
private static string[] _userIgnoreFields { get; set; }
|
|
|
|
|
|
private static string[] UserIgnoreFields
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (_userIgnoreFields != null) return _userIgnoreFields;
|
|
|
List<string> fields = new List<string>();
|
|
|
fields.AddRange(CreateFields);
|
|
|
fields.AddRange(ModifyFields);
|
|
|
_userIgnoreFields = fields.ToArray();
|
|
|
return _userIgnoreFields;
|
|
|
}
|
|
|
}
|
|
|
private static string[] _createFields { get; set; }
|
|
|
private static string[] CreateFields
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (_createFields != null) return _createFields;
|
|
|
_createFields = AppSetting.CreateMember.GetType().GetProperties()
|
|
|
.Select(x => x.GetValue(AppSetting.CreateMember)?.ToString())
|
|
|
.Where(w => !string.IsNullOrEmpty(w)).ToArray();
|
|
|
return _createFields;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private static string[] _modifyFields { get; set; }
|
|
|
private static string[] ModifyFields
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (_modifyFields != null) return _modifyFields;
|
|
|
_modifyFields = AppSetting.ModifyMember.GetType().GetProperties()
|
|
|
.Select(x => x.GetValue(AppSetting.ModifyMember)?.ToString())
|
|
|
.Where(w => !string.IsNullOrEmpty(w)).ToArray();
|
|
|
return _modifyFields;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 编辑
|
|
|
/// 1、明细表必须把主表的主键字段也设置为可编辑
|
|
|
/// 2、修改、增加只会操作设置为编辑列的数据
|
|
|
/// </summary>
|
|
|
/// <param name="saveModel"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Update(SaveModel saveModel)
|
|
|
{
|
|
|
if (UpdateOnExecute != null)
|
|
|
{
|
|
|
Response = UpdateOnExecute(saveModel);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
if (saveModel == null)
|
|
|
return Response.Error(ResponseType.ParametersLack);
|
|
|
|
|
|
Type type = typeof(T);
|
|
|
|
|
|
//设置修改时间,修改人的默认值
|
|
|
UserInfo userInfo = UserContext.Current.UserInfo;
|
|
|
saveModel.SetDefaultVal(AppSetting.ModifyMember, userInfo);
|
|
|
|
|
|
|
|
|
//判断提交的数据与实体格式是否一致
|
|
|
string result = type.ValidateDicInEntity(saveModel.MainData, true, false, UserIgnoreFields);
|
|
|
if (result != string.Empty)
|
|
|
return Response.Error(result);
|
|
|
|
|
|
PropertyInfo mainKeyProperty = type.GetKeyProperty();
|
|
|
//验证明细
|
|
|
Type detailType = null;
|
|
|
if (saveModel.DetailData != null || saveModel.DelKeys != null)
|
|
|
{
|
|
|
saveModel.DetailData = saveModel.DetailData == null
|
|
|
? new List<Dictionary<string, object>>()
|
|
|
: saveModel.DetailData.Where(x => x.Count > 0).ToList();
|
|
|
|
|
|
detailType = typeof(T).GetCustomAttribute<EntityAttribute>().DetailTable[0];
|
|
|
|
|
|
result = detailType.ValidateDicInEntity(saveModel.DetailData, true, false, new string[] { mainKeyProperty.Name });
|
|
|
if (result != string.Empty) return Response.Error(result);
|
|
|
|
|
|
//主从关系指定外键,即从表的外键可以不是主键的主表,还需要改下代码生成器设置属性外键,功能预留后面再开发(2020.04.25)
|
|
|
//string foreignKey = type.GetTypeCustomValue<System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute>(x => new { x.Name });
|
|
|
//if (!string.IsNullOrEmpty(foreignKey))
|
|
|
//{
|
|
|
// var _mainKeyProperty = detailType.GetProperties().Where(x => x.Name.ToLower() == foreignKey.ToLower()).FirstOrDefault();
|
|
|
// if (_mainKeyProperty != null)
|
|
|
// {
|
|
|
// mainKeyProperty = _mainKeyProperty;
|
|
|
// }
|
|
|
//}
|
|
|
}
|
|
|
|
|
|
//获取主建类型的默认值用于判断后面数据是否正确,int long默认值为0,guid :0000-000....
|
|
|
object keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance("System.Int32");
|
|
|
if (mainKeyProperty.PropertyType.FullName == "System.String") keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance("System.Guid");
|
|
|
else
|
|
|
keyDefaultVal = mainKeyProperty.PropertyType.Assembly.CreateInstance(mainKeyProperty.PropertyType.FullName);//.ToString();
|
|
|
|
|
|
//判断是否包含主键
|
|
|
if (mainKeyProperty == null
|
|
|
|| !saveModel.MainData.ContainsKey(mainKeyProperty.Name)
|
|
|
|| saveModel.MainData[mainKeyProperty.Name] == null
|
|
|
)
|
|
|
{
|
|
|
return Response.Error(ResponseType.NoKey);
|
|
|
}
|
|
|
|
|
|
object mainKeyVal = saveModel.MainData[mainKeyProperty.Name];
|
|
|
|
|
|
if (!addLockKey(mainKeyVal)){
|
|
|
return Response.Error("该业务正在进行操作 请稍后");
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
//判断主键类型是否正确
|
|
|
(bool, string, object) validation = mainKeyProperty.ValidationValueForDbType(mainKeyVal).FirstOrDefault();
|
|
|
if (!validation.Item1)
|
|
|
return Response.Error(ResponseType.KeyError);
|
|
|
|
|
|
object valueType = mainKeyVal.ToString().ChangeType(mainKeyProperty.PropertyType);
|
|
|
//判断主键值是不是当前类型的默认值
|
|
|
if (valueType == null ||
|
|
|
(!valueType.GetType().Equals(mainKeyProperty.PropertyType)
|
|
|
|| valueType.ToString() == keyDefaultVal.ToString()
|
|
|
))
|
|
|
return Response.Error(ResponseType.KeyError);
|
|
|
|
|
|
if (saveModel.MainData.Count <= 1) return Response.Error("系统没有配置好编辑的数据,请检查model!");
|
|
|
|
|
|
// 2020.08.15添加多租户数据过滤(编辑)
|
|
|
if (IsMultiTenancy && !UserContext.Current.IsSuperAdmin)
|
|
|
{
|
|
|
CheckUpdateMultiTenancy(mainKeyProperty.PropertyType == typeof(Guid) ? "'" + mainKeyVal.ToString() + "'" : mainKeyVal.ToString(), mainKeyProperty.Name);
|
|
|
if (!Response.Status)
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Expression<Func<T, bool>> expression = mainKeyProperty.Name.CreateExpression<T>(mainKeyVal.ToString(), LinqExpressionType.Equal);
|
|
|
if (!repository.Exists(expression)) return Response.Error("保存的数据不存在!");
|
|
|
//没有明细的直接保存主表数据
|
|
|
if (detailType == null)
|
|
|
{
|
|
|
saveModel.SetDefaultVal(AppSetting.ModifyMember, userInfo);
|
|
|
T mainEntity = saveModel.MainData.DicToEntity<T>();
|
|
|
if (UpdateOnExecuting != null)
|
|
|
{
|
|
|
Response = UpdateOnExecuting(mainEntity, null, null, null);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
//不修改!CreateFields.Contains创建人信息
|
|
|
repository.Update(mainEntity, type.GetEditField().Where(c => saveModel.MainData.Keys.Contains(c) && !CreateFields.Contains(c)).ToArray());
|
|
|
if (base.UpdateOnExecuted == null)
|
|
|
{
|
|
|
repository.SaveChanges();
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.SaveChanges();
|
|
|
Response = UpdateOnExecuted(mainEntity, null, null, null);
|
|
|
return Response;
|
|
|
});
|
|
|
}
|
|
|
if (Response.Status) Response.Data = new SaveResult( mainEntity);
|
|
|
if (Response.Status && string.IsNullOrEmpty(Response.Message))
|
|
|
Response.OK(ResponseType.SaveSuccess);
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
saveModel.DetailData = saveModel.DetailData.Where(x => x.Count > 0).ToList();
|
|
|
|
|
|
//明细操作
|
|
|
PropertyInfo detailKeyInfo = detailType.GetKeyProperty();
|
|
|
//主键类型
|
|
|
// string detailKeyType = mainKeyProperty.GetTypeCustomValue<ColumnAttribute>(c => new { c.TypeName });
|
|
|
//判断明细是否包含了主表的主键
|
|
|
|
|
|
string deatilDefaultVal = detailKeyInfo.PropertyType.Assembly.CreateInstance(detailKeyInfo.PropertyType.FullName).ToString();
|
|
|
foreach (Dictionary<string, object> dic in saveModel.DetailData)
|
|
|
{
|
|
|
//不包含主键的默认添加主键默认值,用于后面判断是否为新增数据
|
|
|
if (!dic.ContainsKey(detailKeyInfo.Name))
|
|
|
{
|
|
|
dic.Add(detailKeyInfo.Name, keyDefaultVal);
|
|
|
if (dic.ContainsKey(mainKeyProperty.Name))
|
|
|
{
|
|
|
dic[mainKeyProperty.Name] = keyDefaultVal;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dic.Add(mainKeyProperty.Name, keyDefaultVal);
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
if (dic[detailKeyInfo.Name] == null)
|
|
|
return Response.Error(ResponseType.NoKey);
|
|
|
|
|
|
//主键值是否正确
|
|
|
string detailKeyVal = dic[detailKeyInfo.Name].ToString();
|
|
|
if (!mainKeyProperty.ValidationValueForDbType(detailKeyVal).FirstOrDefault().Item1
|
|
|
|| deatilDefaultVal == detailKeyVal)
|
|
|
return Response.Error(ResponseType.KeyError);
|
|
|
|
|
|
//判断主表的值是否正确
|
|
|
if (detailKeyVal != keyDefaultVal.ToString() && (!dic.ContainsKey(mainKeyProperty.Name) || dic[mainKeyProperty.Name] == null || dic[mainKeyProperty.Name].ToString() == keyDefaultVal.ToString()))
|
|
|
{
|
|
|
return Response.Error(mainKeyProperty.Name + "是必填项!");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (saveModel.DetailData.Exists(c => c.Count <= 2))
|
|
|
return Response.Error("系统没有配置好明细编辑的数据,请检查model!");
|
|
|
return this.GetType().GetMethod("UpdateToEntity")
|
|
|
.MakeGenericMethod(new Type[] { detailType })
|
|
|
.Invoke(this, new object[] { saveModel, mainKeyProperty, detailKeyInfo, keyDefaultVal })
|
|
|
as WebResponseContent;
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
return Response.Error(e.Message);
|
|
|
}
|
|
|
finally {
|
|
|
delLockKey(mainKeyVal);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 删除明细数据
|
|
|
/// 前台使用时,调用该表自己的URL/DelDetail 参数delKey
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TDetail"></typeparam>
|
|
|
/// <param name="list"></param>
|
|
|
/// <param name="Delkeys"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent DelDetail(SaveModel saveDataModel)
|
|
|
{
|
|
|
Type DetailType = typeof(T);
|
|
|
|
|
|
var keys = saveDataModel.DelKeys.ToArray();
|
|
|
FieldType fieldType = DetailType.GetFieldType();
|
|
|
|
|
|
for (var _i= 0; _i < keys.Length;_i++) {
|
|
|
if (keys[_i]==null ) {
|
|
|
if (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
|
|
|
{
|
|
|
keys[_i] = 0;
|
|
|
}
|
|
|
else {
|
|
|
keys[_i] = Guid.Empty.ToString();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var DetailkeyProperty = DetailType.GetKeyProperty();
|
|
|
if (DetailkeyProperty == null || keys == null || keys.Length == 0) return Response.Error(ResponseType.NoKeyDel);
|
|
|
|
|
|
string tKey = DetailkeyProperty.Name;
|
|
|
if (string.IsNullOrEmpty(tKey))
|
|
|
return Response.Error("没有主键不能删除");
|
|
|
|
|
|
if (DelOnExecuting != null)
|
|
|
{
|
|
|
Response = DelOnExecuting(keys);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
|
|
|
|
|
|
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
|
|
|
? string.Join(",", keys)
|
|
|
: $"'{string.Join("','", keys)}'";
|
|
|
// 2020.08.15添加判断多租户数据(删除)
|
|
|
if (IsMultiTenancy && !UserContext.Current.IsSuperAdmin)
|
|
|
{
|
|
|
CheckDelMultiTenancy(joinKeys, tKey);
|
|
|
if (!Response.Status)
|
|
|
{
|
|
|
return Response;
|
|
|
}
|
|
|
}
|
|
|
string sql = $"DELETE FROM {DetailType.GetEntityTableName() } where {tKey} in ({joinKeys});";
|
|
|
|
|
|
//repository.DapperContext.ExcuteNonQuery(sql, CommandType.Text, null, true);
|
|
|
|
|
|
//可能在删除后还要做一些其它数据库新增或删除操作,这样就可能需要与删除保持在同一个事务中处理
|
|
|
//采用此方法 repository.DbContextBeginTransaction(()=>{//do delete......and other});
|
|
|
//做的其他操作,在DelOnExecuted中加入委托实现
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.ExecuteSqlCommand(sql);
|
|
|
if (DelOnExecuted != null)
|
|
|
{
|
|
|
Response = DelOnExecuted(keys);
|
|
|
}
|
|
|
return Response;
|
|
|
});
|
|
|
if (Response.Status && string.IsNullOrEmpty(Response.Message)) Response.OK(ResponseType.DelSuccess);
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
public virtual string GetKeysStr(SaveModel saveDataModel) {
|
|
|
try
|
|
|
{
|
|
|
Type DetailType = typeof(T);
|
|
|
var keys = saveDataModel.DelKeys.ToArray();
|
|
|
FieldType fieldType = DetailType.GetFieldType();
|
|
|
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
|
|
|
? string.Join(",", keys)
|
|
|
: $"'{string.Join("','", keys)}'";
|
|
|
return joinKeys;
|
|
|
}
|
|
|
catch { return ""; }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查找前台传回数据结构中的 WorkKeys 数组
|
|
|
/// 通常用来放置需要处理的业务编号组
|
|
|
/// </summary>
|
|
|
/// <param name="saveDataModel"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual string GetWorkKeysStr(SaveModel saveDataModel)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
Type DetailType = typeof(T);
|
|
|
var keys = saveDataModel.WorkKeys.ToArray();
|
|
|
FieldType fieldType = DetailType.GetFieldType();
|
|
|
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
|
|
|
? string.Join(",", keys)
|
|
|
: $"'{string.Join("','", keys)}'";
|
|
|
return joinKeys;
|
|
|
}
|
|
|
catch { return ""; }
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <param name="keys"></param>
|
|
|
/// <param name="delList">是否删除明细数据(默认会删除明细)</param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Del(object[] keys, bool delList = true)
|
|
|
{
|
|
|
Type entityType = typeof(T);
|
|
|
var keyProperty = entityType.GetKeyProperty();
|
|
|
if (keyProperty == null || keys == null || keys.Length == 0) return Response.Error(ResponseType.NoKeyDel);
|
|
|
|
|
|
IEnumerable<(bool, string, object)> validation = keyProperty.ValidationValueForDbType(keys);
|
|
|
if (validation.Any(x => !x.Item1))
|
|
|
{
|
|
|
return Response.Error(validation.Where(x => !x.Item1).Select(s => s.Item2 + "</br>").Serialize());
|
|
|
}
|
|
|
string tKey = keyProperty.Name;
|
|
|
if (string.IsNullOrEmpty(tKey))
|
|
|
return Response.Error("没有主键不能删除");
|
|
|
|
|
|
if (DelOnExecuting != null)
|
|
|
{
|
|
|
Response = DelOnExecuting(keys);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
|
|
|
FieldType fieldType = entityType.GetFieldType();
|
|
|
string joinKeys = (fieldType == FieldType.Int || fieldType == FieldType.BigInt)
|
|
|
? string.Join(",", keys)
|
|
|
: $"'{string.Join("','", keys)}'";
|
|
|
string sql = $"DELETE FROM {entityType.GetEntityTableName() } where {tKey} in ({joinKeys});";
|
|
|
// 2020.08.06增加pgsql删除功能
|
|
|
if (DBType.Name == DbCurrentType.PgSql.ToString())
|
|
|
{
|
|
|
sql = $"DELETE FROM \"public\".\"{entityType.GetEntityTableName() }\" where \"{tKey}\" in ({joinKeys});";
|
|
|
}
|
|
|
if (delList)
|
|
|
{
|
|
|
Type detailType = entityType.GetCustomAttribute<EntityAttribute>()?.DetailTable?[0];
|
|
|
if (detailType != null)
|
|
|
{
|
|
|
if (DBType.Name == DbCurrentType.PgSql.ToString())
|
|
|
{
|
|
|
sql += $"DELETE FROM \"public\".\"{detailType.GetEntityTableName()}\" where \"{tKey}\" in ({joinKeys});";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sql += $"DELETE FROM {detailType.GetEntityTableName()} where {tKey} in ({joinKeys});";
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//repository.DapperContext.ExcuteNonQuery(sql, CommandType.Text, null, true);
|
|
|
|
|
|
//可能在删除后还要做一些其它数据库新增或删除操作,这样就可能需要与删除保持在同一个事务中处理
|
|
|
//采用此方法 repository.DbContextBeginTransaction(()=>{//do delete......and other});
|
|
|
//做的其他操作,在DelOnExecuted中加入委托实现
|
|
|
Response = repository.DbContextBeginTransaction(() =>
|
|
|
{
|
|
|
repository.ExecuteSqlCommand(sql);
|
|
|
if (DelOnExecuted != null)
|
|
|
{
|
|
|
Response = DelOnExecuted(keys);
|
|
|
}
|
|
|
return Response;
|
|
|
});
|
|
|
if (Response.Status && string.IsNullOrEmpty(Response.Message)) Response.OK(ResponseType.DelSuccess);
|
|
|
return Response;
|
|
|
}
|
|
|
|
|
|
|
|
|
private static string[] auditFields = new string[] { "auditid", "auditstatus", "auditor", "auditdate", "auditreason" };
|
|
|
|
|
|
/// <summary>
|
|
|
/// 审核默认对应数据库字段为AuditId审核人ID ,AuditStatus审核状态,Auditor审核人,Auditdate审核时间,Auditreason审核原因
|
|
|
/// </summary>
|
|
|
/// <param name="keys"></param>
|
|
|
/// <param name="auditStatus"></param>
|
|
|
/// <param name="auditReason"></param>
|
|
|
/// <returns></returns>
|
|
|
public virtual WebResponseContent Audit(object[] keys, int? auditStatus, string auditReason)
|
|
|
{
|
|
|
if (keys == null || keys.Length == 0)
|
|
|
return Response.Error("未获取到参数!");
|
|
|
if (auditStatus != 1 && auditStatus != 2)
|
|
|
return Response.Error("请提求正确的审核结果!");
|
|
|
|
|
|
//获取主键
|
|
|
PropertyInfo property = TProperties.GetKeyProperty();
|
|
|
if (property == null)
|
|
|
return Response.Error("没有配置好主键!");
|
|
|
|
|
|
UserInfo userInfo = UserContext.Current.UserInfo;
|
|
|
|
|
|
//表如果有审核相关字段,设置默认审核
|
|
|
|
|
|
PropertyInfo[] updateFields = TProperties.Where(x => auditFields.Contains(x.Name.ToLower())).ToArray();
|
|
|
List<T> auditList = new List<T>();
|
|
|
foreach (var value in keys)
|
|
|
{
|
|
|
object convertVal = value.ToString().ChangeType(property.PropertyType);
|
|
|
if (convertVal == null) continue;
|
|
|
|
|
|
T entity = Activator.CreateInstance<T>();
|
|
|
property.SetValue(entity, convertVal);
|
|
|
foreach (var item in updateFields)
|
|
|
{
|
|
|
switch (item.Name.ToLower())
|
|
|
{
|
|
|
case "auditid":
|
|
|
item.SetValue(entity, userInfo.User_Id);
|
|
|
break;
|
|
|
case "auditstatus":
|
|
|
item.SetValue(entity, auditStatus);
|
|
|
break;
|
|
|
case "auditor":
|
|
|
item.SetValue(entity, userInfo.UserTrueName);
|
|
|
break;
|
|
|
case "auditdate":
|
|
|
item.SetValue(entity, DateTime.Now);
|
|
|
break;
|
|
|
case "auditreason":
|
|
|
item.SetValue(entity, auditReason);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
auditList.Add(entity);
|
|
|
}
|
|
|
if (base.AuditOnExecuting != null)
|
|
|
{
|
|
|
Response = AuditOnExecuting(auditList);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
repository.UpdateRange(auditList, updateFields.Select(x => x.Name).ToArray(), true);
|
|
|
if (base.AuditOnExecuted != null)
|
|
|
{
|
|
|
Response = AuditOnExecuted(auditList);
|
|
|
if (!Response.Status) return Response;
|
|
|
}
|
|
|
return Response.OK(ResponseType.AuditSuccess);
|
|
|
}
|
|
|
|
|
|
public virtual WebResponseContent PushStatus(object[] keys, int execution, string reason) {
|
|
|
|
|
|
return Response.Error("未指定的执行参数【"+ execution + "】!");
|
|
|
}
|
|
|
|
|
|
public virtual WebResponseContent SaveAndPushStatus(SaveModel saveDataModel)
|
|
|
{
|
|
|
|
|
|
return Response.Error("未指定的执行参数【" + saveDataModel.GetExection() + "】!");
|
|
|
}
|
|
|
|
|
|
public virtual (string, T, bool) ApiValidate(string bizContent, Expression<Func<T, object>> expression = null)
|
|
|
{
|
|
|
return ApiValidateInput<T>(bizContent, expression);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 对指定类与api的参数进行验证
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TInput"></typeparam>
|
|
|
/// <param name="bizContent"></param>
|
|
|
/// <param name="input"></param>
|
|
|
/// <param name="expression">对指属性验证</param>
|
|
|
/// <returns>(string,TInput, bool) string:返回验证消息,TInput:bizContent序列化后的对象,bool:验证是否通过</returns>
|
|
|
public virtual (string, TInput, bool) ApiValidateInput<TInput>(string bizContent, Expression<Func<TInput, object>> expression)
|
|
|
{
|
|
|
return ApiValidateInput(bizContent, expression, null);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TInput"></typeparam>
|
|
|
/// <param name="bizContent"></param>
|
|
|
/// <param name="expression">对指属性验证格式如:x=>new { x.UserName,x.Value }</param>
|
|
|
/// <param name="validateExpression">对指定的字段只做合法性判断比如长度是是否超长</param>
|
|
|
/// <returns>(string,TInput, bool) string:返回验证消息,TInput:bizContent序列化后的对象,bool:验证是否通过</returns>
|
|
|
public virtual (string, TInput, bool) ApiValidateInput<TInput>(string bizContent, Expression<Func<TInput, object>> expression, Expression<Func<TInput, object>> validateExpression)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
TInput input = JsonConvert.DeserializeObject<TInput>(bizContent);
|
|
|
if (!(input is System.Collections.IList))
|
|
|
{
|
|
|
Response = input.ValidationEntity(expression, validateExpression);
|
|
|
return (Response.Message, input, Response.Status);
|
|
|
}
|
|
|
System.Collections.IList list = input as System.Collections.IList;
|
|
|
for (int i = 0; i < list.Count; i++)
|
|
|
{
|
|
|
Response = list[i].ValidationEntity(expression?.GetExpressionProperty(),
|
|
|
validateExpression?.GetExpressionProperty());
|
|
|
if (!Response.Status)
|
|
|
return (Response.Message, default(TInput), false);
|
|
|
}
|
|
|
return ("", input, true);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
Response.Status = false;
|
|
|
Response.Message = ApiMessage.ParameterError;
|
|
|
Logger.Error(LoggerType.HandleError, bizContent, null, ex.Message);
|
|
|
}
|
|
|
return (Response.Message, default(TInput), Response.Status);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将数据源映射到新的数据中,目前只支持List<TSource>映射到List<TResult>或TSource映射到TResult
|
|
|
/// 目前只支持Dictionary或实体类型
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TSource"></typeparam>
|
|
|
/// <typeparam name="TResult"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="resultExpression">只映射返回对象的指定字段</param>
|
|
|
/// <param name="sourceExpression">只映射数据源对象的指定字段</param>
|
|
|
/// 过滤条件表达式调用方式:List表达式x => new { x[0].MenuName, x[0].Menu_Id},表示指定映射MenuName,Menu_Id字段
|
|
|
/// List<Sys_Menu> list = new List<Sys_Menu>();
|
|
|
/// list.MapToObject<List<Sys_Menu>, List<Sys_Menu>>(x => new { x[0].MenuName, x[0].Menu_Id}, null);
|
|
|
///
|
|
|
///过滤条件表达式调用方式:实体表达式x => new { x.MenuName, x.Menu_Id},表示指定映射MenuName,Menu_Id字段
|
|
|
/// Sys_Menu sysMenu = new Sys_Menu();
|
|
|
/// sysMenu.MapToObject<Sys_Menu, Sys_Menu>(x => new { x.MenuName, x.Menu_Id}, null);
|
|
|
/// <returns></returns>
|
|
|
public virtual TResult MapToEntity<TSource, TResult>(TSource source, Expression<Func<TResult, object>> resultExpression,
|
|
|
Expression<Func<TSource, object>> sourceExpression = null) where TResult : class
|
|
|
{
|
|
|
return source.MapToObject<TSource, TResult>(resultExpression, sourceExpression);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将一个实体的赋到另一个实体上,应用场景:
|
|
|
/// 两个实体,a a1= new a();b b1= new b(); a1.P=b1.P; a1.Name=b1.Name;
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TSource"></typeparam>
|
|
|
/// <typeparam name="TResult"></typeparam>
|
|
|
/// <param name="source"></param>
|
|
|
/// <param name="result"></param>
|
|
|
/// <param name="expression">指定对需要的字段赋值,格式x=>new {x.Name,x.P},返回的结果只会对Name与P赋值</param>
|
|
|
public virtual void MapValueToEntity<TSource, TResult>(TSource source, TResult result, Expression<Func<TResult, object>> expression = null) where TResult : class
|
|
|
{
|
|
|
source.MapValueToEntity<TSource, TResult>(result, expression);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 处理扩展的子列表数据 返回addList和updateList
|
|
|
/// 子表当中与父表连接的字段需增加 【ParentId属性】 ,
|
|
|
/// 如一个子表关联多个子表,需要在属性中添加父表名字;如只关联一个父表,可以传空字符串进去
|
|
|
/// 在调用时,如不传表名,将会取得子表中第一个包含【ParentId属性】的字段
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TDetail"></typeparam>
|
|
|
/// <param name="BodyList"></param>
|
|
|
/// <returns></returns>
|
|
|
public static List<List<TDetail>> DealBodyList<TDetail>(object MainKeyValue, List<TDetail> BodyList, string HeadTableName="")
|
|
|
{
|
|
|
|
|
|
PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty();
|
|
|
|
|
|
PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(HeadTableName);
|
|
|
//id=0的默认为新增的数据
|
|
|
List<TDetail> addList = new List<TDetail>();
|
|
|
List<TDetail> updateList = new List<TDetail>();
|
|
|
|
|
|
bool pidisnull(object obj) {
|
|
|
if (obj == null || obj.ToString() == "" || obj.ToString() == "0" || obj.ToString() == "00000000-0000-0000-0000-000000000000")
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
BodyList.ForEach(x =>
|
|
|
{
|
|
|
if (BodyPK.PropertyType == typeof(Guid) || BodyPK.PropertyType == typeof(Guid?))
|
|
|
{
|
|
|
var pkvalue = (Guid)BodyPK.GetValue(x);
|
|
|
if (pkvalue == Guid.Empty)
|
|
|
{
|
|
|
x.SetCreateDefaultVal();
|
|
|
x.SetModifyDefaultVal();
|
|
|
|
|
|
var mk = new Guid(MainKeyValue.ToString());
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if(pidisnull( detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, mk);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
if (pidisnull(detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, MainKeyValue);
|
|
|
}
|
|
|
BodyPK.SetValue(x, Guid.NewGuid());
|
|
|
addList.Add(x);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
updateList.Add(x);
|
|
|
}
|
|
|
}
|
|
|
else if (BodyPK.PropertyType == typeof(string)|| BodyPK.PropertyType == typeof(String))
|
|
|
{
|
|
|
if ((string)BodyPK.GetValue(x) == string.Empty || (string)BodyPK.GetValue(x) == "" || (string)BodyPK.GetValue(x) == null
|
|
|
|
|
|
|| (string)BodyPK.GetValue(x) == "00000000-0000-0000-0000-000000000000"
|
|
|
)
|
|
|
{
|
|
|
x.SetCreateDefaultVal();
|
|
|
x.SetModifyDefaultVal();
|
|
|
|
|
|
var mk = new Guid(MainKeyValue.ToString());
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (pidisnull(detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, mk);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
if (pidisnull(detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, MainKeyValue);
|
|
|
}
|
|
|
BodyPK.SetValue(x, Guid.NewGuid().ToString());
|
|
|
addList.Add(x);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
updateList.Add(x);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (BodyPK.PropertyType == typeof(string))
|
|
|
{
|
|
|
if (string.IsNullOrWhiteSpace((string)BodyPK.GetValue(x)))
|
|
|
{
|
|
|
x.SetCreateDefaultVal();
|
|
|
x.SetModifyDefaultVal();
|
|
|
if (pidisnull(detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, MainKeyValue.ToString());
|
|
|
BodyPK.SetValue(x, Guid.NewGuid().ToString());
|
|
|
addList.Add(x);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
updateList.Add(x);
|
|
|
}
|
|
|
}
|
|
|
else if (BodyPK.PropertyType == typeof(Int32))
|
|
|
{
|
|
|
if ((Int32)BodyPK.GetValue(x) == 0)
|
|
|
{
|
|
|
x.SetCreateDefaultVal();
|
|
|
x.SetModifyDefaultVal();
|
|
|
if (pidisnull(detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, MainKeyValue);
|
|
|
addList.Add(x);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
updateList.Add(x);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
else
|
|
|
{
|
|
|
if ((Int64)BodyPK.GetValue(x) == 0)
|
|
|
{
|
|
|
x.SetCreateDefaultVal();
|
|
|
x.SetModifyDefaultVal();
|
|
|
if (pidisnull(detailMainKey.GetValue(x)))
|
|
|
detailMainKey.SetValue(x, MainKeyValue);
|
|
|
addList.Add(x);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
updateList.Add(x);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
|
|
|
var result = new List<List<TDetail>>();
|
|
|
result.Add(addList);
|
|
|
result.Add(updateList);
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
////当前用户只能操作自己(与下级角色)创建的数据,如:查询、删除、修改等操作(待完)
|
|
|
//private Expression<Func<T, bool>> GetCurrentUserCondition(Type type)
|
|
|
//{
|
|
|
// var userContext = UserContext.Current;
|
|
|
// if (userContext.IsSuperAdmin)
|
|
|
// {
|
|
|
// return null;
|
|
|
// }
|
|
|
// //LimitCurrentUserPermission开启用户权限与代码生成器同时开起了用户权限才会生效
|
|
|
// if (!LimitCurrentUserPermission || !type.GetCustomAttribute<EntityAttribute>().CurrentUserPermission) { return null; }
|
|
|
|
|
|
// //表的创建人字段必须与配置文件appsettings.json中的创建人字段相同(大小写也必须相同)
|
|
|
// string createId = AppSetting.CreateMember.UserIdField;
|
|
|
// if (type.GetProperty(createId) == null)
|
|
|
// {
|
|
|
// return null;
|
|
|
// }
|
|
|
|
|
|
// Expression<Func<T, bool>> whereExpression = createId.CreateExpression<T>(userContext.UserId, LinqExpressionType.Equal);
|
|
|
// List<int> roles = RoleContext.GetAllChildrenIds(userContext.RoleId);
|
|
|
// //没有下级角色的直看当前用户的数据
|
|
|
// if (roles == null || roles.Count == 0)
|
|
|
// {
|
|
|
// return whereExpression;
|
|
|
// }
|
|
|
// // type.GetProperty();
|
|
|
// return null;
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
public virtual String GetBillNo(string OPLBNAME,string RULEBLNO="委托编号",string ACCDATE="")
|
|
|
{
|
|
|
var result = "";
|
|
|
|
|
|
UserInfo userInfo = UserContext.Current.UserInfo;
|
|
|
|
|
|
SqlParameter[] Param =
|
|
|
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@companyid", System.Data.SqlDbType.VarChar), //输出一定要定义字符类型长度 以免报错
|
|
|
};
|
|
|
Param[0].Value = OPLBNAME;
|
|
|
Param[1].Value = RULEBLNO;
|
|
|
Param[2].Value = userInfo.CompanyId.ToString();
|
|
|
|
|
|
|
|
|
List<Dictionary<string,object>> billnoset =
|
|
|
|
|
|
repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO and companyid=@companyid ", Param);
|
|
|
|
|
|
if (billnoset.Count > 0)
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
|
|
|
|
|
|
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
|
|
|
|
|
|
result = DoGetBillNo(billnoset[0], today, ACCDATE, userInfo);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
else {
|
|
|
SqlParameter[] Param2 =
|
|
|
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
|
|
|
};
|
|
|
Param2[0].Value = OPLBNAME;
|
|
|
Param2[1].Value = RULEBLNO;
|
|
|
|
|
|
|
|
|
billnoset = repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO ", Param2);
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
|
|
|
|
|
|
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
|
|
|
|
|
|
result = DoGetBillNo(billnoset[0], today, ACCDATE, userInfo);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#region 董家镇项目串口服务获取单据编号 修改
|
|
|
|
|
|
public virtual String GetDJZBillNo(string OPLBNAME, string RULEBLNO = "委托编号", string ACCDATE = "")
|
|
|
{
|
|
|
var result = "";
|
|
|
|
|
|
|
|
|
|
|
|
SqlParameter[] Param =
|
|
|
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@companyid", System.Data.SqlDbType.VarChar), //输出一定要定义字符类型长度 以免报错
|
|
|
};
|
|
|
Param[0].Value = OPLBNAME;
|
|
|
Param[1].Value = RULEBLNO;
|
|
|
Param[2].Value = "Comcab2d43f60454327af30a131fc1d3abd";
|
|
|
|
|
|
|
|
|
List<Dictionary<string, object>> billnoset =
|
|
|
|
|
|
repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO and companyid=@companyid ", Param);
|
|
|
|
|
|
if (billnoset.Count > 0)
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
|
|
|
|
|
|
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
|
|
|
|
|
|
result = DoGetBillNoDJZ(billnoset[0], today, ACCDATE);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SqlParameter[] Param2 =
|
|
|
{ new SqlParameter("@OPLBNAME", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@RULEBLNO", System.Data.SqlDbType.VarChar),
|
|
|
};
|
|
|
Param2[0].Value = OPLBNAME;
|
|
|
Param2[1].Value = RULEBLNO;
|
|
|
|
|
|
|
|
|
billnoset = repository.Exec($"SELECT GID,OPLBNAME,RULEBLNO,RULEDATETYPE,BILLTYPE,COMPANYID,ISEDIT,ISAUTO,CUSTOMHEAD ,(select BillName from tSysBillType where BillCode=sys_billno_set.BILLTYPE) BILLTYPEREF from sys_billno_set where oplbname=@OPLBNAME and ruleblno=@RULEBLNO ", Param2);
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(billnoset[0]["BILLTYPE"].ToString())) return "";
|
|
|
|
|
|
var today = DateTime.Now.AddDays(0).ToString("yyyy-MM-dd");
|
|
|
|
|
|
result = DoGetBillNoDJZ(billnoset[0], today, ACCDATE);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
private string DoGetBillNoDJZ(Dictionary<string, object> billType, string bsdate, string accdate)
|
|
|
{
|
|
|
var orgCode = "Comcab2d43f60454327af30a131fc1d3abd";
|
|
|
var UserCode = "EC269890-F167-454D-AD00-5424BE1C6D06";
|
|
|
|
|
|
var _paramdata = "";
|
|
|
|
|
|
|
|
|
if (billType["RULEDATETYPE"].ToString() == "业务日期")
|
|
|
{
|
|
|
_paramdata = bsdate;
|
|
|
}
|
|
|
if (billType["RULEDATETYPE"].ToString() == "会计期间")
|
|
|
{
|
|
|
_paramdata = accdate;
|
|
|
}
|
|
|
SqlParameter[] Param =
|
|
|
{
|
|
|
//new SqlParameter("@ps_BillType", $"'{billType["BILLTYPE"].ToString()}'"),
|
|
|
//new SqlParameter("@ps_OrgCode", $"'{orgCode}'"),
|
|
|
//new SqlParameter("@ps_EmpCode", $"'{UserCode}'"),
|
|
|
//new SqlParameter("@ps_Date", $"'{_paramdata}'"),
|
|
|
new SqlParameter("@ps_BillType", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_OrgCode", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_EmpCode", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_Date", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_bshead", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_BillNo", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_RefBillNo", System.Data.SqlDbType.VarChar),
|
|
|
};
|
|
|
Param[0].Value = billType["BILLTYPE"].ToString();
|
|
|
Param[1].Value = orgCode;
|
|
|
Param[2].Value = UserCode;
|
|
|
Param[3].Value = _paramdata;
|
|
|
Param[4].Value = "";
|
|
|
Param[5].Value = "";
|
|
|
Param[6].Value = "";
|
|
|
|
|
|
var resultdic = repository.ExecSp("sSysGetBillNo_new", Param);
|
|
|
|
|
|
var result = resultdic[0]["BillNo"].ToString();
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
private string DoGetBillNo(Dictionary<string, object> billType, string bsdate, string accdate, UserInfo userInfo)
|
|
|
{
|
|
|
var orgCode = userInfo.CompanyId.ToString();
|
|
|
var UserCode = userInfo.User_Id.ToString();
|
|
|
|
|
|
var _paramdata = "";
|
|
|
|
|
|
|
|
|
if (billType["RULEDATETYPE"].ToString() == "业务日期") {
|
|
|
_paramdata = bsdate;
|
|
|
}
|
|
|
if (billType["RULEDATETYPE"].ToString() == "会计期间")
|
|
|
{
|
|
|
_paramdata = accdate;
|
|
|
}
|
|
|
SqlParameter[] Param =
|
|
|
{
|
|
|
//new SqlParameter("@ps_BillType", $"'{billType["BILLTYPE"].ToString()}'"),
|
|
|
//new SqlParameter("@ps_OrgCode", $"'{orgCode}'"),
|
|
|
//new SqlParameter("@ps_EmpCode", $"'{UserCode}'"),
|
|
|
//new SqlParameter("@ps_Date", $"'{_paramdata}'"),
|
|
|
new SqlParameter("@ps_BillType", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_OrgCode", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_EmpCode", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_Date", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_bshead", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_BillNo", System.Data.SqlDbType.VarChar),
|
|
|
new SqlParameter("@ps_RefBillNo", System.Data.SqlDbType.VarChar),
|
|
|
};
|
|
|
Param[0].Value = billType["BILLTYPE"].ToString();
|
|
|
Param[1].Value = orgCode;
|
|
|
Param[2].Value = UserCode;
|
|
|
Param[3].Value = _paramdata;
|
|
|
Param[4].Value = "";
|
|
|
Param[5].Value = "";
|
|
|
Param[6].Value = "";
|
|
|
|
|
|
var resultdic = repository.ExecSp("sSysGetBillNo_new", Param);
|
|
|
|
|
|
var result = resultdic[0]["BillNo"].ToString();
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private object GetPropertyValue(T entity, string propertyName)
|
|
|
{
|
|
|
object result = null;
|
|
|
|
|
|
Type entityType = typeof(T);
|
|
|
try
|
|
|
{
|
|
|
PropertyInfo proInfo = entityType.GetProperty(propertyName);
|
|
|
result = proInfo.GetValue(entity);
|
|
|
}
|
|
|
catch (Exception)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
public void wms_add<toT,fromT>(ref toT tot, fromT fromt)
|
|
|
where fromT:class , new()
|
|
|
where toT:class
|
|
|
{
|
|
|
fieldadd(ref tot, fromt, "KGS");
|
|
|
fieldadd(ref tot, fromt, "NETWEIGHT");
|
|
|
fieldadd(ref tot, fromt, "CBM");
|
|
|
fieldadd(ref tot, fromt, "PKGS");
|
|
|
fieldadd(ref tot, fromt, "STORAGEUNITCOUNT");
|
|
|
fieldadd(ref tot, fromt, "RULEUNITCOUNT");
|
|
|
fieldadd(ref tot, fromt, "SMALLPKGS");
|
|
|
fieldadd(ref tot, fromt, "MINPKGS");
|
|
|
}
|
|
|
|
|
|
public void wms_cut<toT, fromT>(ref toT tot, fromT fromt)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
fieldcut(ref tot, fromt, "KGS");
|
|
|
fieldcut(ref tot, fromt, "NETWEIGHT");
|
|
|
fieldcut(ref tot, fromt, "CBM");
|
|
|
fieldcut(ref tot, fromt, "PKGS");
|
|
|
fieldcut(ref tot, fromt, "STORAGEUNITCOUNT");
|
|
|
fieldcut(ref tot, fromt, "RULEUNITCOUNT");
|
|
|
fieldcut(ref tot, fromt, "SMALLPKGS");
|
|
|
fieldcut(ref tot, fromt, "MINPKGS");
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将与数量相关的6个字段从后赋值到前
|
|
|
/// (KGS PKGS CBM NETWEIGHT STORAGEUNITCOUNT RULEUNITCOUNT)
|
|
|
/// </summary>
|
|
|
/// <typeparam name="toT"></typeparam>
|
|
|
/// <typeparam name="fromT"></typeparam>
|
|
|
/// <param name="tot"></param>
|
|
|
/// <param name="fromt"></param>
|
|
|
public void wms_copy<toT, fromT>(ref toT tot, fromT fromt)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
fieldcopy(ref tot, fromt, "KGS");
|
|
|
fieldcopy(ref tot, fromt, "NETWEIGHT");
|
|
|
fieldcopy(ref tot, fromt, "CBM");
|
|
|
fieldcopy(ref tot, fromt, "PKGS");
|
|
|
fieldcopy(ref tot, fromt, "STORAGEUNITCOUNT");
|
|
|
fieldcopy(ref tot, fromt, "RULEUNITCOUNT");
|
|
|
fieldcopy(ref tot, fromt, "SMALLPKGS");
|
|
|
fieldcopy(ref tot, fromt, "MINPKGS");
|
|
|
}
|
|
|
|
|
|
public void wms_getPkgs<toT, fromT>(ref toT tot, fromT fromt,decimal NEWPKGS =1m)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
var OLDPKGS = fieldGetValue(fromt, "PKGS");
|
|
|
var bili = NEWPKGS / OLDPKGS;
|
|
|
|
|
|
//fieldcopy(ref tot, fromt, "KGS");
|
|
|
//fieldcopy(ref tot, fromt, "NETWEIGHT");
|
|
|
//fieldcopy(ref tot, fromt, "CBM");
|
|
|
//fieldcopy(ref tot, fromt, "PKGS");
|
|
|
//fieldcopy(ref tot, fromt, "STORAGEUNITCOUNT");
|
|
|
//fieldcopy(ref tot, fromt, "RULEUNITCOUNT");
|
|
|
|
|
|
var NewKGS = fieldGetValue(fromt, "KGS") * bili;
|
|
|
var NewNETWEIGHT = fieldGetValue(fromt, "NETWEIGHT") * bili;
|
|
|
var NewCBM = fieldGetValue(fromt, "CBM") * bili;
|
|
|
var NewSTORAGEUNITCOUNT = fieldGetValue(fromt, "STORAGEUNITCOUNT") * bili;
|
|
|
var NewRULEUNITCOUNT = fieldGetValue(fromt, "RULEUNITCOUNT") * bili;
|
|
|
var NewSMALLPKGS = fieldGetValue(fromt, "SMALLPKGS") * bili;
|
|
|
var NewMINPKGS = fieldGetValue(fromt, "MINPKGS") * bili;
|
|
|
|
|
|
fieldSetValue(tot, "KGS", NewKGS);
|
|
|
fieldSetValue(tot, "NETWEIGHT", NewNETWEIGHT);
|
|
|
fieldSetValue(tot, "CBM", NewCBM);
|
|
|
//fieldSetValue(tot, "PKGS");
|
|
|
fieldSetValue(tot, "STORAGEUNITCOUNT", NewSTORAGEUNITCOUNT);
|
|
|
fieldSetValue(tot, "RULEUNITCOUNT", NewRULEUNITCOUNT);
|
|
|
fieldSetValue(tot, "SMALLPKGS", NewSMALLPKGS);
|
|
|
fieldSetValue(tot, "MINPKGS", NewMINPKGS);
|
|
|
}
|
|
|
public void wms_getStorageunitcount<toT, fromT>(ref toT tot, fromT fromt, decimal NEWSTORAGEUNITCOUNT = 1m)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
var OLDSTORAGEUNITCOUNT = fieldGetValue(fromt, "STORAGEUNITCOUNT");
|
|
|
var bili = NEWSTORAGEUNITCOUNT / OLDSTORAGEUNITCOUNT;
|
|
|
|
|
|
//fieldcopy(ref tot, fromt, "KGS");
|
|
|
//fieldcopy(ref tot, fromt, "NETWEIGHT");
|
|
|
//fieldcopy(ref tot, fromt, "CBM");
|
|
|
//fieldcopy(ref tot, fromt, "PKGS");
|
|
|
//fieldcopy(ref tot, fromt, "STORAGEUNITCOUNT");
|
|
|
//fieldcopy(ref tot, fromt, "RULEUNITCOUNT");
|
|
|
|
|
|
var NewKGS = fieldGetValue(fromt, "KGS") * bili;
|
|
|
var NewNETWEIGHT = fieldGetValue(fromt, "NETWEIGHT") * bili;
|
|
|
var NewCBM = fieldGetValue(fromt, "CBM") * bili;
|
|
|
//var NewSTORAGEUNITCOUNT = fieldGetValue(fromt, "STORAGEUNITCOUNT") * bili;
|
|
|
var NewPKGS = Math.Floor( fieldGetValue(fromt, "PKGS") * bili);
|
|
|
var NewRULEUNITCOUNT = fieldGetValue(fromt, "RULEUNITCOUNT") * bili;
|
|
|
var NewSMALLPKGS = fieldGetValue(fromt, "SMALLPKGS") * bili;
|
|
|
var NewMINPKGS = fieldGetValue(fromt, "MINPKGS") * bili;
|
|
|
|
|
|
fieldSetValue(tot, "KGS", NewKGS);
|
|
|
fieldSetValue(tot, "NETWEIGHT", NewNETWEIGHT);
|
|
|
fieldSetValue(tot, "CBM", NewCBM);
|
|
|
fieldSetValue(tot, "PKGS", NewPKGS);
|
|
|
fieldSetValue(tot, "STORAGEUNITCOUNT", NEWSTORAGEUNITCOUNT);
|
|
|
fieldSetValue(tot, "RULEUNITCOUNT", NewRULEUNITCOUNT);
|
|
|
fieldSetValue(tot, "SMALLPKGS", NewSMALLPKGS);
|
|
|
fieldSetValue(tot, "MINPKGS", NewMINPKGS);
|
|
|
}
|
|
|
public void wms_new<toT>(ref toT tot)
|
|
|
where toT : class
|
|
|
{
|
|
|
fieldSetValue(tot, "KGS");
|
|
|
fieldSetValue(tot, "NETWEIGHT");
|
|
|
fieldSetValue(tot, "CBM");
|
|
|
fieldSetValue(tot, "PKGS");
|
|
|
fieldSetValue(tot, "STORAGEUNITCOUNT");
|
|
|
fieldSetValue(tot, "RULEUNITCOUNT");
|
|
|
fieldSetValue(tot, "SMALLPKGS");
|
|
|
fieldSetValue(tot, "MINPKGS");
|
|
|
}
|
|
|
|
|
|
public bool wms_isequal<toT, fromT>(toT tot, fromT fromt)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
return fieldisequal(tot, fromt, "KGS")&& fieldisequal(tot, fromt, "NETWEIGHT") && fieldisequal(tot, fromt, "CBM") && fieldisequal(tot, fromt, "PKGS")&& fieldisequal(tot, fromt, "STORAGEUNITCOUNT") && fieldisequal(tot, fromt, "RULEUNITCOUNT");
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 前方tot大于后面的fromt
|
|
|
/// </summary>
|
|
|
/// <typeparam name="toT"></typeparam>
|
|
|
/// <typeparam name="fromT"></typeparam>
|
|
|
/// <param name="tot"></param>
|
|
|
/// <param name="fromt"></param>
|
|
|
/// <returns></returns>
|
|
|
public bool wms_isBig<toT, fromT>(toT tot, fromT fromt)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
return fieldisBig(tot, fromt, "KGS") || fieldisBig(tot, fromt, "NETWEIGHT") || fieldisBig(tot, fromt, "CBM") || fieldisBig(tot, fromt, "PKGS") || fieldisBig(tot, fromt, "STORAGEUNITCOUNT") || fieldisBig(tot, fromt, "RULEUNITCOUNT");
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 两个对象的指定字段相加,后者加入到前者内。
|
|
|
/// </summary>
|
|
|
/// <typeparam name="fromT"></typeparam>
|
|
|
/// <param name="tot"></param>
|
|
|
/// <param name="fromt"></param>
|
|
|
/// <param name="fieldname"></param>
|
|
|
public void fieldadd<toT,fromT>(ref toT tot, fromT fromt,string fieldname)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
Type entityType = typeof(toT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);//(decimal)to_proInfo.GetValue(tot);
|
|
|
|
|
|
Type fromType = typeof(fromT);
|
|
|
PropertyInfo profrom = fromType.GetProperty(fieldname);
|
|
|
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
|
|
|
|
|
|
to_proInfo.SetValue(tot, tofield + fromfield);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 两个对象的指定字段相减,从前者内去掉后者。
|
|
|
/// </summary>
|
|
|
/// <typeparam name="fromT"></typeparam>
|
|
|
/// <param name="tot"></param>
|
|
|
/// <param name="fromt"></param>
|
|
|
/// <param name="fieldname"></param>
|
|
|
public void fieldcut<toT, fromT>(ref toT tot, fromT fromt, string fieldname)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
Type entityType = typeof(toT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);//(decimal)to_proInfo.GetValue(tot);
|
|
|
|
|
|
Type fromType = typeof(fromT);
|
|
|
PropertyInfo profrom = fromType.GetProperty(fieldname);
|
|
|
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
|
|
|
|
|
|
to_proInfo.SetValue(tot, tofield - fromfield);
|
|
|
}
|
|
|
|
|
|
public void fieldcopy<toT, fromT>(ref toT tot, fromT fromt, string fieldname)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
Type entityType = typeof(toT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
//var tofield = (decimal)to_proInfo.GetValue(tot);
|
|
|
|
|
|
Type fromType = typeof(fromT);
|
|
|
PropertyInfo profrom = fromType.GetProperty(fieldname);
|
|
|
var fromfield = profrom.GetValue(fromt)==null?0: (decimal)profrom.GetValue(fromt);
|
|
|
|
|
|
to_proInfo.SetValue(tot, fromfield);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 相同
|
|
|
/// </summary>
|
|
|
/// <typeparam name="toT"></typeparam>
|
|
|
/// <typeparam name="fromT"></typeparam>
|
|
|
/// <param name="tot"></param>
|
|
|
/// <param name="fromt"></param>
|
|
|
/// <param name="fieldname"></param>
|
|
|
/// <returns></returns>
|
|
|
public bool fieldisequal<toT, fromT>(toT tot, fromT fromt, string fieldname)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
Type entityType = typeof(toT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);//(decimal)to_proInfo.GetValue(tot);
|
|
|
|
|
|
Type fromType = typeof(fromT);
|
|
|
PropertyInfo profrom = fromType.GetProperty(fieldname);
|
|
|
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
|
|
|
|
|
|
return (tofield == fromfield);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 较大
|
|
|
/// </summary>
|
|
|
/// <typeparam name="toT"></typeparam>
|
|
|
/// <typeparam name="fromT"></typeparam>
|
|
|
/// <param name="tot"></param>
|
|
|
/// <param name="fromt"></param>
|
|
|
/// <param name="fieldname"></param>
|
|
|
/// <returns></returns>
|
|
|
public bool fieldisBig<toT, fromT>(toT tot, fromT fromt, string fieldname)
|
|
|
where fromT : class, new()
|
|
|
where toT : class
|
|
|
{
|
|
|
Type entityType = typeof(toT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
var tofield = to_proInfo.GetValue(tot) == null ? 0 : (decimal)to_proInfo.GetValue(tot);// (decimal)to_proInfo.GetValue(tot);
|
|
|
|
|
|
Type fromType = typeof(fromT);
|
|
|
PropertyInfo profrom = fromType.GetProperty(fieldname);
|
|
|
var fromfield = profrom.GetValue(fromt) == null ? 0 : (decimal)profrom.GetValue(fromt);//(decimal)profrom.GetValue(fromt);
|
|
|
|
|
|
return (tofield > fromfield);
|
|
|
}
|
|
|
|
|
|
public void fieldSetValue<toT>(toT tot, string fieldname,decimal value=0)
|
|
|
where toT : class
|
|
|
{
|
|
|
Type entityType = typeof(toT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
to_proInfo.SetValue(tot, value);
|
|
|
|
|
|
}
|
|
|
public decimal fieldGetValue<fromT>(fromT fromt, string fieldname, decimal value = 0)
|
|
|
where fromT : class
|
|
|
{
|
|
|
Type entityType = typeof(fromT);
|
|
|
PropertyInfo to_proInfo = entityType.GetProperty(fieldname);
|
|
|
return to_proInfo.GetValue(fromt) == null ? 0 : (decimal)to_proInfo.GetValue(fromt);
|
|
|
}
|
|
|
|
|
|
public void RemoveSearchParam(ref List<SearchParameters> parameters,string FieldName) {
|
|
|
|
|
|
for (var _i = parameters.Count - 1; _i >= 0; _i--)
|
|
|
{
|
|
|
if (parameters[_i].Name == FieldName)
|
|
|
parameters.Remove(parameters[_i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public Expression<Func<T, bool>> GetOrExpression(string FieldName, string paramStr) {
|
|
|
Expression<Func<T, bool>> _true = x => 1 == 1;
|
|
|
if (!string.IsNullOrWhiteSpace(paramStr))
|
|
|
{
|
|
|
var _paramlist = paramStr.Split(",");
|
|
|
var paramlist = new List<string>();
|
|
|
foreach (var item in _paramlist) {
|
|
|
if (!string.IsNullOrWhiteSpace(item.Trim())) {
|
|
|
paramlist.Add(item);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (paramlist == null || paramlist.Count == 0) {
|
|
|
return _true;
|
|
|
}
|
|
|
|
|
|
//if (paramlist.Count() == 1)
|
|
|
//{
|
|
|
// Expression<Func<T, bool>> _oneParam = FieldName.CreateExpression<T>(paramlist[0].ToString(), LinqExpressionType.Contains);
|
|
|
// return _oneParam;
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
//PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault();
|
|
|
Expression<Func<T, bool>> expre = FieldName.CreateExpression<T>(paramlist[0].ToString(), LinqExpressionType.Contains);
|
|
|
foreach (var param in paramlist)
|
|
|
{
|
|
|
if (param == paramlist[0]) continue;
|
|
|
expre = ExpressionFuncExtender.Or(expre, FieldName.CreateExpression<T>(param.ToString(), LinqExpressionType.Contains));
|
|
|
}
|
|
|
return expre;
|
|
|
//}
|
|
|
}
|
|
|
else {
|
|
|
|
|
|
return _true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将查询条件中的指定字段 改为指定形式
|
|
|
/// 默认改为startwith的形式
|
|
|
/// </summary>
|
|
|
/// <param name="options"></param>
|
|
|
/// <param name="FieldName"></param>
|
|
|
public void SetFieldSearchType(ref PageDataOptions options, string FieldName,string newtype="StartWith") {
|
|
|
try
|
|
|
{
|
|
|
var searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
|
|
|
|
|
|
if (searchParametersList.Exists(x => x.Name == FieldName))
|
|
|
{
|
|
|
searchParametersList.First(x => x.Name == FieldName).SearchType = newtype;
|
|
|
}
|
|
|
|
|
|
options.Wheres = Newtonsoft.Json.JsonConvert.SerializeObject(searchParametersList);
|
|
|
}
|
|
|
catch { }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public class SaveResult:object {
|
|
|
public object data { get; set; }
|
|
|
public object message { get; set; }
|
|
|
public bool status { get; set; }
|
|
|
|
|
|
public SaveResult(object Data, string Message="",bool Status= true) {
|
|
|
data = Data;
|
|
|
message = Message;
|
|
|
status = Status;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 基础工具类
|
|
|
/// 通用工具类
|
|
|
/// </summary>
|
|
|
public static class BasicDataRef {
|
|
|
/// <summary>
|
|
|
/// 返回两个时间的间隔天数之差+1
|
|
|
/// 如
|
|
|
/// </summary>
|
|
|
/// <param name="dt1"></param>
|
|
|
/// <param name="dt2"></param>
|
|
|
/// <returns></returns>
|
|
|
public static decimal days(DateTime dt1, DateTime dt2)
|
|
|
{
|
|
|
TimeSpan ts = dt2.Subtract(dt1);
|
|
|
if (ts.TotalDays < 0) ts = dt1.Subtract(dt2);
|
|
|
return decimal.Parse(Math.Floor(ts.TotalDays + 1).ToString());
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通过公司ID获取公司名称
|
|
|
/// </summary>
|
|
|
/// <param name="companyid"></param>
|
|
|
/// <returns></returns>
|
|
|
public static string getCompanyFullName(string companyid) {
|
|
|
var companydiclist = DBServerProvider.SqlDapper.QueryList<SourceKeyVaule>("select GID [key],fullname [value] from company ", null)
|
|
|
.Where(x => (x.Key).ToString() == companyid)
|
|
|
.Select(s => new Sys_DictionaryList()
|
|
|
{
|
|
|
DicName = s.Value,
|
|
|
DicValue = s.Key.ToString()
|
|
|
}).ToList();
|
|
|
|
|
|
var companydic = companydiclist[0];
|
|
|
|
|
|
return companydic.DicName;
|
|
|
}
|
|
|
|
|
|
public static CompanyField getCompany(string companyid)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var companydiclist = DBServerProvider.SqlDapper.QueryList<CompanyField>("select [GID],[CODENAME],[NAME],[FULLNAME],[ENNAME],[ADDRESS],[ENADDRESS],[POSTCODE],[OFFICEPHONE],[FAX],[EMAIL],[WEBSITEURL],[LICENSECODE],[TAXCODE],[LOGO],[CREATEUSER],[CREATETIME],[MODIFIEDUSER],[MODIFIEDTIME],[ISDELETED],[ISDISABLE],[PARENTID],[BILLRISES],[CHEQUEPAYABLE],[PRTHEADXML1],[PRTHEADXML2],[PRTHEADXML3],[PRTHEADXML4],[PRTHEADXML5],[BANKSHEAD],[GPSUser],[GPSPassWord],[ORGANIZATIONCODE],[DBNAME],[LOCALCURR],[WORKFLOWMSG],[openCustom],[allowOpenMark2],[TRADE_CODE],[UNIT],[VGMCODE],[bxid],[CLOSEETDDAY],MANAGER from company ", null)
|
|
|
.Where(x => (x.GID).ToString() == companyid)
|
|
|
.ToList();
|
|
|
|
|
|
var company = companydiclist[0];
|
|
|
|
|
|
return company;
|
|
|
}
|
|
|
catch (Exception e) {
|
|
|
return new CompanyField();
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 消息实体
|
|
|
/// </summary>
|
|
|
public class NoticeInput
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 标题
|
|
|
/// </summary>
|
|
|
public string Title { get; set; }
|
|
|
/// <summary>
|
|
|
/// 公司Id
|
|
|
/// </summary>
|
|
|
public string CompanyId { get; set; }
|
|
|
/// <summary>
|
|
|
/// 内容
|
|
|
/// </summary>
|
|
|
public string Content { get; set; }
|
|
|
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 发送系统消息
|
|
|
/// </summary>
|
|
|
/// <param name="notice"></param>
|
|
|
public static void SendSysNotice(NoticeInput input)
|
|
|
{
|
|
|
var Gid = Guid.NewGuid();
|
|
|
var notice = new Sys_Announcement
|
|
|
{
|
|
|
Gid = Gid,
|
|
|
Title = input.Title,
|
|
|
AnnouncementType = 2,//系统消息
|
|
|
ReceiveType = 2,//指定用户
|
|
|
Abstract = input.Content,
|
|
|
Content = input.Content,
|
|
|
SendStatus = 1,
|
|
|
EndTime = DateTime.Now.AddMonths(1),
|
|
|
SendTime = DateTime.Now,
|
|
|
Status = 0,
|
|
|
CreateDate = DateTime.Now,
|
|
|
CreateID = Guid.Parse("1BEC90E1-9780-472F-90C2-0C6390C044A4"),
|
|
|
Creator = "系统管理员",
|
|
|
};
|
|
|
DBServerProvider.SqlDapper.Add(notice);
|
|
|
|
|
|
var relation = new Sys_AnnouncementCompany
|
|
|
{
|
|
|
AnnouncementId = Gid,
|
|
|
CompanyId = input.CompanyId,
|
|
|
IsRead = false,
|
|
|
};
|
|
|
DBServerProvider.SqlDapper.Add(relation);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取某一字符串第N到第N+1空格的字符
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public static Func<int, int, string, string, string> GetStrOfStringInBlankIndex()
|
|
|
{
|
|
|
return (x, y, z, f) =>
|
|
|
{
|
|
|
int start = GetBlankIndexOfString()(x, z, f);
|
|
|
int end = GetBlankIndexOfString()(y, z, f);
|
|
|
string str = f.Substring(start, end - start);
|
|
|
return str;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取第N个空格所在
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public static Func<int, string, string, int> GetBlankIndexOfString()
|
|
|
{
|
|
|
return (x, y, z) =>
|
|
|
{
|
|
|
int result = 0, index = 0;
|
|
|
string str = z;
|
|
|
for (int i = 0; i < x; i++)
|
|
|
{
|
|
|
index = str.IndexOf(y);
|
|
|
str = str.Substring(index, str.Length - index).TrimStart();
|
|
|
result = z.LastIndexOf(str);
|
|
|
}
|
|
|
return result;
|
|
|
};
|
|
|
}
|
|
|
|
|
|
public static string GetSqlIDList(List<string> strlist) {
|
|
|
var result = "'" + string.Join("','", strlist.ToArray()) + "'" ;
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
|
|
|
public static long ConvertDateTimeToInt(DateTime time)
|
|
|
{
|
|
|
DateTimeOffset dto = new DateTimeOffset(time);
|
|
|
return dto.ToUnixTimeMilliseconds();
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// AutoMapper的帮助类
|
|
|
/// </summary>
|
|
|
public static class AutoMapperHelper
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 来源,目标
|
|
|
/// 单条实体类型映射,默认字段名字一一对应
|
|
|
///
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TSource">Dto类型</typeparam>
|
|
|
/// <typeparam name="TDestination">要被转化的数据</typeparam>
|
|
|
/// <param name="source">转化之后的实体</param>
|
|
|
/// <returns></returns>
|
|
|
public static TDestination MapTo<TSource, TDestination>(this TSource source)
|
|
|
where TDestination : class, new()
|
|
|
where TSource : class
|
|
|
{
|
|
|
if (source == null) return new TDestination();
|
|
|
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
|
|
|
var mapper = config.CreateMapper();
|
|
|
return mapper.Map<TDestination>(source);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 实体列表类型映射,默认字段名字一一对应
|
|
|
/// </summary>
|
|
|
/// <typeparam name="TDestination">Dto类型</typeparam>
|
|
|
/// <typeparam name="TSource">要被转化的数据</typeparam>
|
|
|
/// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
|
|
|
/// <returns>转化之后的实体列表</returns>
|
|
|
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
|
|
|
where TDestination : class
|
|
|
where TSource : class
|
|
|
{
|
|
|
if (source == null) return new List<TDestination>();
|
|
|
var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
|
|
|
var mapper = config.CreateMapper();
|
|
|
return mapper.Map<List<TDestination>>(source);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
public class Query
|
|
|
{
|
|
|
public enum Operators
|
|
|
{
|
|
|
None = 0,
|
|
|
Equal = 1,
|
|
|
GreaterThan = 2,
|
|
|
GreaterThanOrEqual = 3,
|
|
|
LessThan = 4,
|
|
|
LessThanOrEqual = 5,
|
|
|
Contains = 6,
|
|
|
StartWith = 7,
|
|
|
EndWidth = 8,
|
|
|
Range = 9,
|
|
|
NotEqual=10
|
|
|
}
|
|
|
public enum Condition
|
|
|
{
|
|
|
OrElse = 1,
|
|
|
AndAlso = 2
|
|
|
}
|
|
|
public string Name { get; set; }
|
|
|
public Operators Operator { get; set; }
|
|
|
public object Value { get; set; }
|
|
|
public object ValueMin { get; set; }
|
|
|
public object ValueMax { get; set; }
|
|
|
}
|
|
|
|
|
|
public class QueryCollection : Collection<Query>
|
|
|
{
|
|
|
public Expression<Func<T, bool>> AsExpression<T>(Query.Condition? condition = Query.Condition.OrElse) where T : class
|
|
|
{
|
|
|
Type targetType = typeof(T);
|
|
|
TypeInfo typeInfo = targetType.GetTypeInfo();
|
|
|
var parameter = Expression.Parameter(targetType, "m");
|
|
|
Expression expression = null;
|
|
|
Func<Expression, Expression, Expression> Append = (exp1, exp2) =>
|
|
|
{
|
|
|
if (exp1 == null)
|
|
|
{
|
|
|
return exp2;
|
|
|
}
|
|
|
return (condition ?? Query.Condition.OrElse) == Query.Condition.OrElse ? Expression.OrElse(exp1, exp2) : Expression.AndAlso(exp1, exp2);
|
|
|
};
|
|
|
foreach (var item in this)
|
|
|
{
|
|
|
var property = typeInfo.GetProperty(item.Name);
|
|
|
if (property == null ||
|
|
|
!property.CanRead ||
|
|
|
(item.Operator != Query.Operators.Range && item.Value == null) ||
|
|
|
(item.Operator == Query.Operators.Range && item.ValueMin == null && item.ValueMax == null))
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
Type realType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
|
|
|
if (item.Value != null)
|
|
|
{
|
|
|
item.Value = Convert.ChangeType(item.Value, realType);
|
|
|
}
|
|
|
Expression<Func<object>> valueLamba = () => item.Value;
|
|
|
switch (item.Operator)
|
|
|
{
|
|
|
case Query.Operators.Equal:
|
|
|
{
|
|
|
expression = Append(expression, Expression.Equal(Expression.Property(parameter, item.Name),
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.GreaterThan:
|
|
|
{
|
|
|
expression = Append(expression, Expression.GreaterThan(Expression.Property(parameter, item.Name),
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.GreaterThanOrEqual:
|
|
|
{
|
|
|
expression = Append(expression, Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name),
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.LessThan:
|
|
|
{
|
|
|
expression = Append(expression, Expression.LessThan(Expression.Property(parameter, item.Name),
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.LessThanOrEqual:
|
|
|
{
|
|
|
expression = Append(expression, Expression.LessThanOrEqual(Expression.Property(parameter, item.Name),
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.Contains:
|
|
|
{
|
|
|
var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
|
|
|
var contains = Expression.Call(Expression.Property(parameter, item.Name), "Contains", null,
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType));
|
|
|
expression = Append(expression, Expression.AndAlso(nullCheck, contains));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.StartWith:
|
|
|
{
|
|
|
var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
|
|
|
var startsWith = Expression.Call(Expression.Property(parameter, item.Name), "StartsWith", null,
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType));
|
|
|
expression = Append(expression, Expression.AndAlso(nullCheck, startsWith));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.EndWidth:
|
|
|
{
|
|
|
var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, Expression.Property(parameter, item.Name)));
|
|
|
var endsWith = Expression.Call(Expression.Property(parameter, item.Name), "EndsWith", null,
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType));
|
|
|
expression = Append(expression, Expression.AndAlso(nullCheck, endsWith));
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.Range:
|
|
|
{
|
|
|
Expression minExp = null, maxExp = null;
|
|
|
if (item.ValueMin != null)
|
|
|
{
|
|
|
var minValue = Convert.ChangeType(item.ValueMin, realType);
|
|
|
Expression<Func<object>> minValueLamda = () => minValue;
|
|
|
minExp = Expression.GreaterThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(minValueLamda.Body, property.PropertyType));
|
|
|
}
|
|
|
if (item.ValueMax != null)
|
|
|
{
|
|
|
var maxValue = Convert.ChangeType(item.ValueMax, realType);
|
|
|
Expression<Func<object>> maxValueLamda = () => maxValue;
|
|
|
maxExp = Expression.LessThanOrEqual(Expression.Property(parameter, item.Name), Expression.Convert(maxValueLamda.Body, property.PropertyType));
|
|
|
}
|
|
|
|
|
|
if (minExp != null && maxExp != null)
|
|
|
{
|
|
|
expression = Append(expression, Expression.AndAlso(minExp, maxExp));
|
|
|
}
|
|
|
else if (minExp != null)
|
|
|
{
|
|
|
expression = Append(expression, minExp);
|
|
|
}
|
|
|
else if (maxExp != null)
|
|
|
{
|
|
|
expression = Append(expression, maxExp);
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
case Query.Operators.NotEqual:
|
|
|
{
|
|
|
expression = Append(expression, Expression.NotEqual(Expression.Property(parameter, item.Name),
|
|
|
Expression.Convert(valueLamba.Body, property.PropertyType)));
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (expression == null)
|
|
|
{
|
|
|
return null;
|
|
|
}
|
|
|
return ((Expression<Func<T, bool>>)Expression.Lambda(expression, parameter));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static class ExpressionFuncExtender
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 以特定的条件运行组合两个Expression表达式
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">表达式的主实体类型</typeparam>
|
|
|
/// <param name="first">第一个Expression表达式</param>
|
|
|
/// <param name="second">要组合的Expression表达式</param>
|
|
|
/// <param name="merge">组合条件运算方式</param>
|
|
|
/// <returns>组合后的表达式</returns>
|
|
|
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second,
|
|
|
Func<Expression, Expression, Expression> merge)
|
|
|
{
|
|
|
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
|
|
|
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
|
|
|
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 以 Expression.AndAlso 组合两个Expression表达式
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">表达式的主实体类型</typeparam>
|
|
|
/// <param name="first">第一个Expression表达式</param>
|
|
|
/// <param name="second">要组合的Expression表达式</param>
|
|
|
/// <returns>组合后的表达式</returns>
|
|
|
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first,
|
|
|
Expression<Func<T, bool>> second)
|
|
|
{
|
|
|
return first.Compose(second, Expression.AndAlso);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 以 Expression.OrElse 组合两个Expression表达式
|
|
|
/// </summary>
|
|
|
/// <typeparam name="T">表达式的主实体类型</typeparam>
|
|
|
/// <param name="first">第一个Expression表达式</param>
|
|
|
/// <param name="second">要组合的Expression表达式</param>
|
|
|
/// <returns>组合后的表达式</returns>
|
|
|
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first,
|
|
|
Expression<Func<T, bool>> second)
|
|
|
{
|
|
|
return first.Compose(second, Expression.OrElse);
|
|
|
}
|
|
|
|
|
|
private class ParameterRebinder : ExpressionVisitor
|
|
|
{
|
|
|
private readonly Dictionary<ParameterExpression, ParameterExpression> _map;
|
|
|
|
|
|
private ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
|
|
|
{
|
|
|
_map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
|
|
|
}
|
|
|
|
|
|
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map,
|
|
|
Expression exp)
|
|
|
{
|
|
|
return new ParameterRebinder(map).Visit(exp);
|
|
|
}
|
|
|
|
|
|
protected override Expression VisitParameter(ParameterExpression node)
|
|
|
{
|
|
|
ParameterExpression replacement;
|
|
|
if (_map.TryGetValue(node, out replacement))
|
|
|
node = replacement;
|
|
|
return base.VisitParameter(node);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 工具类 用于处理【用逗号隔开的文本字段】的内容
|
|
|
/// </summary>
|
|
|
public class STRLISTField {
|
|
|
private List<string> strlist { get; set; }
|
|
|
|
|
|
public string getStr() {
|
|
|
|
|
|
var result = "";
|
|
|
|
|
|
foreach (var item in strlist) {
|
|
|
if (result != "") result += ",";
|
|
|
result += item;
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private static List<string> getstrlist(string fieldvalue) {
|
|
|
var _strlist = new List<string>();
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(fieldvalue))
|
|
|
{
|
|
|
_strlist = fieldvalue.Split(",").ToList();
|
|
|
}
|
|
|
return _strlist;
|
|
|
}
|
|
|
public STRLISTField() { }
|
|
|
|
|
|
public STRLISTField(string fieldvalue) {
|
|
|
strlist = getstrlist(fieldvalue);
|
|
|
}
|
|
|
|
|
|
public STRLISTField(string fieldvalue,string addfield)
|
|
|
{
|
|
|
strlist = getstrlist(fieldvalue);
|
|
|
|
|
|
add(addfield);
|
|
|
}
|
|
|
|
|
|
public void add(string fieldvalue) {
|
|
|
var addlist = getstrlist(fieldvalue);
|
|
|
|
|
|
foreach (var additem in addlist) {
|
|
|
if (!strlist.Exists(x => x == additem)) {
|
|
|
strlist.Add(additem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void del(string fieldvalue)
|
|
|
{
|
|
|
var dellist = getstrlist(fieldvalue);
|
|
|
|
|
|
foreach (var delitem in dellist)
|
|
|
{
|
|
|
if (strlist.Exists(x => x == delitem))
|
|
|
{
|
|
|
strlist.Remove(delitem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|