Browse Source

Merge pull request #698 from colinin/upt-5.3.4

entity change records are searchable
pull/712/head
yx lin 3 years ago
committed by GitHub
parent
commit
c2c29491e7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs
  2. 407
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchEntityChangeStore.cs
  3. 4
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs
  4. 115
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/EntityChangeStore.cs
  5. 2
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs
  6. 4
      aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs
  7. 3
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN.Abp.TuiJuhe.SettingManagement.csproj
  8. 6
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/AbpTuiJuheSettingManagementModule.cs

13
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs

@ -47,13 +47,22 @@ namespace LINGYUN.Abp.AuditLogging
var entityChanges = auditLogInfo
.EntityChanges?
.Select(entityChangeInfo => new EntityChange(GuidGenerator, auditLogId, entityChangeInfo, tenantId: auditLogInfo.TenantId))
.Select(entityChangeInfo => new EntityChange(
GuidGenerator,
auditLogId,
entityChangeInfo,
tenantId: auditLogInfo.TenantId,
entityTenantId: entityChangeInfo.EntityTenantId))
.ToList()
?? new List<EntityChange>();
var actions = auditLogInfo
.Actions?
.Select(auditLogActionInfo => new AuditLogAction(GuidGenerator.Create(), auditLogId, auditLogActionInfo, tenantId: auditLogInfo.TenantId))
.Select(auditLogActionInfo => new AuditLogAction(
GuidGenerator.Create(),
auditLogId,
auditLogActionInfo,
tenantId: auditLogInfo.TenantId))
.ToList()
?? new List<AuditLogAction>();

407
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchEntityChangeStore.cs

@ -40,29 +40,37 @@ public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDepe
{
var client = _clientFactory.Create();
var resposne = await client.SearchAsync<EntityChange>(
dsl => dsl.Index(CreateIndex())
.Query(query =>
query.Bool(bo =>
bo.Must(m =>
m.Nested(n =>
n.InnerHits()
.Path("EntityChanges")
.Query(nq =>
nq.Term(nqt =>
nqt.Field(GetField(nameof(EntityChange.Id))).Value(entityChangeId)))))))
.Source(x => x.Excludes(f => f.Field("*")))
.Sort(entity => entity.Field("EntityChanges.ChangeTime", SortOrder.Descending))
.Size(1),
ct: cancellationToken);
if (resposne.Shards.Successful > 0)
var sortOrder = SortOrder.Descending;
var querys = BuildQueryDescriptor(entityChangeId: entityChangeId);
static SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
{
var hits = resposne.Hits.FirstOrDefault();
if (hits.InnerHits.Count > 0)
{
return hits.InnerHits.First().Value.Documents<EntityChange>().FirstOrDefault();
}
selector.IncludeAll()
.Excludes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions));
return selector;
}
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.Sort(log => log.Field(GetField(nameof(EntityChange.ChangeTime)), sortOrder))
.From(0)
.Size(1),
cancellationToken);
var auditLog = response.Documents.FirstOrDefault();
if (auditLog != null)
{
return auditLog
.EntityChanges
.Select(e => e)
.FirstOrDefault();
}
return null;
@ -77,40 +85,39 @@ public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDepe
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
await Task.CompletedTask;
return 0;
//var client = _clientFactory.Create();
//var querys = BuildQueryDescriptor(
// auditLogId,
// startTime,
// endTime,
// changeType,
// entityId,
// entityTypeFullName);
//Func<QueryContainerDescriptor<EntityChange>, QueryContainer> selector = q => q.MatchAll();
//if (querys.Count > 0)
//{
// selector = q => q.Bool(b => b.Must(querys.ToArray()));
//}
//var response = await client.CountAsync<EntityChange>(dsl =>
// dsl.Index(CreateIndex())
// .Query(q =>
// q.Bool(b =>
// b.Must(m =>
// m.Nested(n =>
// n.InnerHits(hit => hit.Source(s => s.ExcludeAll()))
// .Path("EntityChanges")
// .Query(selector)
// )
// )
// )
// ),
// ct: cancellationToken);
//return response.Count;
var client = _clientFactory.Create();
var querys = BuildQueryDescriptor(
auditLogId,
startTime,
endTime,
changeType,
entityId,
entityTypeFullName);
SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
{
return selector
.Includes(field =>
field.Field(f => f.UserName)
.Field(f => f.EntityChanges))
.Excludes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions));
}
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.From(0)
.Size(1000),
cancellationToken);
var auditLogs = response.Documents.ToList();
return auditLogs.Sum(log => log.EntityChanges.Count);
}
public async virtual Task<List<EntityChange>> GetListAsync(
@ -126,72 +133,74 @@ public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDepe
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
// TODO: 需要解决Nested格式数据返回方式
//var client = _clientFactory.Create();
//var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
// ? SortOrder.Ascending : SortOrder.Descending;
//sorting = !sorting.IsNullOrWhiteSpace()
// ? sorting.Split()[0]
// : nameof(EntityChange.ChangeTime);
//var querys = BuildQueryDescriptor(
// auditLogId,
// startTime,
// endTime,
// changeType,
// entityId,
// entityTypeFullName);
//SourceFilterDescriptor<EntityChange> SourceFilter(SourceFilterDescriptor<EntityChange> selector)
//{
// selector.Includes(GetEntityChangeSources());
// if (!includeDetails)
// {
// selector.Excludes(field =>
// field.Field("EntityChanges.PropertyChanges")
// .Field("EntityChanges.ExtraProperties"));
// }
// return selector;
//}
//Func<QueryContainerDescriptor<EntityChange>, QueryContainer> selector = q => q.MatchAll();
//if (querys.Count > 0)
//{
// selector = q => q.Bool(b => b.Must(querys.ToArray()));
//}
//var response = await client.SearchAsync<EntityChange>(dsl =>
// dsl.Index(CreateIndex())
// .Query(q =>
// q.Bool(b =>
// b.Must(m =>
// m.Nested(n =>
// n.InnerHits(hit => hit.Source(SourceFilter))
// .Path("EntityChanges")
// .Query(selector)
// )
// )
// )
// )
// .Source(x => x.Excludes(f => f.Field("*")))
// .Sort(entity => entity.Field(GetField(sorting), sortOrder))
// .From(skipCount)
// .Size(maxResultCount),
// cancellationToken);
//if (response.Shards.Successful > 0)
//{
// var hits = response.Hits.FirstOrDefault();
// if (hits.InnerHits.Count > 0)
// {
// return hits.InnerHits.First().Value.Documents<EntityChange>().ToList();
// }
//}
await Task.CompletedTask;
return new List<EntityChange>();
// TODO: 正确的索引可以避免性能损耗
var result = new List<EntityChange>();
var client = _clientFactory.Create();
var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
? SortOrder.Ascending : SortOrder.Descending;
sorting = !sorting.IsNullOrWhiteSpace()
? sorting.Split()[0]
: nameof(EntityChange.ChangeTime);
var querys = BuildQueryDescriptor(
auditLogId,
startTime,
endTime,
changeType,
entityId,
entityTypeFullName);
SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
{
selector
.Includes(field =>
field.Field(f => f.UserName)
.Field(f => f.EntityChanges));
if (includeDetails)
{
selector.Includes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions));
}
return selector;
}
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.Sort(log => log.Field(GetField(nameof(EntityChange.ChangeTime)), sortOrder))
.From(0)
.Size(1000),
cancellationToken);
var auditLogs = response.Documents.ToList();
if (auditLogs.Any())
{
var groupAuditLogs = auditLogs.GroupBy(log => log.UserName);
foreach (var group in groupAuditLogs)
{
var entityChangesList = group.Select(log => log.EntityChanges);
foreach (var entityChanges in entityChangesList)
{
foreach (var entityChange in entityChanges)
{
result.Add(entityChange);
}
}
}
}
// TODO: 临时在内存中分页
return result
.AsQueryable()
.PageBy(skipCount, maxResultCount)
.ToList();
}
public async virtual Task<EntityChangeWithUsername> GetWithUsernameAsync(
@ -200,41 +209,43 @@ public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDepe
{
var client = _clientFactory.Create();
var response = await client.SearchAsync<AuditLog>(
dsl => dsl.Index(CreateIndex())
.Query(query =>
query.Bool(bo =>
bo.Must(m =>
m.Nested(n =>
n.InnerHits()
.Path("EntityChanges")
.Query(nq =>
nq.Bool(nb =>
nb.Must(nm =>
nm.Term(nt =>
nt.Field(GetField(nameof(EntityChange.Id))).Value(entityChangeId)))))))))
.Source(selector => selector.Includes(field =>
field.Field(f => f.UserName)))
.Size(1),
ct: cancellationToken);
var sortOrder = SortOrder.Descending;
var auditLog = response.Documents.FirstOrDefault();
EntityChange entityChange = null;
var querys = BuildQueryDescriptor(entityChangeId: entityChangeId);
if (response.Shards.Successful > 0)
static SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
{
var hits = response.Hits.FirstOrDefault();
if (hits.InnerHits.Count > 0)
{
entityChange = hits.InnerHits.First().Value.Documents<EntityChange>().FirstOrDefault();
}
selector.IncludeAll()
.Excludes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions));
return selector;
}
return new EntityChangeWithUsername()
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.Sort(log => log.Field(GetField(nameof(EntityChange.ChangeTime)), sortOrder))
.From(0)
.Size(1),
cancellationToken);
var auditLog = response.Documents.FirstOrDefault();
if (auditLog != null)
{
EntityChange = entityChange,
UserName = auditLog?.UserName
};
return auditLog.EntityChanges.Select(e =>
new EntityChangeWithUsername
{
UserName = auditLog.UserName,
EntityChange = e
})
.FirstOrDefault();
}
return null;
}
public async virtual Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(
@ -242,61 +253,69 @@ public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDepe
string entityTypeFullName,
CancellationToken cancellationToken = default)
{
var result = new List<EntityChangeWithUsername>();
var client = _clientFactory.Create();
var response = await client.SearchAsync<AuditLog>(
dsl => dsl.Index(CreateIndex())
.Query(query =>
query.Bool(bo =>
bo.Must(m =>
m.Nested(n =>
n.InnerHits()
.Path("EntityChanges")
.Query(nq =>
nq.Bool(nb =>
nb.Must(nm =>
nm.Term(nt =>
nt.Field(GetField(nameof(EntityChange.EntityId))).Value(entityId)),
nm =>
nm.Term(nt =>
nt.Field(GetField(nameof(EntityChange.EntityTypeFullName))).Value(entityTypeFullName))
)
)
)
)
)
)
)
.Source(selector => selector.Includes(field =>
field.Field(f => f.UserName)))
.Sort(entity => entity.Field(f => f.ExecutionTime, SortOrder.Descending)),
ct: cancellationToken);
if (response.Hits.Count > 0)
var sortOrder = SortOrder.Descending;
var querys = BuildQueryDescriptor(entityId: entityId, entityTypeFullName: entityTypeFullName);
static SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
{
selector.IncludeAll()
.Excludes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions));
return selector;
}
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.Sort(log => log.Field(GetField(nameof(EntityChange.ChangeTime)), sortOrder))
.From(0)
.Size(100),
cancellationToken);
var auditLogs = response.Documents.ToList();
if (auditLogs.Any())
{
return response.Hits.
Select(hit => new EntityChangeWithUsername
var groupAuditLogs = auditLogs.GroupBy(log => log.UserName);
foreach (var group in groupAuditLogs)
{
var entityChangesList = group.Select(log => log.EntityChanges);
foreach (var entityChanges in entityChangesList)
{
UserName = hit.Source.UserName,
EntityChange = hit.InnerHits.Any() ?
hit.InnerHits.First().Value.Documents<EntityChange>().FirstOrDefault()
: null
})
.ToList();
foreach (var entityChange in entityChanges.Where(e => e.EntityId.Equals(entityId) && e.EntityTypeFullName.Equals(entityTypeFullName)))
{
result.Add(
new EntityChangeWithUsername
{
UserName = group.Key,
EntityChange = entityChange
});
}
}
}
}
return new List<EntityChangeWithUsername>();
return result;
}
protected virtual List<Func<QueryContainerDescriptor<EntityChange>, QueryContainer>> BuildQueryDescriptor(
protected virtual List<Func<QueryContainerDescriptor<AuditLog>, QueryContainer>> BuildQueryDescriptor(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null)
string entityTypeFullName = null,
Guid? entityChangeId = null)
{
var querys = new List<Func<QueryContainerDescriptor<EntityChange>, QueryContainer>>();
var querys = new List<Func<QueryContainerDescriptor<AuditLog>, QueryContainer>>();
if (auditLogId.HasValue)
{
@ -322,6 +341,10 @@ public class ElasticsearchEntityChangeStore : IEntityChangeStore, ITransientDepe
{
querys.Add(entity => entity.Wildcard(q => q.Field(GetField(nameof(EntityChange.EntityTypeFullName))).Value($"*{entityTypeFullName}*")));
}
if (entityChangeId.HasValue)
{
querys.Add(entity => entity.Term(q => q.Field(GetField(nameof(EntityChange.Id))).Value(entityChangeId)));
}
return querys;
}

4
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs

@ -15,7 +15,7 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
{
[Dependency(ReplaceServices = true)]
public class AuditLogManager : IAuditLogManager, ISingletonDependency
public class AuditLogManager : IAuditLogManager, ITransientDependency
{
protected IObjectMapper ObjectMapper { get; }
protected IAuditLogRepository AuditLogRepository { get; }
@ -139,6 +139,8 @@ namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
}
}
// 避免循环记录
[DisableAuditing]
public async virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default(CancellationToken))

115
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/EntityChangeStore.cs

@ -0,0 +1,115 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.AuditLogging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.ObjectMapping;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
[Dependency(ReplaceServices = true)]
public class EntityChangeStore : IEntityChangeStore, ITransientDependency
{
protected IObjectMapper ObjectMapper { get; }
protected IAuditLogRepository AuditLogRepository { get; }
public ILogger<EntityChangeStore> Logger { protected get; set; }
public EntityChangeStore(
IObjectMapper objectMapper,
IAuditLogRepository auditLogRepository)
{
ObjectMapper = objectMapper;
AuditLogRepository = auditLogRepository;
Logger = NullLogger<EntityChangeStore>.Instance;
}
public async virtual Task<EntityChange> GetAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default)
{
var entityChange = await AuditLogRepository.GetEntityChange(
entityChangeId,
cancellationToken);
return ObjectMapper.Map<Volo.Abp.AuditLogging.EntityChange, EntityChange>(entityChange);
}
public async virtual Task<long> GetCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
return await AuditLogRepository.GetEntityChangeCountAsync(
auditLogId,
startTime,
endTime,
changeType,
entityId,
entityTypeFullName,
cancellationToken);
}
public async virtual Task<List<EntityChange>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var entityChanges = await AuditLogRepository.GetEntityChangeListAsync(
sorting,
maxResultCount,
skipCount,
auditLogId,
startTime,
endTime,
changeType,
entityId,
entityTypeFullName,
includeDetails,
cancellationToken);
return ObjectMapper.Map<List<Volo.Abp.AuditLogging.EntityChange>, List<EntityChange>>(entityChanges);
}
public async virtual Task<EntityChangeWithUsername> GetWithUsernameAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default)
{
var entityChangeWithUsername = await AuditLogRepository.GetEntityChangeWithUsernameAsync(
entityChangeId,
cancellationToken);
return ObjectMapper.Map<Volo.Abp.AuditLogging.EntityChangeWithUsername, EntityChangeWithUsername>(entityChangeWithUsername);
}
public async virtual Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default)
{
var entityChangesWithUsername = await AuditLogRepository.GetEntityChangesWithUsernameAsync(
entityId,
entityTypeFullName,
cancellationToken);
return ObjectMapper.Map<List<Volo.Abp.AuditLogging.EntityChangeWithUsername>, List<EntityChangeWithUsername>>(entityChangesWithUsername);
}
}

2
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs

@ -14,7 +14,7 @@ using Volo.Abp.Uow;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
{
[Dependency(ReplaceServices = true)]
public class SecurityLogManager : ISecurityLogManager, ISingletonDependency
public class SecurityLogManager : ISecurityLogManager, ITransientDependency
{
public ILogger<SecurityLogManager> Logger { get; set; }

4
aspnet-core/modules/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs

@ -40,11 +40,13 @@ namespace LINGYUN.Abp.AuditLogging
IGuidGenerator guidGenerator,
Guid auditLogId,
EntityChangeInfo entityChangeInfo,
Guid? tenantId = null)
Guid? tenantId = null,
Guid? entityTenantId = null)
{
Id = guidGenerator.Create();
AuditLogId = auditLogId;
TenantId = tenantId;
EntityTenantId = entityTenantId;
ChangeTime = entityChangeInfo.ChangeTime;
ChangeType = entityChangeInfo.ChangeType;
EntityId = entityChangeInfo.EntityId;

3
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN.Abp.TuiJuhe.SettingManagement.csproj

@ -13,8 +13,7 @@
</ItemGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\TuiJuhe\SettingManagement\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\TuiJuhe\SettingManagement\Localization\Resources\zh-Hans.json" />
<None Remove="LINGYUN\Abp\TuiJuhe\SettingManagement\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>

6
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/AbpTuiJuheSettingManagementModule.cs

@ -11,13 +11,13 @@ namespace LINGYUN.Abp.TuiJuhe.SettingManagement
[DependsOn(
typeof(AbpTuiJuheModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpWxPusherSettingManagementModule : AbpModule
public class AbpTuiJuheSettingManagementModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpWxPusherSettingManagementModule).Assembly);
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpTuiJuheSettingManagementModule).Assembly);
});
}
@ -25,7 +25,7 @@ namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWxPusherSettingManagementModule>();
options.FileSets.AddEmbedded<AbpTuiJuheSettingManagementModule>();
});
Configure<AbpLocalizationOptions>(options =>

Loading…
Cancel
Save