|
@ -1,33 +1,27 @@ |
|
|
using Volo.Abp.Domain.Entities.Auditing; |
|
|
using System; |
|
|
using Volo.Abp.Identity; |
|
|
|
|
|
|
|
|
|
|
|
namespace WinIn.FasterZ.Wms.AppBase; |
|
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
|
|
using System.Collections; |
|
|
using System.Collections; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Generic; |
|
|
using System.IO; |
|
|
using System.IO; |
|
|
using System.Linq; |
|
|
using System.Linq; |
|
|
using System.Linq.Dynamic.Core; |
|
|
using System.Linq.Dynamic.Core; |
|
|
using System.Linq.Expressions; |
|
|
using System.Linq.Expressions; |
|
|
using System.Reflection; |
|
|
|
|
|
using System.Threading; |
|
|
using System.Threading; |
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
|
|
|
using AutoMapper; |
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.EntityFrameworkCore; |
|
|
using Microsoft.EntityFrameworkCore; |
|
|
|
|
|
using Microsoft.Extensions.Caching.Distributed; |
|
|
using Microsoft.Extensions.Localization; |
|
|
using Microsoft.Extensions.Localization; |
|
|
|
|
|
|
|
|
using NPOI.SS.UserModel; |
|
|
using NPOI.SS.UserModel; |
|
|
using NPOI.XSSF.UserModel; |
|
|
using NPOI.XSSF.UserModel; |
|
|
|
|
|
using Volo.Abp; |
|
|
using Volo.Abp.Application.Dtos; |
|
|
using Volo.Abp.Application.Dtos; |
|
|
using Volo.Abp.Application.Services; |
|
|
using Volo.Abp.Application.Services; |
|
|
|
|
|
using Volo.Abp.Caching; |
|
|
using Volo.Abp.Domain.Entities; |
|
|
using Volo.Abp.Domain.Entities; |
|
|
|
|
|
using Volo.Abp.Domain.Entities.Auditing; |
|
|
using Volo.Abp.Domain.Repositories; |
|
|
using Volo.Abp.Domain.Repositories; |
|
|
|
|
|
|
|
|
using WinIn.FasterZ.Store.AppBase; |
|
|
|
|
|
using WinIn.FasterZ.Store.AppBase.Filters; |
|
|
using WinIn.FasterZ.Store.AppBase.Filters; |
|
|
using WinIn.FasterZ.Store.AppBase.TableColumnTypeDto; |
|
|
using WinIn.FasterZ.Store.AppBase.TableColumnTypeDto; |
|
|
using WinIn.FasterZ.Store.Enums; |
|
|
using WinIn.FasterZ.Store.Enums; |
|
@ -35,6 +29,8 @@ using WinIn.FasterZ.Wms.AppBase.Extensions; |
|
|
using WinIn.FasterZ.Wms.AppBaseBusiness.ExportCustomUserSetting; |
|
|
using WinIn.FasterZ.Wms.AppBaseBusiness.ExportCustomUserSetting; |
|
|
using WinIn.FasterZ.Wms.Localization; |
|
|
using WinIn.FasterZ.Wms.Localization; |
|
|
|
|
|
|
|
|
|
|
|
namespace WinIn.FasterZ.Wms.AppBase; |
|
|
|
|
|
|
|
|
public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> : |
|
|
public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> : |
|
|
CrudAppService<TEntity, TEntityDto, TKey, |
|
|
CrudAppService<TEntity, TEntityDto, TKey, |
|
|
TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput>, |
|
|
TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput>, |
|
@ -42,19 +38,33 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
where TEntity : class, IEntity<TKey> |
|
|
where TEntity : class, IEntity<TKey> |
|
|
where TEntityDto : IEntityDto<TKey> |
|
|
where TEntityDto : IEntityDto<TKey> |
|
|
{ |
|
|
{ |
|
|
|
|
|
#region 定义
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// redis缓存时间 分钟
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private const int CacheMinute = 30; |
|
|
|
|
|
|
|
|
private readonly IRepository<TEntity, TKey> _repository; |
|
|
private readonly IRepository<TEntity, TKey> _repository; |
|
|
|
|
|
|
|
|
protected IStringLocalizer<WmsResource> Localizer => |
|
|
private IMapper _mapper; |
|
|
|
|
|
|
|
|
|
|
|
private IStringLocalizer<WmsResource> Localizer => |
|
|
LazyServiceProvider.LazyGetRequiredService<IStringLocalizer<WmsResource>>(); |
|
|
LazyServiceProvider.LazyGetRequiredService<IStringLocalizer<WmsResource>>(); |
|
|
|
|
|
|
|
|
protected ExportCustomUserSettingAppService ExportCustomUserSettingAppService => |
|
|
private ExportCustomUserSettingAppService ExportCustomUserSettingAppService => |
|
|
LazyServiceProvider.LazyGetRequiredService<ExportCustomUserSettingAppService>(); |
|
|
LazyServiceProvider.LazyGetRequiredService<ExportCustomUserSettingAppService>(); |
|
|
|
|
|
|
|
|
|
|
|
private IDistributedCache<TEntity> Cache => |
|
|
|
|
|
LazyServiceProvider.LazyGetRequiredService<IDistributedCache<TEntity>>(); |
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// 构造方法
|
|
|
/// 构造方法
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
/// <param name="repository"></param>
|
|
|
/// <param name="repository"></param>
|
|
|
public ZbxBase(IRepository<TEntity, TKey> repository) : base(repository) |
|
|
protected ZbxBase(IRepository<TEntity, TKey> repository) : base(repository) |
|
|
{ |
|
|
{ |
|
|
_repository = repository; |
|
|
_repository = repository; |
|
|
} |
|
|
} |
|
@ -172,6 +182,7 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
|
|
|
|
|
|
TryToSetTenantId(entity); |
|
|
TryToSetTenantId(entity); |
|
|
await Repository.InsertAsync(entity, true); |
|
|
await Repository.InsertAsync(entity, true); |
|
|
|
|
|
|
|
|
return await MapToGetOutputDtoAsync(entity); |
|
|
return await MapToGetOutputDtoAsync(entity); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -193,75 +204,81 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
/// <param name="input"></param>
|
|
|
/// <param name="input"></param>
|
|
|
/// <returns></returns>
|
|
|
/// <returns></returns>
|
|
|
[HttpPut("api/[controller]/base/update-by-id")]
|
|
|
[HttpPut("api/[controller]/base/update-by-id")]
|
|
|
public override async Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input) |
|
|
public new async Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input) |
|
|
{ |
|
|
{ |
|
|
//return base.UpdateAsync(id, input);
|
|
|
//return base.UpdateAsync(id, input);
|
|
|
|
|
|
|
|
|
await CheckUpdatePolicyAsync().ConfigureAwait(false); |
|
|
await CheckUpdatePolicyAsync().ConfigureAwait(true); |
|
|
var entity = await GetEntityByIdAsync(id).ConfigureAwait(false); |
|
|
var entity = await GetEntityByIdAsync(id).ConfigureAwait(true); |
|
|
entity.FromObject(input!); |
|
|
if (entity.GetType().GetProperty("ConcurrencyStamp").GetValue(entity).ToString() != |
|
|
|
|
|
input.GetType().GetProperty("ConcurrencyStamp").GetValue(input).ToString()) |
|
|
|
|
|
{ |
|
|
|
|
|
throw new UserFriendlyException($"您操作的数据已经被修改:\r\n" + |
|
|
|
|
|
$"已经由【{Newtonsoft.Json.JsonConvert.SerializeObject(entity)}】\r\n" + |
|
|
|
|
|
$"变更为【{Newtonsoft.Json.JsonConvert.SerializeObject(input)}】\r\n"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#region 给所有字表的 Id和MasterId赋值 否则默认的会是000000-000-....的id 插入时会报错
|
|
|
Type inputDetailDtoType = null; |
|
|
|
|
|
Type entityDetailType = null; |
|
|
|
|
|
bool inputDetailDtoTypeFlag = false; |
|
|
|
|
|
bool entityDetailTypeFlag = false; |
|
|
|
|
|
|
|
|
var propertyInfos = entity.GetType().GetProperties(); |
|
|
var t3 = typeof(TUpdateInput); |
|
|
foreach (var propertyInfo in propertyInfos) |
|
|
|
|
|
|
|
|
var entityProperties = entity.GetType().GetProperties(); |
|
|
|
|
|
var inputProperties = input.GetType().GetProperties(); |
|
|
|
|
|
|
|
|
|
|
|
//InputDto的
|
|
|
|
|
|
foreach (var propertyInfo in inputProperties) |
|
|
{ |
|
|
{ |
|
|
//判断是否是List集合
|
|
|
|
|
|
if (propertyInfo.Name == "Details" |
|
|
if (propertyInfo.Name == "Details" |
|
|
&& propertyInfo.PropertyType.IsGenericType |
|
|
&& propertyInfo.PropertyType.IsGenericType |
|
|
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
|
|
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
|
|
{ |
|
|
{ |
|
|
var listProperty = typeof(TEntity).GetProperty("Details"); |
|
|
var listProperty = typeof(TUpdateInput).GetProperty("Details"); |
|
|
|
|
|
|
|
|
// 获取 List 的元素类型
|
|
|
|
|
|
if (listProperty != null) |
|
|
if (listProperty != null) |
|
|
{ |
|
|
{ |
|
|
var listItemType = listProperty.PropertyType.GetGenericArguments()[0]; |
|
|
inputDetailDtoType = listProperty.PropertyType.GetGenericArguments()[0]; |
|
|
|
|
|
inputDetailDtoTypeFlag = true; |
|
|
// 获取元素类型的 ID 属性
|
|
|
} |
|
|
var detailIdProperty = listItemType.GetProperty("Id"); |
|
|
} |
|
|
var masterIdProperty = listItemType.GetProperty("MasterId"); |
|
|
} |
|
|
|
|
|
|
|
|
if (detailIdProperty != null) |
|
|
if (inputDetailDtoTypeFlag == true) |
|
|
{ |
|
|
{ |
|
|
// 获取 List 属性的值
|
|
|
//实体的
|
|
|
var list = (IList)listProperty.GetValue(entity); |
|
|
foreach (var propertyInfo in entityProperties) |
|
|
|
|
|
|
|
|
// 遍历 List 集合中的每个元素,给 ID 属性赋值
|
|
|
|
|
|
if (list != null) |
|
|
|
|
|
{ |
|
|
{ |
|
|
foreach (var item in list) |
|
|
//判断是否是List集合
|
|
|
|
|
|
if (propertyInfo.Name == "Details" |
|
|
|
|
|
&& propertyInfo.PropertyType.IsGenericType |
|
|
|
|
|
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
|
|
{ |
|
|
{ |
|
|
if ((Guid)detailIdProperty.GetValue(item)! == Guid.Empty) |
|
|
var listProperty = typeof(TEntity).GetProperty("Details"); |
|
|
|
|
|
// 获取 List 的元素类型
|
|
|
|
|
|
if (listProperty != null) |
|
|
{ |
|
|
{ |
|
|
detailIdProperty.SetValue(item, Guid.NewGuid()); |
|
|
entityDetailType = listProperty.PropertyType.GetGenericArguments()[0]; |
|
|
|
|
|
entityDetailTypeFlag = true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (masterIdProperty != null) |
|
|
if (inputDetailDtoTypeFlag == true && entityDetailTypeFlag==true) |
|
|
{ |
|
|
{ |
|
|
// 获取 List 属性的值
|
|
|
var config = new MapperConfiguration(cfg => |
|
|
var list = (IList)listProperty.GetValue(entity); |
|
|
|
|
|
|
|
|
|
|
|
// 遍历 List 集合中的每个元素,给 ID 属性赋值
|
|
|
|
|
|
if (list != null) |
|
|
|
|
|
{ |
|
|
|
|
|
foreach (var item in list) |
|
|
|
|
|
{ |
|
|
{ |
|
|
masterIdProperty.SetValue(item, id); |
|
|
// 动态创建映射关系
|
|
|
} |
|
|
cfg.CreateMap(typeof(TEntityDto), typeof(TEntity)); |
|
|
} |
|
|
cfg.CreateMap(typeof(TUpdateInput), typeof(TEntity)); |
|
|
} |
|
|
cfg.CreateMap(inputDetailDtoType, entityDetailType); |
|
|
} |
|
|
}); |
|
|
} |
|
|
_mapper = new Mapper(config); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#endregion
|
|
|
await ReMoveCaCheAsync(id).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
await Repository.UpdateAsync(entity, true); |
|
|
await Repository.UpdateAsync(entity, true); |
|
|
|
|
|
|
|
|
return await MapToGetOutputDtoAsync(entity); |
|
|
return await MapToGetOutputDtoAsync(entity); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -456,7 +473,7 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
for (var i = 0; i < mainProperties.Length + splitDetailsColumnNumber + detailProperties.Length; i++) |
|
|
for (var i = 0; i < mainProperties.Length + splitDetailsColumnNumber + detailProperties.Length; i++) |
|
|
{ |
|
|
{ |
|
|
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15); |
|
|
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15); |
|
|
if (colWidth > 255 * 256)//excel列有最大宽度限制
|
|
|
if (colWidth > 255 * 256) //excel列有最大宽度限制
|
|
|
{ |
|
|
{ |
|
|
colWidth = 6000; |
|
|
colWidth = 6000; |
|
|
} |
|
|
} |
|
@ -470,7 +487,7 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
for (var i = 0; i < mainProperties.Length; i++) |
|
|
for (var i = 0; i < mainProperties.Length; i++) |
|
|
{ |
|
|
{ |
|
|
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15); |
|
|
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15); |
|
|
if (colWidth > 255 * 256)//excel列有最大宽度限制
|
|
|
if (colWidth > 255 * 256) //excel列有最大宽度限制
|
|
|
{ |
|
|
{ |
|
|
colWidth = 6000; |
|
|
colWidth = 6000; |
|
|
} |
|
|
} |
|
@ -516,10 +533,34 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
return tableColumnTypeDtos; |
|
|
return tableColumnTypeDtos; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 【基础】-【获取 增 改 查基础的Dto数据类型】
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpPost("api/[controller]/base/get-cache-by-id/{id}")]
|
|
|
|
|
|
public virtual async Task<TEntityDto> GetCacheByIdAsync(TKey id) |
|
|
|
|
|
{ |
|
|
|
|
|
var entity = await Cache.GetOrAddAsync( |
|
|
|
|
|
$"{typeof(TEntityDto).Name}:{id}".ToString(), |
|
|
|
|
|
async () => await GetEntityByIdAsync(id), GetCacheTime); |
|
|
|
|
|
var dto = ObjectMapper.Map<TEntity, TEntityDto>(entity!); |
|
|
|
|
|
return dto; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#endregion
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 私有处理
|
|
|
#region 私有处理
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 清楚缓存
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private async Task ReMoveCaCheAsync(TKey id) |
|
|
|
|
|
{ |
|
|
|
|
|
await Cache.RemoveAsync(id?.ToString()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// 按表达式条件获取分页列表
|
|
|
/// 按表达式条件获取分页列表
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
@ -565,7 +606,7 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
var createTimePropertyInfo = typeof(TEntity).GetProperty(nameof(AuditedEntity.CreationTime)); |
|
|
var createTimePropertyInfo = typeof(TEntity).GetProperty(nameof(AuditedEntity.CreationTime)); |
|
|
if (createTimePropertyInfo != null) |
|
|
if (createTimePropertyInfo != null) |
|
|
{ |
|
|
{ |
|
|
entities = entities.OrderBy(nameof(AuditedEntity.CreationTime) +" DESC"); |
|
|
entities = entities.OrderBy(nameof(AuditedEntity.CreationTime) + " DESC"); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
@ -653,6 +694,22 @@ public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, |
|
|
return count; |
|
|
return count; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取缓存redis时间
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private static DistributedCacheEntryOptions GetCacheTime() |
|
|
|
|
|
{ |
|
|
|
|
|
var random = new Random(); |
|
|
|
|
|
//解决雪崩 添加随机缓存时间
|
|
|
|
|
|
var time = CacheMinute + random.Next(10, 30); |
|
|
|
|
|
return new DistributedCacheEntryOptions |
|
|
|
|
|
{ |
|
|
|
|
|
AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(time) |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Excel导出的样式设置
|
|
|
#region Excel导出的样式设置
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|