| using Magicodes.ExporterAndImporter.Core; | 
| using Magicodes.ExporterAndImporter.Core.Models; | 
| using Magicodes.ExporterAndImporter.Excel; | 
| using Microsoft.AspNetCore.Http; | 
| using Microsoft.Extensions.Options; | 
| using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; | 
| using SqlSugar; | 
| using System.Drawing.Drawing2D; | 
| using System.Dynamic; | 
| using System.Linq.Expressions; | 
| using System.Reflection; | 
| using WIDESEA_Core.BaseRepository; | 
| using WIDESEA_Core.Enums; | 
| using WIDESEA_Core.Helper; | 
| using WIDESEA_Core.Utilities; | 
|   | 
| namespace WIDESEA_Core.BaseServices | 
| { | 
|     public class ServiceBase<TEntity, TRepository> : ServiceFunFilter<TEntity>, IService<TEntity> | 
|          where TEntity : class, new() | 
|          where TRepository : IRepository<TEntity> | 
|   | 
|     { | 
|         public ServiceBase(TRepository BaseDal) | 
|         { | 
|             this.BaseDal = BaseDal; | 
|         } | 
|   | 
|         public TRepository BaseDal { get; set; } //通过在子类的构造函数中注入,这里是基类,不用构造函数 | 
|   | 
|         public ISqlSugarClient Db => BaseDal.Db; | 
|   | 
|         private PropertyInfo[] _propertyInfo { get; set; } = null; | 
|         public PropertyInfo[] TProperties | 
|         { | 
|             get | 
|             { | 
|                 if (_propertyInfo != null) | 
|                 { | 
|                     return _propertyInfo; | 
|                 } | 
|                 _propertyInfo = typeof(TEntity).GetProperties(); | 
|                 return _propertyInfo; | 
|             } | 
|         } | 
|   | 
|         public virtual PageGridData<TEntity> GetPageData(PageDataOptions options) | 
|         { | 
|             string wheres = ValidatePageOptions(options); | 
|             //获取排序字段 | 
|             Dictionary<string, OrderByType> orderbyDic = GetPageDataSort(options, TProperties); | 
|   | 
|             PageGridData<TEntity> pageGridData = new PageGridData<TEntity>(); | 
|             //if (QueryRelativeExpression != null) | 
|             //{ | 
|             //    queryable = QueryRelativeExpression.Invoke(queryable); | 
|             //} | 
|             //if (options.Export) | 
|             //{ | 
|             //    queryable = queryable.GetIQueryableOrderBy(orderbyDic); | 
|             //    if (Limit > 0) | 
|             //    { | 
|             //        queryable = queryable.Take(Limit); | 
|             //    } | 
|             //    pageGridData.rows = queryable.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); | 
|   | 
|             pageGridData = BaseDal.QueryPage | 
|                 (wheres, options.Page, options.Rows, orderbyDic); | 
|   | 
|             return pageGridData; | 
|         } | 
|   | 
|   | 
|         protected string ValidatePageOptions(PageDataOptions options) | 
|         { | 
|             options = options ?? new PageDataOptions(); | 
|             string where = ""; | 
|             List<SearchParameters> searchParametersList = new List<SearchParameters>(); | 
|             if (options.Filter != null && options.Filter.Count > 0) | 
|             { | 
|                 searchParametersList.AddRange(options.Filter); | 
|             } | 
|             else if (!string.IsNullOrEmpty(options.Wheres)) | 
|             { | 
|                 try | 
|                 { | 
|                     searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>(); | 
|                     options.Filter = searchParametersList; | 
|                 } | 
|                 catch { } | 
|             } | 
|             QueryRelativeList?.Invoke(searchParametersList); | 
|   | 
|             for (int i = 0; i < searchParametersList.Count; i++) | 
|             { | 
|                 if (string.IsNullOrEmpty(searchParametersList[i].Value)) | 
|                 { | 
|                     continue; | 
|                 } | 
|   | 
|                 PropertyInfo property = TProperties.Where(c => c.Name.ToUpper() == searchParametersList[i].Name.ToUpper()).FirstOrDefault(); | 
|   | 
|                 if (property == null) continue; | 
|   | 
|                 (bool, string, object) result = property.ValidationVal(searchParametersList[i].Value); | 
|                 if (!result.Item1) | 
|                 { | 
|                     continue; | 
|                 } | 
|   | 
|                 LinqExpressionType expressionType = searchParametersList[i].DisplayType.GetLinqCondition(); | 
|                 if (expressionType == LinqExpressionType.Equal) | 
|                 { | 
|                     if (string.IsNullOrEmpty(where)) | 
|                     { | 
|                         // 针对字符串类型的字段使用模糊查询 | 
|                         //where += $"{searchParametersList[i].Name} like '%{searchParametersList[i].Value}%'"; | 
|                         if (searchParametersList[i].Value.ToLower() == "true" || searchParametersList[i].Value.ToLower() == "false") | 
|                         { | 
|                             where += $" {searchParametersList[i].Name} = '{searchParametersList[i].Value.ToLower()}'"; | 
|                         } | 
|                         else | 
|                         { | 
|                             where += $"{searchParametersList[i].Name} like '%{searchParametersList[i].Value}%'"; | 
|                         } | 
|                     } | 
|                     else | 
|                     { | 
|                         // 针对布尔类型字段进行精确查询 | 
|                         if (searchParametersList[i].Value.ToLower() == "true" || searchParametersList[i].Value.ToLower() == "false") | 
|                         { | 
|                             where += $" and {searchParametersList[i].Name} = '{searchParametersList[i].Value.ToLower()}'"; | 
|                         } | 
|                         else | 
|                         { | 
|                             where += $" and {searchParametersList[i].Name} like '%{searchParametersList[i].Value}%'"; | 
|                         } | 
|                     } | 
|                 } | 
|                 else | 
|                 { | 
|                     if (string.IsNullOrEmpty(where)) | 
|                         where += $"{searchParametersList[i].Name} {searchParametersList[i].DisplayType} '{searchParametersList[i].Value}'"; | 
|                     else | 
|                         where += $" and {searchParametersList[i].Name} {searchParametersList[i].DisplayType} '{searchParametersList[i].Value}'"; | 
|                 } | 
|             } | 
|             return where; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 获取排序字段 | 
|         /// </summary> | 
|         /// <param name="pageData"></param> | 
|         /// <param name="propertyInfo"></param> | 
|         /// <returns></returns> | 
|         public Dictionary<string, OrderByType> GetPageDataSort(PageDataOptions pageData, PropertyInfo[] propertyInfo) | 
|         { | 
|             if (!string.IsNullOrEmpty(pageData.Sort)) | 
|             { | 
|                 if (pageData.Sort.Contains(",")) | 
|                 { | 
|                     List<string> sortArr = pageData.Sort.Split(",").Where(x => propertyInfo.Any(p => p.Name == x)).ToList(); | 
|                     Dictionary<string, OrderByType> sortDic = new Dictionary<string, OrderByType>(); | 
|                     foreach (var item in sortArr) | 
|                     { | 
|                         sortDic[item] = pageData.Order?.ToLower() == OrderByType.Asc.ToString() ? OrderByType.Asc : OrderByType.Desc; | 
|                     } | 
|                     return sortDic; | 
|                 } | 
|                 else if (propertyInfo.Any(x => x.Name.ToUpper() == pageData.Sort.ToUpper())) | 
|                 { | 
|                     return new Dictionary<string, OrderByType> { | 
|                         { | 
|                             pageData.Sort,pageData.Order?.ToLower() == OrderByType.Asc.ToString().ToLower()? OrderByType.Asc : OrderByType.Desc | 
|                         } }; | 
|                 } | 
|             } | 
|             return new Dictionary<string, OrderByType> { { "CreateDate", pageData.Order?.ToLower() == OrderByType.Asc.ToString() ? OrderByType.Asc : OrderByType.Desc } }; | 
|         } | 
|   | 
|         public virtual object GetDetailPage(PageDataOptions pageData) | 
|         { | 
|             Type t = typeof(TEntity); | 
|   | 
|             if (pageData.Value == null) return new PageGridData<object>(total: 0, null); | 
|             string keyName = t.GetKeyName(); | 
|             ////生成查询条件 | 
|             //Expression<Func<TEntity, bool>> whereExpression = keyName.CreateExpression<TEntity>(pageData.Value, LinqExpressionType.Equal); | 
|             int totalCount = 0; | 
|             PropertyInfo propertyInfo = t.GetProperties().FirstOrDefault(x => x.GetCustomAttribute<Navigate>() != null); | 
|             if (propertyInfo != null) | 
|             { | 
|                 Type detailType = propertyInfo.PropertyType.GetGenericArguments()[0]; | 
|                 Navigate navigate = propertyInfo.GetCustomAttribute<Navigate>(); | 
|                 List<ExpandoObject> list = BaseDal.Db.Queryable(detailType.Name, "detail").Where(navigate.GetName(), "=", pageData.Value).ToPageList(pageData.Page, pageData.Rows, ref totalCount); | 
|                 return new PageGridData<ExpandoObject>(totalCount, list); | 
|             } | 
|             return new PageGridData<object>(total: 0, null); | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 添加数据 | 
|         /// </summary> | 
|         /// <param name="entity">单个实体</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent AddData(TEntity entity) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.AddData(entity) > 0 ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 添加数据 | 
|         /// </summary> | 
|         /// <param name="entities">实体集合</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent AddData(List<TEntity> entities) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.AddData(entities) > 0 ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 添加数据 | 
|         /// </summary> | 
|         /// <param name="saveModel"></param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent AddData(SaveModel saveModel) | 
|         { | 
|             try | 
|             { | 
|                 if (saveModel == null || saveModel.MainData == null || saveModel.MainData.Count == 0)//判断参数是否传入 | 
|                 { | 
|                     return WebResponseContent.Instance.Error("传参错误,参数不能为空"); | 
|                 } | 
|                 string validResult = typeof(TEntity).ValidateDicInEntity(saveModel.MainData, true, TProperties); | 
|   | 
|                 if (!string.IsNullOrEmpty(validResult)) | 
|                 { | 
|                     return WebResponseContent.Instance.Error(validResult); | 
|                 } | 
|   | 
|                 PropertyInfo keyPro = typeof(TEntity).GetKeyProperty(); | 
|                 if (keyPro == null) | 
|                 { | 
|                     return WebResponseContent.Instance.Error("请先设置主键"); | 
|                 } | 
|                 if (keyPro.PropertyType == typeof(Guid)) | 
|                 { | 
|                     saveModel.MainData.Add(keyPro.Name, Guid.NewGuid()); | 
|                 } | 
|                 else if (keyPro.PropertyType == typeof(int) || keyPro.PropertyType == typeof(long)) | 
|                 { | 
|                     SugarColumn sugarColumn = keyPro.GetCustomAttribute<SugarColumn>(); | 
|                     if (sugarColumn.IsIdentity) | 
|                     { | 
|                         saveModel.MainData.Remove(keyPro.Name.FirstLetterToUpper()); | 
|                         saveModel.MainData.Remove(keyPro.Name.FirstLetterToLower()); | 
|                     } | 
|                 } | 
|                 TEntity entity = saveModel.MainData.DicToModel<TEntity>(); | 
|                 //if (saveModel.DetailData == null && saveModel.DetailData.Count == 0) | 
|                 if (saveModel.DetailData == null ) | 
|                 { | 
|                     BaseDal.AddData(entity); | 
|                     return WebResponseContent.Instance.OK(); | 
|                 } | 
|   | 
|                 if (typeof(TEntity).GetNavigatePro() == null) | 
|                 { | 
|                     return WebResponseContent.Instance.Error("未配置导航属性"); | 
|                 } | 
|   | 
|                 Type detailType = typeof(TEntity).GetDetailType(); | 
|                 MethodInfo? methodInfo = GetType().GetMethod("AddDataIncludesDetail"); | 
|                 methodInfo = methodInfo?.MakeGenericMethod(new Type[] { detailType }); | 
|                 object? obj = methodInfo?.Invoke(this, new object[] { entity, detailType, saveModel.DetailData }); | 
|                 return obj as WebResponseContent; | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         public WebResponseContent AddDataIncludesDetail<TDetail>(TEntity entity, Type detailType, List<Dictionary<string, object>> detailDics) where TDetail : class, new() | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 string name = typeof(TEntity).GetMainIdByDetail(); | 
|                 string reslut = detailType.ValidateDicInEntity(detailDics, true, new string[] { name }); | 
|                 if (reslut != string.Empty) | 
|                     return WebResponseContent.Instance.Error(reslut); | 
|   | 
|                 List<TDetail> list = detailDics.DicToIEnumerable<TDetail>(); | 
|   | 
|                 ((SqlSugarClient)BaseDal.Db).BeginTran(); | 
|   | 
|                 int id = BaseDal.Db.Insertable(entity).ExecuteReturnIdentity(); | 
|   | 
|                 for (int i = 0; i < list.Count; i++) | 
|                 { | 
|                     TDetail detail = list[i]; | 
|                     typeof(TDetail).SetDetailId(detail, id, name); | 
|                 } | 
|   | 
|                 BaseDal.Db.Insertable(list).ExecuteCommand(); | 
|   | 
|                 ((SqlSugarClient)BaseDal.Db).CommitTran(); | 
|   | 
|                 content = WebResponseContent.Instance.OK(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 ((SqlSugarClient)BaseDal.Db).RollbackTran(); | 
|                 content = WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|   | 
|   | 
|         /// <summary> | 
|         /// 修改数据 | 
|         /// </summary> | 
|         /// <param name="entity">单个实体</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent UpdateData(TEntity entity) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.UpdateData(entity) ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 修改数据 | 
|         /// </summary> | 
|         /// <param name="entities">实体集合</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent UpdateData(List<TEntity> entities) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.UpdateData(entities) ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 修改数据 | 
|         /// </summary> | 
|         /// <param name="saveModel"></param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent UpdateData(SaveModel saveModel) | 
|         { | 
|             try | 
|             { | 
|                 List<string>? list = UpdateIgnoreColOnExecute?.Invoke(saveModel); | 
|                 if (saveModel == null || saveModel.MainData == null || saveModel.MainData.Count == 0)//判断参数是否传入 | 
|                 { | 
|                     return WebResponseContent.Instance.Error("传参错误,参数不能为空"); | 
|                 } | 
|                 string validResult = typeof(TEntity).ValidateDicInEntity(saveModel.MainData, false, TProperties, list?.ToArray()); | 
|   | 
|                 if (!string.IsNullOrEmpty(validResult)) | 
|                 { | 
|                     return WebResponseContent.Instance.Error(validResult); | 
|                 } | 
|   | 
|                 PropertyInfo keyPro = typeof(TEntity).GetKeyProperty(); | 
|                 if (keyPro == null) | 
|                 { | 
|                     return WebResponseContent.Instance.Error("请先设置主键"); | 
|                 } | 
|   | 
|                 TEntity entity = saveModel.MainData.DicToModel<TEntity>(); | 
|   | 
|                 List<string> listCol = new List<string>(); | 
|                 foreach (var item in saveModel.MainData) | 
|                 { | 
|                     PropertyInfo propertyInfo = typeof(TEntity).GetProperty(item.Key); | 
|                     if (propertyInfo == null) | 
|                     { | 
|                         propertyInfo = typeof(TEntity).GetProperty(item.Key.FirstLetterToLower()); | 
|                         if (propertyInfo == null) | 
|                         { | 
|                             propertyInfo = typeof(TEntity).GetProperty(item.Key.FirstLetterToUpper()); | 
|                         } | 
|                     } | 
|   | 
|                     listCol.Add(propertyInfo?.Name); | 
|                 } | 
|   | 
|                 //if (saveModel.DetailData == null && saveModel.DetailData.Count == 0) | 
|                 if (saveModel.DetailData == null) | 
|                 { | 
|                     if (list != null) | 
|                         listCol = listCol.Where(x => !list.Contains(x)).ToList(); | 
|                     bool result = BaseDal.UpdateData(entity, listCol, list); | 
|                     return WebResponseContent.Instance.OK(); | 
|                 } | 
|   | 
|                 if (typeof(TEntity).GetNavigatePro() == null) | 
|                 { | 
|                     return WebResponseContent.Instance.Error("未配置导航属性"); | 
|                 } | 
|   | 
|                 Type detailType = typeof(TEntity).GetDetailType(); | 
|                 MethodInfo? methodInfo = GetType().GetMethod("UpdateDataInculdesDetail"); | 
|                 methodInfo = methodInfo?.MakeGenericMethod(new Type[] { detailType }); | 
|                 object? obj = methodInfo?.Invoke(this, new object[] { entity, detailType, saveModel.DetailData, saveModel.DelKeys }); | 
|                 return obj as WebResponseContent; | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         public WebResponseContent UpdateDataInculdesDetail<TDetail>(TEntity entity, Type detailType, List<Dictionary<string, object>> detailDics, List<object> delKeys) where TDetail : class, new() | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 string name = typeof(TEntity).GetMainIdByDetail(); | 
|                 string reslut = detailType.ValidateDicInEntity(detailDics, true, new string[] { name }); | 
|                 if (reslut != string.Empty) | 
|                     return WebResponseContent.Instance.Error(reslut); | 
|   | 
|                 List<TDetail> list = detailDics.DicToIEnumerable<TDetail>(); | 
|   | 
|                 List<object> dynamicDelKeys = new List<object>(); | 
|                 if (delKeys != null) | 
|                 { | 
|                     for (int i = 0; i < delKeys.Count; i++) | 
|                     { | 
|                         dynamicDelKeys.Add(delKeys[i]); | 
|                     } | 
|                 } | 
|   | 
|                 List<TDetail> updateRows = new List<TDetail>(); | 
|                 List<TDetail> addRows = new List<TDetail>(); | 
|   | 
|                 for (int i = 0; i < list.Count; i++) | 
|                 { | 
|                     object detailId = typeof(TDetail).GetPropertyValue(list[i], typeof(TDetail).GetKeyName()); | 
|                     if (detailId != null) | 
|                     { | 
|                         if (detailId.ToString() != "0") | 
|                         { | 
|                             updateRows.Add(list[i]); | 
|                         } | 
|                         else | 
|                         { | 
|                             addRows.Add(list[i]); | 
|                         } | 
|                     } | 
|                 } | 
|   | 
|                 object mainId = typeof(TEntity).GetPropertyValue(entity, typeof(TEntity).GetKeyName()); | 
|                 if (mainId != null) | 
|                 { | 
|                     ((SqlSugarClient)BaseDal.Db).BeginTran(); | 
|   | 
|                     if (dynamicDelKeys.Count > 0) | 
|                         BaseDal.Db.Deleteable<object>().AS(detailType.Name).Where($"{detailType.GetKeyName()} in (@id)", new { id = dynamicDelKeys.ToArray() }).ExecuteCommandHasChange(); | 
|   | 
|                     BaseDal.Db.Updateable(entity).ExecuteCommandHasChange(); | 
|   | 
|                     BaseDal.Db.Updateable(updateRows).ExecuteCommand(); | 
|   | 
|                     for (int i = 0; i < addRows.Count; i++) | 
|                     { | 
|                         TDetail detail = addRows[i]; | 
|                         typeof(TDetail).SetDetailId(detail, mainId, name); | 
|                     } | 
|   | 
|                     BaseDal.Db.Insertable(addRows).ExecuteCommand(); | 
|   | 
|                     ((SqlSugarClient)BaseDal.Db).CommitTran(); | 
|   | 
|                     content = WebResponseContent.Instance.OK(); | 
|                 } | 
|                 else | 
|                 { | 
|                     content = WebResponseContent.Instance.Error("未找到主表主键值"); | 
|                 } | 
|   | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 ((SqlSugarClient)BaseDal.Db).RollbackTran(); | 
|                 content = WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|   | 
|   | 
|         /// <summary> | 
|         /// 删除数据 | 
|         /// </summary> | 
|         /// <param name="key">主键</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent DeleteData(object key) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.DeleteDataById(key) ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 删除数据 | 
|         /// </summary> | 
|         /// <param name="keys">主键数组</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent DeleteData(object[] keys) | 
|         { | 
|             try | 
|             { | 
|                 if (typeof(TEntity).GetNavigatePro() == null) | 
|                     return BaseDal.DeleteDataByIds(keys) ? WebResponseContent.Instance.OK("删除成功") : WebResponseContent.Instance.Error(); | 
|                 else | 
|                 { | 
|                     if (keys != null) | 
|                     { | 
|                         Type detailType = typeof(TEntity).GetDetailType(); | 
|                         string name = typeof(TEntity).GetMainIdByDetail(); | 
|                         List<object> dynamicDelKeys = new List<object>(); | 
|   | 
|                         for (int i = 0; i < keys.Length; i++) | 
|                         { | 
|                             dynamicDelKeys.Add(keys[i]); | 
|                         } | 
|                         ((SqlSugarClient)BaseDal.Db).BeginTran(); | 
|   | 
|                         if (dynamicDelKeys.Count > 0) | 
|                             BaseDal.Db.Deleteable<object>().AS(detailType.Name).Where($"{name} in (@id)", new { id = dynamicDelKeys.ToArray() }).ExecuteCommandHasChange(); | 
|   | 
|                         BaseDal.DeleteDataByIds(keys); | 
|   | 
|                         ((SqlSugarClient)BaseDal.Db).CommitTran(); | 
|   | 
|                         return WebResponseContent.Instance.OK("删除成功"); | 
|                     } | 
|                     else | 
|                     { | 
|                         return WebResponseContent.Instance.Error("参数错误"); | 
|                     } | 
|                 } | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 ((SqlSugarClient)BaseDal.Db).RollbackTran(); | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 删除数据 | 
|         /// </summary> | 
|         /// <param name="entity">单个实体</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent DeleteData(TEntity entity) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.DeleteData(entity) ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 删除数据 | 
|         /// </summary> | 
|         /// <param name="entities">实体集合</param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent DeleteData(List<TEntity> entities) | 
|         { | 
|             try | 
|             { | 
|                 return BaseDal.DeleteData(entities) ? WebResponseContent.Instance.OK() : WebResponseContent.Instance.Error(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 导出数据 | 
|         /// </summary> | 
|         /// <param name="pageData"></param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent Export(PageDataOptions options) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 Type t = typeof(TEntity); | 
|   | 
|                 string savePath = AppDomain.CurrentDomain.BaseDirectory + $"ExcelExport"; | 
|                 IExporter exporter = new ExcelExporter(); | 
|                 string wheres = ValidatePageOptions(options); | 
|                 //获取排序字段 | 
|                 Dictionary<string, OrderByType> orderbyDic = GetPageDataSort(options, TProperties); | 
|   | 
|                 List<TEntity> entities = BaseDal.QueryData(wheres, orderbyDic); | 
|   | 
|                 byte[] data = exporter.ExportAsByteArray(entities).Result; | 
|   | 
|                 string fileName = ""; | 
|                 SugarTable sugarTable = t.GetCustomAttribute<SugarTable>(); | 
|                 if (sugarTable != null) | 
|                 { | 
|                     fileName = sugarTable.TableDescription + ".xlsx"; | 
|                 } | 
|                 else | 
|                 { | 
|                     fileName = nameof(TEntity) + ".xlsx"; | 
|                 } | 
|   | 
|                 FileHelper.WriteFile(savePath, fileName, data); | 
|   | 
|                 content = WebResponseContent.Instance.OK(data: savePath + "\\" + fileName); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content = WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 导入数据 | 
|         /// </summary> | 
|         /// <param name="files"></param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent Import(List<IFormFile> files) | 
|         { | 
|             try | 
|             { | 
|                 if (files == null || files.Count == 0) | 
|                     return new WebResponseContent { Status = true, Message = "请选择上传的文件" }; | 
|                 Microsoft.AspNetCore.Http.IFormFile formFile = files[0]; | 
|                 string dicPath = AppDomain.CurrentDomain.BaseDirectory + $"ExcelImprot/{DateTime.Now.ToString("yyyMMdd")}/{typeof(TEntity).Name}/"; | 
|                 if (!Directory.Exists(dicPath)) Directory.CreateDirectory(dicPath); | 
|                 string fileName = $"{Guid.NewGuid()}_{formFile.FileName}"; | 
|                 dicPath = $"{dicPath}{fileName}"; | 
|                 using (FileStream stream = new FileStream(dicPath, FileMode.Create)) | 
|                 { | 
|                     formFile.CopyTo(stream); | 
|                 } | 
|                 ExcelImporter importer = new ExcelImporter(); | 
|                 ImportResult<TEntity> importResult = importer.Import<TEntity>(dicPath, "").Result; | 
|                 if (importResult.HasError) | 
|                 { | 
|                     return WebResponseContent.Instance.Error(importResult.TemplateErrors.Serialize()); | 
|                 } | 
|                 BaseDal.AddData(importResult.Data.ToList()); | 
|                 return WebResponseContent.Instance.OK(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 return WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 上传文件 | 
|         /// </summary> | 
|         /// <param name="files"></param> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent Upload(List<IFormFile> files) | 
|         { | 
|             throw new NotImplementedException(); | 
|         } | 
|   | 
|         /// <summary> | 
|         /// 模板下载 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public virtual WebResponseContent DownLoadTemplate() | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             Type t = typeof(TEntity); | 
|             IExporter exporter = new ExcelExporter(); | 
|             byte[] data = exporter.ExportHeaderAsByteArray(new TEntity()).Result; | 
|             string fileName = ""; | 
|             SugarTable sugarTable = t.GetCustomAttribute<SugarTable>(); | 
|             if (sugarTable != null) | 
|             { | 
|                 fileName = sugarTable.TableDescription + "导入模板.xlsx"; | 
|             } | 
|             else | 
|             { | 
|                 fileName = nameof(TEntity) + "导入模板.xlsx"; | 
|             } | 
|             string savePath = AppDomain.CurrentDomain.BaseDirectory + $"ExcelImprotTemplate"; | 
|             FileHelper.WriteFile(savePath, fileName, data); | 
|   | 
|             content = WebResponseContent.Instance.OK(data: savePath + "\\" + fileName); | 
|             return content; | 
|         } | 
|     } | 
| } |