75 changed files with 7649 additions and 21 deletions
File diff suppressed because it is too large
@ -0,0 +1,95 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.Migrations |
|||
{ |
|||
/// <inheritdoc />
|
|||
public partial class AddDemoModule : Migration |
|||
{ |
|||
/// <inheritdoc />
|
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "Demo_Authors", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
Name = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
BirthDate = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
ShortBio = table.Column<string>(type: "longtext", nullable: true) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ExtraProperties = table.Column<string>(type: "longtext", nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false), |
|||
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_Demo_Authors", x => x.Id); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "Demo_Books", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
Name = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
Type = table.Column<int>(type: "int", nullable: false), |
|||
PublishDate = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
Price = table.Column<float>(type: "float", nullable: false), |
|||
AuthorId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
|||
ExtraProperties = table.Column<string>(type: "longtext", nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false) |
|||
.Annotation("MySql:CharSet", "utf8mb4"), |
|||
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"), |
|||
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
|||
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci") |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_Demo_Books", x => x.Id); |
|||
table.ForeignKey( |
|||
name: "FK_Demo_Books_Demo_Authors_AuthorId", |
|||
column: x => x.AuthorId, |
|||
principalTable: "Demo_Authors", |
|||
principalColumn: "Id", |
|||
onDelete: ReferentialAction.Cascade); |
|||
}) |
|||
.Annotation("MySql:CharSet", "utf8mb4"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Demo_Authors_Name", |
|||
table: "Demo_Authors", |
|||
column: "Name"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Demo_Books_AuthorId", |
|||
table: "Demo_Books", |
|||
column: "AuthorId"); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "Demo_Books"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "Demo_Authors"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> |
|||
<IsPackable>false</IsPackable> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Authorization.Abstractions" /> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\framework\exporter\LINGYUN.Abp.Exporter.Application.Contracts\LINGYUN.Abp.Exporter.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Demo.Domain.Shared\LINGYUN.Abp.Demo.Domain.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,15 @@ |
|||
using LINGYUN.Abp.Exporter; |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.Authorization; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpExporterApplicationContractsModule), |
|||
typeof(AbpAuthorizationAbstractionsModule), |
|||
typeof(AbpDddApplicationContractsModule), |
|||
typeof(AbpDemoDomainSharedModule))] |
|||
public class AbpDemoApplicationContractsModule : AbpModule |
|||
{ |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class AuthorDto : EntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public DateTime BirthDate { get; set; } |
|||
|
|||
public string? ShortBio { get; set; } |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class CreateAuthorDto |
|||
{ |
|||
[Required] |
|||
[StringLength(AuthorConsts.MaxNameLength)] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
public DateTime BirthDate { get; set; } |
|||
|
|||
public string? ShortBio { get; set; } |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class GetAuthorListDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string? Filter { get; set; } |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public interface IAuthorAppService : IApplicationService |
|||
{ |
|||
Task<AuthorDto> GetAsync(Guid id); |
|||
|
|||
Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input); |
|||
|
|||
Task<AuthorDto> CreateAsync(CreateAuthorDto input); |
|||
|
|||
Task UpdateAsync(Guid id, UpdateAuthorDto input); |
|||
|
|||
Task DeleteAsync(Guid id); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class UpdateAuthorDto |
|||
{ |
|||
[Required] |
|||
[StringLength(AuthorConsts.MaxNameLength)] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
public DateTime BirthDate { get; set; } |
|||
|
|||
public string ShortBio { get; set; } |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class AuthorLookupDto : EntityDto<Guid> |
|||
{ |
|||
public string Name { get; set; } |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class BookDto : AuditedEntityDto<Guid> |
|||
{ |
|||
[DisplayName("名称")] |
|||
public string Name { get; set; } |
|||
|
|||
[DisplayName("类型")] |
|||
public BookType Type { get; set; } |
|||
|
|||
[DisplayName("出版日期")] |
|||
public DateTime PublishDate { get; set; } |
|||
|
|||
[DisplayName("价格")] |
|||
public float Price { get; set; } |
|||
|
|||
public Guid AuthorId { get; set; } |
|||
|
|||
[DisplayName("作者")] |
|||
public string AuthorName { get; set; } |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class BookExportListInput : LimitedResultRequestDto, ISortedResultRequest |
|||
{ |
|||
[Required] |
|||
public string FileName { get; set; } |
|||
public string? Filterr { get; set; } |
|||
public string? Sorting { get; set; } |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class BookImportDto |
|||
{ |
|||
[Required] |
|||
[StringLength(128)] |
|||
[DisplayName("名称")] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
[DisplayName("类型")] |
|||
public BookType Type { get; set; } = BookType.Undefined; |
|||
|
|||
[Required] |
|||
[DataType(DataType.Date)] |
|||
[DisplayName("出版日期")] |
|||
public DateTime PublishDate { get; set; } = DateTime.Now; |
|||
|
|||
[Required] |
|||
[DisplayName("价格")] |
|||
public float Price { get; set; } |
|||
|
|||
public Guid AuthorId { get; set; } |
|||
|
|||
[DisplayName("作者")] |
|||
public string AuthorName { get; set; } |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class BookImportInput |
|||
{ |
|||
[Required] |
|||
public IRemoteStreamContent Content { get; set; } |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class CreateUpdateBookDto |
|||
{ |
|||
[Required] |
|||
[StringLength(128)] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
public BookType Type { get; set; } = BookType.Undefined; |
|||
|
|||
[Required] |
|||
[DataType(DataType.Date)] |
|||
public DateTime PublishDate { get; set; } = DateTime.Now; |
|||
|
|||
[Required] |
|||
public float Price { get; set; } |
|||
|
|||
public Guid AuthorId { get; set; } |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using LINGYUN.Abp.Exporter; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
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
|
|||
IExporterAppService<BookDto, BookExportListInput>, |
|||
IImporterAppService<BookImportInput> |
|||
{ |
|||
Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync(); |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.Demo; |
|||
public static class DemoRemoteServiceConsts |
|||
{ |
|||
public const string RemoteServiceName = "Demo"; |
|||
public const string ModuleName = "demo"; |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using LINGYUN.Abp.Demo.Localization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Permissions; |
|||
public class DemoPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var demoGroup = context.AddGroup(DemoPermissions.GroupName, L("Permission:Demo")); |
|||
|
|||
var booksPermission = demoGroup.AddPermission(DemoPermissions.Books.Default, L("Permission:Books")); |
|||
booksPermission.AddChild(DemoPermissions.Books.Create, L("Permission:Books.Create")); |
|||
booksPermission.AddChild(DemoPermissions.Books.Edit, L("Permission:Books.Edit")); |
|||
booksPermission.AddChild(DemoPermissions.Books.Delete, L("Permission:Books.Delete")); |
|||
booksPermission.AddChild(DemoPermissions.Books.Export, L("Permission:Books.Export")); |
|||
booksPermission.AddChild(DemoPermissions.Books.Import, L("Permission:Books.Import")); |
|||
|
|||
var authorsPermission = demoGroup.AddPermission( |
|||
DemoPermissions.Authors.Default, L("Permission:Authors")); |
|||
authorsPermission.AddChild( |
|||
DemoPermissions.Authors.Create, L("Permission:Authors.Create")); |
|||
authorsPermission.AddChild( |
|||
DemoPermissions.Authors.Edit, L("Permission:Authors.Edit")); |
|||
authorsPermission.AddChild( |
|||
DemoPermissions.Authors.Delete, L("Permission:Authors.Delete")); |
|||
|
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<DemoResource>(name); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
namespace LINGYUN.Abp.Demo.Permissions; |
|||
public static class DemoPermissions |
|||
{ |
|||
public const string GroupName = "Demo"; |
|||
|
|||
public static class Books |
|||
{ |
|||
public const string Default = GroupName + ".Books"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Edit = Default + ".Edit"; |
|||
public const string Delete = Default + ".Delete"; |
|||
|
|||
public const string Export = Default + ".Export"; |
|||
public const string Import = Default + ".Import"; |
|||
} |
|||
|
|||
// *** ADDED a NEW NESTED CLASS ***
|
|||
public static class Authors |
|||
{ |
|||
public const string Default = GroupName + ".Authors"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string Edit = Default + ".Edit"; |
|||
public const string Delete = Default + ".Delete"; |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,28 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> |
|||
<IsPackable>false</IsPackable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\framework\exporter\LINGYUN.Abp.Exporter.Application\LINGYUN.Abp.Exporter.Application.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Demo.Application.Contracts\LINGYUN.Abp.Demo.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Demo.Domain\LINGYUN.Abp.Demo.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,25 @@ |
|||
using LINGYUN.Abp.Exporter; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpDddApplicationModule), |
|||
typeof(AbpDemoDomainModule), |
|||
typeof(AbpExporterApplicationModule), |
|||
typeof(AbpDemoApplicationContractsModule))] |
|||
public class AbpDemoApplicationModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAutoMapperObjectMapper<AbpDemoApplicationModule>(); |
|||
|
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<DemoApplicationMapperProfile>(validate: true); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
using LINGYUN.Abp.Demo.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
|
|||
[Authorize(DemoPermissions.Authors.Default)] |
|||
public class AuthorAppService : DemoApplicationServiceBase, IAuthorAppService |
|||
{ |
|||
private readonly IAuthorRepository _authorRepository; |
|||
private readonly AuthorManager _authorManager; |
|||
|
|||
public AuthorAppService( |
|||
IAuthorRepository authorRepository, |
|||
AuthorManager authorManager) |
|||
{ |
|||
_authorRepository = authorRepository; |
|||
_authorManager = authorManager; |
|||
} |
|||
|
|||
public async Task<AuthorDto> GetAsync(Guid id) |
|||
{ |
|||
var author = await _authorRepository.GetAsync(id); |
|||
return ObjectMapper.Map<Author, AuthorDto>(author); |
|||
} |
|||
|
|||
public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input) |
|||
{ |
|||
if (input.Sorting.IsNullOrWhiteSpace()) |
|||
{ |
|||
input.Sorting = nameof(Author.Name); |
|||
} |
|||
|
|||
var authors = await _authorRepository.GetListAsync( |
|||
input.SkipCount, |
|||
input.MaxResultCount, |
|||
input.Sorting, |
|||
input.Filter |
|||
); |
|||
|
|||
var totalCount = input.Filter == null |
|||
? await _authorRepository.CountAsync() |
|||
: await _authorRepository.CountAsync( |
|||
author => author.Name.Contains(input.Filter)); |
|||
|
|||
return new PagedResultDto<AuthorDto>( |
|||
totalCount, |
|||
ObjectMapper.Map<List<Author>, List<AuthorDto>>(authors) |
|||
); |
|||
} |
|||
|
|||
[Authorize(DemoPermissions.Authors.Create)] |
|||
public async Task<AuthorDto> CreateAsync(CreateAuthorDto input) |
|||
{ |
|||
var author = await _authorManager.CreateAsync( |
|||
input.Name, |
|||
input.BirthDate, |
|||
input.ShortBio |
|||
); |
|||
|
|||
await _authorRepository.InsertAsync(author); |
|||
|
|||
return ObjectMapper.Map<Author, AuthorDto>(author); |
|||
} |
|||
|
|||
[Authorize(DemoPermissions.Authors.Edit)] |
|||
public async Task UpdateAsync(Guid id, UpdateAuthorDto input) |
|||
{ |
|||
var author = await _authorRepository.GetAsync(id); |
|||
|
|||
if (author.Name != input.Name) |
|||
{ |
|||
await _authorManager.ChangeNameAsync(author, input.Name); |
|||
} |
|||
|
|||
author.BirthDate = input.BirthDate; |
|||
author.ShortBio = input.ShortBio; |
|||
|
|||
await _authorRepository.UpdateAsync(author); |
|||
} |
|||
|
|||
[Authorize(DemoPermissions.Authors.Delete)] |
|||
public async Task DeleteAsync(Guid id) |
|||
{ |
|||
await _authorRepository.DeleteAsync(id); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,206 @@ |
|||
using LINGYUN.Abp.Demo.Authors; |
|||
using LINGYUN.Abp.Demo.Permissions; |
|||
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; |
|||
|
|||
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
|
|||
{ |
|||
private readonly IAuthorRepository _authorRepository; |
|||
private readonly AuthorManager _authorManager; |
|||
|
|||
private readonly IExporterProvider _exporterProvider; |
|||
private readonly IImporterProvider _importerProvider; |
|||
|
|||
public BookAppService( |
|||
IExporterProvider exporterProvider, |
|||
IImporterProvider importerProvider, |
|||
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; |
|||
} |
|||
|
|||
public async virtual Task ImportAsync(BookImportInput input) |
|||
{ |
|||
await CheckCreatePolicyAsync(); |
|||
await CheckPolicyAsync(DemoPermissions.Books.Import); |
|||
|
|||
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 = ObjectMapper.Map<BookImportDto, Book>(dto); |
|||
|
|||
TryToSetTenantId(book); |
|||
|
|||
return book; |
|||
}); |
|||
|
|||
if (createAuthors.Count > 0) |
|||
{ |
|||
await _authorRepository.InsertManyAsync(createAuthors, autoSave: true); |
|||
} |
|||
|
|||
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 => |
|||
{ |
|||
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 override async Task<BookDto> GetAsync(Guid id) |
|||
{ |
|||
//Get the IQueryable<Book> from the repository
|
|||
var queryable = await Repository.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 |
|||
where book.Id == id |
|||
select new { book, author }; |
|||
|
|||
//Execute the query and get the book with author
|
|||
var queryResult = await AsyncExecuter.FirstOrDefaultAsync(query); |
|||
if (queryResult == null) |
|||
{ |
|||
throw new EntityNotFoundException(typeof(Book), id); |
|||
} |
|||
|
|||
var bookDto = ObjectMapper.Map<Book, BookDto>(queryResult.book); |
|||
bookDto.AuthorName = queryResult.author.Name; |
|||
return bookDto; |
|||
} |
|||
|
|||
public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input) |
|||
{ |
|||
//Get the IQueryable<Book> from the repository
|
|||
var queryable = await Repository.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 |
|||
select new { book, author }; |
|||
|
|||
//Paging
|
|||
query = query |
|||
.OrderBy(NormalizeSorting(input.Sorting)) |
|||
.Skip(input.SkipCount) |
|||
.Take(input.MaxResultCount); |
|||
|
|||
//Execute the query and get a list
|
|||
var queryResult = await AsyncExecuter.ToListAsync(query); |
|||
|
|||
//Convert the query result to a list of BookDto objects
|
|||
var bookDtos = queryResult.Select(x => |
|||
{ |
|||
var bookDto = ObjectMapper.Map<Book, BookDto>(x.book); |
|||
bookDto.AuthorName = x.author.Name; |
|||
return bookDto; |
|||
}).ToList(); |
|||
|
|||
//Get the total count with another query
|
|||
var totalCount = await Repository.GetCountAsync(); |
|||
|
|||
return new PagedResultDto<BookDto>( |
|||
totalCount, |
|||
bookDtos |
|||
); |
|||
} |
|||
|
|||
public async Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync() |
|||
{ |
|||
var authors = await _authorRepository.GetListAsync(); |
|||
|
|||
return new ListResultDto<AuthorLookupDto>( |
|||
ObjectMapper.Map<List<Author>, List<AuthorLookupDto>>(authors) |
|||
); |
|||
} |
|||
|
|||
private static string NormalizeSorting(string? sorting) |
|||
{ |
|||
if (sorting.IsNullOrEmpty()) |
|||
{ |
|||
return $"book.{nameof(Book.Name)}"; |
|||
} |
|||
|
|||
if (sorting.Contains("authorName", StringComparison.OrdinalIgnoreCase)) |
|||
{ |
|||
return sorting.Replace( |
|||
"authorName", |
|||
"author.Name", |
|||
StringComparison.OrdinalIgnoreCase |
|||
); |
|||
} |
|||
|
|||
return $"book.{sorting}"; |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using AutoMapper; |
|||
using LINGYUN.Abp.Demo.Authors; |
|||
using LINGYUN.Abp.Demo.Books; |
|||
using Volo.Abp.AutoMapper; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
public class DemoApplicationMapperProfile : Profile |
|||
{ |
|||
public DemoApplicationMapperProfile() |
|||
{ |
|||
CreateMap<Book, BookDto>() |
|||
.Ignore(dto => dto.AuthorName); |
|||
CreateMap<BookImportDto, Book>() |
|||
.IgnoreAuditedObjectProperties() |
|||
.Ignore(dto => dto.Id) |
|||
.Ignore(dto => dto.ExtraProperties) |
|||
.Ignore(dto => dto.ConcurrencyStamp); |
|||
CreateMap<CreateUpdateBookDto, Book>() |
|||
.IgnoreAuditedObjectProperties() |
|||
.Ignore(dto => dto.Id) |
|||
.Ignore(dto => dto.ExtraProperties) |
|||
.Ignore(dto => dto.ConcurrencyStamp); |
|||
CreateMap<Author, AuthorDto>(); |
|||
CreateMap<Author, AuthorLookupDto>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
public abstract class DemoApplicationServiceBase : ApplicationService |
|||
{ |
|||
protected DemoApplicationServiceBase() |
|||
{ |
|||
LocalizationResource = typeof(AbpDemoApplicationModule); |
|||
ObjectMapperContext = typeof(AbpDemoApplicationModule); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,30 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> |
|||
<IsPackable>false</IsPackable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\Demo\Localization\Resources\en.json" /> |
|||
<None Remove="LINGYUN\Abp\Demo\Localization\Resources\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Demo\Localization\Resources\en.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Demo\Localization\Resources\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Domain.Shared" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,31 @@ |
|||
using LINGYUN.Abp.Demo.Localization; |
|||
using Volo.Abp.Domain; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Localization.ExceptionHandling; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
|
|||
[DependsOn(typeof(AbpDddDomainSharedModule))] |
|||
public class AbpDemoDomainSharedModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpDemoDomainSharedModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<DemoResource>("en") |
|||
.AddVirtualJson("/LINGYUN/Abp/Demo/Localization/Resources"); |
|||
}); |
|||
Configure<AbpExceptionLocalizationOptions>(options => |
|||
{ |
|||
options.MapCodeNamespace(DemoErrorCodes.Namespace, typeof(DemoResource)); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public static class AuthorConsts |
|||
{ |
|||
public const int MaxNameLength = 64; |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public enum BookType |
|||
{ |
|||
Undefined, |
|||
Adventure, |
|||
Biography, |
|||
Dystopia, |
|||
Fantastic, |
|||
Horror, |
|||
Science, |
|||
ScienceFiction, |
|||
Poetry |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
namespace LINGYUN.Abp.Demo; |
|||
public static class DemoErrorCodes |
|||
{ |
|||
public const string Namespace = "Demo"; |
|||
|
|||
public static class Author |
|||
{ |
|||
public const string Prefix = Namespace + ":00"; |
|||
/// <summary>
|
|||
/// 作者 {Name} 已经存在!
|
|||
/// </summary>
|
|||
public const string AuthorAlreadyExists = Prefix + "001"; |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Localization; |
|||
|
|||
[LocalizationResourceName("Demo")] |
|||
public class DemoResource |
|||
{ |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Permission:Books": "Books", |
|||
"Permission:Books.Create": "Create Books", |
|||
"Permission:Books.Edit": "Edit Books", |
|||
"Permission:Books.Delete": "Delete Books", |
|||
"Permission:Books.Export": "Export Books", |
|||
"Permission:Books.Import": "Import Books", |
|||
"Permission:Authors": "Authors", |
|||
"Permission:Authors.Create": "Create Authors", |
|||
"Permission:Authors.Edit": "Edit Authors", |
|||
"Permission:Authors.Delete": "Delete Authors", |
|||
"Demo:00001": "Author {Name} already exists!" |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Permission:Books": "书籍管理", |
|||
"Permission:Books.Create": "新增书籍", |
|||
"Permission:Books.Edit": "编辑书籍", |
|||
"Permission:Books.Delete": "删除书籍", |
|||
"Permission:Books.Export": "导出书籍", |
|||
"Permission:Books.Import": "导入书籍", |
|||
"Permission:Authors": "作者管理", |
|||
"Permission:Authors.Create": "新增作者", |
|||
"Permission:Authors.Edit": "编辑作者", |
|||
"Permission:Authors.Delete": "删除作者", |
|||
"Demo:00001": "作者 {Name} 已经存在!" |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,28 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> |
|||
<IsPackable>false</IsPackable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AutoMapper" /> |
|||
<PackageReference Include="Volo.Abp.Ddd.Domain" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\framework\data-protection\LINGYUN.Abp.DataProtection\LINGYUN.Abp.DataProtection.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Demo.Domain.Shared\LINGYUN.Abp.Demo.Domain.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,37 @@ |
|||
using LINGYUN.Abp.DataProtection; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Domain; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(AbpDddDomainModule), |
|||
typeof(AbpDataProtectionModule), |
|||
typeof(AbpDemoDomainSharedModule))] |
|||
public class AbpDemoDomainModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAutoMapperObjectMapper<AbpDemoDomainModule>(); |
|||
|
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<DemoDomainMapperProfile>(validate: true); |
|||
}); |
|||
|
|||
//Configure<AbpLocalizationPersistenceOptions>(options =>
|
|||
//{
|
|||
// options.AddPersistenceResource<DemoResource>();
|
|||
//});
|
|||
|
|||
// 分布式事件
|
|||
//Configure<AbpDistributedEntityEventOptions>(options =>
|
|||
//{
|
|||
// options.AutoEventSelectors.Add<Text>();
|
|||
// options.EtoMappings.Add<Text, TextEto>();
|
|||
//});
|
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class Author : FullAuditedAggregateRoot<Guid> |
|||
{ |
|||
public string Name { get; private set; } |
|||
public DateTime BirthDate { get; set; } |
|||
public string? ShortBio { get; set; } |
|||
|
|||
private Author() |
|||
{ |
|||
/* This constructor is for deserialization / ORM purpose */ |
|||
} |
|||
|
|||
internal Author( |
|||
Guid id, |
|||
[NotNull] string name, |
|||
DateTime birthDate, |
|||
[CanBeNull] string? shortBio = null) |
|||
: base(id) |
|||
{ |
|||
SetName(name); |
|||
BirthDate = birthDate; |
|||
ShortBio = shortBio; |
|||
} |
|||
|
|||
internal Author ChangeName([NotNull] string name) |
|||
{ |
|||
SetName(name); |
|||
return this; |
|||
} |
|||
|
|||
private void SetName([NotNull] string name) |
|||
{ |
|||
Name = Check.NotNullOrWhiteSpace( |
|||
name, |
|||
nameof(name), |
|||
maxLength: AuthorConsts.MaxNameLength |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class AuthorAlreadyExistsException : BusinessException |
|||
{ |
|||
public AuthorAlreadyExistsException(string name) |
|||
: base(DemoErrorCodes.Author.AuthorAlreadyExists) |
|||
{ |
|||
WithData("Name", name); |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class AuthorManager : DomainService |
|||
{ |
|||
private readonly IAuthorRepository _authorRepository; |
|||
|
|||
public AuthorManager(IAuthorRepository authorRepository) |
|||
{ |
|||
_authorRepository = authorRepository; |
|||
} |
|||
|
|||
public async Task<Author> CreateAsync( |
|||
[NotNull] string name, |
|||
DateTime birthDate, |
|||
[CanBeNull] string? shortBio = null) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|||
|
|||
var existingAuthor = await _authorRepository.FindByNameAsync(name); |
|||
if (existingAuthor != null) |
|||
{ |
|||
throw new AuthorAlreadyExistsException(name); |
|||
} |
|||
|
|||
return new Author( |
|||
GuidGenerator.Create(), |
|||
name, |
|||
birthDate, |
|||
shortBio |
|||
); |
|||
} |
|||
|
|||
public async Task ChangeNameAsync( |
|||
[NotNull] Author author, |
|||
[NotNull] string newName) |
|||
{ |
|||
Check.NotNull(author, nameof(author)); |
|||
Check.NotNullOrWhiteSpace(newName, nameof(newName)); |
|||
|
|||
var existingAuthor = await _authorRepository.FindByNameAsync(newName); |
|||
if (existingAuthor != null && existingAuthor.Id != author.Id) |
|||
{ |
|||
throw new AuthorAlreadyExistsException(newName); |
|||
} |
|||
|
|||
author.ChangeName(newName); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public interface IAuthorRepository : IRepository<Author, Guid> |
|||
{ |
|||
Task<Author?> FindByNameAsync(string name); |
|||
|
|||
Task<List<Author>> GetListAsync( |
|||
int skipCount, |
|||
int maxResultCount, |
|||
string sorting, |
|||
string? filter = null |
|||
); |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using LINGYUN.Abp.DataProtection; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class Book : AuditedAggregateRoot<Guid>, IDataProtected |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public BookType Type { get; set; } |
|||
|
|||
public DateTime PublishDate { get; set; } |
|||
|
|||
public float Price { get; set; } |
|||
|
|||
public Guid AuthorId { get; set; } |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public interface IBookRepository : IRepository<Book, Guid> |
|||
{ |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace LINGYUN.Abp.Demo; |
|||
public static class DemoDbProterties |
|||
{ |
|||
public static string DbTablePrefix { get; set; } = "Demo_"; |
|||
|
|||
public static string? DbSchema { get; set; } = null; |
|||
|
|||
|
|||
public const string ConnectionStringName = "Demo"; |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
public class DemoDomainMapperProfile : Profile |
|||
{ |
|||
public DemoDomainMapperProfile() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,23 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> |
|||
<IsPackable>false</IsPackable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\framework\data-protection\LINGYUN.Abp.DataProtection.EntityFrameworkCore\LINGYUN.Abp.DataProtection.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Demo.Domain\LINGYUN.Abp.Demo.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,41 @@ |
|||
using LINGYUN.Abp.Demo.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using System.Linq.Dynamic.Core; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
public class EfCoreAuthorRepository |
|||
: EfCoreRepository<DemoDbContext, Author, Guid>, |
|||
IAuthorRepository |
|||
{ |
|||
public EfCoreAuthorRepository( |
|||
IDbContextProvider<DemoDbContext> dbContextProvider) |
|||
: base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async Task<Author?> FindByNameAsync(string name) |
|||
{ |
|||
var dbSet = await GetDbSetAsync(); |
|||
return await dbSet.FirstOrDefaultAsync(author => author.Name == name); |
|||
} |
|||
|
|||
public async Task<List<Author>> GetListAsync( |
|||
int skipCount, |
|||
int maxResultCount, |
|||
string sorting, |
|||
string? filter = null) |
|||
{ |
|||
var dbSet = await GetDbSetAsync(); |
|||
return await dbSet |
|||
.WhereIf( |
|||
!filter.IsNullOrWhiteSpace(), |
|||
author => author.Name.Contains(filter!) |
|||
) |
|||
.OrderBy(sorting) |
|||
.Skip(skipCount) |
|||
.Take(maxResultCount) |
|||
.ToListAsync(); |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using JetBrains.Annotations; |
|||
using LINGYUN.Abp.DataProtection; |
|||
using LINGYUN.Abp.DataProtection.EntityFrameworkCore; |
|||
using LINGYUN.Abp.Demo.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
public class EfCoreBookRepository : EfCoreDataProtectionRepository<DemoDbContext, Book, Guid>, IBookRepository |
|||
{ |
|||
public EfCoreBookRepository( |
|||
[NotNull] IDbContextProvider<DemoDbContext> dbContextProvider, |
|||
[NotNull] IDataAuthorizationService dataAuthorizationService, |
|||
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder) |
|||
: base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder) |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using LINGYUN.Abp.DataProtection.EntityFrameworkCore; |
|||
using LINGYUN.Abp.Demo.Authors; |
|||
using LINGYUN.Abp.Demo.Books; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Demo.EntityFrameworkCore; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpDemoDomainModule), |
|||
typeof(AbpDataProtectionEntityFrameworkCoreModule))] |
|||
public class AbpDemoEntityFrameworkCoreModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAbpDbContext<DemoDbContext>(options => |
|||
{ |
|||
//
|
|||
options.AddRepository<Author, EfCoreAuthorRepository>(); |
|||
options.AddRepository<Book, EfCoreBookRepository>(); |
|||
|
|||
options.AddDefaultRepositories(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using LINGYUN.Abp.DataProtection.EntityFrameworkCore; |
|||
using LINGYUN.Abp.Demo.Authors; |
|||
using LINGYUN.Abp.Demo.Books; |
|||
using Microsoft.EntityFrameworkCore; |
|||
|
|||
namespace LINGYUN.Abp.Demo.EntityFrameworkCore; |
|||
public class DemoDbContext : AbpDataProtectionDbContext<DemoDbContext> |
|||
{ |
|||
public DbSet<Book> Books { get; set; } |
|||
|
|||
public DbSet<Author> Authors { get; set; } |
|||
|
|||
|
|||
public DemoDbContext(DbContextOptions<DemoDbContext> options) : base(options) |
|||
{ |
|||
} |
|||
|
|||
protected override void OnModelCreating(ModelBuilder modelBuilder) |
|||
{ |
|||
base.OnModelCreating(modelBuilder); |
|||
|
|||
modelBuilder.ConfigureDemo(); ; |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using LINGYUN.Abp.Demo.Authors; |
|||
using LINGYUN.Abp.Demo.Books; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
|
|||
namespace LINGYUN.Abp.Demo.EntityFrameworkCore; |
|||
public static class DemoDbContextModelCreatingExtensions |
|||
{ |
|||
public static void ConfigureDemo( |
|||
this ModelBuilder builder, |
|||
Action<DemoModelBuilderConfigurationOptions>? optionsAction = null) |
|||
{ |
|||
Check.NotNull(builder, nameof(builder)); |
|||
|
|||
var options = new DemoModelBuilderConfigurationOptions( |
|||
DemoDbProterties.DbTablePrefix, |
|||
DemoDbProterties.DbSchema |
|||
); |
|||
optionsAction?.Invoke(options); |
|||
|
|||
builder.Entity<Book>(b => |
|||
{ |
|||
b.ToTable(options.TablePrefix + "Books", options.Schema); |
|||
b.ConfigureByConvention(); //auto configure for the base class props
|
|||
b.Property(x => x.Name).IsRequired().HasMaxLength(128); |
|||
|
|||
// ADD THE MAPPING FOR THE RELATION
|
|||
b.HasOne<Author>().WithMany().HasForeignKey(x => x.AuthorId).IsRequired(); |
|||
}); |
|||
|
|||
builder.Entity<Author>(b => |
|||
{ |
|||
b.ToTable(options.TablePrefix + "Authors", options.Schema); |
|||
|
|||
b.ConfigureByConvention(); |
|||
|
|||
b.Property(x => x.Name) |
|||
.IsRequired() |
|||
.HasMaxLength(AuthorConsts.MaxNameLength); |
|||
|
|||
b.HasIndex(x => x.Name); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
|
|||
namespace LINGYUN.Abp.Demo.EntityFrameworkCore; |
|||
public class DemoModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions |
|||
{ |
|||
public DemoModelBuilderConfigurationOptions( |
|||
[NotNull] string tablePrefix = "", |
|||
[CanBeNull] string? schema = null) |
|||
: base( |
|||
tablePrefix, |
|||
schema) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,26 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> |
|||
<IsPackable>false</IsPackable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Demo.Application.Contracts\LINGYUN.Abp.Demo.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,28 @@ |
|||
using LINGYUN.Abp.Demo.Localization; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Demo; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcModule), |
|||
typeof(AbpDemoApplicationContractsModule))] |
|||
public class AbpDemoHttpApiModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpDemoHttpApiModule).Assembly); |
|||
}); |
|||
|
|||
PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource( |
|||
typeof(DemoResource), |
|||
typeof(AbpDemoApplicationContractsModule).Assembly); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using LINGYUN.Abp.Demo.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Authors; |
|||
|
|||
[Controller] |
|||
[Authorize(DemoPermissions.Authors.Default)] |
|||
[RemoteService(Name = DemoRemoteServiceConsts.RemoteServiceName)] |
|||
[Area(DemoRemoteServiceConsts.ModuleName)] |
|||
[Route($"api/{DemoRemoteServiceConsts.ModuleName}/authors")] |
|||
public class AuthorController : AbpControllerBase, IAuthorAppService |
|||
{ |
|||
private readonly IAuthorAppService _service; |
|||
public AuthorController(IAuthorAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(DemoPermissions.Authors.Create)] |
|||
public virtual Task<AuthorDto> CreateAsync(CreateAuthorDto input) |
|||
{ |
|||
return _service.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
[Authorize(DemoPermissions.Authors.Delete)] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return _service.DeleteAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public virtual Task<AuthorDto> GetAsync(Guid id) |
|||
{ |
|||
return _service.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input) |
|||
{ |
|||
return _service.GetListAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
[Authorize(DemoPermissions.Authors.Edit)] |
|||
public virtual Task UpdateAsync(Guid id, UpdateAuthorDto input) |
|||
{ |
|||
return _service.UpdateAsync(id, input); |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using LINGYUN.Abp.Demo.Permissions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.Demo.Books; |
|||
|
|||
[Controller] |
|||
[Authorize(DemoPermissions.Books.Default)] |
|||
[RemoteService(Name = DemoRemoteServiceConsts.RemoteServiceName)] |
|||
[Area(DemoRemoteServiceConsts.ModuleName)] |
|||
[Route($"api/{DemoRemoteServiceConsts.ModuleName}/books")] |
|||
public class BookController : AbpControllerBase, IBookAppService |
|||
{ |
|||
private readonly IBookAppService _service; |
|||
|
|||
public BookController(IBookAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(DemoPermissions.Books.Create)] |
|||
public virtual Task<BookDto> CreateAsync(CreateUpdateBookDto input) |
|||
{ |
|||
return _service.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
[Authorize(DemoPermissions.Books.Delete)] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return _service.DeleteAsync(id); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("import")] |
|||
public virtual Task ImportAsync([FromForm] BookImportInput input) |
|||
{ |
|||
return _service.ImportAsync(input); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("export")] |
|||
public virtual Task<IRemoteStreamContent> ExportAsync(BookExportListInput input) |
|||
{ |
|||
return _service.ExportAsync(input); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public virtual Task<BookDto> GetAsync(Guid id) |
|||
{ |
|||
return _service.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("lookup")] |
|||
public virtual Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync() |
|||
{ |
|||
return _service.GetAuthorLookupAsync(); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public virtual Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input) |
|||
{ |
|||
return _service.GetListAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
[Authorize(DemoPermissions.Books.Edit)] |
|||
public virtual Task<BookDto> UpdateAsync(Guid id, CreateUpdateBookDto input) |
|||
{ |
|||
return _service.UpdateAsync(id, input); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue