28 changed files with 637 additions and 0 deletions
@ -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,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> |
|||
@ -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"); |
|||
}); |
|||
} |
|||
} |
|||
@ -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>(); |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -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); |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.EntityChange; |
|||
|
|||
public interface IEntityRestoreAppService : IEntityChangeAppService |
|||
{ |
|||
Task RestoreEntityAsync(RestoreEntityInput input); |
|||
|
|||
Task RestoreEntitesAsync(RestoreEntitiesInput input); |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.EntityChange.Localization; |
|||
|
|||
[LocalizationResourceName("AbpEntityChange")] |
|||
public class AbpEntityChangeResource |
|||
{ |
|||
} |
|||
@ -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" |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"DisplayName:EntityId": "实体标识", |
|||
"DisplayName:EntityChangeId": "版本标识", |
|||
"DisplayName:Entities": "实体列表", |
|||
"DisplayName:AuditLogId": "审计标识", |
|||
"DisplayName:StartTime": "起始时间", |
|||
"DisplayName:EndTime": "截止时间", |
|||
"DisplayName:ChangeType": "变更类型" |
|||
} |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -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; } |
|||
} |
|||
@ -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> |
|||
<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> |
|||
@ -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); |
|||
}); |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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)); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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,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> |
|||
@ -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); |
|||
}); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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…
Reference in new issue