Browse Source

add entity-change manage

pull/834/head
colin 3 years ago
parent
commit
75110de789
  1. 24
      aspnet-core/LINGYUN.MicroService.All.sln
  2. 3
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/FodyWeavers.xml
  3. 30
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/FodyWeavers.xsd
  4. 27
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN.Abp.EntityChange.Application.Contracts.csproj
  5. 29
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/AbpEntityChangeApplicationContractsModule.cs
  6. 26
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/EntityChangeDto.cs
  7. 14
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/EntityChangeGetListInput.cs
  8. 15
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/EntityPropertyChangeDto.cs
  9. 10
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/IEntityChangeAppService.cs
  10. 10
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/IEntityRestoreAppService.cs
  11. 8
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/Localization/AbpEntityChangeResource.cs
  12. 12
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/Localization/Resources/en.json
  13. 12
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/Localization/Resources/zh-Hans.json
  14. 10
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/RestoreEntitiesInput.cs
  15. 21
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/RestoreEntityInput.cs
  16. 3
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/FodyWeavers.xml
  17. 30
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/FodyWeavers.xsd
  18. 20
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN.Abp.EntityChange.Application.csproj
  19. 23
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/AbpEntityChangeApplicationModule.cs
  20. 13
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/AbpEntityChangeMapperProfile.cs
  21. 44
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/EntityChangeAppService.cs
  22. 117
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/EntityRestoreAppService.cs
  23. 3
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/FodyWeavers.xml
  24. 30
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/FodyWeavers.xsd
  25. 19
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN.Abp.EntityChange.HttpApi.csproj
  26. 26
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN/Abp/EntityChange/AbpEntityChangeHttpApiModule.cs
  27. 26
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN/Abp/EntityChange/EntityChangeController.cs
  28. 32
      aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN/Abp/EntityChange/EntityRestoreController.cs

24
aspnet-core/LINGYUN.MicroService.All.sln

@ -633,6 +633,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Elsa.Notificati
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Elsa.Server", "modules\elsa\LINGYUN.Abp.Elsa.Server\LINGYUN.Abp.Elsa.Server.csproj", "{C465BB41-9DB7-470F-BC7F-A59D2A7D6083}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "entity-change", "entity-change", "{DD1B10ED-73E2-41BE-928A-46501050FE2A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EntityChange.Application.Contracts", "modules\entity-change\LINGYUN.Abp.EntityChange.Application.Contracts\LINGYUN.Abp.EntityChange.Application.Contracts.csproj", "{7779D9BD-5928-49A2-965F-537967004238}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EntityChange.Application", "modules\entity-change\LINGYUN.Abp.EntityChange.Application\LINGYUN.Abp.EntityChange.Application.csproj", "{AC41F335-E240-47E0-B409-AFAD1400E626}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.EntityChange.HttpApi", "modules\entity-change\LINGYUN.Abp.EntityChange.HttpApi\LINGYUN.Abp.EntityChange.HttpApi.csproj", "{1D420BA6-2155-4E0D-AAAF-EECC0330A38C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1623,6 +1631,18 @@ Global
{C465BB41-9DB7-470F-BC7F-A59D2A7D6083}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C465BB41-9DB7-470F-BC7F-A59D2A7D6083}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C465BB41-9DB7-470F-BC7F-A59D2A7D6083}.Release|Any CPU.Build.0 = Release|Any CPU
{7779D9BD-5928-49A2-965F-537967004238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7779D9BD-5928-49A2-965F-537967004238}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7779D9BD-5928-49A2-965F-537967004238}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7779D9BD-5928-49A2-965F-537967004238}.Release|Any CPU.Build.0 = Release|Any CPU
{AC41F335-E240-47E0-B409-AFAD1400E626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC41F335-E240-47E0-B409-AFAD1400E626}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC41F335-E240-47E0-B409-AFAD1400E626}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC41F335-E240-47E0-B409-AFAD1400E626}.Release|Any CPU.Build.0 = Release|Any CPU
{1D420BA6-2155-4E0D-AAAF-EECC0330A38C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D420BA6-2155-4E0D-AAAF-EECC0330A38C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D420BA6-2155-4E0D-AAAF-EECC0330A38C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D420BA6-2155-4E0D-AAAF-EECC0330A38C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1929,6 +1949,10 @@ Global
{10CF8240-4276-4199-B3D1-C45F16468EBD} = {0A00FAF9-A96B-4BF5-8D42-15C8678F70F3}
{39DFEFCD-7C73-450F-9A2F-7426188A890B} = {0A00FAF9-A96B-4BF5-8D42-15C8678F70F3}
{C465BB41-9DB7-470F-BC7F-A59D2A7D6083} = {0A00FAF9-A96B-4BF5-8D42-15C8678F70F3}
{DD1B10ED-73E2-41BE-928A-46501050FE2A} = {C5CAD011-DF84-4914-939C-0C029DCEF26F}
{7779D9BD-5928-49A2-965F-537967004238} = {DD1B10ED-73E2-41BE-928A-46501050FE2A}
{AC41F335-E240-47E0-B409-AFAD1400E626} = {DD1B10ED-73E2-41BE-928A-46501050FE2A}
{1D420BA6-2155-4E0D-AAAF-EECC0330A38C} = {DD1B10ED-73E2-41BE-928A-46501050FE2A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

3
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/FodyWeavers.xsd

@ -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>

27
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN.Abp.EntityChange.Application.Contracts.csproj

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\EntityChange\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\EntityChange\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\auditing\LINGYUN.Abp.AuditLogging\LINGYUN.Abp.AuditLogging.csproj" />
</ItemGroup>
</Project>

29
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/AbpEntityChangeApplicationContractsModule.cs

@ -0,0 +1,29 @@
using LINGYUN.Abp.EntityChange.Localization;
using Volo.Abp.Application;
using Volo.Abp.Auditing;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.EntityChange;
[DependsOn(
typeof(AbpAuditingModule),
typeof(AbpDddApplicationContractsModule))]
public class AbpEntityChangeApplicationContractsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpEntityChangeApplicationContractsModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AbpEntityChangeResource>()
.AddVirtualJson("/LINGYUN/Abp/EntityChange/Localization/Resources");
});
}
}

26
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/EntityChangeDto.cs

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.EntityChange;
public class EntityChangeDto : ExtensibleEntityDto<Guid>
{
public DateTime ChangeTime { get; set; }
public EntityChangeType ChangeType { get; set; }
public Guid? EntityTenantId { get; set; }
public string EntityId { get; set; }
public string EntityTypeFullName { get; set; }
public List<EntityPropertyChangeDto> PropertyChanges { get; set; }
public EntityChangeDto()
{
PropertyChanges = new List<EntityPropertyChangeDto>();
}
}

14
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/EntityChangeGetListInput.cs

@ -0,0 +1,14 @@
using System;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.EntityChange;
public class EntityChangeGetListInput : PagedAndSortedResultRequestDto
{
public Guid? AuditLogId { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
public EntityChangeType? ChangeType { get; set; }
public string EntityId { get; set; }
}

15
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/EntityPropertyChangeDto.cs

@ -0,0 +1,15 @@
using System;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Abp.EntityChange;
public class EntityPropertyChangeDto : EntityDto<Guid>
{
public string NewValue { get; set; }
public string OriginalValue { get; set; }
public string PropertyName { get; set; }
public string PropertyTypeFullName { get; set; }
}

10
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/IEntityChangeAppService.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.EntityChange;
public interface IEntityChangeAppService : IApplicationService
{
Task<PagedResultDto<EntityChangeDto>> GetListAsync(EntityChangeGetListInput input);
}

10
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/IEntityRestoreAppService.cs

@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.EntityChange;
public interface IEntityRestoreAppService : IEntityChangeAppService
{
Task RestoreEntityAsync(RestoreEntityInput input);
Task RestoreEntitesAsync(RestoreEntitiesInput input);
}

8
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/Localization/AbpEntityChangeResource.cs

@ -0,0 +1,8 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.EntityChange.Localization;
[LocalizationResourceName("AbpEntityChange")]
public class AbpEntityChangeResource
{
}

12
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/Localization/Resources/en.json

@ -0,0 +1,12 @@
{
"culture": "en",
"texts": {
"DisplayName:EntityId": "Entity Id",
"DisplayName:EntityChangeId": "Version",
"DisplayName:Entities": "Entities",
"DisplayName:AuditLogId": "Auditlog Id",
"DisplayName:StartTime": "Start Time",
"DisplayName:EndTime": "End Time",
"DisplayName:ChangeType": "Change Type"
}
}

12
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/Localization/Resources/zh-Hans.json

@ -0,0 +1,12 @@
{
"culture": "zh-Hans",
"texts": {
"DisplayName:EntityId": "实体标识",
"DisplayName:EntityChangeId": "版本标识",
"DisplayName:Entities": "实体列表",
"DisplayName:AuditLogId": "审计标识",
"DisplayName:StartTime": "起始时间",
"DisplayName:EndTime": "截止时间",
"DisplayName:ChangeType": "变更类型"
}
}

10
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/RestoreEntitiesInput.cs

@ -0,0 +1,10 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Abp.EntityChange;
public class RestoreEntitiesInput
{
[Required]
public List<RestoreEntityInput> Entities { get; set; }
}

21
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application.Contracts/LINGYUN/Abp/EntityChange/RestoreEntityInput.cs

@ -0,0 +1,21 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Abp.EntityChange;
public class RestoreEntityInput
{
/// <summary>
/// 实体标识
/// </summary>
[Required]
public string EntityId { get; set; }
/// <summary>
/// 还原到某个版本标识
/// </summary>
/// <remarks>
/// 注: 当传递此值时, 将还原到指定版本的NewValue
/// 否则,还原为最近一次版本的OriginalValue
/// </remarks>
public Guid? EntityChangeId { get; set; }
}

3
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/FodyWeavers.xsd

@ -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>

20
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN.Abp.EntityChange.Application.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.EntityChange.Application.Contracts\LINGYUN.Abp.EntityChange.Application.Contracts.csproj" />
</ItemGroup>
</Project>

23
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/AbpEntityChangeApplicationModule.cs

@ -0,0 +1,23 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.EntityChange;
[DependsOn(
typeof(AbpEntityChangeApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule))]
public class AbpEntityChangeApplicationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpEntityChangeApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpEntityChangeMapperProfile>(validate: true);
});
}
}

13
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/AbpEntityChangeMapperProfile.cs

@ -0,0 +1,13 @@
using AutoMapper;
using LINGYUN.Abp.AuditLogging;
namespace LINGYUN.Abp.EntityChange;
public class AbpEntityChangeMapperProfile : Profile
{
public AbpEntityChangeMapperProfile()
{
CreateMap<EntityPropertyChange, EntityPropertyChangeDto>();
CreateMap<AuditLogging.EntityChange, EntityChangeDto>()
.MapExtraProperties();
}
}

44
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/EntityChangeAppService.cs

@ -0,0 +1,44 @@
using LINGYUN.Abp.AuditLogging;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.EntityChange;
public abstract class EntityChangeAppService<TEntity> : ApplicationService, IEntityChangeAppService
where TEntity : class
{
protected virtual string GetListPolicy { get; set; }
protected IEntityChangeStore EntityChangeStore { get; }
protected EntityChangeAppService(IEntityChangeStore entityChangeStore)
{
EntityChangeStore = entityChangeStore;
}
public async virtual Task<PagedResultDto<EntityChangeDto>> GetListAsync(EntityChangeGetListInput input)
{
if (!GetListPolicy.IsNullOrWhiteSpace())
{
await AuthorizationService.AuthorizeAsync(GetListPolicy);
}
var entityTypeFullName = typeof(TEntity).FullName;
var totalCount = await EntityChangeStore.GetCountAsync(
input.AuditLogId, input.StartTime, input.EndTime,
input.ChangeType, input.EntityId, entityTypeFullName);
var entities = await EntityChangeStore.GetListAsync(
input.Sorting, input.MaxResultCount, input.SkipCount,
input.AuditLogId, input.StartTime, input.EndTime,
input.ChangeType, input.EntityId, entityTypeFullName);
return new PagedResultDto<EntityChangeDto>(totalCount,
ObjectMapper.Map<List<AuditLogging.EntityChange>, List<EntityChangeDto>>(entities));
}
}

117
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.Application/LINGYUN/Abp/EntityChange/EntityRestoreAppService.cs

@ -0,0 +1,117 @@
using LINGYUN.Abp.AuditLogging;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Json;
using Volo.Abp.Reflection;
namespace LINGYUN.Abp.EntityChange;
public abstract class EntityRestoreAppService<TEntity, TKey> : EntityChangeAppService<TEntity>, IEntityRestoreAppService
where TEntity : class, IEntity<TKey>
{
protected virtual string RestorePolicy { get; set; }
protected IRepository<TEntity, TKey> Repository { get; }
protected IJsonSerializer JsonSerializer => LazyServiceProvider.LazyGetRequiredService<IJsonSerializer>();
protected EntityRestoreAppService(
IEntityChangeStore entityChangeStore,
IRepository<TEntity, TKey> repository)
: base(entityChangeStore)
{
Repository = repository;
}
public async virtual Task RestoreEntitesAsync(RestoreEntitiesInput input)
{
if (!RestorePolicy.IsNullOrWhiteSpace())
{
await AuthorizationService.AuthorizeAsync(RestorePolicy);
}
foreach (var restoreEntity in input.Entities)
{
await RestoreEntityByAuditLogAsync(restoreEntity);
}
await CurrentUnitOfWork.SaveChangesAsync();
}
public async virtual Task RestoreEntityAsync(RestoreEntityInput input)
{
if (!RestorePolicy.IsNullOrWhiteSpace())
{
await AuthorizationService.AuthorizeAsync(RestorePolicy);
}
await RestoreEntityByAuditLogAsync(input);
await CurrentUnitOfWork.SaveChangesAsync();
}
protected virtual TKey MapToEntityKey(string entityId)
{
return (TKey)Convert.ChangeType(entityId, typeof(TKey));
}
protected async virtual Task RestoreEntityByAuditLogAsync(RestoreEntityInput input)
{
var entityChanges = await EntityChangeStore.GetListAsync(
entityId: input.EntityId,
entityTypeFullName: typeof(TEntity).FullName);
var entityKey = MapToEntityKey(input.EntityId);
if (entityChanges != null && entityChanges.Any())
{
var entity = await Repository.GetAsync(entityKey);
var entityProperties = typeof(TEntity).GetProperties();
var entityChange = entityChanges
.WhereIf(input.EntityChangeId.HasValue, x => x.Id == input.EntityChangeId)
.OrderByDescending(x => x.ChangeTime)
.First();
foreach (var propertyChange in entityChange.PropertyChanges)
{
var propertyName = propertyChange.PropertyName;
var entityProperty = entityProperties.FirstOrDefault(x => x.Name == propertyName && x.GetSetMethod(true) != null);
if (entityProperty != null)
{
if (TypeHelper.IsPrimitiveExtended(entityProperty.PropertyType, includeEnums: true))
{
var conversionType = entityProperty.PropertyType;
var isNullableType = TypeHelper.IsNullable(conversionType);
if (isNullableType)
{
conversionType = conversionType.GetFirstGenericArgumentIfNullable();
}
var currentValue = propertyChange.OriginalValue;
if (input.EntityChangeId.HasValue)
{
currentValue = propertyChange.NewValue;
}
if (currentValue.IsNullOrWhiteSpace() || string.Equals("null", currentValue, StringComparison.InvariantCultureIgnoreCase))
{
if (isNullableType)
{
entityProperty.SetValue(entity, null);
}
continue;
}
var setPropertyValue = JsonSerializer.Deserialize(conversionType, currentValue);
entityProperty.SetValue(entity, setPropertyValue);
}
}
}
await Repository.UpdateAsync(entity);
}
}
}

3
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/FodyWeavers.xsd

@ -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>

19
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN.Abp.EntityChange.HttpApi.csproj

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.EntityChange.Application.Contracts\LINGYUN.Abp.EntityChange.Application.Contracts.csproj" />
</ItemGroup>
</Project>

26
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN/Abp/EntityChange/AbpEntityChangeHttpApiModule.cs

@ -0,0 +1,26 @@
using LINGYUN.Abp.EntityChange.Localization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.EntityChange;
[DependsOn(
typeof(AbpEntityChangeApplicationContractsModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpEntityChangeHttpApiModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpEntityChangeHttpApiModule).Assembly);
});
PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(typeof(AbpEntityChangeResource), typeof(AbpEntityChangeApplicationContractsModule).Assembly);
});
}
}

26
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN/Abp/EntityChange/EntityChangeController.cs

@ -0,0 +1,26 @@
using LINGYUN.Abp.EntityChange.Localization;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.EntityChange;
public abstract class EntityChangeController : AbpControllerBase, IEntityChangeAppService
{
protected IEntityChangeAppService EntityChangeAppService { get; }
protected EntityChangeController(IEntityChangeAppService entityChangeAppService)
{
EntityChangeAppService = entityChangeAppService;
LocalizationResource = typeof(AbpEntityChangeResource);
}
[HttpGet]
[Route("entity-changes")]
public virtual Task<PagedResultDto<EntityChangeDto>> GetListAsync(EntityChangeGetListInput input)
{
return EntityChangeAppService.GetListAsync(input);
}
}

32
aspnet-core/modules/entity-change/LINGYUN.Abp.EntityChange.HttpApi/LINGYUN/Abp/EntityChange/EntityRestoreController.cs

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
namespace LINGYUN.Abp.EntityChange;
public abstract class EntityRestoreController : EntityChangeController, IEntityRestoreAppService
{
protected IEntityRestoreAppService EntityRestoreAppService { get; }
protected EntityRestoreController(IEntityRestoreAppService entityRestoreAppService)
: base(entityRestoreAppService)
{
EntityRestoreAppService = entityRestoreAppService;
}
[HttpPut]
[Route("entites-restore")]
public virtual Task RestoreEntitesAsync(RestoreEntitiesInput input)
{
return EntityRestoreAppService.RestoreEntitesAsync(input);
}
[HttpPut]
[Route("entity-restore")]
[Route("{EntityId}/entity-restore")]
[Route("{EntityId}/v/{EntityChangeId}/entity-restore")]
public virtual Task RestoreEntityAsync(RestoreEntityInput input)
{
return EntityRestoreAppService.RestoreEntityAsync(input);
}
}
Loading…
Cancel
Save