| using AutoMapper.Execution; | 
| using Magicodes.ExporterAndImporter.Core; | 
| using Magicodes.ExporterAndImporter.Core.Models; | 
| using Magicodes.ExporterAndImporter.Excel; | 
| using Microsoft.AspNetCore.Http; | 
| using Microsoft.AspNetCore.Mvc.RazorPages; | 
| using Microsoft.Extensions.Options; | 
| using Newtonsoft.Json; | 
| using SqlSugar; | 
| using System.Drawing.Drawing2D; | 
| using System.Dynamic; | 
| using System.Linq.Expressions; | 
| using System.Reflection; | 
| using System.Reflection.Metadata; | 
| using WIDESEA_Core.BaseRepository; | 
| using WIDESEA_Core.Const; | 
| using WIDESEA_Core.DB.Models; | 
| using WIDESEA_Core.Enums; | 
| using WIDESEA_Core.Helper; | 
| using WIDESEA_Core.HostedService; | 
| using WIDESEA_Core.Utilities; | 
| using ICacheService = WIDESEA_Core.Caches.ICacheService; | 
|   | 
| 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 = options.ValidatePageOptions(TProperties); | 
|   | 
|   | 
|             //Expression<Func<TEntity, bool>> test = ValidatePageOptions(options, _propertyInfo); | 
|   | 
|             //获取排序字段 | 
|             Dictionary<string, OrderByType> orderbyDic = options.GetPageDataSort(TProperties); | 
|             PageGridData<TEntity> pageGridData = new PageGridData<TEntity>(); | 
|             string dataWheres = GetDataRole(typeof(TEntity)); | 
|             if (!string.IsNullOrEmpty(wheres)) | 
|             { | 
|                 dataWheres += " and "; | 
|             } | 
|             pageGridData = BaseDal.QueryPage(dataWheres + wheres, options.Page, options.Rows, orderbyDic); | 
|             //int count = 0; | 
|             //ISugarQueryable<TEntity> sugarQueryable = BaseDal.Db.Queryable<TEntity>().Where(dataWheres); | 
|             //ValidatePageOptions(options, _propertyInfo, ref sugarQueryable); | 
|             //List<TEntity> rows = sugarQueryable.ToPageList(options.Page, options.Rows, ref count); | 
|   | 
|             //PageGridData<TEntity> pageGridData = new PageGridData<TEntity>() | 
|             //{ | 
|             //    Rows = rows, | 
|             //    Total = count, | 
|             //}; | 
|             return pageGridData; | 
|         } | 
|   | 
|         protected void ValidatePageOptions(PageDataOptions options, PropertyInfo[] entityProperties, ref ISugarQueryable<TEntity> sugarQueryable) | 
|         { | 
|             string where = string.Empty; | 
|             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 { } | 
|             } | 
|             for (int i = 0; i < searchParametersList.Count; i++) | 
|             { | 
|                 if (string.IsNullOrEmpty(searchParametersList[i].Value)) | 
|                 { | 
|                     continue; | 
|                 } | 
|   | 
|                 PropertyInfo? property = entityProperties.Where(c => c.Name.ToUpper() == searchParametersList[i].Name.ToUpper()).FirstOrDefault(); | 
|   | 
|                 if (property == null) continue; | 
|   | 
|                 List<(bool, string, object)> results = property.ValidationValueForDbType(searchParametersList[i].Value.Split(',')).ToList(); | 
|                 if (results == null || results.Count() == 0) | 
|                 { | 
|                     continue; | 
|                 } | 
|                 for (int j = 0; j < results.Count(); j++) | 
|                 { | 
|                     LinqExpressionType expressionType = searchParametersList[i].DisplayType.GetLinqCondition(); | 
|                     Expression<Func<TEntity, bool>> expression = GetWhereExpression(property.Name, results[j].Item3, null, expressionType); | 
|                     sugarQueryable = sugarQueryable.Where(expression); | 
|                 } | 
|             } | 
|         } | 
|   | 
|         protected Expression<Func<TEntity, bool>> GetWhereExpression(string propertyName, object propertyValue, ParameterExpression parameter, LinqExpressionType expressionType) | 
|         { | 
|             Type proType = typeof(TEntity).GetProperty(propertyName).PropertyType; | 
|             ConstantExpression constant = proType.ToString() == "System.String" | 
|                ? Expression.Constant(propertyValue) : Expression.Constant(propertyValue.ToString().ChangeType(proType)); | 
|   | 
|             // DateTime只选择了日期的时候自动在结束日期加一天,修复DateTime类型使用日期区间查询无法查询到结束日期的问题 | 
|             if ((proType == typeof(DateTime) || proType == typeof(DateTime?)) && expressionType == LinqExpressionType.LessThanOrEqual && propertyValue.ToString().Length == 10) | 
|             { | 
|                 constant = Expression.Constant(Convert.ToDateTime(propertyValue.ToString()).AddDays(1)); | 
|             } | 
|             parameter = parameter ?? Expression.Parameter(typeof(TEntity), "x"); | 
|             //创建节点的属性p=>p.name 属性name | 
|             MemberExpression memberProperty = Expression.PropertyOrField(parameter, propertyName); | 
|             UnaryExpression member = Expression.Convert(memberProperty, constant.Type); | 
|             Expression<Func<TEntity, bool>> expression = p => false; | 
|             switch (expressionType) | 
|             { | 
|                 //p=>p.propertyName == propertyValue | 
|                 case LinqExpressionType.Equal: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(member, constant), parameter); | 
|                     break; | 
|                 //p=>p.propertyName != propertyValue | 
|                 case LinqExpressionType.NotEqual: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.NotEqual(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName > propertyValue | 
|                 case LinqExpressionType.GreaterThan: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.GreaterThan(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName < propertyValue | 
|                 case LinqExpressionType.LessThan: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.LessThan(member, constant), parameter); | 
|                     break; | 
|                 // p => p.propertyName >= propertyValue | 
|                 case LinqExpressionType.ThanOrEqual: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter); | 
|                     break; | 
|                 // p => p.propertyName <= propertyValue | 
|                 case LinqExpressionType.LessThanOrEqual: | 
|                     expression = Expression.Lambda<Func<TEntity, bool>>(Expression.LessThanOrEqual(member, constant), parameter); | 
|                     break; | 
|                 //   p => p.propertyName.Contains(propertyValue) | 
|                 // p => !p.propertyName.Contains(propertyValue) | 
|                 case LinqExpressionType.Contains: | 
|                 case LinqExpressionType.NotContains: | 
|                     MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); | 
|                     constant = Expression.Constant(propertyValue, typeof(string)); | 
|                     if (expressionType == LinqExpressionType.Contains) | 
|                     { | 
|                         expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Call(member, method, constant), parameter); | 
|                     } | 
|                     else | 
|                     { | 
|                         expression = Expression.Lambda<Func<TEntity, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter); | 
|                     } | 
|                     break; | 
|                 default: | 
|                     //  | 
|                     expression = p => false; | 
|                     break; | 
|             } | 
|             return expression; | 
|         } | 
|   | 
|         private string GetDataRole(Type type) | 
|         { | 
|             try | 
|             { | 
|                 UserRole? userRole = PermissionDataHostService.UserRoles.FirstOrDefault(x => x.UserId == App.User.UserId); | 
|                 if (userRole == null) | 
|                     throw new Exception($"无权限"); | 
|   | 
|                 if (type.IsAssignableFrom(typeof(BaseWarehouseEntity)) || type.GetProperty(nameof(BaseWarehouseEntity.WarehouseId)) != null) | 
|                 { | 
|                     if (userRole.WarehouseIds.Count > 0) | 
|                     { | 
|                         return $"{nameof(BaseWarehouseEntity.WarehouseId)} in ({userRole.WarehouseIds.Serialize().Replace("[", "").Replace("]", "")})"; | 
|                     } | 
|   | 
|                     else | 
|                         return $"1 != 1"; | 
|                 } | 
|                 else | 
|                 { | 
|                     return "1 = 1"; | 
|                 } | 
|   | 
|                 //UserRole? userRole = PermissionDataHostService.UserRoles.FirstOrDefault(x => x.UserId == App.User.UserId); | 
|                 //if (userRole == null) | 
|                 //    throw new Exception($"无权限"); | 
|   | 
|                 //if (userRole.AuthorityScope == (int)AuthorityScopeEnum.CurrentRole) | 
|                 //{ | 
|                 //    List<int> userId = PermissionDataHostService.UserRoles.Where(x => x.RoleId == userRole.RoleId).Select(x => x.UserId).ToList(); | 
|                 //    return $"creater in ({userId.Serialize()})"; | 
|                 //} | 
|                 //else if (userRole.AuthorityScope == (int)AuthorityScopeEnum.OnlySelf) | 
|                 //{ | 
|                 //    return $"creater = '{userRole.UserName}'"; | 
|                 //} | 
|                 //else if (userRole.AuthorityScope == (int)AuthorityScopeEnum.None) | 
|                 //{ | 
|                 //    return $"1 != 1"; | 
|                 //} | 
|                 //return ""; | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 throw new Exception($"无权限,{ex.Message}"); | 
|             } | 
|         } | 
|   | 
|         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 ?? true) | 
|                     { | 
|                         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) | 
|                 { | 
|                     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() ?? null); | 
|   | 
|                 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 (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 = options.ValidatePageOptions(TProperties); | 
|                 //获取排序字段 | 
|                 Dictionary<string, OrderByType> orderbyDic = options.GetPageDataSort(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; | 
|         } | 
|   | 
|         public WebResponseContent ExportSeedData() | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 string seedDataFolder = $"WIDESEA_DB.DBSeed.Json/{typeof(TEntity).Name}.tsv"; | 
|                 List<TEntity> deviceInfos = BaseDal.QueryData(); | 
|                 string str = JsonConvert.SerializeObject(deviceInfos, Formatting.Indented); | 
|                 List<Dictionary<string, object>> keyValuePairs = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(str); | 
|                 FileHelper.WriteFileAndDelOldFile($"wwwroot/{seedDataFolder}", str); | 
|                 content = WebResponseContent.Instance.OK(); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content = WebResponseContent.Instance.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|     } | 
| } |