Browse Source

feat(data-protected): 更新演示模块查询参数

pull/1166/head
colin 10 months ago
parent
commit
87ec36e44a
  1. 8
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/BookGetListInput.cs
  2. 5
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/CreateBookDto.cs
  3. 16
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/IBookAppService.cs
  4. 19
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/UpdateBookDto.cs
  5. 227
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/Books/BookAppService.cs
  6. 2
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/DemoApplicationMapperProfile.cs
  7. 24
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain/LINGYUN/Abp/Demo/Books/Book.cs
  8. 19
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain/LINGYUN/Abp/Demo/Books/BookAuth.cs
  9. 2
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/Books/EfCoreBookRepository.cs
  10. 6
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/EntityFrameworkCore/DemoDbContext.cs
  11. 5
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/EntityFrameworkCore/DemoDbContextModelCreatingExtensions.cs
  12. 6
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.HttpApi/LINGYUN/Abp/Demo/Books/BookController.cs

8
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/BookGetListInput.cs

@ -0,0 +1,8 @@
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Abp.Demo.Books;
public class BookGetListInput : PagedAndSortedResultRequestDto
{
public string? Filter { get; set; }
}

5
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/CreateUpdateBookDto.cs → aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/CreateBookDto.cs

@ -2,7 +2,8 @@
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Abp.Demo.Books;
public class CreateUpdateBookDto
public class CreateBookDto
{
[Required]
[StringLength(128)]
@ -19,4 +20,4 @@ public class CreateUpdateBookDto
public float Price { get; set; }
public Guid AuthorId { get; set; }
}
}

16
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/IBookAppService.cs

@ -7,14 +7,20 @@ using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.Demo.Books;
public interface IBookAppService :
ICrudAppService< //Defines CRUD methods
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdateBookDto>, //Used to create/update a book
IApplicationService,
IExporterAppService<BookDto, BookExportListInput>,
IImporterAppService<BookImportInput>
{
Task<BookDto> CreateAsync(CreateBookDto input);
Task<BookDto> UpdateAsync(Guid id, UpdateBookDto input);
Task<BookDto> GetAsync(Guid id);
Task DeleteAsync(Guid id);
Task<PagedResultDto<BookDto>> GetListAsync(BookGetListInput input);
Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync();
/// <summary>
/// 获取实体可访问规则

19
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/UpdateBookDto.cs

@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Abp.Demo.Books;
public class UpdateBookDto
{
[Required]
[StringLength(128)]
public string Name { get; set; }
public BookType? Type { get; set; }
[DataType(DataType.Date)]
public DateTime? PublishDate { get; set; }
public float? Price { get; set; }
public Guid AuthorId { get; set; }
}

227
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/Books/BookAppService.cs

@ -7,7 +7,6 @@ using LINGYUN.Abp.Exporter;
using Microsoft.AspNetCore.Authorization;
using System.Linq.Dynamic.Core;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Localization;
@ -15,15 +14,9 @@ using Volo.Abp.Localization;
namespace LINGYUN.Abp.Demo.Books;
[Authorize(DemoPermissions.Books.Default)]
public class BookAppService :
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
public class BookAppService : DemoApplicationServiceBase, IBookAppService //implement the IBookAppService
{
private readonly IBookRepository _bookRepository;
private readonly IAuthorRepository _authorRepository;
private readonly AuthorManager _authorManager;
@ -38,111 +31,80 @@ public class BookAppService :
IBookRepository bookRepository,
AuthorManager authorManager,
IAuthorRepository authorRepository)
: base(bookRepository)
{
_exporterProvider = exporterProvider;
_importerProvider = importerProvider;
_authorManager = authorManager;
_authorRepository = authorRepository;
GetPolicyName = DemoPermissions.Books.Default;
GetListPolicyName = DemoPermissions.Books.Default;
CreatePolicyName = DemoPermissions.Books.Create;
UpdatePolicyName = DemoPermissions.Books.Edit;
DeletePolicyName = DemoPermissions.Books.Delete;
_bookRepository = bookRepository;
LocalizationResource = typeof(DemoResource);
ObjectMapperContext = typeof(AbpDemoApplicationModule);
}
[DisableDataProtected(DataAccessOperation.Read)]// 更新时禁用查询过滤
public override Task<BookDto> UpdateAsync(Guid id, CreateUpdateBookDto input)
{
return base.UpdateAsync(id, input);
}
[DisableDataProtected(DataAccessOperation.Read)]
public override Task DeleteAsync(Guid id)
[Authorize(DemoPermissions.Books.Create)]
[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();
await CheckPolicyAsync(DemoPermissions.Books.Import);
var book = await _bookRepository.GetAsync(id);
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)
if (!input.Name.IsNullOrWhiteSpace() && !string.Equals(input.Name, book.Name, StringComparison.InvariantCultureIgnoreCase))
{
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;
book.Name = input.Name;
}
var createManyBooks = createManyDtos.Select(dto =>
if (input.Type.HasValue && input.Type != book.Type)
{
var book = ObjectMapper.Map<BookImportDto, Book>(dto);
TryToSetTenantId(book);
return book;
});
if (createAuthors.Count > 0)
book.Type = input.Type.Value;
}
if (input.PublishDate.HasValue && input.PublishDate != book.PublishDate)
{
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);
}
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 =>
if (input.AuthorId != book.AuthorId)
{
var bookDto = ObjectMapper.Map<Book, BookDto>(x.book);
bookDto.AuthorName = x.author.Name;
return bookDto;
}).ToList();
var newAuthor = await _authorRepository.GetAsync(input.AuthorId);
book.AuthorId = newAuthor.Id;
}
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
var queryable = await Repository.GetQueryableAsync();
var queryable = await _bookRepository.GetQueryableAsync();
//Prepare a query to join books and authors
var query = from book in queryable
@ -162,11 +124,9 @@ public class BookAppService :
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 Repository.GetQueryableAsync();
var queryable = await _bookRepository.GetQueryableAsync();
//Prepare a query to join books and authors
var query = from book in queryable
join author in await _authorRepository.GetQueryableAsync() on book.AuthorId equals author.Id
@ -174,6 +134,7 @@ public class BookAppService :
//Paging
query = query
.WhereIf(!input.Filter.IsNullOrWhiteSpace(), x => x.book.Name.Contains(input.Filter))
.OrderBy(NormalizeSorting(input.Sorting))
.Skip(input.SkipCount)
.Take(input.MaxResultCount);
@ -190,7 +151,7 @@ public class BookAppService :
}).ToList();
//Get the total count with another query
var totalCount = await Repository.GetCountAsync();
var totalCount = await AsyncExecuter.CountAsync(query);
return new PagedResultDto<BookDto>(
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()
{
var authors = await _authorRepository.GetListAsync();

2
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/DemoApplicationMapperProfile.cs

@ -15,7 +15,7 @@ public class DemoApplicationMapperProfile : Profile
.Ignore(dto => dto.Id)
.Ignore(dto => dto.ExtraProperties)
.Ignore(dto => dto.ConcurrencyStamp);
CreateMap<CreateUpdateBookDto, Book>()
CreateMap<UpdateBookDto, Book>()
.IgnoreAuditedObjectProperties()
.Ignore(dto => dto.Id)
.Ignore(dto => dto.ExtraProperties)

24
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain/LINGYUN/Abp/Demo/Books/Book.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.DataProtection;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities.Auditing;
namespace LINGYUN.Abp.Demo.Books;
@ -13,4 +14,27 @@ public class Book : AuditedAggregateRoot<Guid>, IDataProtected
public float Price { get; set; }
public Guid AuthorId { get; set; }
protected Book()
{
ExtraProperties = new ExtraPropertyDictionary();
}
public Book(
Guid id,
string name,
BookType type,
DateTime publishDate,
float price,
Guid authorId)
: base(id)
{
Name = name;
Type = type;
PublishDate = publishDate;
Price = price;
AuthorId = authorId;
ExtraProperties = new ExtraPropertyDictionary();
}
}

19
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain/LINGYUN/Abp/Demo/Books/BookAuth.cs

@ -0,0 +1,19 @@
using LINGYUN.Abp.DataProtection;
namespace LINGYUN.Abp.Demo.Books;
public class BookAuth : DataAuthBase<Book, Guid>
{
public BookAuth()
{
}
public BookAuth(
Guid entityId,
string role,
string organizationUnit,
Guid? tenantId = null)
: base(entityId, role, organizationUnit, tenantId)
{
}
}

2
aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/Books/EfCoreBookRepository.cs

@ -5,7 +5,7 @@ using LINGYUN.Abp.Demo.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.Demo.Books;
public class EfCoreBookRepository : EfCoreDataProtectionRepository<DemoDbContext, Book, Guid>, IBookRepository
public class EfCoreBookRepository : EfCoreDataProtectionRepository<DemoDbContext, Book, Guid, BookAuth>, IBookRepository
{
public EfCoreBookRepository(
[NotNull] IDbContextProvider<DemoDbContext> dbContextProvider,

6
aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/EntityFrameworkCore/DemoDbContext.cs

@ -15,6 +15,12 @@ public class DemoDbContext : AbpDataProtectionDbContext<DemoDbContext>
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.EnableSensitiveDataLogging();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

5
aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/EntityFrameworkCore/DemoDbContextModelCreatingExtensions.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Demo.Authors;
using LINGYUN.Abp.DataProtection.EntityFrameworkCore;
using LINGYUN.Abp.Demo.Authors;
using LINGYUN.Abp.Demo.Books;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
@ -41,5 +42,7 @@ public static class DemoDbContextModelCreatingExtensions
b.HasIndex(x => x.Name);
});
builder.ConfigureEntityAuth<Book, Guid, BookAuth>();
}
}

6
aspnet-core/modules/demo/LINGYUN.Abp.Demo.HttpApi/LINGYUN/Abp/Demo/Books/BookController.cs

@ -25,7 +25,7 @@ public class BookController : AbpControllerBase, IBookAppService
[HttpPost]
[Authorize(DemoPermissions.Books.Create)]
public virtual Task<BookDto> CreateAsync(CreateUpdateBookDto input)
public virtual Task<BookDto> CreateAsync(CreateBookDto input)
{
return _service.CreateAsync(input);
}
@ -67,7 +67,7 @@ public class BookController : AbpControllerBase, IBookAppService
}
[HttpGet]
public virtual Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
public virtual Task<PagedResultDto<BookDto>> GetListAsync(BookGetListInput input)
{
return _service.GetListAsync(input);
}
@ -75,7 +75,7 @@ public class BookController : AbpControllerBase, IBookAppService
[HttpPut]
[Route("{id}")]
[Authorize(DemoPermissions.Books.Edit)]
public virtual Task<BookDto> UpdateAsync(Guid id, CreateUpdateBookDto input)
public virtual Task<BookDto> UpdateAsync(Guid id, UpdateBookDto input)
{
return _service.UpdateAsync(id, input);
}

Loading…
Cancel
Save