committed by
GitHub
165 changed files with 9213 additions and 137 deletions
@ -1,9 +1,27 @@ |
|||
using Volo.Abp.Modularity; |
|||
using LINGYUN.Abp.DataProtection.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.DataProtection; |
|||
|
|||
[DependsOn(typeof(AbpLocalizationModule))] |
|||
[DependsOn(typeof(AbpObjectExtendingModule))] |
|||
public class AbpDataProtectionAbstractionsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpDataProtectionAbstractionsModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<DataProtectionResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/DataProtection/Localization/Resources"); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"DataProtection:010001": "Data access permission not granted to protected resources!" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"DataProtection:010001": "未授予受保护资源的数据访问权限!" |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.DataProtection; |
|||
public class AbpDataAccessDeniedException : BusinessException |
|||
{ |
|||
public AbpDataAccessDeniedException() |
|||
{ |
|||
} |
|||
|
|||
public AbpDataAccessDeniedException(string message) |
|||
: base("DataProtection:010001", message) |
|||
{ |
|||
} |
|||
} |
|||
@ -1,6 +1,8 @@ |
|||
namespace LINGYUN.Abp.DataProtection; |
|||
using System.Linq.Expressions; |
|||
|
|||
namespace LINGYUN.Abp.DataProtection; |
|||
public interface IDataAccessKeywordContributor |
|||
{ |
|||
string Keyword { get; } |
|||
object Contribute(DataAccessKeywordContributorContext context); |
|||
Expression Contribute(DataAccessKeywordContributorContext context); |
|||
} |
|||
|
|||
@ -0,0 +1,43 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Clients; |
|||
|
|||
namespace LINGYUN.Abp.DataProtection.Subjects; |
|||
public class DataAccessClientIdContributor : IDataAccessSubjectContributor |
|||
{ |
|||
public string Name => ClientPermissionValueProvider.ProviderName; |
|||
|
|||
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context) |
|||
{ |
|||
var allowProperties = new List<string>(); |
|||
var currentClient = context.ServiceProvider.GetRequiredService<ICurrentClient>(); |
|||
if (currentClient.IsAuthenticated) |
|||
{ |
|||
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>(); |
|||
var resource = resourceStore.Get(Name, currentClient.Id, context.EntityTypeFullName, context.Operation); |
|||
if (resource?.AllowProperties.Any() == true) |
|||
{ |
|||
allowProperties.AddIfNotContains(resource.AllowProperties); |
|||
} |
|||
} |
|||
return allowProperties; |
|||
} |
|||
|
|||
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context) |
|||
{ |
|||
var groups = new List<DataAccessFilterGroup>(); |
|||
var currentClient = context.ServiceProvider.GetRequiredService<ICurrentClient>(); |
|||
if (currentClient.IsAuthenticated) |
|||
{ |
|||
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>(); |
|||
var resource = resourceStore.Get(Name, currentClient.Id, context.EntityTypeFullName, context.Operation); |
|||
if (resource?.FilterGroup != null) |
|||
{ |
|||
groups.Add(resource.FilterGroup); |
|||
} |
|||
} |
|||
return groups; |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</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,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Exporter.Application.Contracts</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Exporter.Application.Contracts</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
[DependsOn(typeof(AbpDddApplicationContractsModule))] |
|||
public class AbpExporterApplicationContractsModule : AbpModule |
|||
{ |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
/// <summary>
|
|||
/// 数据导出服务接口
|
|||
/// </summary>
|
|||
/// <typeparam name="TEntityExportDto">导出的实体数据传输对象</typeparam>
|
|||
/// <typeparam name="TEntityListGetInput">实体数据过滤数据对象</typeparam>
|
|||
public interface IExporterAppService<TEntityExportDto, TEntityListGetInput> |
|||
where TEntityExportDto : class, new() |
|||
{ |
|||
/// <summary>
|
|||
/// 导出数据(默认实现Excel)
|
|||
/// </summary>
|
|||
/// <param name="input">数据过滤条件</param>
|
|||
/// <returns></returns>
|
|||
Task<IRemoteStreamContent> ExportAsync(TEntityListGetInput input); |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
/// <summary>
|
|||
/// 数据导入服务接口
|
|||
/// </summary>
|
|||
/// <typeparam name="TEntityImportDto"></typeparam>
|
|||
public interface IImporterAppService<TEntityImportDto> |
|||
where TEntityImportDto: class, new() |
|||
{ |
|||
/// <summary>
|
|||
/// 导入数据(默认从Excel)
|
|||
/// </summary>
|
|||
/// <param name="input">导入的数据文件流</param>
|
|||
/// <returns></returns>
|
|||
Task ImportAsync(TEntityImportDto input); |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
# LINGYUN.Abp.Exporter.Application.Contracts |
|||
|
|||
数据导出/导入接口契约层,定义通用的数据导入/导入服务接口 |
|||
|
|||
## 配置使用 |
|||
|
|||
|
|||
> 配置模块依赖 |
|||
```csharp |
|||
|
|||
[DependsOn( |
|||
typeof(AbpExporterApplicationContractsModule) |
|||
)] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
``` |
|||
|
|||
> 定义导出类型 |
|||
```csharp |
|||
public class DemoClassDto |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Remarks { get; set; } |
|||
|
|||
public DemoClassDto() |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> 定义导入类型 |
|||
```csharp |
|||
public class DemoClassImportInput |
|||
{ |
|||
[Required] |
|||
public IRemoteStreamContent Content { get; set; } |
|||
|
|||
public DemoClassImportInput() |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> 定义数据过滤类型 |
|||
```csharp |
|||
public class DemoClassExportListInput |
|||
{ |
|||
public string Filter { get; set; } |
|||
|
|||
[Required] |
|||
public string FileName { get; set; } |
|||
|
|||
public DemoClassExportListInput() |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> 导出数据 |
|||
```csharp |
|||
public class ExportDemoClassExportAppService : IExporterAppService<DemoClassDto, DemoClassExportListInput> |
|||
{ |
|||
private readonly IExporterProvider _exporterProvider; |
|||
|
|||
public ExportDemoClassExportAppService(IExporterProvider exporterProvider) |
|||
{ |
|||
_exporterProvider = exporterProvider; |
|||
} |
|||
|
|||
public async virtual Task<IRemoteStreamContent> ExportAsync(DemoClassExportListInput input) |
|||
{ |
|||
var dtos = 通过仓储接口查询数据列表; |
|||
|
|||
var stream = await _exporterProvider.ExportAsync(dtos); |
|||
|
|||
return new RemoteStreamContent(stream, input.FileName); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> 导入数据 |
|||
```csharp |
|||
public class ExportDemoClassImportAppService : IImporterAppService<DemoClassImportInput> |
|||
{ |
|||
private readonly IImporterProvider _importerProvider; |
|||
|
|||
public ExportDemoClassImportAppService(IImporterProvider importerProvider) |
|||
{ |
|||
_importerProvider = importerProvider; |
|||
} |
|||
|
|||
public async virtual Task ImportAsync(DemoClassImportInput input) |
|||
{ |
|||
var stream = input.Content.GetStream(); |
|||
|
|||
var demos = await _importerProvider.ImportAsync<DemoClass>(stream); |
|||
|
|||
// 其他操作 |
|||
} |
|||
} |
|||
``` |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</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,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Exporter.Application</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Exporter.Application</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Ddd.Application" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Application.Contracts\LINGYUN.Abp.Exporter.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Core\LINGYUN.Abp.Exporter.Core.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpDddApplicationModule), |
|||
typeof(AbpExporterCoreModule), |
|||
typeof(AbpExporterApplicationContractsModule))] |
|||
public class AbpExporterApplicationModule : AbpModule |
|||
{ |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
public abstract class ExporterAppService<TEntity, TEntityExportDto, TEntityListGetInput> : ApplicationService, IExporterAppService<TEntityExportDto, TEntityListGetInput> |
|||
where TEntityExportDto : class, new() |
|||
{ |
|||
private readonly IExporterProvider _exporterProvider; |
|||
|
|||
protected ExporterAppService(IExporterProvider exporterProvider) |
|||
{ |
|||
_exporterProvider = exporterProvider; |
|||
} |
|||
|
|||
public async virtual Task<IRemoteStreamContent> ExportAsync(TEntityListGetInput input) |
|||
{ |
|||
var fileName = GetExportFileName(input); |
|||
|
|||
var entities = await GetListAsync(input); |
|||
var entitieDtoList = MapEntitiesToDto(entities); |
|||
|
|||
var stream = await _exporterProvider.ExportAsync(entitieDtoList); |
|||
|
|||
return new RemoteStreamContent(stream, fileName); |
|||
} |
|||
/// <summary>
|
|||
/// 实现方法用以返回导出文件名
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
protected abstract string GetExportFileName(TEntityListGetInput input); |
|||
/// <summary>
|
|||
/// 实现方法用以查询需要导出的实体列表
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
protected abstract Task<List<TEntity>> GetListAsync(TEntityListGetInput input); |
|||
/// <summary>
|
|||
/// 实现方法用以实体数据传输对象映射
|
|||
/// </summary>
|
|||
/// <param name="entities"></param>
|
|||
/// <returns></returns>
|
|||
protected virtual List<TEntityExportDto> MapEntitiesToDto(List<TEntity> entities) |
|||
{ |
|||
return ObjectMapper.Map<List<TEntity>, List<TEntityExportDto>>(entities); |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
public abstract class ImporterAppService<TEntity, TEntityImportDto> : ApplicationService, IImporterAppService<TEntityImportDto> |
|||
where TEntityImportDto : class, new() |
|||
{ |
|||
private readonly IImporterProvider _importerProvider; |
|||
protected ImporterAppService(IImporterProvider importerProvider) |
|||
{ |
|||
_importerProvider = importerProvider; |
|||
} |
|||
|
|||
public async virtual Task ImportAsync(TEntityImportDto input) |
|||
{ |
|||
var stream = await GetImportStream(input); |
|||
var entitieDtoList = await _importerProvider.ImportAsync<TEntityImportDto>(stream); |
|||
|
|||
var entities = MapDtoToEntities([.. entitieDtoList]); |
|||
|
|||
await SaveManyEntities(entities); |
|||
} |
|||
/// <summary>
|
|||
/// 实现方法用以从导入数据中提取文件流
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <returns></returns>
|
|||
protected abstract Task<Stream> GetImportStream(TEntityImportDto input); |
|||
/// <summary>
|
|||
/// 实现方法用以保存实体列表到持久化设施
|
|||
/// </summary>
|
|||
/// <param name="entities"></param>
|
|||
/// <returns></returns>
|
|||
protected abstract Task SaveManyEntities(ICollection<TEntity> entities); |
|||
/// <summary>
|
|||
/// 实现方法用以实体数据传输对象映射
|
|||
/// </summary>
|
|||
/// <param name="entitieDtoList"></param>
|
|||
/// <returns></returns>
|
|||
protected virtual List<TEntity> MapDtoToEntities(List<TEntityImportDto> entitieDtoList) |
|||
{ |
|||
return ObjectMapper.Map<List<TEntityImportDto>, List<TEntity>>(entitieDtoList); |
|||
} |
|||
} |
|||
@ -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> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Exporter.Core</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Exporter.Core</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="LINGYUN\Abp\Exporter\Localization\Resources\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Exporter\Localization\Resources\en.json" /> |
|||
<EmbeddedResource Include="LINGYUN\Abp\Exporter\Localization\Resources\zh-Hans.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Localization" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,31 @@ |
|||
using LINGYUN.Abp.Exporter.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Localization.ExceptionHandling; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
[DependsOn(typeof(AbpLocalizationModule))] |
|||
public class AbpExporterCoreModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpExporterCoreModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<AbpExporterResource>("en") |
|||
.AddVirtualJson("/LINGYUN/Abp/Exporter/Localization/Resources"); |
|||
}); |
|||
|
|||
Configure<AbpExceptionLocalizationOptions>(options => |
|||
{ |
|||
options.MapCodeNamespace(ExporterErrorCodes.Namespace, typeof(AbpExporterResource)); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
namespace LINGYUN.Abp.Exporter; |
|||
public static class ExporterErrorCodes |
|||
{ |
|||
public const string Namespace = "AbpExporter"; |
|||
/// <summary>
|
|||
/// 导入数据过程中出现一些错误,请检查数据有效性!
|
|||
/// </summary>
|
|||
public const string ImportDataError = Namespace + ":010001"; |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
/// <summary>
|
|||
/// 数据导出提供者
|
|||
/// </summary>
|
|||
public interface IExporterProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 数据导出
|
|||
/// </summary>
|
|||
/// <param name="data">导出数据</param>
|
|||
/// <param name="cancellationToken"></param>
|
|||
/// <returns></returns>
|
|||
Task<Stream> ExportAsync<T>(ICollection<T> data, CancellationToken cancellationToken = default) |
|||
where T : class, new(); |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
/// <summary>
|
|||
/// 数据导入提供者
|
|||
/// </summary>
|
|||
public interface IImporterProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 数据导入
|
|||
/// </summary>
|
|||
/// <typeparam name="T"></typeparam>
|
|||
/// <param name="stream"></param>
|
|||
/// <returns></returns>
|
|||
Task<IReadOnlyCollection<T>> ImportAsync<T>(Stream stream) |
|||
where T : class, new(); |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.Localization; |
|||
|
|||
[LocalizationResourceName("AbpExporter")] |
|||
public class AbpExporterResource |
|||
{ |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"AbpExporter:010001": "There were some errors during the data import process. Please check the validity of the data!" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"AbpExporter:010001": "导入数据过程中出现一些错误,请检查数据有效性!" |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
[Dependency(TryRegister = true)] |
|||
public class NullExporterProvider : IExporterProvider, ISingletonDependency |
|||
{ |
|||
private readonly static Stream _nullStreamCache = Stream.Null; |
|||
public Task<Stream> ExportAsync<T>(ICollection<T> data, CancellationToken cancellationToken = default) where T : class, new() |
|||
{ |
|||
return Task.FromResult(_nullStreamCache); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
[Dependency(TryRegister = true)] |
|||
public class NullImporterProvider : IImporterProvider, ISingletonDependency |
|||
{ |
|||
public Task<IReadOnlyCollection<T>> ImportAsync<T>(Stream stream) where T : class, new() |
|||
{ |
|||
IReadOnlyCollection<T> empty = Array.Empty<T>(); |
|||
|
|||
return Task.FromResult(empty); |
|||
} |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
# LINGYUN.Abp.Exporter.Core |
|||
|
|||
数据导出/导入核心层 |
|||
|
|||
## 配置使用 |
|||
|
|||
|
|||
```csharp |
|||
|
|||
[DependsOn( |
|||
typeof(AbpExporterCoreModule) |
|||
)] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
``` |
|||
|
|||
> 导出数据 |
|||
```csharp |
|||
public class ExportDemoClass |
|||
{ |
|||
private readonly IExporterProvider _exporterProvider; |
|||
|
|||
public ExportDemoClass(IExporterProvider exporterProvider) |
|||
{ |
|||
_exporterProvider = exporterProvider; |
|||
} |
|||
|
|||
public async virtual Task<IRemoteStreamContent> ExportAsync() |
|||
{ |
|||
var dataItems = new object[] |
|||
{ |
|||
new |
|||
{ |
|||
Name = "name1", |
|||
Remakrs = "remarks1" |
|||
} |
|||
}; |
|||
|
|||
var stream = await _exporterProvider.ExportAsync(dataItems); |
|||
|
|||
return new RemoteStreamContent(stream, "demo.xlsx"); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
> 导入数据 |
|||
```csharp |
|||
public class ImportDemoClass |
|||
{ |
|||
private readonly IImporterProvider _importerProvider; |
|||
|
|||
public ImportDemoClass(IImporterProvider importerProvider) |
|||
{ |
|||
_importerProvider = importerProvider; |
|||
} |
|||
|
|||
public async virtual Task ImportAsync(Stream stream) |
|||
{ |
|||
var demos = await _importerProvider.ImportAsync<DemoClass>(stream); |
|||
|
|||
// 其他操作 |
|||
} |
|||
} |
|||
|
|||
public class DemoClass |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Remarks { get; set; } |
|||
|
|||
public DemoClass() |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<AssemblyName>LINGYUN.Abp.Exporter.HttpApi</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Exporter.HttpApi</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Application.Contracts\LINGYUN.Abp.Exporter.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Application; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpDddApplicationModule), |
|||
typeof(AbpExporterApplicationContractsModule))] |
|||
public class AbpExporterHttpApiModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
public abstract class ExporterController<TEntityExportDto, TEntityListGetInput> : AbpControllerBase, IExporterAppService<TEntityExportDto, TEntityListGetInput> |
|||
where TEntityExportDto : class, new() |
|||
{ |
|||
private readonly IExporterAppService<TEntityExportDto, TEntityListGetInput> _exportService; |
|||
protected ExporterController(IExporterAppService<TEntityExportDto, TEntityListGetInput> exportService) |
|||
{ |
|||
_exportService = exportService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("export")] |
|||
public virtual Task<IRemoteStreamContent> ExportAsync(TEntityListGetInput input) |
|||
{ |
|||
return _exportService.ExportAsync(input); |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace LINGYUN.Abp.Exporter; |
|||
|
|||
public abstract class ImporterController<TEntityImportDto> : AbpControllerBase, IImporterAppService<TEntityImportDto> |
|||
where TEntityImportDto : class, new() |
|||
{ |
|||
private readonly IImporterAppService<TEntityImportDto> _importService; |
|||
|
|||
protected ImporterController(IImporterAppService<TEntityImportDto> importService) |
|||
{ |
|||
_importService = importService; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("import")] |
|||
public virtual Task ImportAsync(IRemoteStreamContent input) |
|||
{ |
|||
return _importService.ImportAsync(input); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,26 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Exporter.MagicodesIE.Excel</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Exporter.MagicodesIE.Excel</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Json" /> |
|||
<PackageReference Include="Magicodes.IE.Excel" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Core\LINGYUN.Abp.Exporter.Core.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,30 @@ |
|||
using Magicodes.ExporterAndImporter.Core; |
|||
using Magicodes.ExporterAndImporter.Excel; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MagicodesIE.Excel; |
|||
|
|||
[DependsOn(typeof(AbpExporterCoreModule))] |
|||
public class AbpExporterMagicodesIEExcelModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddScoped<IExcelExporter, ExcelExporter>(); |
|||
|
|||
context.Services.AddScoped<IExcelImporter, ExcelImporter>(); |
|||
|
|||
context.Services.AddScoped<IExportFileByTemplate, ExcelExporter>(); |
|||
|
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient( |
|||
typeof(IExporterProvider), |
|||
typeof(MagicodesIEExcelExporterProvider))); |
|||
|
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient( |
|||
typeof(IImporterProvider), |
|||
typeof(MagicodesIEExcelImporterProvider))); |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using Magicodes.ExporterAndImporter.Excel; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MagicodesIE.Excel; |
|||
public class AbpExporterMagicodesIEExcelOptions |
|||
{ |
|||
/// <summary>
|
|||
/// 数据导出设置
|
|||
/// </summary>
|
|||
public IDictionary<Type, Action<ExcelExporterAttribute>> ExportSettingMapping { get; } |
|||
/// <summary>
|
|||
/// 数据导入设置
|
|||
/// </summary>
|
|||
public IDictionary<Type, Action<ExcelImporterAttribute>> ImportSettingMapping { get; } |
|||
public AbpExporterMagicodesIEExcelOptions() |
|||
{ |
|||
ExportSettingMapping = new Dictionary<Type, Action<ExcelExporterAttribute>>(); |
|||
ImportSettingMapping = new Dictionary<Type, Action<ExcelImporterAttribute>>(); |
|||
} |
|||
|
|||
public void MapExportSetting(Type dataType, Action<ExcelExporterAttribute> exportSettingsSetup) |
|||
{ |
|||
ExportSettingMapping[dataType] = exportSettingsSetup; |
|||
} |
|||
|
|||
public void MapImportSetting(Type dataType, Action<ExcelImporterAttribute> importSettingsSetup) |
|||
{ |
|||
ImportSettingMapping[dataType] = importSettingsSetup; |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using Magicodes.ExporterAndImporter.Excel; |
|||
using Magicodes.ExporterAndImporter.Excel.Utility; |
|||
using System; |
|||
using System.IO; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MagicodesIE.Excel; |
|||
public class AbpImportHelper<T> : ImportHelper<T> where T : class, new() |
|||
{ |
|||
public AbpImportHelper(string? filePath = null, string? labelingFilePath = null) |
|||
: base(filePath, labelingFilePath) |
|||
{ |
|||
} |
|||
|
|||
public AbpImportHelper(Stream stream, Stream? labelingFileStream) |
|||
: base(stream, labelingFileStream) |
|||
{ |
|||
} |
|||
|
|||
internal void ConfigureExcelImportSettings(Action<ExcelImporterAttribute>? excelImportSettingsConfig) |
|||
{ |
|||
excelImportSettingsConfig?.Invoke(ExcelImporterSettings); |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
using Magicodes.ExporterAndImporter.Excel; |
|||
using Magicodes.ExporterAndImporter.Excel.Utility; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MagicodesIE.Excel; |
|||
public class MagicodesIEExcelExporterProvider : IExporterProvider, ITransientDependency |
|||
{ |
|||
private readonly AbpExporterMagicodesIEExcelOptions _options; |
|||
private readonly IExcelExporter _excelExporter; |
|||
|
|||
public MagicodesIEExcelExporterProvider(IOptions<AbpExporterMagicodesIEExcelOptions> options) |
|||
{ |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public async virtual Task<Stream> ExportAsync<T>(ICollection<T> data, CancellationToken cancellationToken = default) |
|||
where T : class, new() |
|||
{ |
|||
var fileBytes = new List<byte>(); |
|||
|
|||
var exportHelper = new ExportHelper<T>(); |
|||
|
|||
// 由于Microsoft.IE.Excel官方此接口未暴露用户配置,做一次转换
|
|||
if (_options.ExportSettingMapping.TryGetValue(typeof(T), out var exportSetting)) |
|||
{ |
|||
exportSetting?.Invoke(exportHelper.ExcelExporterSettings); |
|||
} |
|||
|
|||
if (exportHelper.ExcelExporterSettings.MaxRowNumberOnASheet > 0 && data.Count > exportHelper.ExcelExporterSettings.MaxRowNumberOnASheet) |
|||
{ |
|||
using (exportHelper.CurrentExcelPackage) |
|||
{ |
|||
var num = data.Count / exportHelper.ExcelExporterSettings.MaxRowNumberOnASheet + ((data.Count % exportHelper.ExcelExporterSettings.MaxRowNumberOnASheet > 0) ? 1 : 0); |
|||
for (var i = 0; i < num; i++) |
|||
{ |
|||
var dataItems2 = data.Skip(i * exportHelper.ExcelExporterSettings.MaxRowNumberOnASheet).Take(exportHelper.ExcelExporterSettings.MaxRowNumberOnASheet).ToList(); |
|||
exportHelper.AddExcelWorksheet(); |
|||
exportHelper.Export(dataItems2); |
|||
} |
|||
|
|||
fileBytes.AddRange(await exportHelper.CurrentExcelPackage.GetAsByteArrayAsync()); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
using var excelPackage2 = exportHelper.Export(data); |
|||
fileBytes.AddRange(await excelPackage2.GetAsByteArrayAsync()); |
|||
} |
|||
|
|||
var memoryStream = new MemoryStream([.. fileBytes]); |
|||
|
|||
memoryStream.Seek(0, SeekOrigin.Begin); |
|||
|
|||
return memoryStream; |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
using Magicodes.ExporterAndImporter.Core.Models; |
|||
using Magicodes.ExporterAndImporter.Excel; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Json; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MagicodesIE.Excel; |
|||
|
|||
public class MagicodesIEExcelImporterProvider : IImporterProvider, ITransientDependency |
|||
{ |
|||
public ILogger<MagicodesIEExcelImporterProvider> Logger { protected get; set; } |
|||
|
|||
private readonly AbpExporterMagicodesIEExcelOptions _options; |
|||
private readonly IJsonSerializer _jsonSerializer; |
|||
private readonly IExcelImporter _excelImporter; |
|||
|
|||
public MagicodesIEExcelImporterProvider( |
|||
IJsonSerializer jsonSerializer, |
|||
IExcelImporter excelImporter, |
|||
IOptions<AbpExporterMagicodesIEExcelOptions> options) |
|||
{ |
|||
_jsonSerializer = jsonSerializer; |
|||
_excelImporter = excelImporter; |
|||
_options = options.Value; |
|||
|
|||
Logger = NullLogger<MagicodesIEExcelImporterProvider>.Instance; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyCollection<T>> ImportAsync<T>(Stream stream) where T : class, new() |
|||
{ |
|||
using var importHelper = new AbpImportHelper<T>(stream, null); |
|||
|
|||
// 由于Microsoft.IE.Excel官方此接口未暴露用户配置,做一次转换
|
|||
if (_options.ImportSettingMapping.TryGetValue(typeof(T), out var importSetting)) |
|||
{ |
|||
importHelper.ConfigureExcelImportSettings(importSetting); |
|||
} |
|||
|
|||
var importResult = await importHelper.Import(null, null); |
|||
|
|||
ThrowImportException(importResult); |
|||
|
|||
return importResult.Data.ToImmutableList(); |
|||
} |
|||
|
|||
protected virtual void ThrowImportException<T>(ImportResult<T> importResult) where T : class, new() |
|||
{ |
|||
if (importResult.HasError) |
|||
{ |
|||
if (importResult.RowErrors.Count > 0) |
|||
{ |
|||
var errorJson = _jsonSerializer.Serialize(importResult.RowErrors); |
|||
Logger.LogWarning("Row validation error occurred during data import process, details: {errorJson}", errorJson); |
|||
} |
|||
|
|||
if (importResult.TemplateErrors.Count > 0) |
|||
{ |
|||
var errorJson = _jsonSerializer.Serialize(importResult.TemplateErrors); |
|||
Logger.LogWarning("Template validation error occurred during data import process, details: {errorJson}", errorJson); |
|||
} |
|||
|
|||
throw new BusinessException( |
|||
code: ExporterErrorCodes.ImportDataError, |
|||
innerException: importResult.Exception); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
# LINGYUN.Abp.Exporter.MagicodesIE.Excel |
|||
|
|||
数据导出接口的 [Magicodes.IE.Excel](https://github.com/dotnetcore/Magicodes.IE) 实现 |
|||
|
|||
Import and export general library, support Dto import and export, template export, fancy export and dynamic export, support Excel, Csv, Word, Pdf and Html. |
|||
|
|||
详情请参考 [Magicodes.IE.Excel 文档](https://github.com/dotnetcore/Magicodes.IE/blob/master/docs/2.%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B%E4%B9%8B%E5%AF%BC%E5%87%BAExcel.md) |
|||
|
|||
## 配置使用 |
|||
|
|||
|
|||
```csharp |
|||
|
|||
[DependsOn( |
|||
typeof(AbpExporterMagicodesIEExcelModule) |
|||
)] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
Configure<AbpExporterMagicodesIEExcelOptions>(options => |
|||
{ |
|||
// 配置类型数据导出 |
|||
options.MapExportSetting(typeof(DemoClass), config => |
|||
{ |
|||
// 表头位置从第二行开始 |
|||
config.HeaderRowIndex = 2; |
|||
// 其他配置 |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
public class DemoClass |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Remarks { get; set; } |
|||
|
|||
public DemoClass() |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
|
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</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,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Exporter.MiniExcel</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Exporter.MiniExcel</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<Nullable>enable</Nullable> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="MiniExcel" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Exporter.Core\LINGYUN.Abp.Exporter.Core.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,22 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MiniExcel; |
|||
|
|||
[DependsOn(typeof(AbpExporterCoreModule))] |
|||
public class AbpExporterMiniExcelModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient( |
|||
typeof(IExporterProvider), |
|||
typeof(MiniExcelExporterProvider))); |
|||
|
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient( |
|||
typeof(IImporterProvider), |
|||
typeof(MiniExcelImporterProvider))); |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using MiniExcelLibs.OpenXml; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MiniExcel; |
|||
public class AbpExporterMiniExcelOptions |
|||
{ |
|||
public IDictionary<Type, Action<OpenXmlConfiguration>> ExportSettingMapping { get; } |
|||
public IDictionary<Type, Action<OpenXmlConfiguration>> ImportSettingMapping { get; } |
|||
public AbpExporterMiniExcelOptions() |
|||
{ |
|||
ExportSettingMapping = new Dictionary<Type, Action<OpenXmlConfiguration>>(); |
|||
ImportSettingMapping = new Dictionary<Type, Action<OpenXmlConfiguration>>(); |
|||
} |
|||
|
|||
public void MapExportSetting(Type dataType, Action<OpenXmlConfiguration> settingMapping) |
|||
{ |
|||
ExportSettingMapping[dataType] = settingMapping; |
|||
} |
|||
|
|||
public void MapImportSetting(Type dataType, Action<OpenXmlConfiguration> settingMapping) |
|||
{ |
|||
ImportSettingMapping[dataType] = settingMapping; |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using MiniExcelLibs; |
|||
using MiniExcelLibs.OpenXml; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MiniExcel; |
|||
public class MiniExcelExporterProvider : IExporterProvider, ITransientDependency |
|||
{ |
|||
private readonly AbpExporterMiniExcelOptions _options; |
|||
|
|||
public MiniExcelExporterProvider(IOptions<AbpExporterMiniExcelOptions> options) |
|||
{ |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public async virtual Task<Stream> ExportAsync<T>(ICollection<T> data, CancellationToken cancellationToken = default) |
|||
where T : class, new() |
|||
{ |
|||
var memoryStream = new MemoryStream(); |
|||
var xmlConfig = new OpenXmlConfiguration(); |
|||
|
|||
if (_options.ExportSettingMapping.TryGetValue(typeof(T), out var exportSetting)) |
|||
{ |
|||
exportSetting?.Invoke(xmlConfig); |
|||
} |
|||
|
|||
await memoryStream.SaveAsAsync( |
|||
value: data, |
|||
excelType: ExcelType.XLSX, |
|||
configuration: xmlConfig, |
|||
cancellationToken: cancellationToken); |
|||
|
|||
memoryStream.Seek(0, SeekOrigin.Begin); |
|||
|
|||
return memoryStream; |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using MiniExcelLibs; |
|||
using MiniExcelLibs.OpenXml; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Exporter.MiniExcel; |
|||
public class MiniExcelImporterProvider : IImporterProvider, ITransientDependency |
|||
{ |
|||
private readonly AbpExporterMiniExcelOptions _options; |
|||
|
|||
public MiniExcelImporterProvider(IOptions<AbpExporterMiniExcelOptions> options) |
|||
{ |
|||
_options = options.Value; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyCollection<T>> ImportAsync<T>(Stream stream) where T : class, new() |
|||
{ |
|||
var xmlConfig = new OpenXmlConfiguration(); |
|||
|
|||
if (_options.ExportSettingMapping.TryGetValue(typeof(T), out var exportSetting)) |
|||
{ |
|||
exportSetting?.Invoke(xmlConfig); |
|||
} |
|||
|
|||
var dataList = await stream.QueryAsync<T>( |
|||
excelType: ExcelType.XLSX, |
|||
configuration: xmlConfig); |
|||
|
|||
return dataList.ToImmutableList(); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
# LINGYUN.Abp.Exporter.MiniExcel |
|||
|
|||
数据导出接口的 [MiniExcel](https://github.com/mini-software/MiniExcel) 实现 |
|||
|
|||
MiniExcel简单、高效避免OOM的.NET处理Excel查、写、填充数据工具。 |
|||
|
|||
目前主流框架大多需要将数据全载入到内存方便操作,但这会导致内存消耗问题,MiniExcel 尝试以 Stream 角度写底层算法逻辑,能让原本1000多MB占用降低到几MB,避免内存不够情况。 |
|||
|
|||
详情请参考 [MiniExcel 文档](https://github.com/mini-software/MiniExcel/blob/master/README.md) |
|||
|
|||
## 配置使用 |
|||
|
|||
|
|||
```csharp |
|||
|
|||
[DependsOn( |
|||
typeof(AbpExporterMiniExcelModule) |
|||
)] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
Configure<AbpExporterMiniExcelOptions>(options => |
|||
{ |
|||
// 配置类型数据导出 |
|||
options.MapExportSetting(typeof(DemoClass), config => |
|||
{ |
|||
config.DynamicColumns = new[] |
|||
{ |
|||
// 忽略Name字段 |
|||
new DynamicExcelColumn(nameof(DemoClass.Name)){ Ignore = true }, |
|||
// 其他配置 |
|||
}; |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
public class DemoClass |
|||
{ |
|||
public string Name { get; set; } |
|||
public string Remarks { get; set; } |
|||
|
|||
public DemoClass() |
|||
{ |
|||
} |
|||
} |
|||
``` |
|||
|
|||
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"); |
|||
} |
|||
} |
|||
} |
|||
@ -1,11 +1,12 @@ |
|||
using Volo.Abp.Application.Services; |
|||
using LINGYUN.Abp.DataProtection.Localization; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.DataProtectionManagement; |
|||
public abstract class DataProtectionManagementApplicationServiceBase : ApplicationService |
|||
{ |
|||
protected DataProtectionManagementApplicationServiceBase() |
|||
{ |
|||
LocalizationResource = typeof(AbpDataProtectionManagementApplicationModule); |
|||
LocalizationResource = typeof(DataProtectionResource); |
|||
ObjectMapperContext = typeof(AbpDataProtectionManagementApplicationModule); |
|||
} |
|||
} |
|||
|
|||
@ -1,10 +1,34 @@ |
|||
using Volo.Abp.Domain; |
|||
using LINGYUN.Abp.DataProtection; |
|||
using LINGYUN.Abp.DataProtection.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.DataProtectionManagement; |
|||
|
|||
[DependsOn(typeof(AbpDddDomainSharedModule))] |
|||
[DependsOn(typeof(AbpDataProtectionAbstractionsModule))] |
|||
public class AbpDataProtectionManagementDomainSharedModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpDataProtectionManagementDomainSharedModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Get<DataProtectionResource>() |
|||
.AddVirtualJson("/LINGYUN/Abp/DataProtectionManagement/Localization/Resources"); |
|||
}); |
|||
|
|||
Configure<AbpExceptionLocalizationOptions>(options => |
|||
{ |
|||
options.MapCodeNamespace(DataProtectionManagementErrorCodes.Namespace, typeof(DataProtectionResource)); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"DataProtectionManagement:001100": "There already exists an entity type definition named {Name}!", |
|||
"DataProtectionManagement:001200": "The entity type already has a property definition named {Name}!", |
|||
"DataProtectionManagement:002100": "The {Operation} access rule for entity {Name} has been assigned to role {RoleName}!", |
|||
"DataProtectionManagement:003100": "The {Operation} access rule for entity {Name} has been assigned to organization {RoleName}!" |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"DataProtectionManagement:001100": "已经存在名为 {Name} 的实体类型定义!", |
|||
"DataProtectionManagement:001200": "实体类型已经存在名为 {Name} 的属性定义!", |
|||
"DataProtectionManagement:002100": "已为角色 {RoleName} 分配了实体 {Name} 的 {Operation} 访问规则!", |
|||
"DataProtectionManagement:003100": "已为组织机构 {OrgCode} 分配了实体 {Name} 的 {Operation} 访问规则!" |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue