diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj new file mode 100644 index 000000000..4589f07e1 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj @@ -0,0 +1,20 @@ + + + + + + + net9.0 + LINGYUN.Abp.AspNetCore.Auditing + LINGYUN.Abp.AspNetCore.Auditing + false + false + false + + + + + + + + diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs new file mode 100644 index 000000000..647ea909a --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.AspNetCore.Auditing; +public class AbpAspNetCoreAuditingHeaderOptions +{ + /// + /// 是否在审计日志中记录Http请求头,默认: true + /// + public bool IsEnabled { get; set; } + /// + /// 要记录的Http请求头 + /// + public IList HttpHeaders { get; } + public AbpAspNetCoreAuditingHeaderOptions() + { + IsEnabled = true; + HttpHeaders = new List(); + } +} diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs new file mode 100644 index 000000000..119d69635 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs @@ -0,0 +1,17 @@ +using Volo.Abp.AspNetCore; +using Volo.Abp.Auditing; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.AspNetCore.Auditing; + +[DependsOn(typeof(AbpAspNetCoreModule))] +public class AbpAspNetCoreAuditingModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Contributors.Add(new AspNetCoreRecordHeaderAuditLogContributor()); + }); + } +} diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs new file mode 100644 index 000000000..67f4a59d3 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs @@ -0,0 +1,51 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Collections.Immutable; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.AspNetCore.Auditing; +public class AspNetCoreRecordHeaderAuditLogContributor : AuditLogContributor, ITransientDependency +{ + private const string HttpHeaderRecordKey = "HttpHeaders"; + + public AspNetCoreRecordHeaderAuditLogContributor() + { + } + + public override void PreContribute(AuditLogContributionContext context) + { + var options = context.ServiceProvider.GetRequiredService>(); + if (!options.Value.IsEnabled) + { + return; + } + + var httpContext = context.ServiceProvider.GetRequiredService().HttpContext; + if (httpContext == null) + { + return; + } + + if (context.AuditInfo.HasProperty(HttpHeaderRecordKey)) + { + return; + } + + var headerRcords = new Dictionary(); + var httpHeaders = httpContext.Request.Headers.ToImmutableDictionary(); + + foreach (var headerKey in options.Value.HttpHeaders) + { + if (httpHeaders.TryGetValue(headerKey, out var headers)) + { + headerRcords[headerKey] = headers.JoinAsString(";"); + } + } + + context.AuditInfo.SetProperty(HttpHeaderRecordKey, headerRcords); + } +} diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md new file mode 100644 index 000000000..de6175010 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md @@ -0,0 +1,19 @@ +# LINGYUN.Abp.AspNetCore.Auditing + +审计日期扩展模块, 用于在审计日志中加入特定的Http请求头记录 + +## 模块引用 + + +```csharp +[DependsOn(typeof(AbpAspNetCoreAuditingModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +* AbpAspNetCoreAuditingHeaderOptions.IsEnabled 是否在审计日志中记录Http请求头,默认: true +* AbpAspNetCoreAuditingHeaderOptions.HttpHeaders 需要在审计日志中记录的Http请求头列表 diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs index cf6500bd8..8194b5edd 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs @@ -75,12 +75,12 @@ public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppS public async virtual Task> GetSessionsAsync(GetMySessionsInput input) { - var user = await GetCurrentUserAsync(); + var userId = CurrentUser.GetId(); var totalCount = await IdentitySessionRepository.GetCountAsync( - user.Id, input.Device, input.ClientId); + userId, input.Device, input.ClientId); var identitySessions = await IdentitySessionRepository.GetListAsync( input.Sorting, input.MaxResultCount, input.SkipCount, - user.Id, input.Device, input.ClientId); + userId, input.Device, input.ClientId); return new PagedResultDto(totalCount, identitySessions.Select(session => new IdentitySessionDto diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs index cfbe9870b..83f45536f 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.AutoMapper; using Volo.Abp.BackgroundWorkers; +using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Identity; using Volo.Abp.Modularity; @@ -14,6 +15,7 @@ namespace LINGYUN.Abp.Identity; [DependsOn( typeof(AbpIdentityDomainSharedModule), + typeof(AbpDistributedLockingAbstractionsModule), typeof(Volo.Abp.Identity.AbpIdentityDomainModule))] public class AbpIdentityDomainModule : AbpModule { diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs index 9ad838cea..1650e7730 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging.Abstractions; using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; @@ -22,15 +23,18 @@ public class IdentitySessionCacheItemSynchronizer : { public ILogger Logger { protected get; set; } protected ISettingProvider SettingProvider { get; } + protected IAbpDistributedLock DistributedLock { get; } protected IIdentitySessionCache IdentitySessionCache { get; } protected IIdentitySessionStore IdentitySessionStore { get; } public IdentitySessionCacheItemSynchronizer( ISettingProvider settingProvider, + IAbpDistributedLock distributedLock, IIdentitySessionCache identitySessionCache, IIdentitySessionStore identitySessionStore) { SettingProvider = settingProvider; + DistributedLock = distributedLock; IdentitySessionCache = identitySessionCache; IdentitySessionStore = identitySessionStore; @@ -45,34 +49,71 @@ public class IdentitySessionCacheItemSynchronizer : [UnitOfWork] public async virtual Task HandleEventAsync(EntityCreatedEto eventData) { - await RefreshSessionCache(eventData.Entity); - await CheckConcurrentLoginStrategy(eventData.Entity); + var lockKey = $"{nameof(IdentitySessionCacheItemSynchronizer)}_{nameof(EntityCreatedEto)}"; + await using (var handle = await DistributedLock.TryAcquireAsync(lockKey)) + { + Logger.LogInformation($"Lock is acquired for {lockKey}"); + + if (handle == null) + { + Logger.LogInformation($"Handle is null because of the locking for : {lockKey}"); + return; + } + + await RefreshSessionCache(eventData.Entity); + await CheckConcurrentLoginStrategy(eventData.Entity); + } } + [UnitOfWork] public async virtual Task HandleEventAsync(IdentitySessionChangeAccessedEvent eventData) { - var idetitySession = await IdentitySessionStore.FindAsync(eventData.SessionId); - if (idetitySession != null) + var lockKey = $"{nameof(IdentitySessionCacheItemSynchronizer)}_{nameof(IdentitySessionChangeAccessedEvent)}"; + await using (var handle = await DistributedLock.TryAcquireAsync(lockKey)) { - if (!eventData.IpAddresses.IsNullOrWhiteSpace()) + Logger.LogInformation($"Lock is acquired for {lockKey}"); + + if (handle == null) { - idetitySession.SetIpAddresses(eventData.IpAddresses.Split(",")); + Logger.LogInformation($"Handle is null because of the locking for : {lockKey}"); + return; } - idetitySession.UpdateLastAccessedTime(eventData.LastAccessed); - await IdentitySessionStore.UpdateAsync(idetitySession); - } - else - { - // 数据库中不存在会话, 清理缓存, 后续请求会话失效 - await IdentitySessionCache.RemoveAsync(eventData.SessionId); + var idetitySession = await IdentitySessionStore.FindAsync(eventData.SessionId); + if (idetitySession != null) + { + if (!eventData.IpAddresses.IsNullOrWhiteSpace()) + { + idetitySession.SetIpAddresses(eventData.IpAddresses.Split(",")); + } + idetitySession.UpdateLastAccessedTime(eventData.LastAccessed); + + await IdentitySessionStore.UpdateAsync(idetitySession); + } + else + { + // 数据库中不存在会话, 清理缓存, 后续请求会话失效 + await IdentitySessionCache.RemoveAsync(eventData.SessionId); + } } } public async virtual Task HandleEventAsync(EntityDeletedEventData eventData) { - // 用户被删除, 移除所有会话 - await IdentitySessionStore.RevokeAllAsync(eventData.Entity.Id); + var lockKey = $"{nameof(IdentitySessionCacheItemSynchronizer)}_{nameof(EntityDeletedEventData)}"; + await using (var handle = await DistributedLock.TryAcquireAsync(lockKey)) + { + Logger.LogInformation($"Lock is acquired for {lockKey}"); + + if (handle == null) + { + Logger.LogInformation($"Handle is null because of the locking for : {lockKey}"); + return; + } + + // 用户被删除, 移除所有会话 + await IdentitySessionStore.RevokeAllAsync(eventData.Entity.Id); + } } protected async virtual Task RefreshSessionCache(IdentitySessionEto session) diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs index 7abbaaccd..b3fab3f24 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs @@ -1,20 +1,25 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Threading.Tasks; using Volo.Abp.BackgroundWorkers; +using Volo.Abp.DistributedLocking; using Volo.Abp.Threading; namespace LINGYUN.Abp.Identity.Session; public class IdentitySessionCleanupBackgroundWorker : AsyncPeriodicBackgroundWorkerBase { + protected IAbpDistributedLock DistributedLock { get; } protected IdentitySessionCleanupOptions Options { get; } public IdentitySessionCleanupBackgroundWorker( AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory, - IOptions options) + IOptions options, + IAbpDistributedLock distributedLock) : base(timer, serviceScopeFactory) { + DistributedLock = distributedLock; Options = options.Value; timer.Period = Options.CleanupPeriod; } @@ -26,9 +31,22 @@ public class IdentitySessionCleanupBackgroundWorker : AsyncPeriodicBackgroundWor return; } - await workerContext - .ServiceProvider - .GetRequiredService() - .CleanAsync(); + await using (var handle = await DistributedLock.TryAcquireAsync(nameof(IdentitySessionCleanupBackgroundWorker))) + { + Logger.LogInformation($"Lock is acquired for {nameof(IdentitySessionCleanupBackgroundWorker)}"); + + if (handle != null) + { + await workerContext + .ServiceProvider + .GetRequiredService() + .CleanAsync(); + + Logger.LogInformation($"Lock is released for {nameof(IdentitySessionCleanupBackgroundWorker)}"); + return; + } + + Logger.LogInformation($"Handle is null because of the locking for : {nameof(IdentitySessionCleanupBackgroundWorker)}"); + } } } diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs deleted file mode 100644 index 0f1a2cf8e..000000000 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; -using Volo.Abp.Content; - -namespace LINGYUN.Abp.OssManagement; - -public interface IFileAppService : IApplicationService -{ - Task UploadAsync(UploadFileInput input); - - Task GetAsync(GetPublicFileInput input); - - Task> GetListAsync(GetFilesInput input); - - Task UploadChunkAsync(UploadFileChunkInput input); - - Task DeleteAsync(GetPublicFileInput input); -} diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs index 3e5c1d8ab..52d557ef3 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs @@ -1,10 +1,22 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Content; namespace LINGYUN.Abp.OssManagement; -public interface IPrivateFileAppService : IFileAppService +public interface IPrivateFileAppService : IApplicationService { + Task UploadAsync(UploadFileInput input); + + Task GetAsync(GetPublicFileInput input); + + Task> GetListAsync(GetFilesInput input); + + Task UploadChunkAsync(UploadFileChunkInput input); + + Task DeleteAsync(GetPublicFileInput input); + Task ShareAsync(FileShareInput input); Task> GetShareListAsync(); diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs index 7e2ed571a..5ec854d6c 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs @@ -1,5 +1,19 @@ -namespace LINGYUN.Abp.OssManagement; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Content; -public interface IPublicFileAppService : IFileAppService +namespace LINGYUN.Abp.OssManagement; + +public interface IPublicFileAppService : IApplicationService { + Task UploadAsync(UploadFileInput input); + + Task GetAsync(GetPublicFileInput input); + + Task> GetListAsync(GetFilesInput input); + + Task UploadChunkAsync(UploadFileChunkInput input); + + Task DeleteAsync(GetPublicFileInput input); } diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs index 8c8e94a9a..dfd2db5c5 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs @@ -14,7 +14,7 @@ using Volo.Abp.Validation; namespace LINGYUN.Abp.OssManagement; -public abstract class FileAppServiceBase : OssManagementApplicationServiceBase, IFileAppService +public abstract class FileAppServiceBase : OssManagementApplicationServiceBase { protected IFileUploader FileUploader { get; } protected IFileValidater FileValidater { get; } diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs index 8a211c7f2..e6e687ad2 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs @@ -15,8 +15,8 @@ using Volo.Abp.Http.Modeling; namespace LINGYUN.Abp.OssManagement; [Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IFileAppService), typeof(PrivateFilesClientProxy))] -public partial class PrivateFilesClientProxy : ClientProxyBase, IFileAppService +[ExposeServices(typeof(IPrivateFileAppService), typeof(PrivateFilesClientProxy))] +public partial class PrivateFilesClientProxy : ClientProxyBase, IPrivateFileAppService { public virtual async Task UploadAsync(UploadFileInput input) { diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs index 7298889ae..f2d593e18 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs @@ -15,8 +15,8 @@ using Volo.Abp.Http.Modeling; namespace LINGYUN.Abp.OssManagement; [Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IFileAppService), typeof(PublicFilesClientProxy))] -public partial class PublicFilesClientProxy : ClientProxyBase, IFileAppService +[ExposeServices(typeof(IPublicFileAppService), typeof(PublicFilesClientProxy))] +public partial class PublicFilesClientProxy : ClientProxyBase, IPublicFileAppService { public virtual async Task UploadAsync(UploadFileInput input) { diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json index 48241ed5b..df42ee8ab 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json @@ -1694,97 +1694,6 @@ } } ] - }, - { - "type": "LINGYUN.Abp.OssManagement.IFileAppService", - "name": "IFileAppService", - "methods": [ - { - "name": "UploadAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "LINGYUN.Abp.OssManagement.OssObjectDto", - "typeSimple": "LINGYUN.Abp.OssManagement.OssObjectDto" - } - }, - { - "name": "GetAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Content.IRemoteStreamContent", - "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" - } - }, - { - "name": "GetListAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetFilesInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetFilesInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetFilesInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Application.Dtos.ListResultDto", - "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" - } - }, - { - "name": "UploadChunkAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileChunkInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - }, - { - "name": "DeleteAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - } - ] } ], "actions": { @@ -2317,97 +2226,6 @@ } } ] - }, - { - "type": "LINGYUN.Abp.OssManagement.IFileAppService", - "name": "IFileAppService", - "methods": [ - { - "name": "UploadAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "LINGYUN.Abp.OssManagement.OssObjectDto", - "typeSimple": "LINGYUN.Abp.OssManagement.OssObjectDto" - } - }, - { - "name": "GetAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Content.IRemoteStreamContent", - "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" - } - }, - { - "name": "GetListAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetFilesInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetFilesInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetFilesInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Application.Dtos.ListResultDto", - "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" - } - }, - { - "name": "UploadChunkAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileChunkInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - }, - { - "name": "DeleteAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - } - ] } ], "actions": { diff --git a/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs b/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs index 2de484bcd..fc47ebc0c 100644 --- a/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs +++ b/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs @@ -81,7 +81,11 @@ public class EmailMessageManager : DomainService, IEmailMessageManager if (!message.CC.IsNullOrWhiteSpace()) { - mailMessage.CC.Add(message.CC); + var ccAddresses = message.CC.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var address in ccAddresses) + { + mailMessage.CC.Add(address.Trim()); + } } if (message.Priority.HasValue) diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj index 188573b06..50a50fc39 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj @@ -4,7 +4,7 @@ - netstandard2.0;netstandard2.1;net8.0 + netstandard2.0;netstandard2.1;net8.0;net9.0 LINGYUN.Abp.Notifications.Templating LINGYUN.Abp.Notifications.Templating false