You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

899 lines
27 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
using Dy_Exchange.Enums;
using Dy_Exchange.Localization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Localization;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Domain.Repositories;
using WinIn.FasterZ.Inventory.AppBase;
using WinIn.FasterZ.Inventory.AppBase.Filters;
using WinIn.FasterZ.Inventory.AppBase.TableColumnTypeDto;
using WinIn.FasterZ.Wms.AppBase.Extensions;
using WinIn.FasterZ.Wms.AppBaseBusiness.ExportCustomUserSetting;
#pragma warning disable CS8602 // Dereference of a possibly null reference.
namespace WinIn.FasterZ.Wms.AppBase;
[Route("Api/[controller]")]
public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> :
CrudAppService<TEntity, TEntityDto, TKey,
TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput>,
IZbxBase<TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput>
where TEntity : class, IEntity<TKey>
where TEntityDto : IEntityDto<TKey>
{
#region 定义
/// <summary>
/// redis缓存时间 分钟
/// </summary>
private const int CacheMinute = 30;
private readonly IRepository<TEntity, TKey> _repository;
private IMapper _mapper;
private IStringLocalizer<Dy_ExchangeResource> Localizer =>
LazyServiceProvider.LazyGetRequiredService<IStringLocalizer<Dy_ExchangeResource>>();
private ExportCustomUserSettingAppService ExportCustomUserSettingAppService =>
LazyServiceProvider.LazyGetRequiredService<ExportCustomUserSettingAppService>();
private IDistributedCache<TEntity> Cache =>
LazyServiceProvider.LazyGetRequiredService<IDistributedCache<TEntity>>();
#endregion
/// <summary>
/// 构造方法
/// </summary>
/// <param name="repository"></param>
protected ZbxBase(IRepository<TEntity, TKey> repository) : base(repository)
{
_repository = repository;
}
#region 公开接口
#region 单体操作
/// <summary>
/// 【基础】-【新增】
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Base/Create")]
[Authorize]
public override async Task<TEntityDto> CreateAsync(TCreateInput input)
{
await CheckCreatePolicyAsync().ConfigureAwait(false);
var entity = input!.ToObject<TEntity>();
//判断id是否是00000-0000 如果是则赋值
var mainId = (Guid)entity.GetType().GetProperty("Id")?.GetValue(entity)!;
if (mainId == Guid.Empty)
{
mainId = Guid.NewGuid();
entity.GetType().GetProperty("Id")?.SetValue(entity, mainId);
}
#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, mainId);
}
}
}
}
}
}
#endregion
TryToSetTenantId(entity);
await Repository.InsertAsync(entity, true).ConfigureAwait(false);
return await MapToGetOutputDtoAsync(entity).ConfigureAwait(false);
}
/// <summary>
/// 【基础】-【删除】
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("Base/Delete")]
[Authorize]
public override async Task DeleteAsync(TKey id)
{
await CheckDeletePolicyAsync().ConfigureAwait(false);
await _repository.DeleteAsync(id, true).ConfigureAwait(false);
}
/// <summary>
/// 【基础】-【修改】
/// </summary>
/// <param name="id"></param>
/// <param name="input"></param>
/// <returns></returns>
[HttpPut("Base/Update")]
[Authorize]
public override async Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input)
{
await CheckUpdatePolicyAsync().ConfigureAwait(true);
var entity = await GetEntityByIdAsync(id).ConfigureAwait(true);
//当一条库存的一部分被人修改了 数据无法提交 例如库存10个 修改了其中4个 这时乐观锁就被修改了 会抛出异常
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");
}
Type? inputDetailDtoType = null;
Type? entityDetailType = null;
var inputDetailDtoTypeFlag = false; //input是否有子集合Details
var entityDetailTypeFlag = false; //entity是否有子集合Details
var entityProperties = entity.GetType().GetProperties();
var inputProperties = input.GetType().GetProperties();
//InputDto的
foreach (var propertyInfo in inputProperties)
{
if (propertyInfo.Name == "Details"
&& propertyInfo.PropertyType.IsGenericType
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
{
var listProperty = typeof(TUpdateInput).GetProperty("Details");
if (listProperty != null)
{
inputDetailDtoType = listProperty.PropertyType.GetGenericArguments()[0];
inputDetailDtoTypeFlag = true;
}
}
}
if (inputDetailDtoTypeFlag)
{
//实体的
foreach (var propertyInfo in entityProperties)
{
//判断是否是List集合
if (propertyInfo.Name == "Details"
&& propertyInfo.PropertyType.IsGenericType
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
{
var listProperty = typeof(TEntity).GetProperty("Details");
// 获取 List 的元素类型
if (listProperty != null)
{
entityDetailType = listProperty.PropertyType.GetGenericArguments()[0];
entityDetailTypeFlag = true;
}
}
}
}
if (inputDetailDtoTypeFlag && entityDetailTypeFlag)
{
var config = new MapperConfiguration(cfg =>
{
// 动态创建映射关系
cfg.CreateMap(typeof(TEntityDto), typeof(TEntity));
cfg.CreateMap(typeof(TUpdateInput), typeof(TEntity));
cfg.CreateMap(inputDetailDtoType, entityDetailType);
});
_mapper = new Mapper(config);
}
else
{
var config = new MapperConfiguration(cfg =>
{
// 动态创建映射关系
//todo 这里先要判断ID是否是000000-000000
cfg.CreateMap(typeof(TEntityDto), typeof(TEntity));
cfg.CreateMap(typeof(TUpdateInput), typeof(TEntity))
.ForMember("Id", opt => opt.Ignore())
.ForMember("ConcurrencyStamp", opt => opt.Ignore());
});
_mapper = new Mapper(config);
}
MapProperties(input, entity);
//entity.GetType().GetProperty("Id")?.SetValue(entity,id);
await ReMoveCaCheAsync(id).ConfigureAwait(false);
await _repository.UpdateAsync(entity, true).ConfigureAwait(true);
return await MapToGetOutputDtoAsync(entity).ConfigureAwait(false);
}
#endregion
#region 批量操作
/// <summary>
/// 【基础】-【批量】-【新增】
/// </summary>
/// <param name="inputList"></param>
/// <returns></returns>
[HttpPost("Base/Create-Many")]
[Authorize]
public async Task<List<TEntityDto>> CreateManyAsync(List<TCreateInput> inputList)
{
var dtoList = new List<TEntityDto>();
foreach (var input in inputList)
{
dtoList.Add(await CreateAsync(input).ConfigureAwait(false));
}
return dtoList;
}
/// <summary>
/// 【基础】-【批量】-【删除】
/// </summary>
/// <param name="keyList"></param>
/// <returns></returns>
[HttpDelete("Base/Delete-Many")]
[Authorize]
public async Task DeleteAsync(IEnumerable<TKey> keyList)
{
await _repository.DeleteManyAsync(keyList.AsEnumerable(), true).ConfigureAwait(false);
}
#endregion
/// <summary>
/// 【基础】-【分页查询】【有筛选条件】
/// </summary>
/// <param name="sfsRequestInputBase"></param>
/// <param name="includeDetails"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("Base/Get-List-Page-By-Filter")]
[Authorize]
public virtual async Task<PagedResultDto<TEntityDto>> GetPageListByFilterAsync(
SfsRequestInputBase sfsRequestInputBase,
bool includeDetails = false, CancellationToken cancellationToken = default)
{
await CheckGetListPolicyAsync();
var expression = sfsRequestInputBase.Condition.Filters?.Count > 0
? sfsRequestInputBase.Condition.Filters.ToLambda<TEntity>()
: p => true;
var resultEntities = await GetQueryListAsync(expression, sfsRequestInputBase.SkipCount,
sfsRequestInputBase.MaxResultCount,
sfsRequestInputBase.Sorting, includeDetails, cancellationToken);
var resultDtos = ObjectMapper.Map<List<TEntity>, List<TEntityDto>>(resultEntities);
//获取总数
var totalCount = await GetCountAsync(expression, cancellationToken);
return new PagedResultDto<TEntityDto>(totalCount, resultDtos);
}
/// <summary>
/// 【基础】-【获取所有数据】
/// </summary>
/// <param name="sfsRequestInputBase"></param>
/// <param name="includeDetails"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("Base/Get-All-List")]
[Authorize]
public virtual async Task<List<TEntityDto>> GetAllListAsync()
{
await CheckGetListPolicyAsync();
var entities = await _repository.GetListAsync();
return await MapToGetListOutputDtosAsync(entities);
}
/// <summary>
/// 【基础】-【导出Excel】【有筛选条件】
/// </summary>
/// <param name="sfsRequestInputBase">查询条件</param>
/// <param name="isRedundance">是否冗余主表数据</param>
/// <param name="isDetailExport">是否导出子表</param>
/// <param name="userId">用户ID</param>
/// <returns></returns>
[HttpPost("Base/Export-To-Excel")]
[Authorize]
public virtual async Task<IActionResult> ExportToExcelAsync(SfsRequestInputBase sfsRequestInputBase,
bool isRedundance, Guid userId, bool isDetailExport = true)
{
var isHasDetail = false; //是否包含从表
var data = (await GetPageListByFilterAsync(sfsRequestInputBase, true)).Items;
var fileStream = new MemoryStream(); //文件流
IWorkbook workbook = new XSSFWorkbook();
var sheet = workbook.CreateSheet(Localizer[typeof(TEntity).Name]);
var splitDetailsColumnNumber = 1; //分割主表和从表的列数量
var excelDetailsCellStyle = SetExcelDetailsCellStyle(workbook); //子表单元格样式
var excelSplitCellStyle = SetSplitCellStyle(workbook); //分割单元格样式
var excelOnlyMainCellStyle = SetExcelOnlyMainCellStyle(workbook);
var excelHeadCellStyle = SetExcelHeadCellStyle(workbook);
// 获取主表的属性 创建主表 表头
var mainAllProperties = typeof(TEntityDto).GetProperties();
var mainProperties = mainAllProperties.Where(p => p.Name != "Details").ToArray(); //去除details属性否则导出时会带出来
#region 用户个性导出 主表
//获取个性导出的字段
var mainUserColumn =
await ExportCustomUserSettingAppService.GetByUserIdAndExportTableNameAsync(userId, typeof(TEntity).Name);
if (mainUserColumn.Any(p => p.CustomUserSetting == Enum_ExportCustomUserSetting.Yes))
{
var showUserColumn = mainUserColumn.Where(p => p.CustomUserSetting == Enum_ExportCustomUserSetting.Yes)
.Select(p => p.ExportColumnName?.ToLower()).Aggregate((a, b) => a + " " + b)?.Split(' ').ToList();
mainProperties = mainProperties.Where(p => showUserColumn.Contains(p.Name.ToLower())).ToArray();
}
#endregion
var headerRow = sheet.CreateRow(0); //标头列
for (var i = 0; i < mainProperties.Length; i++)
{
var englishName = mainProperties[i].Name;
//本地化
var localizerName = Localizer[typeof(TEntity).Name + englishName];
var headCell = headerRow.CreateCell(i);
headCell.SetCellValue(localizerName);
headCell.CellStyle = excelHeadCellStyle;
}
// 获取从表的属性 创建从表 表头
var detailProperties = typeof(TEntityDto).GetProperty("Details")?.PropertyType.GetGenericArguments()[0]
.GetProperties();
if (detailProperties != null)
{
isHasDetail = true;
if (!isDetailExport) //是否要导出子表
{
isHasDetail = false;
}
if (isHasDetail)
{
headerRow.CreateCell(mainProperties.Length).SetCellValue("---【分割】---");
#region 用户个性导出 从表
//获取个性导出的字段
var detailDtoName = mainAllProperties.First(p => p.Name == "Details");
var detailUserColumn = await ExportCustomUserSettingAppService.GetByUserIdAndExportTableNameAsync(
userId, detailDtoName.PropertyType.GenericTypeArguments.First().Name.Replace("Dto", ""));
var detailNotShowUserColumn = detailUserColumn
.Where(p => p.CustomUserSetting == Enum_ExportCustomUserSetting.No).Select(p => p.ExportColumnName)
.ToList();
if (detailUserColumn.Any())
{
detailProperties = detailProperties.Where(p => !detailNotShowUserColumn.Contains(p.Name)).ToArray();
}
#endregion
for (var i = 0; i < detailProperties.Length; i++)
{
headerRow.CreateCell(mainProperties.Length + splitDetailsColumnNumber + i)
.SetCellValue(detailProperties[i].Name);
var headCell = headerRow.GetCell(mainProperties.Length + splitDetailsColumnNumber + i);
headCell.CellStyle = excelHeadCellStyle;
}
}
}
// 填充数据行
var rowIndex = 1;
foreach (var mainDto in data)
{
if (isHasDetail)
{
// 获取从表数据
var detailsIndex = mainAllProperties.FindIndex(p => p.Name == "Details");
// 子表
var detailList = (IEnumerable<object>)mainAllProperties[detailsIndex].GetValue(mainDto);
var startMainRowIndex = rowIndex;
for (var datailCount = 0; datailCount < detailList.Count(); datailCount++)
{
var dataRow = sheet.CreateRow(rowIndex);
if (isRedundance)
{
// 填充主表数据
for (var i = 0; i < mainProperties.Length; i++)
{
var value = mainProperties[i].GetValue(mainDto);
dataRow.CreateCell(i).SetCellValue(value?.ToString());
}
}
else
{
if (datailCount == 0)
{
// 填充主表数据
for (var i = 0; i < mainProperties.Length; i++)
{
var value = mainProperties[i].GetValue(mainDto);
dataRow.CreateCell(i).SetCellValue(value?.ToString());
}
}
}
rowIndex++;
}
var overMainRowIndex = rowIndex;
foreach (var detail in detailList)
{
if (startMainRowIndex <= overMainRowIndex)
{
//填充子表数据
var detailRow = sheet.GetRow(startMainRowIndex);
var splitCell = detailRow.CreateCell(mainProperties.Length);
splitCell.CellStyle = excelSplitCellStyle;
for (var i = 0; i < detailProperties.Length; i++)
{
var value = detailProperties[i].GetValue(detail);
detailRow.CreateCell(mainProperties.Length + splitDetailsColumnNumber + i)
.SetCellValue(value?.ToString());
var detailCell = detailRow.GetCell(mainProperties.Length + splitDetailsColumnNumber + i);
detailCell.CellStyle = excelDetailsCellStyle;
}
}
startMainRowIndex++;
}
}
else
{
var dataRow = sheet.CreateRow(rowIndex);
// 填充主表数据
for (var i = 0; i < mainProperties.Length; i++)
{
var value = mainProperties[i].GetValue(mainDto);
dataRow.CreateCell(i).SetCellValue(value?.ToString());
}
if (rowIndex % 2 == 0)
{
dataRow.RowStyle = excelOnlyMainCellStyle;
}
}
//添加1个空行将2条数据分割开
rowIndex++;
}
#region 自动调整列宽
// 自动调整列宽 注意:这个影响性能 会遍历所有行 并且找出宽度最大值
//sheet.AutoSizeColumn(i);
if (isHasDetail)
{
for (var i = 0; i < mainProperties.Length + splitDetailsColumnNumber + detailProperties.Length; i++)
{
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15);
if (colWidth > 255 * 256) //excel列有最大宽度限制
{
colWidth = 6000;
}
sheet.SetColumnWidth(i, colWidth);
sheet.SetColumnWidth(mainProperties.Length, 3600);
}
}
else
{
for (var i = 0; i < mainProperties.Length; i++)
{
var colWidth = Math.Max(sheet.GetColumnWidth(i) + 150, 265 * 15);
if (colWidth > 255 * 256) //excel列有最大宽度限制
{
colWidth = 6000;
}
sheet.SetColumnWidth(i, colWidth);
}
}
#endregion
// 保存Excel文件到MemoryStream
workbook.Write(fileStream, true);
fileStream.Position = 0;
// 创建FileContentResult返回Excel文件
var fileContentResult = new FileContentResult(fileStream.ToArray(),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = Localizer[typeof(TEntity).Name] + ".xlsx"
};
await Task.CompletedTask;
return fileContentResult;
}
/// <summary>
/// 【基础】-【获取 增 改 查基础的Dto中属性的数据类型】
/// </summary>
/// <returns></returns>
[HttpPost("Base/Get-Dto-Column-Type")]
[Authorize]
public virtual async Task<List<AllTableColumnTypeDto>> GetDtoColumnTypeAsync()
{
var tableColumnTypeDtos = new List<AllTableColumnTypeDto>
{
GetTableColumnTypeByTable(typeof(TEntity), "S"),
GetTableColumnTypeByTable(typeof(TCreateInput), "C"),
GetTableColumnTypeByTable(typeof(TUpdateInput), "U"),
GetTableColumnTypeByTable(typeof(TEntity), "G")
};
await Task.CompletedTask;
return tableColumnTypeDtos;
}
/// <summary>
/// 【基础】-【获取数据】-【缓存中读取】
/// </summary>
/// <returns></returns>
[HttpPost("Base/Get-Cache-By-Id/{id}")]
[Authorize]
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;
}
/// <summary>
/// 【基础】-【获取数据】
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("Base/Get-By-Id/{id}")]
[Authorize]
public override Task<TEntityDto> GetAsync(TKey id)
{
return base.GetAsync(id);
}
/// <summary>
/// 【基础】-【获取数据】
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Base/Get-List")]
[Authorize]
public override Task<PagedResultDto<TEntityDto>> GetListAsync(TPagedAndSortedResultRequestDto input)
{
return base.GetListAsync(input);
}
#endregion
#region 私有处理
/// <summary>
/// 清除缓存
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
protected async Task ReMoveCaCheAsync(TKey id)
{
await Cache.RemoveAsync(id?.ToString());
}
/// <summary>
/// 按表达式条件获取分页列表
/// </summary>
/// <param name="expression"></param>
/// <param name="skipCount"></param>
/// <param name="maxResultCount"></param>
/// <param name="sorting"></param>
/// <param name="includeDetails"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<List<TEntity>> GetQueryListAsync(Expression<Func<TEntity, bool>> expression,
int skipCount, int maxResultCount, string sorting,
bool includeDetails = false, CancellationToken cancellationToken = default)
{
var query = await Repository.WithDetailsAsync();
//var query = await Repository.GetQueryableAsync();
var entities = query.Where(expression);
entities = GetSortingQueryable(entities, sorting);
var str = entities.ToQueryString();
Console.WriteLine("---------查询开始---------");
Console.WriteLine();
Console.WriteLine(str);
Console.WriteLine();
Console.WriteLine("---------查询结束---------");
var result = entities.Skip(skipCount).Take(maxResultCount).ToList();
return result;
}
/// <summary>
/// 设置排序
/// </summary>
/// <param name="entities"></param>
/// <param name="sorting"></param>
/// <returns></returns>
private IQueryable<TEntity> GetSortingQueryable(IQueryable<TEntity> entities, string sorting)
{
if (string.IsNullOrEmpty(sorting))
{
var createTimePropertyInfo = typeof(TEntity).GetProperty(nameof(AuditedEntity.CreationTime));
if (createTimePropertyInfo != null)
{
entities = entities.OrderBy(nameof(AuditedEntity.CreationTime) + " DESC");
}
else
{
entities = entities.OrderBy("Id DESC");
}
}
else
{
entities = entities.OrderBy(sorting);
}
return entities;
}
/// <summary>
/// 获取Dto的属性名字和数据类型
/// </summary>
/// <param name="dtoType"></param>
/// <param name="strDtoType"></param>
/// <returns></returns>
private AllTableColumnTypeDto GetTableColumnTypeByTable(Type dtoType, string strDtoType)
{
var gDto = new AllTableColumnTypeDto
{
DtoType = strDtoType,
DtoName = dtoType.FullName,
ColumnsTypes = new List<ColumnType>()
};
var propertyInfos = dtoType.GetProperties();
foreach (var propertyInfo in propertyInfos)
{
var columnType = new ColumnType();
columnType.IsEnum = false;
if (propertyInfo.PropertyType.GenericTypeArguments.Length > 0)
{
if (propertyInfo.PropertyType.GenericTypeArguments[0].IsEnum)
{
columnType.IsEnum = true;
}
columnType.Z_ColumnBaseType = propertyInfo.PropertyType.GenericTypeArguments[0].FullName!;
}
else
{
columnType.Z_ColumnBaseType = propertyInfo.PropertyType.FullName!;
}
columnType.Z_ColumnName = propertyInfo.Name;
columnType.Z_ColumnType = propertyInfo.PropertyType.Name;
gDto.ColumnsTypes.Add(columnType);
}
return gDto;
}
/// <summary>
/// 【记录数量查询】【有筛选条件】
/// </summary>
/// <param name="expression"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task<long> GetCountAsync(Expression<Func<TEntity, bool>> expression,
CancellationToken cancellationToken = default)
{
var count = await _repository.LongCountAsync(expression, cancellationToken);
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导出的样式设置
/// <summary>
/// 导出设置子表单元格样式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
private static ICellStyle SetExcelDetailsCellStyle(IWorkbook workbook)
{
var cellStyle = workbook.CreateCellStyle();
cellStyle.FillBackgroundColor = IndexedColors.Grey25Percent.Index;
cellStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
return cellStyle;
}
/// <summary>
/// 导出设置只有主表时的交替行 单元格样式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
private static ICellStyle SetExcelOnlyMainCellStyle(IWorkbook workbook)
{
var cellStyle = workbook.CreateCellStyle();
cellStyle.FillBackgroundColor = IndexedColors.Grey25Percent.Index;
cellStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
return cellStyle;
}
/// <summary>
/// 设置分割单元格的样式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
private static ICellStyle SetSplitCellStyle(IWorkbook workbook)
{
var cellStyle = workbook.CreateCellStyle();
cellStyle.BorderLeft = BorderStyle.MediumDashed;
cellStyle.BorderRight = BorderStyle.MediumDashed;
cellStyle.LeftBorderColor = IndexedColors.BrightGreen.Index;
cellStyle.RightBorderColor = IndexedColors.Grey25Percent.Index;
cellStyle.FillBackgroundColor = IndexedColors.White.Index;
cellStyle.FillForegroundColor = IndexedColors.White.Index;
cellStyle.FillPattern = FillPattern.ThickVerticalBands;
return cellStyle;
}
/// <summary>
/// 导出设置表头单元格样式
/// </summary>
/// <param name="workbook"></param>
/// <returns></returns>
private static ICellStyle SetExcelHeadCellStyle(IWorkbook workbook)
{
var cellStyle = workbook.CreateCellStyle();
cellStyle.FillBackgroundColor = IndexedColors.LightOrange.Index;
cellStyle.FillForegroundColor = IndexedColors.LightOrange.Index;
cellStyle.FillPattern = FillPattern.SolidForeground;
return cellStyle;
}
public static void MapProperties<TSrc, TDest>(TSrc source, TDest destination)
{
if (source == null || destination == null)
{
throw new ArgumentNullException("Source and destination objects must not be null.");
}
var sourceType = typeof(TSrc);
var destType = typeof(TDest);
var sourceProperties = sourceType.GetProperties();
var destProperties = destType.GetProperties();
foreach (var sourceProperty in sourceProperties)
{
var destProperty = Array.Find(destProperties,
p => p.Name == sourceProperty.Name && p.PropertyType == sourceProperty.PropertyType);
if (destProperty != null && destProperty.CanWrite && destProperty.Name != "Id" &&
destProperty.Name != "ConcurrencyStamp")
{
var value = sourceProperty.GetValue(source);
destProperty.SetValue(destination, value);
}
}
}
#endregion
#endregion
}