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 : ServiceFunFilter where T : BaseEntity where TRepository : IRepository { public ICacheService CacheContext { get { return AutofacContainerModule.GetService(); } } public Microsoft.AspNetCore.Http.HttpContext Context { get { return HttpContext.Current; } } private WebResponseContent Response { get; set; } protected IRepository 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 LockKeyList; public class LockKeyHelper { private static readonly Lazy lazy = new Lazy(() => 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(); if (LockKeyList.Contains(key.ToString())) return false; LockKeyList.Add(key.ToString()); return true; } catch (Exception ex) { //logger.Debug("获取编号错误"); return false; } finally { } } } /// /// 原锁定key方法 由于线程不安全 改为调用lazy单例的模式 /// /// /// public bool addLockKey(object key) { //if (LockKeyList == null) // LockKeyList = new List(); //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(); 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 repository) { } /// /// 2020.08.15添加自定义原生查询sql或多租户(查询、导出) /// /// private IQueryable GetSearchQueryable() { //UserContext.Current.IsSuperAdmin超级管理员不限制数据 //自定sql,没有使用多租户,直接执行自定义sql if (QuerySql != null && (!IsMultiTenancy || UserContext.Current.IsSuperAdmin)) { //将 return repository.DbContext.Set().FromSqlRaw(QuerySql); } //没有自定sql与多租户执行默认查询 if ((QuerySql == null && !IsMultiTenancy) ) { return repository.DbContext.Set(); } 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().FromSqlRaw(multiTenancyString); } protected void SetQuerySqlCondition(PageDataOptions options, Dictionary SearchName) { options = options ?? new PageDataOptions(); List searchParametersList = new List(); if (!string.IsNullOrEmpty(options.Wheres)) { try { searchParametersList = options.Wheres.DeserializeObject>(); } 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} "; } } } } /// /// 2020.08.15添加获取多租户数据过滤sql(删除、编辑) /// /// 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; } /// /// 2020.08.15添加多租户数据过滤(编辑) /// 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("不能编辑此数据"); } } /// /// 2020.08.15添加多租户数据过滤(删除) /// 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"; /// /// 生成排序字段 /// /// /// private Dictionary 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(); return new Dictionary() { { pageData.Sort, pageData.Order?.ToLower() == _asc? QueryOrderBy.Asc: QueryOrderBy.Desc } }; } /// /// 验证排序与查询字段合法性 /// /// /// /// public PageDataOptions ValidatePageOptions(PageDataOptions options, out IQueryable queryable) { options = options ?? new PageDataOptions(); List searchParametersList = new List(); if (!string.IsNullOrEmpty(options.Wheres)) { try { searchParametersList = options.Wheres.DeserializeObject>(); } catch { } } QueryRelativeList?.Invoke(searchParametersList); // Connection // queryable = repository.DbContext.Set(); //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(values, expressionType)) : queryable.Where(x.Name.CreateExpression(x.Value, expressionType)); } options.TableName = base.TableName ?? typeof(T).Name; return options; } /// /// 加载页面数据 通用查询 基类 /// /// /// public virtual PageGridData GetPageData(PageDataOptions options) { options = ValidatePageOptions(options, out IQueryable queryable); //获取排序字段 //Dictionary orderbyDic = GetPageDataSort(options, TProperties); //PageGridData pageGridData = new PageGridData(); //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 groupExpress = x =>x; // //pageGridData.summary = queryable.GroupBy(groupExpress).Select(SummaryExpress).FirstOrDefault(); // } //} //GetPageDataOnExecuted?.Invoke(pageGridData); //return pageGridData; return Do_GetPageData(options, queryable); } public PageGridData Do_GetPageData(PageDataOptions options, IQueryable queryable) { Dictionary orderbyDic = GetPageDataSort(options, TProperties); PageGridData pageGridData = new PageGridData(); 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 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()?.DetailTable?[0]; if (detailType == null) { return null; } object obj = typeof(ServiceBase) .GetMethod("GetDetailPage", BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(new Type[] { detailType }).Invoke(this, new object[] { pageData }); return obj; } protected override object GetDetailSummary(IQueryable queryeable) { return null; } private PageGridData GetDetailPage(PageDataOptions options) where Detail : class { //校验查询值,排序字段,分页大小规则待完 PageGridData gridData = new PageGridData(); if (options.Value == null) return gridData; //主表主键字段 string keyName = typeof(T).GetKeyName(); //生成查询条件 Expression> whereExpression = keyName.CreateExpression(options.Value, LinqExpressionType.Equal); var queryeable = repository.DbContext.Set().Where(whereExpression); gridData.total = queryeable.Count(); string sortName = options.Sort ?? typeof(Detail).GetKeyName(); Dictionary orderBy = new Dictionary() { { 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(queryeable); return gridData; } /// /// 上传文件 /// /// /// public virtual WebResponseContent Upload(List 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 fileNames = new List(); 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); } /// /// 上传文件-董家镇 /// /// /// public virtual WebResponseContent UploadDJZ(List 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 fileNames = new List(); 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 GetIgnoreTemplate() { //忽略创建人、修改人、审核等字段 List 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(DownLoadTemplateColumns, GetIgnoreTemplate(), dicPath, fileName); return Response.OK(null, dicPath + fileName); } /// /// 导入表数据Excel文件夹 /// /// /// public virtual WebResponseContent Import(List 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(dicPath, DownLoadTemplateColumns, GetIgnoreTemplate()); } catch (Exception ex) { Response.Error("未能处理导入的文件,请检查导入的文件是否正确"); Logger.Error($"表{typeof(T).GetEntityTableCnName()}导入失败{ex.Message + ex.InnerException?.Message}"); } if (!Response.Status) return Response; List list = Response.Data as List; 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 GetListByExcel(List files,out WebResponseContent _webResponseContent) { if (files == null || files.Count == 0) { _webResponseContent = new WebResponseContent().Error("没有找到文件"); return new List(); } 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(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(); List list = Response.Data as List; File.Delete(dicPath); return list; } /// /// 导出 /// /// /// public virtual WebResponseContent Export(PageDataOptions pageData) { pageData.Export = true; List 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 ignoreColumn = new List(); 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)); } /// /// 新建 新建方法 /// /// /// 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(); 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().DetailTable[0]; return typeof(ServiceBase) .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(entity, null, validationEntity); } /// /// 保存主、明细数据 /// /// /// /// /// 是否进行实体验证 /// public WebResponseContent Add(T entity, List 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(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(T entity, List list1=null, List list2=null, List list3 = null, List list4 = null, List list5 = null, List 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(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(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(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(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(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(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(List list) { if (list != null && list.Count > 0) { Response = list.ValidationEntity(); return (!Response.Status) ; } return false; } public void AddDetailToDBSet() where TDetail : class { List listChilds = TProperties.Where(x => x.PropertyType.Name == "List`1").ToList(); // repository.DbContext.Set().AddRange(); } private WebResponseContent Add(SaveModel saveDataModel) where TDetail : class { T mainEntity = saveDataModel.MainData.DicToEntity(); //验证明细 string reslut = typeof(TDetail).ValidateDicInEntity(saveDataModel.DetailData, true, false, new string[] { TProperties.GetKeyName() }); if (reslut != string.Empty) return Response.Error(reslut); List list = saveDataModel.DetailData.DicToList(); Response = Add(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 编辑 /// /// 获取编辑明细主键 /// /// /// /// /// /// /// public List GetUpdateDetailSelectKeys(string detailKeyName, string mainKeyName, string mainKeyValue) where DetailT : class { IQueryable queryable = repository.DbContext.Set(); Expression> selectExpression = detailKeyName.GetExpression(); Expression> whereExpression = mainKeyName.CreateExpression(mainKeyValue, LinqExpressionType.Equal); List detailKeys = queryable.Where(whereExpression).Select(selectExpression).ToList(); return detailKeys; } /// /// 将数据转换成对象后最终保存 /// /// /// /// /// /// /// public WebResponseContent UpdateToEntity(SaveModel saveModel, PropertyInfo mainKeyProperty, PropertyInfo detailKeyInfo, object keyDefaultVal) where DetailT : class { T mainEnity = saveModel.MainData.DicToEntity(); List detailList = saveModel.DetailData.DicToList(); //删除的主键 //查出所有明细表数据的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 addList = new List(); // List containsKeys = new List(); //编辑对象 List editList = new List(); //删除的主键 List delKeys = new List(); 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(x, updateField); }); //明细新增 addList.ForEach(x => { x.SetCreateDefaultVal(); repository.DbContext.Entry(x).State = EntityState.Added; }); //明细删除 delKeys.ForEach(x => { DetailT delT = Activator.CreateInstance(); detailKeyInfo.SetValue(delT, x); repository.DbContext.Entry(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; } /// /// 获取配置的创建人ID创建时间创建人,修改人ID修改时间、修改人与数据相同的字段 /// private static string[] _userIgnoreFields { get; set; } private static string[] UserIgnoreFields { get { if (_userIgnoreFields != null) return _userIgnoreFields; List fields = new List(); 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; } } /// /// 编辑 /// 1、明细表必须把主表的主键字段也设置为可编辑 /// 2、修改、增加只会操作设置为编辑列的数据 /// /// /// 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>() : saveModel.DetailData.Where(x => x.Count > 0).ToList(); detailType = typeof(T).GetCustomAttribute().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(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> expression = mainKeyProperty.Name.CreateExpression(mainKeyVal.ToString(), LinqExpressionType.Equal); if (!repository.Exists(expression)) return Response.Error("保存的数据不存在!"); //没有明细的直接保存主表数据 if (detailType == null) { saveModel.SetDefaultVal(AppSetting.ModifyMember, userInfo); T mainEntity = saveModel.MainData.DicToEntity(); 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(c => new { c.TypeName }); //判断明细是否包含了主表的主键 string deatilDefaultVal = detailKeyInfo.PropertyType.Assembly.CreateInstance(detailKeyInfo.PropertyType.FullName).ToString(); foreach (Dictionary 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 /// /// 删除明细数据 /// 前台使用时,调用该表自己的URL/DelDetail 参数delKey /// /// /// /// /// 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 ""; } } /// /// 查找前台传回数据结构中的 WorkKeys 数组 /// 通常用来放置需要处理的业务编号组 /// /// /// 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 ""; } } /// /// /// /// /// 是否删除明细数据(默认会删除明细) /// 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 + "
").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()?.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" }; /// /// 审核默认对应数据库字段为AuditId审核人ID ,AuditStatus审核状态,Auditor审核人,Auditdate审核时间,Auditreason审核原因 /// /// /// /// /// 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 auditList = new List(); foreach (var value in keys) { object convertVal = value.ToString().ChangeType(property.PropertyType); if (convertVal == null) continue; T entity = Activator.CreateInstance(); 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> expression = null) { return ApiValidateInput(bizContent, expression); } /// /// 对指定类与api的参数进行验证 /// /// /// /// /// 对指属性验证 /// (string,TInput, bool) string:返回验证消息,TInput:bizContent序列化后的对象,bool:验证是否通过 public virtual (string, TInput, bool) ApiValidateInput(string bizContent, Expression> expression) { return ApiValidateInput(bizContent, expression, null); } /// /// /// /// /// /// 对指属性验证格式如:x=>new { x.UserName,x.Value } /// 对指定的字段只做合法性判断比如长度是是否超长 /// (string,TInput, bool) string:返回验证消息,TInput:bizContent序列化后的对象,bool:验证是否通过 public virtual (string, TInput, bool) ApiValidateInput(string bizContent, Expression> expression, Expression> validateExpression) { try { TInput input = JsonConvert.DeserializeObject(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); } /// /// 将数据源映射到新的数据中,目前只支持List映射到List或TSource映射到TResult /// 目前只支持Dictionary或实体类型 /// /// /// /// /// 只映射返回对象的指定字段 /// 只映射数据源对象的指定字段 /// 过滤条件表达式调用方式:List表达式x => new { x[0].MenuName, x[0].Menu_Id},表示指定映射MenuName,Menu_Id字段 /// List list = new List(); /// list.MapToObject, List>(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(x => new { x.MenuName, x.Menu_Id}, null); /// public virtual TResult MapToEntity(TSource source, Expression> resultExpression, Expression> sourceExpression = null) where TResult : class { return source.MapToObject(resultExpression, sourceExpression); } /// /// 将一个实体的赋到另一个实体上,应用场景: /// 两个实体,a a1= new a();b b1= new b(); a1.P=b1.P; a1.Name=b1.Name; /// /// /// /// /// /// 指定对需要的字段赋值,格式x=>new {x.Name,x.P},返回的结果只会对Name与P赋值 public virtual void MapValueToEntity(TSource source, TResult result, Expression> expression = null) where TResult : class { source.MapValueToEntity(result, expression); } /// /// 处理扩展的子列表数据 返回addList和updateList /// 子表当中与父表连接的字段需增加 【ParentId属性】 , /// 如一个子表关联多个子表,需要在属性中添加父表名字;如只关联一个父表,可以传空字符串进去 /// 在调用时,如不传表名,将会取得子表中第一个包含【ParentId属性】的字段 /// /// /// /// public static List> DealBodyList(object MainKeyValue, List BodyList, string HeadTableName="") { PropertyInfo BodyPK = typeof(TDetail).GetKeyProperty(); PropertyInfo detailMainKey = typeof(TDetail).GetParentIdProperty(HeadTableName); //id=0的默认为新增的数据 List addList = new List(); List updateList = new List(); 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>(); result.Add(addList); result.Add(updateList); return result; } ////当前用户只能操作自己(与下级角色)创建的数据,如:查询、删除、修改等操作(待完) //private Expression> GetCurrentUserCondition(Type type) //{ // var userContext = UserContext.Current; // if (userContext.IsSuperAdmin) // { // return null; // } // //LimitCurrentUserPermission开启用户权限与代码生成器同时开起了用户权限才会生效 // if (!LimitCurrentUserPermission || !type.GetCustomAttribute().CurrentUserPermission) { return null; } // //表的创建人字段必须与配置文件appsettings.json中的创建人字段相同(大小写也必须相同) // string createId = AppSetting.CreateMember.UserIdField; // if (type.GetProperty(createId) == null) // { // return null; // } // Expression> whereExpression = createId.CreateExpression(userContext.UserId, LinqExpressionType.Equal); // List 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> 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> 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 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 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(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(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"); } /// /// 将与数量相关的6个字段从后赋值到前 /// (KGS PKGS CBM NETWEIGHT STORAGEUNITCOUNT RULEUNITCOUNT) /// /// /// /// /// public void wms_copy(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(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(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(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 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"); } /// /// 前方tot大于后面的fromt /// /// /// /// /// /// public bool wms_isBig(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"); } /// /// 两个对象的指定字段相加,后者加入到前者内。 /// /// /// /// /// public void fieldadd(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 fieldcut(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(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); } /// /// 相同 /// /// /// /// /// /// /// public bool fieldisequal(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 bool fieldisBig(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, 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, 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 parameters,string FieldName) { for (var _i = parameters.Count - 1; _i >= 0; _i--) { if (parameters[_i].Name == FieldName) parameters.Remove(parameters[_i]); } } public Expression> GetOrExpression(string FieldName, string paramStr) { Expression> _true = x => 1 == 1; if (!string.IsNullOrWhiteSpace(paramStr)) { var _paramlist = paramStr.Split(","); var paramlist = new List(); 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> _oneParam = FieldName.CreateExpression(paramlist[0].ToString(), LinqExpressionType.Contains); // return _oneParam; //} //else //{ //PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == x.Name.ToUpper()).FirstOrDefault(); Expression> expre = FieldName.CreateExpression(paramlist[0].ToString(), LinqExpressionType.Contains); foreach (var param in paramlist) { if (param == paramlist[0]) continue; expre = ExpressionFuncExtender.Or(expre, FieldName.CreateExpression(param.ToString(), LinqExpressionType.Contains)); } return expre; //} } else { return _true; } } /// /// 将查询条件中的指定字段 改为指定形式 /// 默认改为startwith的形式 /// /// /// public void SetFieldSearchType(ref PageDataOptions options, string FieldName,string newtype="StartWith") { try { var searchParametersList = options.Wheres.DeserializeObject>(); 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; } } /// /// 基础工具类 /// 通用工具类 /// public static class BasicDataRef { /// /// 返回两个时间的间隔天数之差+1 /// 如 /// /// /// /// 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()); } /// /// 通过公司ID获取公司名称 /// /// /// public static string getCompanyFullName(string companyid) { var companydiclist = DBServerProvider.SqlDapper.QueryList("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("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(); } } /// /// 消息实体 /// public class NoticeInput { /// /// 标题 /// public string Title { get; set; } /// /// 公司Id /// public string CompanyId { get; set; } /// /// 内容 /// public string Content { get; set; } } /// /// 发送系统消息 /// /// 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); } /// /// 获取某一字符串第N到第N+1空格的字符 /// /// public static Func 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; }; } /// /// 获取第N个空格所在 /// /// public static Func 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 strlist) { var result = "'" + string.Join("','", strlist.ToArray()) + "'" ; return result; } public static long ConvertDateTimeToInt(DateTime time) { DateTimeOffset dto = new DateTimeOffset(time); return dto.ToUnixTimeMilliseconds(); } } /// /// AutoMapper的帮助类 /// public static class AutoMapperHelper { /// /// 来源,目标 /// 单条实体类型映射,默认字段名字一一对应 /// /// /// Dto类型 /// 要被转化的数据 /// 转化之后的实体 /// public static TDestination MapTo(this TSource source) where TDestination : class, new() where TSource : class { if (source == null) return new TDestination(); var config = new MapperConfiguration(cfg => cfg.CreateMap()); var mapper = config.CreateMapper(); return mapper.Map(source); } /// /// 实体列表类型映射,默认字段名字一一对应 /// /// Dto类型 /// 要被转化的数据 /// 可以使用这个扩展方法的类型,任何引用类型 /// 转化之后的实体列表 public static List MapToList(this IEnumerable source) where TDestination : class where TSource : class { if (source == null) return new List(); var config = new MapperConfiguration(cfg => cfg.CreateMap()); var mapper = config.CreateMapper(); return mapper.Map>(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 { public Expression> AsExpression(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 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> 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> 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> 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>)Expression.Lambda(expression, parameter)); } } public static class ExpressionFuncExtender { /// /// 以特定的条件运行组合两个Expression表达式 /// /// 表达式的主实体类型 /// 第一个Expression表达式 /// 要组合的Expression表达式 /// 组合条件运算方式 /// 组合后的表达式 public static Expression Compose(this Expression first, Expression second, Func 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(merge(first.Body, secondBody), first.Parameters); } /// /// 以 Expression.AndAlso 组合两个Expression表达式 /// /// 表达式的主实体类型 /// 第一个Expression表达式 /// 要组合的Expression表达式 /// 组合后的表达式 public static Expression> And(this Expression> first, Expression> second) { return first.Compose(second, Expression.AndAlso); } /// /// 以 Expression.OrElse 组合两个Expression表达式 /// /// 表达式的主实体类型 /// 第一个Expression表达式 /// 要组合的Expression表达式 /// 组合后的表达式 public static Expression> Or(this Expression> first, Expression> second) { return first.Compose(second, Expression.OrElse); } private class ParameterRebinder : ExpressionVisitor { private readonly Dictionary _map; private ParameterRebinder(Dictionary map) { _map = map ?? new Dictionary(); } public static Expression ReplaceParameters(Dictionary 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); } } } /// /// 工具类 用于处理【用逗号隔开的文本字段】的内容 /// public class STRLISTField { private List strlist { get; set; } public string getStr() { var result = ""; foreach (var item in strlist) { if (result != "") result += ","; result += item; } return result; } private static List getstrlist(string fieldvalue) { var _strlist = new List(); 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); } } } } }