Browse Source

修改基类

master
boxu.zheng 1 year ago
parent
commit
34375a91f4
  1. 134
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/AppBase/ZbxBase.cs
  2. 23
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/ExpressionExtensions.cs
  3. 49
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/ObjectExpressionExtensions.cs
  4. 113
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/ObjectMapperExtensions.cs
  5. 16
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/StringExtensions.cs
  6. 2
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Faster.Zheng.Winin.Application.csproj
  7. 6
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.EntityFrameworkCore/EntityFrameworkCore/WininDbContext.cs
  8. 2
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebAutoMapperProfile.cs
  9. 2
      Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebModule.cs

134
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/AppBase/ZbxBase.cs

@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
@ -8,8 +9,11 @@ using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
using Faster.Zheng.Winin.AppBase.Filters;
using Faster.Zheng.Winin.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Entities;
@ -17,6 +21,7 @@ using Volo.Abp.Domain.Repositories;
using Volo.Abp.EntityFrameworkCore;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using static OpenIddict.Abstractions.OpenIddictConstants;
using static Volo.Abp.UI.Navigation.DefaultMenuNames.Application;
namespace Faster.Zheng.Winin.AppBase;
@ -92,20 +97,7 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto,
{
await CheckCreatePolicyAsync();
var mapperConfig = new MapperConfiguration(cfg =>
{
cfg.CreateMap<TCreateInput, TEntity>();
});
var _mapper = mapperConfig.CreateMapper();
var source = Expression.Parameter(typeof(TCreateInput), "source");
_mapFunc = Expression.Lambda<Func<TCreateInput, TEntity>>(
Expression.Invoke(Expression.Constant(_mapper.Map<TCreateInput, TEntity>)), source)
.Compile();
var tt= _mapper.Map<TCreateInput, TEntity>(input);
var entity = await MapToEntityAsync(input);
var entity = input!.ToObject<TEntity>();
//判断id是否是00000-0000 如果是则赋值
var mainId = (Guid)entity.GetType().GetProperty("Id")?.GetValue(entity)!;
@ -197,9 +189,119 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto,
/// <param name="input"></param>
/// <returns></returns>
[HttpPut("api/[controller]/base/update-by-id")]
public override Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input)
public override async Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input)
{
return base.UpdateAsync(id, input);
//return base.UpdateAsync(id, input);
await CheckUpdatePolicyAsync().ConfigureAwait(continueOnCapturedContext: false);
TEntity entity = await GetEntityByIdAsync(id).ConfigureAwait(continueOnCapturedContext: false);
entity.FromObject(input!);
#region 给所有字表的 Id和MasterId赋值 否则默认的会是000000-000-....的id 插入时会报错
var propertyInfos = entity.GetType().GetProperties();
foreach (var propertyInfo in propertyInfos)
{
//判断是否是List集合
if (propertyInfo.Name == "Details"
&& propertyInfo.PropertyType.IsGenericType
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
{
var listProperty = typeof(TEntity).GetProperty("Details");
// 获取 List 的元素类型
if (listProperty != null)
{
var listItemType = listProperty.PropertyType.GetGenericArguments()[0];
// 获取元素类型的 ID 属性
var detailIdProperty = listItemType.GetProperty("Id");
var masterIdProperty = listItemType.GetProperty("MasterId");
if (detailIdProperty != null)
{
// 获取 List 属性的值
var list = (IList)listProperty.GetValue(entity);
// 遍历 List 集合中的每个元素,给 ID 属性赋值
if (list != null)
{
foreach (var item in list)
{
if ((Guid)detailIdProperty.GetValue(item)! == Guid.Empty)
{
detailIdProperty.SetValue(item, Guid.NewGuid());
}
}
}
}
if (masterIdProperty != null)
{
// 获取 List 属性的值
var list = (IList)listProperty.GetValue(entity);
// 遍历 List 集合中的每个元素,给 ID 属性赋值
if (list != null)
{
foreach (var item in list)
{
masterIdProperty.SetValue(item, id);
}
}
}
}
}
}
#endregion
await Repository.UpdateAsync(entity, autoSave: true);
return await MapToGetOutputDtoAsync(entity);
}
/// <summary>
/// 导出Excel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <param name="filePath"></param>
[HttpPost("api/[controller]/base/export-to-excel")]
public void ExportToExcel<T>(IEnumerable<T> data, string filePath)
{
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");
// 获取泛型参数的类型
var type = typeof(T);
var properties = type.GetProperties();
// 创建表头
IRow headerRow = sheet.CreateRow(0);
for (int i = 0; i < properties.Length; i++)
{
headerRow.CreateCell(i).SetCellValue(properties[i].Name);
}
// 填充数据行
int rowIndex = 1;
foreach (var item in data)
{
IRow dataRow = sheet.CreateRow(rowIndex);
for (int i = 0; i < properties.Length; i++)
{
var value = properties[i].GetValue(item);
dataRow.CreateCell(i).SetCellValue(value?.ToString());
}
rowIndex++;
}
// 保存Excel文件
using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
workbook.Write(fileStream,true);
}
}
#endregion

23
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/ExpressionExtensions.cs

@ -0,0 +1,23 @@
using System.Linq.Expressions;
namespace Faster.Zheng.Winin.Extensions;
public static class ExpressionExtensions
{
public static string GetMemberName(Expression expression)
{
if (expression is MemberExpression member)
{
return member.Member.Name;
}
else if (expression is MethodCallExpression method)
{
return method.Method.Name;
}
else if (expression is UnaryExpression unary)
{
return GetMemberName(unary);
}
return null;
}
}

49
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/ObjectExpressionExtensions.cs

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Reflection;
namespace Faster.Zheng.Winin.Extensions;
public static class ObjectExpressionExtensions
{
public static IQueryable<TEntity> WhereByKey<TEntity, TModel>(this IQueryable<TEntity> source, TModel model)
{
if (model == null)
{
return null;
}
var modelType = model.GetType();
var properties = modelType.GetProperties().Where(o => o.GetCustomAttribute<KeyAttribute>() != null).ToList();
if (properties.Any())
{
foreach (var property in properties)
{
var propertyName = property.Name;
var propertyValue = property.GetValue(model, null);
source = source.Where($"{propertyName} == @0", propertyValue);
}
return source;
}
return null;
}
public static List<IGrouping<object, T>> GroupByKey<T>(this IQueryable<T> source)
{
var properties = typeof(T).GetProperties().Where(o => o.GetCustomAttribute<KeyAttribute>() != null).ToList();
var names = string.Join(",", properties.Select(o => o.Name));
return source.AsQueryable().GroupBy($"new ({names})").ToDynamicList<IGrouping<object, T>>();
}
public static Expression<Func<TEntity, bool>> GetExpressionByProperty<TEntity>(this Type type, string propertyName, string propertyValue)
{
var o = Expression.Parameter(type, "p");
var memberExpression = Expression.Property(o, propertyName);
var body = Expression.Call(typeof(string).GetMethod("Contains", new[] { typeof(string) }), memberExpression);
var predicate = Expression.Lambda<Func<TEntity, bool>>(body, o);
return predicate;
}
}

113
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/ObjectMapperExtensions.cs

@ -0,0 +1,113 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Omu.ValueInjecter;
using Omu.ValueInjecter.Injections;
using Volo.Abp;
namespace Faster.Zheng.Winin.Extensions;
/// <summary>
/// 对象映射
/// </summary>
public static class ObjectMapperExtensions
{
/// <summary>
/// 从模型更新实体
/// </summary>
public static T FromObject<T>(this T to, object from)
{
try
{
to.InjectFrom<DeepInjectionForUpdate>(from);
return to;
}
catch (Exception ex)
{
throw new UserFriendlyException($"{from.GetType().FullName}映射到${typeof(T).FullName}时失败:{ex.Message},{ex}");
}
}
/// <summary>
/// 从实体创建模型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="from"></param>
/// <returns></returns>
public static T ToObject<T>(this object from)
{
try
{
if (typeof(T).IsGenericType && typeof(T).IsAssignableTo(typeof(IList)) && from is IList list)
{
var toListType = typeof(T);
var elementType = typeof(T).GetGenericArguments()[0];
var toList = (IList)Activator.CreateInstance(typeof(T))!;
var fromList = list;
foreach (var item in fromList)
{
toList.Add(Activator.CreateInstance(elementType).InjectFrom<DeepInjection>(item));
}
return (T)toList;
}
return (T)Activator.CreateInstance<T>().InjectFrom<DeepInjection>(from);
}
catch (Exception ex)
{
throw new UserFriendlyException($"{from.GetType().FullName}映射到${typeof(T).FullName}时失败:{ex.Message},{ex}");
}
}
private class DeepInjection : LoopInjection
{
protected override bool MatchTypes(Type sourceType, Type targetType)
{
if (sourceType != typeof(string) &&
targetType != typeof(string) &&
sourceType.IsGenericType &&
targetType.IsGenericType &&
sourceType.IsAssignableTo(typeof(IEnumerable)) &&
sourceType.IsAssignableTo(typeof(IEnumerable))
)
{
return true;
}
return base.MatchTypes(sourceType, targetType);
}
protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
{
if (sp.PropertyType != typeof(string) &&
sp.PropertyType != typeof(string) &&
sp.PropertyType.IsAssignableTo(typeof(IList)) &&
tp.PropertyType.IsAssignableTo(typeof(IList)))
{
var targetGenericType = tp.PropertyType.GetGenericArguments()[0];
var listType = typeof(List<>).MakeGenericType(targetGenericType);
var addMethod = listType.GetMethod("Add");
var list = Activator.CreateInstance(listType);
var sourceList = (IList)sp.GetValue(source);
foreach (var item in sourceList)
{
addMethod.Invoke(list, new[] { Activator.CreateInstance(targetGenericType).FromObject(item) });
}
tp.SetValue(target, list);
return;
}
base.SetValue(source, target, sp, tp);
}
}
private class DeepInjectionForUpdate : DeepInjection
{
protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
{
//if (tp.GetCustomAttribute<IgnoreUpdateAttribute>() != null)
//{
// return;
//}
base.SetValue(source, target, sp, tp);
}
}
}

16
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Extensions/StringExtensions.cs

@ -0,0 +1,16 @@
using System;
using System.Security.Cryptography;
using System.Text;
namespace Faster.Zheng.Winin.Extensions;
public static class StringExtensions
{
public static string Md5(this string input)
{
using (var md5 = MD5.Create())
{
return BitConverter.ToString(md5.ComputeHash(Encoding.ASCII.GetBytes(input))).Replace("-", "");
}
}
}

2
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Application/Faster.Zheng.Winin.Application.csproj

@ -16,6 +16,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="NPOI" Version="2.6.0" />
<PackageReference Include="ValueInjecter" Version="3.2.0" />
<PackageReference Include="Volo.Abp.Account.Application" Version="7.2.1" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="7.2.1" />
<PackageReference Include="Volo.Abp.Identity.Application" Version="7.2.1" />

6
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.EntityFrameworkCore/EntityFrameworkCore/WininDbContext.cs

@ -102,8 +102,10 @@ public class WininDbContext :
builder.Entity<TestSchool>(b =>
{
b.ToTable(WininConsts.DbTablePrefix + "TestSchools", WininConsts.DbSchema, table => table.HasComment(""));
b.ConfigureByConvention();
b.ConfigureByConvention();
// 【手动】如果需要添加级联删除
b.HasMany(q => q.Details).WithOne().HasForeignKey(d => d.MasterId).IsRequired();
/* Configure more properties here */
});

2
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebAutoMapperProfile.cs

@ -5,6 +5,7 @@ using Faster.Zheng.Winin.Web.Pages.AppBusiness.TestSchool.TestStudentDetail.View
using Faster.Zheng.Winin.AppBusiness.DemoCar.Dtos;
using Faster.Zheng.Winin.Web.Pages.AppBusiness.DemoCar.DemoCar.ViewModels;
using AutoMapper;
using Microsoft.AspNetCore.Http.HttpResults;
namespace Faster.Zheng.Winin.Web;
@ -21,3 +22,4 @@ public class WininWebAutoMapperProfile : Profile
CreateMap<CreateEditDemoCarViewModel, CreateUpdateDemoCarDto>();
}
}

2
Code/Be/Faster.Zheng.Winin/src/Faster.Zheng.Winin.Web/WininWebModule.cs

@ -43,6 +43,8 @@ using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.Settings;
using Polly;
using Autofac.Core;
using static Faster.Zheng.Winin.Web.WininWebAutoMapperProfile;
namespace Faster.Zheng.Winin.Web;

Loading…
Cancel
Save