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