using iWare.Wms.Core;
using Furion.ClayObject.Extensions;
using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.FriendlyException;
using Furion.JsonSerialization;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
using Yitter.IdGenerator;
namespace iWare.Wms.Application
{
///
/// 通用方法
///
///
///
///
///
///
///
///
///
///
public class BaseService
where TEntity : DEntityBase, new()
where TUpdateDto : BaseDto
where TSearchDto : PageInputBase
where TPageListDto : new()
where TExportDto : class, new()
where TImportDto : class, new()
{
///
/// 数据仓储
///
protected readonly IRepository Repository;
///
/// 构造函数
///
///
public BaseService(IRepository repository)
{
Repository = repository;
}
#region 查询/分页查询
///
/// 主键查询
///
///
///
public virtual async Task Get(long id)
{
var entity = await Repository.DetachedEntities.FirstOrDefaultAsync(e => e.Id == id);
return entity.Adapt();
}
///
/// 分页搜索前
///
protected Func>> SearchExpression = null;
///
/// 自定义分页搜索(复杂查询)
///
protected Func> SearchQueryable = null;
///
/// 分页数据返回前处理
///
///
protected Action> PageListHandle = null;
///
/// 分页查询
///
///
///
///
[HttpPost("page")]
public virtual async Task> PageList(TSearchDto searchDto)
{
IQueryable queryable;
if (SearchQueryable != null)
{
// 通过派生类中定义的委托方法自定义查询条件
queryable = SearchQueryable(searchDto);
}
else
{
// 动态构建查询条件
GetSearchParameters(searchDto);
queryable = Repository.DetachedEntities.Search(searchDto);
// 有自定义的查询条件
if (SearchExpression != null)
queryable = queryable.Where(SearchExpression(searchDto));
}
var pageList = await queryable.ToADPagedListAsync(searchDto.PageNo, searchDto.PageSize);
PageListHandle?.Invoke(pageList);
return pageList;
}
#endregion 查询/分页查询
#region 新增
///
/// 新增前验证或处理
///
protected Action BeforeAddAction = null;
///
/// 新增后处理
///
protected Action AfterAddAction = null;
///
/// 新增
///
///
public virtual async Task Add(TAddDto addDto)
{
// 新增前操作
BeforeAddAction?.Invoke(addDto);
// 写数据
var entity = await addDto.Adapt().InsertAsync();
// 新增后操作
AfterAddAction?.Invoke(entity.Entity);
}
#endregion 新增
#region 删除/假删除
///
/// 删除前验证或处理
///
protected Action> BeforeDeleteAction = null;
///
/// 删除后处理
///
protected Action, int> AfterDeleteAction = null;
///
/// 删除
///
///
public virtual async Task Delete(List ids)
{
BeforeDeleteAction?.Invoke(ids);
var count = await Repository.Context.DeleteRangeAsync(x => ids.Contains(x.Id));
AfterDeleteAction?.Invoke(ids, count);
}
///
/// 假删除前验证或处理
///
protected Action> BeforeFakeDeleteAction = null;
///
/// 假删除后处理
///
protected Action, int> AfterFakeDeleteAction = null;
///
/// 假删除
///
///
[HttpDelete("fakeDelete")]
public virtual async Task FakeDelete(List ids)
{
BeforeFakeDeleteAction?.Invoke(ids);
var count = await Repository.Context.BatchUpdate()
.Set(x => x.IsDeleted, x => true)
.Where(x => ids.Contains(x.Id))
.ExecuteAsync();
AfterFakeDeleteAction?.Invoke(ids, count);
}
#endregion 删除/假删除
#region 修改
///
/// 更新前验证或处理
///
protected Action BeforeUpdateAction = null;
///
/// 更新后处理
///
protected Action AfterUpdateAction = null;
///
/// 修改
///
///
[HttpPut("edit")]
public virtual async Task Update(TUpdateDto updateDto)
{
BeforeUpdateAction?.Invoke(updateDto);
var entity = await updateDto.Adapt().UpdateAsync(true);
AfterUpdateAction?.Invoke(entity.Entity);
}
#endregion 修改
#region 导入
///
/// 导入模版下载
///
///
[HttpGet("importTemplate")]
public virtual async Task ImportTemplate()
{
// 创建Excel导入对象
IImporter importer = new ExcelImporter();
var byteArray = await importer.GenerateTemplateBytes();
// 文件名称
var fileName = typeof(TEntity).GetDescriptionValue().Comment + "导入模版.xlsx";
return await Task.FromResult(
new FileContentResult(byteArray, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = fileName
});
}
///
/// 导入前验证或处理
///
protected Action> BeforeImportAction = null;
///
/// 导入后处理
///
protected Action> AfterImportAction = null;
///
/// 导入
///
///
///
[UnitOfWork]
public virtual async Task Import(IFormFile file)
{
var path = Path.Combine(Path.GetTempPath(), $"{YitIdHelper.NextId()}.xlsx");
await using (var stream = File.Create(path))
{
await file.CopyToAsync(stream);
}
// 创建Excel导入对象
IImporter importer = new ExcelImporter();
var import = await importer.Import(path);
if (import == null)
throw Oops.Oh("导入模版解析异常");
if (import.Exception != null)
throw Oops.Oh("导入异常:" + import.Exception);
if (import.RowErrors.Count > 0)
throw Oops.Oh("数据校验:" + JSON.Serialize(import.RowErrors));
BeforeImportAction?.Invoke(import.Data);
await Repository.InsertAsync(import.Data.Adapt>());
AfterImportAction?.Invoke(import.Data);
}
#endregion 导入
#region 导出
///
/// 导出搜索前
///
protected Func>> ExportSearchExpression = null;
///
/// 自定义导出搜索(复杂查询)
///
protected Func> ExportSearchQueryable = null;
///
/// 导出数据返回前处理
///
///
protected Action> ExportHandle = null;
///
/// 导出
///
///
///
[HttpGet("export")]
public virtual async Task Export(TSearchDto searchDto)
{
IQueryable queryable;
if (ExportSearchQueryable != null)
{
// 通过派生类中定义的委托方法自定义查询条件
queryable = ExportSearchQueryable(searchDto);
}
else
{
// 动态构建查询条件
GetSearchParameters(searchDto);
queryable = Repository.DetachedEntities.Search(searchDto);
// 有自定义的查询条件
if (ExportSearchExpression != null)
queryable = queryable.Where(ExportSearchExpression(searchDto));
}
var entitys = await queryable.ToListAsync();
// 创建Excel导出对象
IExporter exporter = new ExcelExporter();
// 导出文件
var byteArray = await exporter.ExportAsByteArray(entitys.Adapt>());
// 文件名称
var fileName = typeof(TEntity).GetDescriptionValue() + DateTime.Now.ToString("yyyyMMddHHssmm") + ".xlsx";
return await Task.FromResult(
new FileContentResult(byteArray, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
FileDownloadName = fileName
});
}
#endregion 导出
#region 打印
///
/// 获取打印数据 todo: 最简单的主键查询单条数据,后续实现单据打印模版模块
///
///
[HttpGet("print")]
public virtual async Task Print(long id)
{
var entity = await Repository.DetachedEntities.FirstOrDefaultAsync(e => e.Id == id);
return entity.Adapt();
}
#endregion 打印
#region 私有方法
///
/// 将查询dto组装成搜索参数
///
///
///
private void GetSearchParameters(TSearchDto searchDto)
{
// 如果没有复杂查询条件,把自定义查询dto中有内容的项加入查询条件
if (searchDto.SearchParameters != null && searchDto.SearchParameters.Any()) return;
// 查询dto转为字典
var searchDictionary = searchDto.ToDictionary();
// 取实体中的字段名称
var entityPropertieNames =
typeof(TEntity).GetProperties().Select(x => x.Name).ToList();
// 将searchDto中有值的属性加入复杂查询条件
foreach (var keyValuePair in searchDictionary)
{
// 跳过自定义属性和空值属性,自定义属性可在查询前委托中定义查询条件
if (!entityPropertieNames.Contains(keyValuePair.Key) || keyValuePair.Value == null) continue;
searchDto.SearchParameters.Add(new Condition()
{
Field = keyValuePair.Key,
Op = QueryTypeEnum.Equals,
Value = keyValuePair.Value
});
}
}
#endregion 私有方法
}
}