using Admin.NET.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 Admin.NET.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 => false) .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 私有方法 } }