|
|
@ -7,7 +7,6 @@ using LINGYUN.Abp.Exporter; |
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using System.Linq.Dynamic.Core; |
|
|
using System.Linq.Dynamic.Core; |
|
|
using Volo.Abp.Application.Dtos; |
|
|
using Volo.Abp.Application.Dtos; |
|
|
using Volo.Abp.Application.Services; |
|
|
|
|
|
using Volo.Abp.Content; |
|
|
using Volo.Abp.Content; |
|
|
using Volo.Abp.Domain.Entities; |
|
|
using Volo.Abp.Domain.Entities; |
|
|
using Volo.Abp.Localization; |
|
|
using Volo.Abp.Localization; |
|
|
@ -15,15 +14,9 @@ using Volo.Abp.Localization; |
|
|
namespace LINGYUN.Abp.Demo.Books; |
|
|
namespace LINGYUN.Abp.Demo.Books; |
|
|
|
|
|
|
|
|
[Authorize(DemoPermissions.Books.Default)] |
|
|
[Authorize(DemoPermissions.Books.Default)] |
|
|
public class BookAppService : |
|
|
public class BookAppService : DemoApplicationServiceBase, IBookAppService //implement the IBookAppService
|
|
|
CrudAppService< |
|
|
|
|
|
Book, //The Book entity
|
|
|
|
|
|
BookDto, //Used to show books
|
|
|
|
|
|
Guid, //Primary key of the book entity
|
|
|
|
|
|
PagedAndSortedResultRequestDto, //Used for paging/sorting
|
|
|
|
|
|
CreateUpdateBookDto>, //Used to create/update a book
|
|
|
|
|
|
IBookAppService //implement the IBookAppService
|
|
|
|
|
|
{ |
|
|
{ |
|
|
|
|
|
private readonly IBookRepository _bookRepository; |
|
|
private readonly IAuthorRepository _authorRepository; |
|
|
private readonly IAuthorRepository _authorRepository; |
|
|
private readonly AuthorManager _authorManager; |
|
|
private readonly AuthorManager _authorManager; |
|
|
|
|
|
|
|
|
@ -38,111 +31,80 @@ public class BookAppService : |
|
|
IBookRepository bookRepository, |
|
|
IBookRepository bookRepository, |
|
|
AuthorManager authorManager, |
|
|
AuthorManager authorManager, |
|
|
IAuthorRepository authorRepository) |
|
|
IAuthorRepository authorRepository) |
|
|
: base(bookRepository) |
|
|
|
|
|
{ |
|
|
{ |
|
|
_exporterProvider = exporterProvider; |
|
|
_exporterProvider = exporterProvider; |
|
|
_importerProvider = importerProvider; |
|
|
_importerProvider = importerProvider; |
|
|
_authorManager = authorManager; |
|
|
_authorManager = authorManager; |
|
|
_authorRepository = authorRepository; |
|
|
_authorRepository = authorRepository; |
|
|
|
|
|
_bookRepository = bookRepository; |
|
|
GetPolicyName = DemoPermissions.Books.Default; |
|
|
|
|
|
GetListPolicyName = DemoPermissions.Books.Default; |
|
|
|
|
|
CreatePolicyName = DemoPermissions.Books.Create; |
|
|
|
|
|
UpdatePolicyName = DemoPermissions.Books.Edit; |
|
|
|
|
|
DeletePolicyName = DemoPermissions.Books.Delete; |
|
|
|
|
|
|
|
|
|
|
|
LocalizationResource = typeof(DemoResource); |
|
|
LocalizationResource = typeof(DemoResource); |
|
|
ObjectMapperContext = typeof(AbpDemoApplicationModule); |
|
|
ObjectMapperContext = typeof(AbpDemoApplicationModule); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[DisableDataProtected(DataAccessOperation.Read)]// 更新时禁用查询过滤
|
|
|
|
|
|
public override Task<BookDto> UpdateAsync(Guid id, CreateUpdateBookDto input) |
|
|
|
|
|
{ |
|
|
|
|
|
return base.UpdateAsync(id, input); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[DisableDataProtected(DataAccessOperation.Read)] |
|
|
[Authorize(DemoPermissions.Books.Create)] |
|
|
public override Task DeleteAsync(Guid id) |
|
|
[DisableDataProtected]// 任何人都可创建
|
|
|
|
|
|
public async virtual Task<BookDto> CreateAsync(CreateBookDto input) |
|
|
{ |
|
|
{ |
|
|
return base.DeleteAsync(id); |
|
|
var author = await _authorRepository.GetAsync(input.AuthorId); |
|
|
|
|
|
var book = new Book( |
|
|
|
|
|
GuidGenerator.Create(), |
|
|
|
|
|
input.Name, |
|
|
|
|
|
input.Type, |
|
|
|
|
|
input.PublishDate, |
|
|
|
|
|
input.Price, |
|
|
|
|
|
author.Id); |
|
|
|
|
|
|
|
|
|
|
|
await _bookRepository.InsertAsync(book); |
|
|
|
|
|
|
|
|
|
|
|
var bookDto = ObjectMapper.Map<Book, BookDto>(book); |
|
|
|
|
|
bookDto.AuthorName = author.Name; |
|
|
|
|
|
|
|
|
|
|
|
return bookDto; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public async virtual Task ImportAsync(BookImportInput input) |
|
|
[Authorize(DemoPermissions.Books.Edit)] |
|
|
|
|
|
[DataProtected(DataAccessOperation.Write)]// 仅启用数据更新过滤器
|
|
|
|
|
|
public async virtual Task<BookDto> UpdateAsync(Guid id, UpdateBookDto input) |
|
|
{ |
|
|
{ |
|
|
await CheckCreatePolicyAsync(); |
|
|
var book = await _bookRepository.GetAsync(id); |
|
|
await CheckPolicyAsync(DemoPermissions.Books.Import); |
|
|
|
|
|
|
|
|
|
|
|
var stream = input.Content.GetStream(); |
|
|
if (!input.Name.IsNullOrWhiteSpace() && !string.Equals(input.Name, book.Name, StringComparison.InvariantCultureIgnoreCase)) |
|
|
var createAuthors = new List<Author>(); |
|
|
|
|
|
var existsAuthors = new List<Author>(); |
|
|
|
|
|
var createManyDtos = await _importerProvider.ImportAsync<BookImportDto>(stream); |
|
|
|
|
|
|
|
|
|
|
|
foreach (var book in createManyDtos) |
|
|
|
|
|
{ |
|
|
{ |
|
|
var author = existsAuthors.Find(x => x.Name == book.AuthorName) ?? |
|
|
book.Name = input.Name; |
|
|
await _authorRepository.FindByNameAsync(book.AuthorName); |
|
|
|
|
|
if (author == null) |
|
|
|
|
|
{ |
|
|
|
|
|
author = await _authorManager.CreateAsync(book.AuthorName, Clock.Now); |
|
|
|
|
|
createAuthors.Add(author); |
|
|
|
|
|
} |
|
|
|
|
|
if (!existsAuthors.Any(x => x.Name == author.Name)) |
|
|
|
|
|
{ |
|
|
|
|
|
existsAuthors.Add(author); |
|
|
|
|
|
} |
|
|
|
|
|
book.AuthorId = author.Id; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
if (input.Type.HasValue && input.Type != book.Type) |
|
|
var createManyBooks = createManyDtos.Select(dto => |
|
|
|
|
|
{ |
|
|
{ |
|
|
var book = ObjectMapper.Map<BookImportDto, Book>(dto); |
|
|
book.Type = input.Type.Value; |
|
|
|
|
|
} |
|
|
TryToSetTenantId(book); |
|
|
if (input.PublishDate.HasValue && input.PublishDate != book.PublishDate) |
|
|
|
|
|
|
|
|
return book; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (createAuthors.Count > 0) |
|
|
|
|
|
{ |
|
|
{ |
|
|
await _authorRepository.InsertManyAsync(createAuthors, autoSave: true); |
|
|
book.PublishDate = input.PublishDate.Value; |
|
|
|
|
|
} |
|
|
|
|
|
if (input.Price.HasValue && input.Price != book.Price) |
|
|
|
|
|
{ |
|
|
|
|
|
book.Price = input.Price.Value; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
await Repository.InsertManyAsync(createManyBooks, autoSave: true); |
|
|
if (input.AuthorId != book.AuthorId) |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public async virtual Task<IRemoteStreamContent> ExportAsync(BookExportListInput input) |
|
|
|
|
|
{ |
|
|
|
|
|
await CheckPolicyAsync(DemoPermissions.Books.Export); |
|
|
|
|
|
|
|
|
|
|
|
var bookSet = await Repository.GetQueryableAsync(); |
|
|
|
|
|
var authorSet = await _authorRepository.GetQueryableAsync(); |
|
|
|
|
|
|
|
|
|
|
|
var query = from book in bookSet |
|
|
|
|
|
join author in authorSet on book.AuthorId equals author.Id |
|
|
|
|
|
select new { book, author }; |
|
|
|
|
|
|
|
|
|
|
|
query = query |
|
|
|
|
|
.OrderBy(NormalizeSorting(input.Sorting)) |
|
|
|
|
|
.Take(input.MaxResultCount); |
|
|
|
|
|
|
|
|
|
|
|
var queryResult = await AsyncExecuter.ToListAsync(query); |
|
|
|
|
|
|
|
|
|
|
|
var bookDtos = queryResult.Select(x => |
|
|
|
|
|
{ |
|
|
{ |
|
|
var bookDto = ObjectMapper.Map<Book, BookDto>(x.book); |
|
|
var newAuthor = await _authorRepository.GetAsync(input.AuthorId); |
|
|
bookDto.AuthorName = x.author.Name; |
|
|
book.AuthorId = newAuthor.Id; |
|
|
return bookDto; |
|
|
} |
|
|
}).ToList(); |
|
|
|
|
|
|
|
|
|
|
|
var stream = await _exporterProvider.ExportAsync(bookDtos); |
|
|
await _bookRepository.UpdateAsync(book); |
|
|
|
|
|
var author = await _authorRepository.GetAsync(input.AuthorId); |
|
|
|
|
|
|
|
|
return new RemoteStreamContent(stream, input.FileName); |
|
|
var bookDto = ObjectMapper.Map<Book, BookDto>(book); |
|
|
|
|
|
bookDto.Name = author.Name; |
|
|
|
|
|
|
|
|
|
|
|
return bookDto; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public override async Task<BookDto> GetAsync(Guid id) |
|
|
public async virtual Task<BookDto> GetAsync(Guid id) |
|
|
{ |
|
|
{ |
|
|
//Get the IQueryable<Book> from the repository
|
|
|
//Get the IQueryable<Book> from the repository
|
|
|
var queryable = await Repository.GetQueryableAsync(); |
|
|
var queryable = await _bookRepository.GetQueryableAsync(); |
|
|
|
|
|
|
|
|
//Prepare a query to join books and authors
|
|
|
//Prepare a query to join books and authors
|
|
|
var query = from book in queryable |
|
|
var query = from book in queryable |
|
|
@ -162,11 +124,9 @@ public class BookAppService : |
|
|
return bookDto; |
|
|
return bookDto; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input) |
|
|
public async virtual Task<PagedResultDto<BookDto>> GetListAsync(BookGetListInput input) |
|
|
{ |
|
|
{ |
|
|
//Get the IQueryable<Book> from the repository
|
|
|
var queryable = await _bookRepository.GetQueryableAsync(); |
|
|
var queryable = await Repository.GetQueryableAsync(); |
|
|
|
|
|
|
|
|
|
|
|
//Prepare a query to join books and authors
|
|
|
//Prepare a query to join books and authors
|
|
|
var query = from book in queryable |
|
|
var query = from book in queryable |
|
|
join author in await _authorRepository.GetQueryableAsync() on book.AuthorId equals author.Id |
|
|
join author in await _authorRepository.GetQueryableAsync() on book.AuthorId equals author.Id |
|
|
@ -174,6 +134,7 @@ public class BookAppService : |
|
|
|
|
|
|
|
|
//Paging
|
|
|
//Paging
|
|
|
query = query |
|
|
query = query |
|
|
|
|
|
.WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.book.Name.Contains(input.Filter)) |
|
|
.OrderBy(NormalizeSorting(input.Sorting)) |
|
|
.OrderBy(NormalizeSorting(input.Sorting)) |
|
|
.Skip(input.SkipCount) |
|
|
.Skip(input.SkipCount) |
|
|
.Take(input.MaxResultCount); |
|
|
.Take(input.MaxResultCount); |
|
|
@ -190,7 +151,7 @@ public class BookAppService : |
|
|
}).ToList(); |
|
|
}).ToList(); |
|
|
|
|
|
|
|
|
//Get the total count with another query
|
|
|
//Get the total count with another query
|
|
|
var totalCount = await Repository.GetCountAsync(); |
|
|
var totalCount = await AsyncExecuter.CountAsync(query); |
|
|
|
|
|
|
|
|
return new PagedResultDto<BookDto>( |
|
|
return new PagedResultDto<BookDto>( |
|
|
totalCount, |
|
|
totalCount, |
|
|
@ -198,6 +159,90 @@ public class BookAppService : |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Authorize(DemoPermissions.Books.Delete)] |
|
|
|
|
|
[DataProtected(DataAccessOperation.Delete)]// 仅启用数据删除过滤器
|
|
|
|
|
|
public async virtual Task DeleteAsync(Guid id) |
|
|
|
|
|
{ |
|
|
|
|
|
var book = await _bookRepository.GetAsync(id); |
|
|
|
|
|
|
|
|
|
|
|
await _bookRepository.DeleteAsync(book); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Authorize(DemoPermissions.Books.Import)] |
|
|
|
|
|
[DisableDataProtected]// 任何人都可创建
|
|
|
|
|
|
public async virtual Task ImportAsync(BookImportInput input) |
|
|
|
|
|
{ |
|
|
|
|
|
var stream = input.Content.GetStream(); |
|
|
|
|
|
var createAuthors = new List<Author>(); |
|
|
|
|
|
var existsAuthors = new List<Author>(); |
|
|
|
|
|
var createManyDtos = await _importerProvider.ImportAsync<BookImportDto>(stream); |
|
|
|
|
|
|
|
|
|
|
|
foreach (var book in createManyDtos) |
|
|
|
|
|
{ |
|
|
|
|
|
var author = existsAuthors.Find(x => x.Name == book.AuthorName) ?? |
|
|
|
|
|
await _authorRepository.FindByNameAsync(book.AuthorName); |
|
|
|
|
|
if (author == null) |
|
|
|
|
|
{ |
|
|
|
|
|
author = await _authorManager.CreateAsync(book.AuthorName, Clock.Now); |
|
|
|
|
|
createAuthors.Add(author); |
|
|
|
|
|
} |
|
|
|
|
|
if (!existsAuthors.Any(x => x.Name == author.Name)) |
|
|
|
|
|
{ |
|
|
|
|
|
existsAuthors.Add(author); |
|
|
|
|
|
} |
|
|
|
|
|
book.AuthorId = author.Id; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var createManyBooks = createManyDtos.Select(dto => |
|
|
|
|
|
{ |
|
|
|
|
|
var book = new Book( |
|
|
|
|
|
GuidGenerator.Create(), |
|
|
|
|
|
dto.Name, |
|
|
|
|
|
dto.Type, |
|
|
|
|
|
dto.PublishDate, |
|
|
|
|
|
dto.Price, |
|
|
|
|
|
dto.AuthorId); |
|
|
|
|
|
|
|
|
|
|
|
return book; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (createAuthors.Count > 0) |
|
|
|
|
|
{ |
|
|
|
|
|
await _authorRepository.InsertManyAsync(createAuthors, autoSave: true); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await _bookRepository.InsertManyAsync(createManyBooks, autoSave: true); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Authorize(DemoPermissions.Books.Export)] |
|
|
|
|
|
public async virtual Task<IRemoteStreamContent> ExportAsync(BookExportListInput input) |
|
|
|
|
|
{ |
|
|
|
|
|
var bookSet = await _bookRepository.GetQueryableAsync(); |
|
|
|
|
|
var authorSet = await _authorRepository.GetQueryableAsync(); |
|
|
|
|
|
|
|
|
|
|
|
var query = from book in bookSet |
|
|
|
|
|
join author in authorSet on book.AuthorId equals author.Id |
|
|
|
|
|
select new { book, author }; |
|
|
|
|
|
|
|
|
|
|
|
query = query |
|
|
|
|
|
.OrderBy(NormalizeSorting(input.Sorting)) |
|
|
|
|
|
.Take(input.MaxResultCount); |
|
|
|
|
|
|
|
|
|
|
|
var queryResult = await AsyncExecuter.ToListAsync(query); |
|
|
|
|
|
|
|
|
|
|
|
var bookDtos = queryResult.Select(x => |
|
|
|
|
|
{ |
|
|
|
|
|
var bookDto = ObjectMapper.Map<Book, BookDto>(x.book); |
|
|
|
|
|
bookDto.AuthorName = x.author.Name; |
|
|
|
|
|
return bookDto; |
|
|
|
|
|
}).ToList(); |
|
|
|
|
|
|
|
|
|
|
|
var stream = await _exporterProvider.ExportAsync(bookDtos); |
|
|
|
|
|
|
|
|
|
|
|
return new RemoteStreamContent(stream, input.FileName); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public async Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync() |
|
|
public async Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync() |
|
|
{ |
|
|
{ |
|
|
var authors = await _authorRepository.GetListAsync(); |
|
|
var authors = await _authorRepository.GetListAsync(); |
|
|
|