From 2def9779a3a93b3c28112737f8e2614fa60eb12b Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Fri, 7 Aug 2020 17:32:32 +0800 Subject: [PATCH 1/3] add module file-management --- aspnet-core/LINGYUN.MicroService.sln | 46 +- .../Abp/Account/AbpAccountDomainModule.cs | 7 + ...ileManagement.Application.Contracts.csproj | 16 + ...ileManagementApplicationContractsModule.cs | 11 + .../Abp/FileManagement/FileCopyOrMoveDto.cs | 22 + .../Abp/FileManagement/FileCreateDto.cs | 39 ++ .../Abp/FileManagement/FileDeleteDto.cs | 15 + .../Abp/FileManagement/FileSystemDto.cs | 14 + .../Abp/FileManagement/FileSystemGetDto.cs | 15 + .../Abp/FileManagement/FileSystemType.cs | 8 + .../Abp/FileManagement/FileSystemUpdateDto.cs | 11 + .../Abp/FileManagement/FolderCopyDto.cs | 11 + .../Abp/FileManagement/FolderCreateDto.cs | 13 + .../Abp/FileManagement/FolderMoveDto.cs | 11 + .../FileManagement/GetFileSystemListDto.cs | 14 + .../FileManagement/IFileSystemAppService.cs | 35 ++ ...eManagementPermissionDefinitionProvider.cs | 34 ++ .../AbpFileManagementPermissions.cs | 44 ++ ...GYUN.Abp.FileManagement.Application.csproj | 13 + .../AbpFileManagementApplicationModule.cs | 12 + .../FileManagementApplicationServiceBase.cs | 15 + .../FileManagement/FileSystemAppService.cs | 392 ++++++++++++++++++ ...UN.Abp.FileManagement.Domain.Shared.csproj | 22 + .../AbpFileManagementDomainSharedModule.cs | 30 ++ .../Localization/AbpFileManagementResource.cs | 9 + .../Localization/Resources/en.json | 25 ++ .../Localization/Resources/zh-Hans.json | 25 ++ .../Settings/AbpFileManagementSettingNames.cs | 18 + .../LINGYUN.Abp.FileManagement.Domain.csproj | 16 + .../AbpFileManagementDomainModule.cs | 15 + .../Abp/FileManagement/FileSystemContainer.cs | 9 + ...FileManagementSettingDefinitionProvider.cs | 44 ++ .../LINGYUN.Abp.FileManagement.HttpApi.csproj | 16 + .../AbpFileManagementHttpApiModule.cs | 21 + .../FileManagement/FileSystemController.cs | 240 +++++++++++ .../Platform/AppPlatformDomainModule.cs | 2 + .../AbpTenantManagementApplicationModule.cs | 6 + .../AppPlatformHttpApiHostModule.cs | 3 + .../LINGYUN.Platform.HttpApi.Host.csproj | 2 + .../BlobStoring/TestObjects/TestContainer1.cs | 5 +- 40 files changed, 1301 insertions(+), 5 deletions(-) create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN.Abp.FileManagement.Application.Contracts.csproj create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemType.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemUpdateDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCopyDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCreateDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderMoveDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/GetFileSystemListDto.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/IFileSystemAppService.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissionDefinitionProvider.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN.Abp.FileManagement.Application.csproj create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationModule.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileManagementApplicationServiceBase.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN.Abp.FileManagement.Domain.Shared.csproj create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/AbpFileManagementDomainSharedModule.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/AbpFileManagementResource.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/en.json create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingNames.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN.Abp.FileManagement.Domain.csproj create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/AbpFileManagementDomainModule.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/FileSystemContainer.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingDefinitionProvider.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN.Abp.FileManagement.HttpApi.csproj create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/AbpFileManagementHttpApiModule.cs create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs diff --git a/aspnet-core/LINGYUN.MicroService.sln b/aspnet-core/LINGYUN.MicroService.sln index 2b9912278..765497dde 100644 --- a/aspnet-core/LINGYUN.MicroService.sln +++ b/aspnet-core/LINGYUN.MicroService.sln @@ -185,13 +185,25 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.EntityFramework EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity", "identity", "{52B5D4F7-237B-4E0A-A167-68442164F70A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.Application.Contracts", "modules\identity\LINGYUN.Abp.Identity.Application.Contracts\LINGYUN.Abp.Identity.Application.Contracts.csproj", "{F19C8B0F-A332-4190-9ABE-95790E0AE864}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Application.Contracts", "modules\identity\LINGYUN.Abp.Identity.Application.Contracts\LINGYUN.Abp.Identity.Application.Contracts.csproj", "{F19C8B0F-A332-4190-9ABE-95790E0AE864}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.Application", "modules\identity\LINGYUN.Abp.Identity.Application\LINGYUN.Abp.Identity.Application.csproj", "{BB1B831F-4AC4-4DE5-A879-D5FC5B1CA9DA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Application", "modules\identity\LINGYUN.Abp.Identity.Application\LINGYUN.Abp.Identity.Application.csproj", "{BB1B831F-4AC4-4DE5-A879-D5FC5B1CA9DA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.HttpApi", "modules\identity\LINGYUN.Abp.Identity.HttpApi\LINGYUN.Abp.Identity.HttpApi.csproj", "{72DCA4CF-8B95-47C9-B02A-2671953B7987}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.HttpApi", "modules\identity\LINGYUN.Abp.Identity.HttpApi\LINGYUN.Abp.Identity.HttpApi.csproj", "{72DCA4CF-8B95-47C9-B02A-2671953B7987}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.HttpApi.Client", "modules\identity\LINGYUN.Abp.Identity.HttpApi.Client\LINGYUN.Abp.Identity.HttpApi.Client.csproj", "{7DDEAEA9-E392-469C-ACB6-908C5BAD669E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.HttpApi.Client", "modules\identity\LINGYUN.Abp.Identity.HttpApi.Client\LINGYUN.Abp.Identity.HttpApi.Client.csproj", "{7DDEAEA9-E392-469C-ACB6-908C5BAD669E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "file-management", "file-management", "{B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.FileManagement.Application", "modules\file-management\LINGYUN.Abp.FileManagement.Application\LINGYUN.Abp.FileManagement.Application.csproj", "{F3D50E3E-34D2-48C1-AB0D-ADCF92DC07D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.FileManagement.Application.Contracts", "modules\file-management\LINGYUN.Abp.FileManagement.Application.Contracts\LINGYUN.Abp.FileManagement.Application.Contracts.csproj", "{86A67B8C-EFA0-4103-B60F-312F07C15A7A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.FileManagement.HttpApi", "modules\file-management\LINGYUN.Abp.FileManagement.HttpApi\LINGYUN.Abp.FileManagement.HttpApi.csproj", "{854E1A42-FEA4-420E-9E83-0A39EE03F1ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.FileManagement.Domain.Shared", "modules\file-management\LINGYUN.Abp.FileManagement.Domain.Shared\LINGYUN.Abp.FileManagement.Domain.Shared.csproj", "{21FCEF89-9A3F-476E-833A-A9C2131B2AE6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.FileManagement.Domain", "modules\file-management\LINGYUN.Abp.FileManagement.Domain\LINGYUN.Abp.FileManagement.Domain.csproj", "{14ECCFD6-2DC1-4124-BE26-15E8D28E3E90}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -511,6 +523,26 @@ Global {7DDEAEA9-E392-469C-ACB6-908C5BAD669E}.Debug|Any CPU.Build.0 = Debug|Any CPU {7DDEAEA9-E392-469C-ACB6-908C5BAD669E}.Release|Any CPU.ActiveCfg = Release|Any CPU {7DDEAEA9-E392-469C-ACB6-908C5BAD669E}.Release|Any CPU.Build.0 = Release|Any CPU + {F3D50E3E-34D2-48C1-AB0D-ADCF92DC07D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3D50E3E-34D2-48C1-AB0D-ADCF92DC07D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3D50E3E-34D2-48C1-AB0D-ADCF92DC07D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3D50E3E-34D2-48C1-AB0D-ADCF92DC07D0}.Release|Any CPU.Build.0 = Release|Any CPU + {86A67B8C-EFA0-4103-B60F-312F07C15A7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86A67B8C-EFA0-4103-B60F-312F07C15A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86A67B8C-EFA0-4103-B60F-312F07C15A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86A67B8C-EFA0-4103-B60F-312F07C15A7A}.Release|Any CPU.Build.0 = Release|Any CPU + {854E1A42-FEA4-420E-9E83-0A39EE03F1ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {854E1A42-FEA4-420E-9E83-0A39EE03F1ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {854E1A42-FEA4-420E-9E83-0A39EE03F1ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {854E1A42-FEA4-420E-9E83-0A39EE03F1ED}.Release|Any CPU.Build.0 = Release|Any CPU + {21FCEF89-9A3F-476E-833A-A9C2131B2AE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {21FCEF89-9A3F-476E-833A-A9C2131B2AE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21FCEF89-9A3F-476E-833A-A9C2131B2AE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {21FCEF89-9A3F-476E-833A-A9C2131B2AE6}.Release|Any CPU.Build.0 = Release|Any CPU + {14ECCFD6-2DC1-4124-BE26-15E8D28E3E90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14ECCFD6-2DC1-4124-BE26-15E8D28E3E90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14ECCFD6-2DC1-4124-BE26-15E8D28E3E90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14ECCFD6-2DC1-4124-BE26-15E8D28E3E90}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -608,6 +640,12 @@ Global {BB1B831F-4AC4-4DE5-A879-D5FC5B1CA9DA} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {72DCA4CF-8B95-47C9-B02A-2671953B7987} = {52B5D4F7-237B-4E0A-A167-68442164F70A} {7DDEAEA9-E392-469C-ACB6-908C5BAD669E} = {52B5D4F7-237B-4E0A-A167-68442164F70A} + {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} = {C5CAD011-DF84-4914-939C-0C029DCEF26F} + {F3D50E3E-34D2-48C1-AB0D-ADCF92DC07D0} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} + {86A67B8C-EFA0-4103-B60F-312F07C15A7A} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} + {854E1A42-FEA4-420E-9E83-0A39EE03F1ED} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} + {21FCEF89-9A3F-476E-833A-A9C2131B2AE6} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} + {14ECCFD6-2DC1-4124-BE26-15E8D28E3E90} = {B05CB08F-C088-4D6D-97EE-A94A5D1AE4A6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs index 38693428c..26100b96d 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Domain/LINGYUN/Abp/Account/AbpAccountDomainModule.cs @@ -1,4 +1,6 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.Identity; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; @@ -21,6 +23,11 @@ namespace LINGYUN.Abp.Account .Get() .AddVirtualJson("/LINGYUN/Abp/Account/Localization/Resources"); }); + + Configure(options => + { + options.AutoEventSelectors.AddNamespace("Volo.Abp.Identity"); + }); } } } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN.Abp.FileManagement.Application.Contracts.csproj b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN.Abp.FileManagement.Application.Contracts.csproj new file mode 100644 index 000000000..382a43c07 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN.Abp.FileManagement.Application.Contracts.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs new file mode 100644 index 000000000..891ac26a2 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Application; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.FileManagement +{ + [DependsOn( + typeof(AbpDddApplicationModule))] + public class AbpFileManagementApplicationContractsModule : AbpModule + { + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs new file mode 100644 index 000000000..bbda957fe --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileCopyOrMoveDto + { + [Required] + [StringLength(255)] + public string Path { get; set; } + + [Required] + [StringLength(255)] + public string Name { get; set; } + + [Required] + [StringLength(255)] + public string ToPath { get; set; } + + [StringLength(255)] + public string ToName { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs new file mode 100644 index 000000000..5a5096e58 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs @@ -0,0 +1,39 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Auditing; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileCreateDto + { + /// + /// 文件名 + /// + [Required] + [StringLength(255)] + public string Name { get; set; } + /// + /// 文件路径 + /// + [StringLength(255)] + public string Path { get; set; } + /// + /// 文件数据,前端无需传递此参数,由控制器传递 + /// + [DisableAuditing] + public byte[] Data { get; set; } + /// + /// 当前字节数 + /// + [Required] + public int CurrentByte { get; set; } + /// + /// 最大字节数 + /// + [Required] + public int TotalByte { get; set; } + /// + /// 是否覆盖文件 + /// + public bool Rewrite { get; set; } = false; + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs new file mode 100644 index 000000000..f74c4d823 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileDeleteDto + { + [Required] + [StringLength(255)] + public string Path { get; set; } + + [Required] + [StringLength(255)] + public string Name { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs new file mode 100644 index 000000000..5efdebc45 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs @@ -0,0 +1,14 @@ +using System; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileSystemDto + { + public FileSystemType Type { get; set; } + public string Name { get; set; } + public string Parent { get; set; } + public long? Size { get; set; } + public DateTime CreationTime { get; set; } + public DateTime? LastModificationTime { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs new file mode 100644 index 000000000..421ae1803 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileSystemGetDto + { + [Required] + [StringLength(255)] + public string Path { get; set; } + + [Required] + [StringLength(255)] + public string Name { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemType.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemType.cs new file mode 100644 index 000000000..ecbcd214d --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemType.cs @@ -0,0 +1,8 @@ +namespace LINGYUN.Abp.FileManagement +{ + public enum FileSystemType + { + Folder = 0, + File = 1 + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemUpdateDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemUpdateDto.cs new file mode 100644 index 000000000..3f4193bf4 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemUpdateDto.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileSystemUpdateDto + { + [Required] + [StringLength(255)] + public string NewName { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCopyDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCopyDto.cs new file mode 100644 index 000000000..ada1ca9a5 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCopyDto.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FolderCopyDto + { + [Required] + [StringLength(255)] + public string CopyToPath { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCreateDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCreateDto.cs new file mode 100644 index 000000000..9d2c09d93 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderCreateDto.cs @@ -0,0 +1,13 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FolderCreateDto + { + [Required] + [StringLength(255)] + public string Path { get; set; } + + public string Parent { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderMoveDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderMoveDto.cs new file mode 100644 index 000000000..760b79ad8 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FolderMoveDto.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; + +namespace LINGYUN.Abp.FileManagement +{ + public class FolderMoveDto + { + [Required] + [StringLength(255)] + public string MoveToPath { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/GetFileSystemListDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/GetFileSystemListDto.cs new file mode 100644 index 000000000..29b4f02cb --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/GetFileSystemListDto.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Application.Dtos; + +namespace LINGYUN.Abp.FileManagement +{ + public class GetFileSystemListDto : PagedAndSortedResultRequestDto + { + // TODO: Windows最大路径长度,超过了貌似也无效了吧 + [StringLength(255)] + public string Parent { get; set; } + + public string Filter { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/IFileSystemAppService.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/IFileSystemAppService.cs new file mode 100644 index 000000000..4a5955161 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/IFileSystemAppService.cs @@ -0,0 +1,35 @@ +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.FileManagement +{ + public interface IFileSystemAppService : IApplicationService + { + Task GetAsync(FileSystemGetDto input); + + Task> GetListAsync(GetFileSystemListDto input); + + Task CreateFolderAsync(FolderCreateDto input); + + Task UpdateAsync([Required, StringLength(255)] string name, FileSystemUpdateDto input); + + Task DeleteFolderAsync([Required, StringLength(255)] string path); + + Task MoveFolderAsync([Required, StringLength(255)] string path, FolderMoveDto input); + + Task CopyFolderAsync([Required, StringLength(255)] string path, FolderCopyDto input); + + Task CreateFileAsync(FileCreateDto input); + + Task DeleteFileAsync(FileDeleteDto input); + + Task MoveFileAsync(FileCopyOrMoveDto input); + + Task CopyFileAsync(FileCopyOrMoveDto input); + + Task DownloadFileAsync(FileSystemGetDto input); + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissionDefinitionProvider.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissionDefinitionProvider.cs new file mode 100644 index 000000000..1c1ac9f1a --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissionDefinitionProvider.cs @@ -0,0 +1,34 @@ +using LINGYUN.Abp.FileManagement.Localization; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.FileManagement.Permissions +{ + public class AbpFileManagementPermissionDefinitionProvider : PermissionDefinitionProvider + { + public override void Define(IPermissionDefinitionContext context) + { + var fileManagement = context.AddGroup(AbpFileManagementPermissions.GroupName, L("Permission:FileManagement")); + + var fileSystem = fileManagement.AddPermission(AbpFileManagementPermissions.FileSystem.Default, L("Permission:FileSystem")); + fileSystem.AddChild(AbpFileManagementPermissions.FileSystem.Create, L("Permission:CreateFolder")); + fileSystem.AddChild(AbpFileManagementPermissions.FileSystem.Delete, L("Permission:DeleteFolder")); + fileSystem.AddChild(AbpFileManagementPermissions.FileSystem.Update, L("Permission:UpdateFolder")); + fileSystem.AddChild(AbpFileManagementPermissions.FileSystem.Copy, L("Permission:CopyFolder")); + fileSystem.AddChild(AbpFileManagementPermissions.FileSystem.Move, L("Permission:MoveFolder")); + + var fileManager = fileSystem.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Default, L("Permission:FileManager")); + fileManager.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Create, L("Permission:AppendFile")); + fileManager.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Update, L("Permission:UpdateFile")); + fileManager.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Delete, L("Permission:DeleteFile")); + fileManager.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Copy, L("Permission:CopyFile")); + fileManager.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Move, L("Permission:MoveFile")); + fileManager.AddChild(AbpFileManagementPermissions.FileSystem.FileManager.Download, L("Permission:DownloadFile")); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs new file mode 100644 index 000000000..0b415358f --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs @@ -0,0 +1,44 @@ +namespace LINGYUN.Abp.FileManagement.Permissions +{ + public class AbpFileManagementPermissions + { + public const string GroupName = "Abp.FileManagement"; + + /// + /// 文件系统 + /// + public class FileSystem + { + public const string Default = GroupName + ".FileSystem"; + + public const string Create = Default + ".Create"; + + public const string Delete = Default + ".Delete"; + + public const string Update = Default + ".Update"; + + public const string Copy = Default + ".Copy"; + + public const string Move = Default + ".Move"; + /// + /// 文件管理 + /// + public class FileManager + { + public const string Default = FileSystem.Default + ".FileManager"; + + public const string Create = Default + ".Create"; + + public const string Copy = Default + ".Copy"; + + public const string Delete = Default + ".Delete"; + + public const string Update = Default + ".Update"; + + public const string Move = Default + ".Move"; + + public const string Download = Default + ".Download"; + } + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN.Abp.FileManagement.Application.csproj b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN.Abp.FileManagement.Application.csproj new file mode 100644 index 000000000..3855f470f --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN.Abp.FileManagement.Application.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0 + + + + + + + + + diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationModule.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationModule.cs new file mode 100644 index 000000000..4d52281a1 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationModule.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.FileManagement +{ + [DependsOn( + typeof(AbpFileManagementDomainModule), + typeof(AbpFileManagementApplicationContractsModule))] + public class AbpFileManagementApplicationModule : AbpModule + { + + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileManagementApplicationServiceBase.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileManagementApplicationServiceBase.cs new file mode 100644 index 000000000..5b0dfbc85 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileManagementApplicationServiceBase.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.Application.Services; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileManagementApplicationServiceBase : ApplicationService + { + protected FileManagementApplicationServiceBase() + { + + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs new file mode 100644 index 000000000..1d2c82838 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.BlobStoring; +using Volo.Abp.BlobStoring.FileSystem; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileSystemAppService : FileManagementApplicationServiceBase, IFileSystemAppService + { + protected IBlobContainer BlobContainer { get; } + protected IBlobContainerConfigurationProvider BlobContainerConfigurationProvider { get; } + public FileSystemAppService( + IBlobContainer blobContainer, + IBlobContainerConfigurationProvider blobContainerConfigurationProvider) + { + BlobContainer = blobContainer; + BlobContainerConfigurationProvider = blobContainerConfigurationProvider; + } + + public virtual Task CopyFileAsync(FileCopyOrMoveDto input) + { + string fileSystemPath = GetFileSystemPath(input.Path); + var fileFullName = Path.Combine(fileSystemPath, input.Name); + if (!File.Exists(fileFullName)) + { + throw new UserFriendlyException("指定的文件不存在!"); + } + var copyToFilePath = GetFileSystemPath(input.ToPath); + var copyToFileFullName = Path.Combine(copyToFilePath, input.ToName ?? input.Name); + if (File.Exists(copyToFileFullName)) + { + throw new UserFriendlyException("指定的路径中已经有相同的文件名存在!"); + } + + File.Copy(fileFullName, copyToFileFullName); + + return Task.CompletedTask; + } + + public virtual Task CopyFolderAsync([Required, StringLength(255)] string path, FolderCopyDto input) + { + string fileSystemPath = GetFileSystemPath(path); + if (!Directory.Exists(fileSystemPath)) + { + throw new UserFriendlyException("指定目录不存在!"); + } + var copyToFilePath = GetFileSystemPath(input.CopyToPath); + if (Directory.Exists(copyToFilePath)) + { + throw new UserFriendlyException("指定的路径中已经有同名的目录存在!"); + } + + CopyDirectory(fileSystemPath, copyToFilePath); + + return Task.CompletedTask; + } + + public virtual async Task CreateFileAsync(FileCreateDto input) + { + string fileSystemPath = GetFileSystemPath(input.Path); + var fileFullName = Path.Combine(fileSystemPath, input.Name); + if (File.Exists(fileFullName) && !input.Rewrite) + { + throw new UserFriendlyException("指定的文件已经存在!"); + } + await BlobContainer.SaveAsync(input.Name, input.Data, input.Rewrite); + } + + public virtual Task CreateFolderAsync(FolderCreateDto input) + { + string fileSystemPath = GetFileSystemBashPath(); + if (!input.Parent.IsNullOrWhiteSpace()) + { + fileSystemPath = GetFileSystemPath(input.Parent); + } + var newFloderPath = Path.Combine(fileSystemPath, input.Path); + if (Directory.Exists(newFloderPath)) + { + throw new UserFriendlyException("指定目录已经存在!"); + } + Directory.CreateDirectory(newFloderPath); + + return Task.CompletedTask; + } + + public virtual Task DeleteFileAsync(FileDeleteDto input) + { + var fileSystemPath = GetFileSystemPath(input.Path); + fileSystemPath = Path.Combine(fileSystemPath, input.Name); + if (File.Exists(fileSystemPath)) + { + File.Delete(fileSystemPath); + } + return Task.CompletedTask; + } + + public virtual Task DeleteFolderAsync([Required, StringLength(255)] string path) + { + string fileSystemPath = GetFileSystemPath(path); + if (!Directory.Exists(fileSystemPath)) + { + throw new UserFriendlyException("指定目录不存在!"); + } + var fileSystemChildrenPath = Directory.GetDirectories(fileSystemPath); + if (fileSystemChildrenPath.Length > 0) + { + throw new UserFriendlyException("指定的目录不为空,不可删除此目录!"); + } + var fileSystemPathFiles = Directory.GetFiles(fileSystemPath); + if (fileSystemPathFiles.Length > 0) + { + throw new UserFriendlyException("指定的目录不为空,不可删除此目录!"); + } + Directory.Delete(fileSystemPath); + return Task.CompletedTask; + } + + public virtual async Task DownloadFileAsync(FileSystemGetDto input) + { + var fileSystemPath = GetFileSystemPath(input.Path); + fileSystemPath = Path.Combine(fileSystemPath, input.Name); + var blobName = GetFileSystemRelativePath(fileSystemPath); + + return await BlobContainer.GetAsync(blobName); + } + + public virtual Task GetAsync(FileSystemGetDto input) + { + var fileSystemPath = GetFileSystemPath(input.Path); + fileSystemPath = Path.Combine(fileSystemPath, input.Name); + if (File.Exists(fileSystemPath)) + { + var fileInfo = new FileInfo(fileSystemPath); + var fileSystem = new FileSystemDto + { + Type = FileSystemType.File, + Name = fileInfo.Name, + Size = fileInfo.Length, + CreationTime = fileInfo.CreationTime, + LastModificationTime = fileInfo.LastWriteTime + }; + if (fileInfo.Directory?.Parent != null && !fileInfo.Directory.Parent.Name.IsNullOrWhiteSpace()) + { + fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.Parent.FullName); + } + return Task.FromResult(fileSystem); + } + if (Directory.Exists(fileSystemPath)) + { + var directoryInfo = new DirectoryInfo(fileSystemPath); + var fileSystem = new FileSystemDto + { + Type = FileSystemType.Folder, + Name = directoryInfo.Name, + CreationTime = directoryInfo.CreationTime, + LastModificationTime = directoryInfo.LastWriteTime + }; + if (directoryInfo.Parent != null && !directoryInfo.Parent.Name.IsNullOrWhiteSpace()) + { + fileSystem.Parent = GetFileSystemRelativePath(directoryInfo.Parent.FullName); + } + return Task.FromResult(fileSystem); + } + throw new UserFriendlyException("文件或目录不存在!"); + } + + public virtual Task> GetListAsync(GetFileSystemListDto input) + { + List fileSystems = new List(); + + string fileSystemPath = GetFileSystemBashPath(); + if (!input.Parent.IsNullOrWhiteSpace()) + { + fileSystemPath = GetFileSystemPath(input.Parent); + } + var directoryInfo = new DirectoryInfo(fileSystemPath); + // 查询全部 + var fileSystemInfos = directoryInfo.GetFileSystemInfos(); + // 指定搜索条件查询目录 + FileSystemInfo[] fileSystemInfoSearchChildren;// = directoryInfo.GetDirectories(input.Filter ?? "*", SearchOption.TopDirectoryOnly); + if (!input.Filter.IsNullOrWhiteSpace()) + { + var searchPattern = $"*{input.Filter}*"; + fileSystemInfoSearchChildren = directoryInfo.GetFileSystemInfos(searchPattern); + } + else + { + fileSystemInfoSearchChildren = directoryInfo.GetFileSystemInfos(); + } + + fileSystemInfoSearchChildren = fileSystemInfoSearchChildren + .Skip((input.SkipCount - 1) * input.MaxResultCount) + .Take(input.MaxResultCount) + .ToArray(); + + foreach (var fileSystemInfo in fileSystemInfoSearchChildren) + { + var fileSystem = new FileSystemDto + { + Name = fileSystemInfo.Name, + CreationTime = fileSystemInfo.CreationTime, + LastModificationTime = fileSystemInfo.LastWriteTime, + }; + if (fileSystemInfo is FileInfo fileInfo) + { + fileSystem.Type = FileSystemType.File; + fileSystem.Size = fileInfo.Length; + if (fileInfo.Directory?.Parent != null && !fileInfo.Directory.Parent.Name.IsNullOrWhiteSpace()) + { + fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.Parent.FullName); + } + } + else if (fileSystemInfo is DirectoryInfo directory) + { + fileSystem.Type = FileSystemType.Folder; + if (directory.Parent != null && !directory.Parent.Name.IsNullOrWhiteSpace()) + { + fileSystem.Parent = GetFileSystemRelativePath(directory.Parent.FullName); + } + } + fileSystems.Add(fileSystem); + } + + return Task.FromResult(new PagedResultDto( + fileSystemInfos.Length, fileSystems + )); + } + + public virtual Task MoveFileAsync(FileCopyOrMoveDto input) + { + string fileSystemPath = GetFileSystemPath(input.Path); + fileSystemPath = Path.Combine(fileSystemPath, input.Name); + if (!File.Exists(fileSystemPath)) + { + throw new UserFriendlyException("指定目录不存在!"); + } + var moveToFilePath = GetFileSystemPath(input.ToPath); + moveToFilePath = Path.Combine(moveToFilePath, input.ToName ?? input.Name); + if (Directory.Exists(moveToFilePath)) + { + throw new UserFriendlyException("指定的路径中已经有同名的文件存在!"); + } + + File.Move(fileSystemPath, moveToFilePath); + + return Task.CompletedTask; + } + + public virtual Task MoveFolderAsync([Required, StringLength(255)] string path, FolderMoveDto input) + { + string fileSystemPath = GetFileSystemPath(path); + if (!Directory.Exists(fileSystemPath)) + { + throw new UserFriendlyException("指定目录不存在!"); + } + var moveToFilePath = GetFileSystemPath(input.MoveToPath); + if (Directory.Exists(moveToFilePath)) + { + throw new UserFriendlyException("指定的路径中已经有同名的目录存在!"); + } + + Directory.Move(fileSystemPath, moveToFilePath); + + return Task.CompletedTask; + } + + public virtual Task UpdateAsync([Required, StringLength(255)] string name, FileSystemUpdateDto input) + { + string fileSystemPath = GetFileSystemPath(name); + var renameFilePath = GetFileSystemPath(input.NewName); + if (File.Exists(fileSystemPath)) + { + if (File.Exists(renameFilePath)) + { + throw new UserFriendlyException("指定的文件名已经存在!"); + } + File.Move(fileSystemPath, renameFilePath); + + var fileInfo = new FileInfo(renameFilePath); + var fileSystem = new FileSystemDto + { + Type = FileSystemType.File, + Name = fileInfo.Name, + Size = fileInfo.Length, + CreationTime = fileInfo.CreationTime, + LastModificationTime = fileInfo.LastWriteTime + }; + if (fileInfo.Directory?.Parent != null && !fileInfo.Directory.Parent.Name.IsNullOrWhiteSpace()) + { + fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.Parent.FullName); + } + return Task.FromResult(fileSystem); + } + if (Directory.Exists(fileSystemPath)) + { + if (Directory.Exists(renameFilePath)) + { + throw new UserFriendlyException("指定的路径中已经有同名的目录存在!"); + } + + Directory.Move(fileSystemPath, renameFilePath); + + var directoryInfo = new DirectoryInfo(renameFilePath); + var fileSystem = new FileSystemDto + { + Type = FileSystemType.Folder, + Name = directoryInfo.Name, + CreationTime = directoryInfo.CreationTime, + LastModificationTime = directoryInfo.LastWriteTime + }; + if (directoryInfo.Parent != null && !directoryInfo.Parent.Name.IsNullOrWhiteSpace()) + { + fileSystem.Parent = GetFileSystemRelativePath(directoryInfo.Parent.FullName); + } + return Task.FromResult(fileSystem); + } + throw new UserFriendlyException("文件或目录不存在!"); + } + + protected virtual string GetFileSystemRelativePath(string path) + { + return path.Replace(Directory.GetCurrentDirectory(), ""); + } + + protected virtual string GetFileSystemPath(string path) + { + var fileSystemConfiguration = GetFileSystemBlobProviderConfiguration(); + var blobPath = GetFileSystemBashPath(); + + if (fileSystemConfiguration.AppendContainerNameToBasePath) + { + blobPath = Path.Combine(blobPath, path); + } + + return blobPath; + } + + protected virtual string GetFileSystemBashPath() + { + var fileSystemConfiguration = GetFileSystemBlobProviderConfiguration(); + var blobPath = fileSystemConfiguration.BasePath; + blobPath = Path.Combine(Directory.GetCurrentDirectory(), blobPath); + if (CurrentTenant.Id == null) + { + blobPath = Path.Combine(blobPath, "host"); + } + else + { + blobPath = Path.Combine(blobPath, "tenants", CurrentTenant.Id.Value.ToString("D")); + } + + return blobPath; + } + + protected virtual FileSystemBlobProviderConfiguration GetFileSystemBlobProviderConfiguration() + { + var blobConfiguration = BlobContainerConfigurationProvider + .Get(); + return blobConfiguration.GetFileSystemConfiguration(); + } + + protected void CopyDirectory(string sourcePath, string copyToPath) + { + var sourceDirectory = new DirectoryInfo(sourcePath); + var fileSystemInfos = sourceDirectory.GetFileSystemInfos(); + + foreach (var fileSystemInfo in fileSystemInfos) + { + var copyToFilePath = Path.Combine(copyToPath, fileSystemInfo.Name); + if (fileSystemInfo is DirectoryInfo) + { + if (!Directory.Exists(copyToFilePath)) + { + Directory.CreateDirectory(copyToFilePath); + } + CopyDirectory(fileSystemInfo.FullName, copyToFilePath); + } + else + { + File.Copy(fileSystemInfo.FullName, copyToFilePath, true); + } + } + + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN.Abp.FileManagement.Domain.Shared.csproj b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN.Abp.FileManagement.Domain.Shared.csproj new file mode 100644 index 000000000..b26f20fbb --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN.Abp.FileManagement.Domain.Shared.csproj @@ -0,0 +1,22 @@ + + + + netstandard2.0 + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/AbpFileManagementDomainSharedModule.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/AbpFileManagementDomainSharedModule.cs new file mode 100644 index 000000000..fe39e6a5e --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/AbpFileManagementDomainSharedModule.cs @@ -0,0 +1,30 @@ +using LINGYUN.Abp.FileManagement.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Validation; +using Volo.Abp.Validation.Localization; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.FileManagement +{ + [DependsOn(typeof(AbpValidationModule))] + public class AbpFileManagementDomainSharedModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + + Configure(options => + { + options.Resources + .Add("en") + .AddBaseTypes( + typeof(AbpValidationResource) + ).AddVirtualJson("/LINGYUN/Abp/FileManagement/Localization/Resources"); + }); + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/AbpFileManagementResource.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/AbpFileManagementResource.cs new file mode 100644 index 000000000..4648b937d --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/AbpFileManagementResource.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Localization; + +namespace LINGYUN.Abp.FileManagement.Localization +{ + [LocalizationResourceName("AbpFileManagement")] + public class AbpFileManagementResource + { + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/en.json b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/en.json new file mode 100644 index 000000000..5635784f2 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/en.json @@ -0,0 +1,25 @@ +{ + "culture": "en", + "texts": { + "Permission:FileManagement": "File management", + "Permission:FileSystem": "File system", + "Permission:FileManager": "Files", + "Permission:CreateFolder": "Create directory", + "Permission:DeleteFolder": "Delete directory", + "Permission:UpdateFolder": "Edit directory", + "Permission:MoveFolder": "Change directory", + "Permission:CopyFolder": "Copy directory", + "Permission:AppendFile": "Add files", + "Permission:UpdateFile": "Change file", + "Permission:DeleteFile": "Delete file", + "Permission:CopyFile": "Copy file", + "Permission:MoveFile": "Move file", + "Permission:DownloadFile": "Download file", + "UploadFileSizeBeyondLimit": "Upload file size cannot exceed {0} MB!", + "NotAllowedFileExtensionName": "Not allowed file extension: {0}!", + "DisplayName:FileLimitLength": "File limit size", + "Description:FileLimitLength": "Limit size of uploaded file in MB", + "DisplayName:AllowFileExtensions": "File extension", + "Description:AllowFileExtensions": "List of allowed extensions to upload files, with multiple extensions separated by, don't need a notation" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/zh-Hans.json b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..e9b15e961 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Localization/Resources/zh-Hans.json @@ -0,0 +1,25 @@ +{ + "culture": "zh-Hans", + "texts": { + "Permission:FileManagement": "文件管理", + "Permission:FileSystem": "文件系统", + "Permission:FileManager": "文件", + "Permission:CreateFolder": "创建目录", + "Permission:DeleteFolder": "删除目录", + "Permission:UpdateFolder": "修改目录", + "Permission:MoveFolder": "变更目录", + "Permission:CopyFolder": "复制目录", + "Permission:AppendFile": "添加文件", + "Permission:UpdateFile": "变更文件", + "Permission:DeleteFile": "删除文件", + "Permission:CopyFile": "复制文件", + "Permission:MoveFile": "移动文件", + "Permission:DownloadFile": "下载文件", + "UploadFileSizeBeyondLimit": "上传文件大小不能超过 {0} MB!", + "NotAllowedFileExtensionName": "不被允许的文件扩展名: {0}!", + "DisplayName:FileLimitLength": "文件限制大小", + "Description:FileLimitLength": "上传文件的限制大小,单位(MB)", + "DisplayName:AllowFileExtensions": "文件扩展名", + "Description:AllowFileExtensions": "允许的上传文件扩展名列表,多个扩展名以,分隔,无需输入.符号" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingNames.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingNames.cs new file mode 100644 index 000000000..18d24cf18 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain.Shared/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingNames.cs @@ -0,0 +1,18 @@ +namespace LINGYUN.Abp.FileManagement.Settings +{ + public class AbpFileManagementSettingNames + { + public const string GroupName = "Abp.FileManagement"; + /// + /// 文件限制长度 + /// + public const string FileLimitLength = GroupName + ".FileLimitLength"; + /// + /// 允许的文件扩展名类型 + /// + public const string AllowFileExtensions = GroupName + ".AllowFileExtensions"; + + public const int DefaultFileLimitLength = 100; + public const string DefaultAllowFileExtensions = "dll,zip,rar,txt,log,xml,config,json,jpeg,jpg,png,bmp,ico,xlsx,xltx,xls,xlt,docs,dots,doc,dot,pptx,potx,ppt,pot,chm"; + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN.Abp.FileManagement.Domain.csproj b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN.Abp.FileManagement.Domain.csproj new file mode 100644 index 000000000..fbc7b1b4c --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN.Abp.FileManagement.Domain.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/AbpFileManagementDomainModule.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/AbpFileManagementDomainModule.cs new file mode 100644 index 000000000..f3781044f --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/AbpFileManagementDomainModule.cs @@ -0,0 +1,15 @@ +using Volo.Abp.Domain; +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.FileManagement +{ + [DependsOn( + typeof(AbpDddDomainModule), + typeof(AbpMultiTenancyModule), + typeof(AbpFileManagementDomainSharedModule) + )] + public class AbpFileManagementDomainModule : AbpModule + { + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/FileSystemContainer.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/FileSystemContainer.cs new file mode 100644 index 000000000..42c643e8f --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/FileSystemContainer.cs @@ -0,0 +1,9 @@ +using Volo.Abp.BlobStoring; + +namespace LINGYUN.Abp.FileManagement +{ + [BlobContainerName("abp-file-management")] + public class FileSystemContainer + { + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingDefinitionProvider.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingDefinitionProvider.cs new file mode 100644 index 000000000..b93566816 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Domain/LINGYUN/Abp/FileManagement/Settings/AbpFileManagementSettingDefinitionProvider.cs @@ -0,0 +1,44 @@ +using LINGYUN.Abp.FileManagement.Localization; +using Volo.Abp.Localization; +using Volo.Abp.Settings; + +namespace LINGYUN.Abp.FileManagement.Settings +{ + public class AbpFileManagementSettingDefinitionProvider : SettingDefinitionProvider + { + public override void Define(ISettingDefinitionContext context) + { + context.Add(CreateFileSystemSettings()); + } + + protected SettingDefinition[] CreateFileSystemSettings() + { + return new SettingDefinition[] + { + new SettingDefinition( + name: AbpFileManagementSettingNames.FileLimitLength, + defaultValue: AbpFileManagementSettingNames.DefaultFileLimitLength.ToString(), + displayName: L("DisplayName:FileLimitLength"), + description: L("Description:FileLimitLength"), + isVisibleToClients: true) + .WithProviders( + GlobalSettingValueProvider.ProviderName, + TenantSettingValueProvider.ProviderName), + new SettingDefinition( + name: AbpFileManagementSettingNames.AllowFileExtensions, + defaultValue: AbpFileManagementSettingNames.DefaultAllowFileExtensions, + displayName: L("DisplayName:AllowFileExtensions"), + description: L("Description:AllowFileExtensions"), + isVisibleToClients: true) + .WithProviders( + GlobalSettingValueProvider.ProviderName, + TenantSettingValueProvider.ProviderName), + }; + } + + protected LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN.Abp.FileManagement.HttpApi.csproj b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN.Abp.FileManagement.HttpApi.csproj new file mode 100644 index 000000000..c2849e212 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN.Abp.FileManagement.HttpApi.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/AbpFileManagementHttpApiModule.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/AbpFileManagementHttpApiModule.cs new file mode 100644 index 000000000..f8d61cf03 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/AbpFileManagementHttpApiModule.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.FileManagement +{ + [DependsOn( + typeof(AbpFileManagementApplicationContractsModule), + typeof(AbpAspNetCoreMvcModule) + )] + public class AbpFileManagementHttpApiModule : AbpModule + { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpFileManagementHttpApiModule).Assembly); + }); + } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs new file mode 100644 index 000000000..52f242ca3 --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs @@ -0,0 +1,240 @@ +using LINGYUN.Abp.FileManagement.Settings; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.StaticFiles; +using System; +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.IO; +using Volo.Abp.Settings; + +namespace LINGYUN.Abp.FileManagement +{ + [Controller] + [RemoteService(Name = "AbpFileManagement")] + [Area("file-management")] + [Route("api/file-management/file-system")] + public class FileSystemController : AbpController + { + protected ISettingProvider SettingProvider { get; } + protected IFileSystemAppService FileSystemAppService { get; } + + public FileSystemController( + ISettingProvider settingProvider, + IFileSystemAppService fileSystemAppService) + { + SettingProvider = settingProvider; + FileSystemAppService = fileSystemAppService; + } + + [HttpPut] + [Route("files/copy")] + public virtual async Task CopyFileAsync(FileCopyOrMoveDto input) + { + await FileSystemAppService.CopyFileAsync(input); + } + + [HttpPut] + [Route("folders/copy")] + public virtual async Task CopyFolderAsync([Required, StringLength(255)] string path, FolderCopyDto input) + { + await FileSystemAppService.CopyFolderAsync(path, input); + } + + [HttpPost] + [Route("files/upload")] + public virtual async Task CreateFileAsync(FileCreateDto input) + { + // 检查文件大小 + var fileSizeLimited = await SettingProvider + .GetAsync( + AbpFileManagementSettingNames.FileLimitLength, + AbpFileManagementSettingNames.DefaultFileLimitLength); + if (fileSizeLimited * 1024 * 1024 < input.TotalByte) + { + throw new UserFriendlyException(L["UploadFileSizeBeyondLimit", fileSizeLimited]); + } + // 采用分块模式上传文件 + + // 保存分块到临时目录 + var fileName = input.Name; + // 文件扩展名 + var fileExtensionName = FileHelper.GetExtension(fileName); + var fileAllowExtension = await SettingProvider + .GetOrNullAsync(AbpFileManagementSettingNames.AllowFileExtensions); + if (fileAllowExtension.IsNullOrWhiteSpace()) + { + fileAllowExtension = AbpFileManagementSettingNames.DefaultAllowFileExtensions; + } + // 检查文件扩展名 + if (!fileAllowExtension.Split(',') + .Any(fe => fe.Equals(fileExtensionName, StringComparison.CurrentCultureIgnoreCase))) + { + throw new UserFriendlyException(L["NotAllowedFileExtensionName", fileExtensionName]); + } + // 当前计算机临时目录 + var tempFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Templates); + // 以上传的文件名创建一个临时目录 + tempFilePath = Path.Combine(tempFilePath, "lingyun-abp-file-management", Path.GetFileNameWithoutExtension(fileName)); + // 以上传的分片索引创建临时文件 + var tempSavedFile = Path.Combine(tempFilePath, $"{input.CurrentByte}.{fileExtensionName}"); + if (!Directory.Exists(tempFilePath)) + { + // 临时目录不存在则创建 + Directory.CreateDirectory(tempFilePath); + } + try + { + if (HttpContext.RequestAborted.IsCancellationRequested) + { + // 如果取消请求,删除临时目录 + Directory.Delete(tempFilePath, true); + return; + } + // 保存临时文件 + using (var fs = new FileStream(tempSavedFile, FileMode.Create, FileAccess.Write)) + { + // 写入当前分片文件 + await Request.Body.CopyToAsync(fs); + } + + if (input.CurrentByte == input.TotalByte) + { + // 合并文件 + var mergeSavedFile = Path.Combine(tempFilePath, $"{fileName}"); + // 获取并排序所有分片文件 + var mergeFiles = Directory.GetFiles(tempFilePath).OrderBy(f => f.Length).ThenBy(f => f); + // 创建临时合并文件 + using (var mergeSavedFileStream = new FileStream(mergeSavedFile, FileMode.Create)) + { + foreach (var mergeFile in mergeFiles) + { + // 读取当前文件字节 + var mergeFileBytes = await FileHelper.ReadAllBytesAsync(mergeFile); + // 写入到合并文件流 + await mergeSavedFileStream.WriteAsync(mergeFileBytes, 0, mergeFileBytes.Length); + // 删除已参与合并的临时文件分片 + FileHelper.DeleteIfExists(mergeFile); + } + // 读取文件数据 + var fileData = await mergeSavedFileStream.GetAllBytesAsync(); + input.Data = fileData; + } + await FileSystemAppService.CreateFileAsync(input); + // 文件保存之后删除临时文件目录 + Directory.Delete(tempFilePath, true); + } + } + catch + { + // 发生异常删除临时文件目录 + Directory.Delete(tempFilePath, true); + throw; + } + } + + [HttpPost] + [Route("folders/add")] + public virtual async Task CreateFolderAsync(FolderCreateDto input) + { + await FileSystemAppService.CreateFolderAsync(input); + } + + [HttpDelete] + [Route("files/delete")] + public virtual async Task DeleteFileAsync(FileDeleteDto input) + { + await FileSystemAppService.DeleteFileAsync(input); + } + + [HttpDelete] + [Route("folders/delete")] + public virtual async Task DeleteFolderAsync([Required, StringLength(255)] string path) + { + await FileSystemAppService.DeleteFolderAsync(path); + } + + [HttpGet] + [Route("files/download")] + public virtual async Task DownloadFileAsync(FileSystemGetDto input) + { + var fileStream = await FileSystemAppService.DownloadFileAsync(input); + + // 得到文件扩展名 + var fileExt = Path.GetExtension(input.Name); + var provider = new FileExtensionContentTypeProvider(); + // Http响应标头的文件类型 + string memi = provider.Mappings[fileExt]; + using (Response.Body) + { + // Http响应标头的文件类型 + Response.ContentType = memi; + // 文件大小 + byte[] contentBytes = await fileStream.GetAllBytesAsync(); + long contentLength = contentBytes.Length; + // 指定响应内容大小 + Response.ContentLength = contentLength; + // 单个分块大小 2MB + int bufferSize = 2 * 1024 * 1024; + // 分块总数 + int contentByteCount = Math.DivRem(contentBytes.Length, bufferSize, out int modResult); + for (int index = 0; index < contentByteCount; index++) + { + // 当前分页传输字节 + byte[] currentTransferBytes = new byte[bufferSize]; + if (index == contentByteCount - 1) + { + // 最后一个分块和余数大小一起传输 + if (modResult > 0) + { + currentTransferBytes = new byte[bufferSize + modResult]; + } + } + // 复制文件流中的当前分块区段 + Array.Copy(contentBytes, index * bufferSize, currentTransferBytes, 0, currentTransferBytes.Length); + // 写入响应流 + await Response.Body.WriteAsync(currentTransferBytes, 0, currentTransferBytes.Length); + // 清空缓冲区 + await Response.Body.FlushAsync(); + } + } + } + + [HttpGet] + [Route("profile")] + public virtual async Task GetAsync(FileSystemGetDto input) + { + return await FileSystemAppService.GetAsync(input); + } + + [HttpGet] + public virtual async Task> GetListAsync(GetFileSystemListDto input) + { + return await FileSystemAppService.GetListAsync(input); + } + + [HttpPut] + [Route("files/move")] + public virtual async Task MoveFileAsync(FileCopyOrMoveDto input) + { + await FileSystemAppService.MoveFileAsync(input); + } + + [HttpPut] + [Route("folders/move")] + public virtual async Task MoveFolderAsync([Required, StringLength(255)] string path, FolderMoveDto input) + { + await FileSystemAppService.MoveFolderAsync(path, input); + } + + [HttpPut] + public virtual async Task UpdateAsync([Required, StringLength(255)] string name, FileSystemUpdateDto input) + { + return await FileSystemAppService.UpdateAsync(name, input); + } + } +} diff --git a/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDomainModule.cs b/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDomainModule.cs index c68379d0a..b4a3786b1 100644 --- a/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDomainModule.cs +++ b/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/AppPlatformDomainModule.cs @@ -41,6 +41,8 @@ namespace LINGYUN.Platform options.EtoMappings.Add(typeof(AppPlatformDomainModule)); options.EtoMappings.Add(typeof(AppPlatformDomainModule)); + + options.AutoEventSelectors.Add(); }); } public override void PostConfigureServices(ServiceConfigurationContext context) diff --git a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/AbpTenantManagementApplicationModule.cs b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/AbpTenantManagementApplicationModule.cs index 4dfbb6b9b..2a247a936 100644 --- a/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/AbpTenantManagementApplicationModule.cs +++ b/aspnet-core/modules/tenants/LINGYUN.Abp.TenantManagement.Application/LINGYUN/Abp/TenantManagement/AbpTenantManagementApplicationModule.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; +using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Modularity; using Volo.Abp.TenantManagement; @@ -17,6 +18,11 @@ namespace LINGYUN.Abp.TenantManagement { options.AddProfile(validate: true); }); + + Configure(options => + { + options.AutoEventSelectors.Add(); + }); } } } diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs index bccd24c78..5fb3e6d81 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs @@ -3,6 +3,7 @@ using IdentityModel; using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.FileManagement; using LINGYUN.Abp.Notifications; using LINGYUN.Platform.EntityFrameworkCore; using LINGYUN.Platform.HttpApi; @@ -40,6 +41,8 @@ using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Platform { [DependsOn( + typeof(AbpFileManagementApplicationModule), + typeof(AbpFileManagementHttpApiModule), typeof(AppPlatformApplicationModule), typeof(AppPlatformHttpApiModule), typeof(AppPlatformEntityFrameworkCoreModule), diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj index 9b89562f0..c24fefacc 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/LINGYUN.Platform.HttpApi.Host.csproj @@ -42,6 +42,8 @@ + + diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Aliyun.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Aliyun.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs index 47562c6a3..2df7073c4 100644 --- a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Aliyun.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Aliyun.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs @@ -1,5 +1,8 @@ -namespace LINGYUN.Abp.BlobStoring.TestObjects +using Volo.Abp.BlobStoring; + +namespace LINGYUN.Abp.BlobStoring.TestObjects { + [BlobContainerName("abp-blob-storing-test-container")] public class TestContainer1 { } From 2ca2897cd0abb3e3d30091cfc3e92cf3f07f5cdd Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Fri, 7 Aug 2020 22:09:53 +0800 Subject: [PATCH 2/3] add file-management view --- .../Abp/FileManagement/FileSystemDto.cs | 1 + .../FileManagement/FileSystemAppService.cs | 60 ++++- .../FileManagement/FileSystemController.cs | 10 +- .../PlatformPermissionDefinitionProvider.cs | 26 +-- .../BackendAdminHostModule.cs | 2 + .../LINGYUN.BackendAdminApp.Host.csproj | 1 + vueJs/src/api/clients.ts | 1 - vueJs/src/api/filemanagement.ts | 103 ++++++++ vueJs/src/lang/zh.ts | 14 +- vueJs/src/router/index.ts | 3 +- vueJs/src/router/modules/file-management.ts | 27 +++ vueJs/src/views/file-management/index.vue | 220 ++++++++++++++++++ 12 files changed, 436 insertions(+), 32 deletions(-) create mode 100644 vueJs/src/api/filemanagement.ts create mode 100644 vueJs/src/router/modules/file-management.ts create mode 100644 vueJs/src/views/file-management/index.vue diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs index 5efdebc45..aecbd0be0 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDto.cs @@ -7,6 +7,7 @@ namespace LINGYUN.Abp.FileManagement public FileSystemType Type { get; set; } public string Name { get; set; } public string Parent { get; set; } + public string Extension { get; set; } public long? Size { get; set; } public DateTime CreationTime { get; set; } public DateTime? LastModificationTime { get; set; } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs index 1d2c82838..68e3b603c 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs @@ -142,12 +142,13 @@ namespace LINGYUN.Abp.FileManagement Type = FileSystemType.File, Name = fileInfo.Name, Size = fileInfo.Length, + Extension = fileInfo.Extension, CreationTime = fileInfo.CreationTime, LastModificationTime = fileInfo.LastWriteTime }; - if (fileInfo.Directory?.Parent != null && !fileInfo.Directory.Parent.Name.IsNullOrWhiteSpace()) + if (fileInfo.Directory != null && !fileInfo.Directory.FullName.IsNullOrWhiteSpace()) { - fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.Parent.FullName); + fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.FullName); } return Task.FromResult(fileSystem); } @@ -161,7 +162,7 @@ namespace LINGYUN.Abp.FileManagement CreationTime = directoryInfo.CreationTime, LastModificationTime = directoryInfo.LastWriteTime }; - if (directoryInfo.Parent != null && !directoryInfo.Parent.Name.IsNullOrWhiteSpace()) + if (directoryInfo.Parent != null && !directoryInfo.Parent.FullName.IsNullOrWhiteSpace()) { fileSystem.Parent = GetFileSystemRelativePath(directoryInfo.Parent.FullName); } @@ -207,19 +208,21 @@ namespace LINGYUN.Abp.FileManagement CreationTime = fileSystemInfo.CreationTime, LastModificationTime = fileSystemInfo.LastWriteTime, }; + if (fileSystemInfo is FileInfo fileInfo) { fileSystem.Type = FileSystemType.File; fileSystem.Size = fileInfo.Length; - if (fileInfo.Directory?.Parent != null && !fileInfo.Directory.Parent.Name.IsNullOrWhiteSpace()) + fileSystem.Extension = fileInfo.Extension; + if (fileInfo.Directory != null && !fileInfo.Directory.FullName.IsNullOrWhiteSpace()) { - fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.Parent.FullName); + fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.FullName); } } else if (fileSystemInfo is DirectoryInfo directory) { fileSystem.Type = FileSystemType.Folder; - if (directory.Parent != null && !directory.Parent.Name.IsNullOrWhiteSpace()) + if (directory.Parent != null && !directory.Parent.FullName.IsNullOrWhiteSpace()) { fileSystem.Parent = GetFileSystemRelativePath(directory.Parent.FullName); } @@ -227,6 +230,11 @@ namespace LINGYUN.Abp.FileManagement fileSystems.Add(fileSystem); } + fileSystems = fileSystems + .OrderBy(f => f.Type) + .ThenBy(f => f.Name) + .ToList(); + return Task.FromResult(new PagedResultDto( fileSystemInfos.Length, fileSystems )); @@ -288,12 +296,13 @@ namespace LINGYUN.Abp.FileManagement Type = FileSystemType.File, Name = fileInfo.Name, Size = fileInfo.Length, + Extension = fileInfo.Extension, CreationTime = fileInfo.CreationTime, LastModificationTime = fileInfo.LastWriteTime }; - if (fileInfo.Directory?.Parent != null && !fileInfo.Directory.Parent.Name.IsNullOrWhiteSpace()) + if (fileInfo.Directory != null && !fileInfo.Directory.FullName.IsNullOrWhiteSpace()) { - fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.Parent.FullName); + fileSystem.Parent = GetFileSystemRelativePath(fileInfo.Directory.FullName); } return Task.FromResult(fileSystem); } @@ -314,7 +323,7 @@ namespace LINGYUN.Abp.FileManagement CreationTime = directoryInfo.CreationTime, LastModificationTime = directoryInfo.LastWriteTime }; - if (directoryInfo.Parent != null && !directoryInfo.Parent.Name.IsNullOrWhiteSpace()) + if (directoryInfo.Parent != null && !directoryInfo.Parent.FullName.IsNullOrWhiteSpace()) { fileSystem.Parent = GetFileSystemRelativePath(directoryInfo.Parent.FullName); } @@ -322,10 +331,31 @@ namespace LINGYUN.Abp.FileManagement } throw new UserFriendlyException("文件或目录不存在!"); } - + /// + /// 获取文件系统相对路径 + /// + /// + /// protected virtual string GetFileSystemRelativePath(string path) { - return path.Replace(Directory.GetCurrentDirectory(), ""); + // 去除完整路径中的文件系统根目录 + var fileSystemConfiguration = GetFileSystemBlobProviderConfiguration(); + var blobPath = fileSystemConfiguration.BasePath; + path = path.Replace(blobPath, ""); + // 去除租户或宿主目录 + if (CurrentTenant.Id == null) + { + path = path.Replace("\\host", ""); + } + else + { + path = path.Replace($"\\tenants\\{CurrentTenant.Id.Value.ToString("D")}", ""); + } + // 去除完整路径中的容器根目录 + var containerName = BlobContainerNameAttribute.GetContainerName(); + path = path.Replace($"\\{containerName}", ""); + + return path; } protected virtual string GetFileSystemPath(string path) @@ -354,6 +384,14 @@ namespace LINGYUN.Abp.FileManagement { blobPath = Path.Combine(blobPath, "tenants", CurrentTenant.Id.Value.ToString("D")); } + var containerName = BlobContainerNameAttribute.GetContainerName(); + + blobPath = Path.Combine(blobPath, containerName); + + if (!Directory.Exists(blobPath)) + { + Directory.CreateDirectory(blobPath); + } return blobPath; } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs index 52f242ca3..de8205cf7 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs @@ -46,7 +46,7 @@ namespace LINGYUN.Abp.FileManagement } [HttpPost] - [Route("files/upload")] + [Route("files")] public virtual async Task CreateFileAsync(FileCreateDto input) { // 检查文件大小 @@ -138,28 +138,28 @@ namespace LINGYUN.Abp.FileManagement } [HttpPost] - [Route("folders/add")] + [Route("folders")] public virtual async Task CreateFolderAsync(FolderCreateDto input) { await FileSystemAppService.CreateFolderAsync(input); } [HttpDelete] - [Route("files/delete")] + [Route("files")] public virtual async Task DeleteFileAsync(FileDeleteDto input) { await FileSystemAppService.DeleteFileAsync(input); } [HttpDelete] - [Route("folders/delete")] + [Route("folders")] public virtual async Task DeleteFolderAsync([Required, StringLength(255)] string path) { await FileSystemAppService.DeleteFolderAsync(path); } [HttpGet] - [Route("files/download")] + [Route("files")] public virtual async Task DownloadFileAsync(FileSystemGetDto input) { var fileStream = await FileSystemAppService.DownloadFileAsync(input); diff --git a/aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissionDefinitionProvider.cs b/aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissionDefinitionProvider.cs index 7a06e6b78..5a8448fa3 100644 --- a/aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissionDefinitionProvider.cs +++ b/aspnet-core/modules/platform/LINGYUN.Platform.Application.Contracts/LINGYUN/Platform/Permissions/PlatformPermissionDefinitionProvider.cs @@ -21,20 +21,20 @@ namespace LINGYUN.Platform.Permissions // TODO: 2020-07-27 目前abp不支持对象存储管理(或者属于企业版?)需要创建一个 LINGYUN.Abp.BlobStoring 项目自行实现 - var fileSystem = platform.AddPermission(PlatformPermissions.FileSystem.Default, L("Permission:FileSystem")); - fileSystem.AddChild(PlatformPermissions.FileSystem.Create, L("Permission:CreateFolder")); - fileSystem.AddChild(PlatformPermissions.FileSystem.Delete, L("Permission:DeleteFolder")); - fileSystem.AddChild(PlatformPermissions.FileSystem.Rename, L("Permission:RenameFolder")); - fileSystem.AddChild(PlatformPermissions.FileSystem.Copy, L("Permission:CopyFolder")); - fileSystem.AddChild(PlatformPermissions.FileSystem.Move, L("Permission:MoveFolder")); + //var fileSystem = platform.AddPermission(PlatformPermissions.FileSystem.Default, L("Permission:FileSystem")); + //fileSystem.AddChild(PlatformPermissions.FileSystem.Create, L("Permission:CreateFolder")); + //fileSystem.AddChild(PlatformPermissions.FileSystem.Delete, L("Permission:DeleteFolder")); + //fileSystem.AddChild(PlatformPermissions.FileSystem.Rename, L("Permission:RenameFolder")); + //fileSystem.AddChild(PlatformPermissions.FileSystem.Copy, L("Permission:CopyFolder")); + //fileSystem.AddChild(PlatformPermissions.FileSystem.Move, L("Permission:MoveFolder")); - var fileManager = fileSystem.AddChild(PlatformPermissions.FileSystem.FileManager.Default, L("Permission:FileManager")); - fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Create, L("Permission:AppendFile")); - fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Update, L("Permission:UpdateFile")); - fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Delete, L("Permission:DeleteFile")); - fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Copy, L("Permission:CopyFile")); - fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Move, L("Permission:MoveFile")); - fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Download, L("Permission:DownloadFile")); + //var fileManager = fileSystem.AddChild(PlatformPermissions.FileSystem.FileManager.Default, L("Permission:FileManager")); + //fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Create, L("Permission:AppendFile")); + //fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Update, L("Permission:UpdateFile")); + //fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Delete, L("Permission:DeleteFile")); + //fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Copy, L("Permission:CopyFile")); + //fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Move, L("Permission:MoveFile")); + //fileManager.AddChild(PlatformPermissions.FileSystem.FileManager.Download, L("Permission:DownloadFile")); } private static LocalizableString L(string name) diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs index 58cde89b4..931a5b941 100644 --- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs +++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs @@ -3,6 +3,7 @@ using IdentityModel; using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling.Emailing; +using LINGYUN.Abp.FileManagement; using LINGYUN.Abp.Location.Tencent; using LINGYUN.Abp.MessageService; using LINGYUN.Abp.SettingManagement; @@ -59,6 +60,7 @@ namespace LINGYUN.BackendAdmin typeof(AbpPermissionManagementDomainIdentityServerModule), typeof(AppPlatformApplicationContractModule), typeof(ApiGatewayApplicationContractsModule), + typeof(AbpFileManagementApplicationContractsModule), typeof(AbpMessageServiceApplicationContractsModule), typeof(LINGYUN.Abp.Identity.AbpIdentityHttpApiModule), typeof(LINGYUN.Abp.Identity.AbpIdentityApplicationModule), diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj index b04ea5122..cc8830e45 100644 --- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj +++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/LINGYUN.BackendAdminApp.Host.csproj @@ -62,6 +62,7 @@ + diff --git a/vueJs/src/api/clients.ts b/vueJs/src/api/clients.ts index bd29d5e40..ba27d5dc8 100644 --- a/vueJs/src/api/clients.ts +++ b/vueJs/src/api/clients.ts @@ -1,4 +1,3 @@ - import ApiService from './serviceBase' import { pagerFormat } from '@/utils/index' import { FullAuditedEntityDto, PagedAndSortedResultRequestDto, PagedResultDto } from './types' diff --git a/vueJs/src/api/filemanagement.ts b/vueJs/src/api/filemanagement.ts new file mode 100644 index 000000000..83a38a4a3 --- /dev/null +++ b/vueJs/src/api/filemanagement.ts @@ -0,0 +1,103 @@ +import ApiService from './serviceBase' +import { PagedAndSortedResultRequestDto, PagedResultDto } from './types' + +const serviceUrl = process.env.VUE_APP_BASE_API +const baseUrl = '/api/file-management/file-system' +export const FileManagementUrl = serviceUrl + baseUrl + +export default class FileManagementService { + public static getFileSystem(name: string, path: string | undefined) { + let _url = baseUrl + '?name=' + name + if (path) { + _url += '&path=' + path + } + return ApiService.Get(_url, serviceUrl) + } + + public static getFileSystemList(payload: FileSystemGetByPaged) { + let _url = baseUrl + '?skipCount=' + payload.skipCount + _url += '&maxResultCount=' + payload.maxResultCount + _url += '&sorting=' + payload.sorting + if (payload.filter) { + _url += '&filter=' + payload.filter + } + if (payload.parent) { + _url += '&parent=' + payload.parent + } + return ApiService.Get>(_url, serviceUrl) + } + + public static editFileSystem(name: string, newName: string) { + const _payload = { newName } + return ApiService.Put(baseUrl, _payload, serviceUrl) + } + + public static createFolder(path: string, parent: string | undefined) { + const _url = baseUrl + '/folders' + const _payload = { + path, + parent + } + return ApiService.Post(_url, _payload, serviceUrl) + } + + public static deleteFolder(path: string) { + const _url = baseUrl + '/folders?path=' + path + return ApiService.Delete(_url, serviceUrl) + } + + public static moveFolder(path: string, toPath: string) { + const _url = baseUrl + '/folders/move?path=' + path + const _payload = { toPath } + return ApiService.Put(_url, _payload, serviceUrl) + } + + public static copyFolder(path: string, toPath: string) { + const _url = baseUrl + '/folders/copy?path=' + path + const _payload = { toPath } + return ApiService.Put(_url, _payload, serviceUrl) + } + + public static deleteFile(path: string, name: string) { + let _url = baseUrl + '/files?path=' + path + _url += '&name=' + name + return ApiService.Delete(_url, serviceUrl) + } + + public static moveFile(payload: FileCopyOrMove) { + const _url = baseUrl + '/files/move' + return ApiService.Put(_url, payload, serviceUrl) + } + + public static copyFile(payload: FileCopyOrMove) { + const _url = baseUrl + '/files/copy' + return ApiService.Put(_url, payload, serviceUrl) + } +} + +export enum FileSystemType { + Folder = 0, + File = 1 +} + +export class FileSystem { + type!: FileSystemType + name!: string + parent?: string + size?: number + extension?: string + creationTime!: Date + lastModificationTime?: Date +} + +export class FileSystemGetByPaged extends PagedAndSortedResultRequestDto { + parent?: string + filter?: string +} + +export class FileCopyOrMove { + path!: string + name!: string + toPath!: string + toName?: string +} diff --git a/vueJs/src/lang/zh.ts b/vueJs/src/lang/zh.ts index 7ecdd356d..864e80807 100644 --- a/vueJs/src/lang/zh.ts +++ b/vueJs/src/lang/zh.ts @@ -78,7 +78,9 @@ export default { clients: '客户端管理', apiresources: 'Api资源管理', identityresources: '身份资源管理', - organizationUnit: '组织机构管理' + organizationUnit: '组织机构管理', + filemanagement: '文件管理', + filesystem: '文件系统' }, navbar: { logOut: '退出登录', @@ -617,5 +619,15 @@ export default { messages: { noNotifications: '没有通知', noMessages: '没有消息' + }, + fileSystem: { + name: '名称', + creationTime: '创建时间', + lastModificationTime: '修改时间', + type: '类型', + folder: '文件夹', + fileType: '{exten}文件', + size: '大小', + root: '根目录' } } diff --git a/vueJs/src/router/index.ts b/vueJs/src/router/index.ts index f7807af70..0022ac0e1 100644 --- a/vueJs/src/router/index.ts +++ b/vueJs/src/router/index.ts @@ -13,9 +13,9 @@ import taskRouter from './modules/task' import adminRouter from './modules/admin' import apigatewayRouter from './modules/apigateway' import identityServerRouter from './modules/identityServer' +import fileManagementRouter from './modules/file-management' Vue.use(Router) - /* Note: sub-menu only appear when children.length>=1 Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html @@ -128,6 +128,7 @@ export const asyncRoutes: RouteConfig[] = [ adminRouter, apigatewayRouter, identityServerRouter, + fileManagementRouter, { path: '*', component: () => import(/* webpackChunkName: "error-page-404" */ '@/views/error-page/404.vue'), diff --git a/vueJs/src/router/modules/file-management.ts b/vueJs/src/router/modules/file-management.ts new file mode 100644 index 000000000..1eab5151a --- /dev/null +++ b/vueJs/src/router/modules/file-management.ts @@ -0,0 +1,27 @@ +import { RouteConfig } from 'vue-router' +import Layout from '@/layout/index.vue' + +const fileManagementRouter: RouteConfig = { + path: '/file-management', + component: Layout, + meta: { + title: 'filemanagement', + icon: 'manager', + roles: ['Abp.FileManagement.FileSystem'], + alwaysShow: true + }, + children: [ + { + path: 'file-system', + component: () => import('@/views/file-management/index.vue'), + name: 'filesystem', + meta: { + title: 'filesystem', + icon: 'file-system', + roles: ['Abp.FileManagement.FileSystem'] + } + } + ] +} + +export default fileManagementRouter diff --git a/vueJs/src/views/file-management/index.vue b/vueJs/src/views/file-management/index.vue new file mode 100644 index 000000000..45fdfa78c --- /dev/null +++ b/vueJs/src/views/file-management/index.vue @@ -0,0 +1,220 @@ + + + + + From c325776b02c1405c8c80686947c64d94469582fb Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Tue, 11 Aug 2020 19:54:04 +0800 Subject: [PATCH 3/3] improve the file management module and add some icons --- aspnet-core/database/ApiGateway-Init.sql | 87 +++++- ...ileManagementApplicationContractsModule.cs | 1 + .../Abp/FileManagement/FileCopyOrMoveDto.cs | 1 - .../Abp/FileManagement/FileCreateDto.cs | 1 - .../Abp/FileManagement/FileDeleteDto.cs | 1 - .../FileManagement/FileSystemDownloadDto.cs | 15 + .../Abp/FileManagement/FileSystemGetDto.cs | 1 - .../AbpFileManagementPermissions.cs | 2 +- .../FileManagement/FileSystemAppService.cs | 27 +- .../FileManagement/FileSystemController.cs | 99 ++++--- .../BackendAdminHostModule.cs | 10 + .../AppPlatformHttpApiHostModule.cs | 11 + vueJs/src/App.vue | 4 +- vueJs/src/api/filemanagement.ts | 13 + vueJs/src/api/users.ts | 7 +- vueJs/src/components/LangSelect/index.vue | 33 +-- vueJs/src/icons/components/404.ts | 2 +- vueJs/src/icons/components/admin.ts | 12 + vueJs/src/icons/components/aggregate.ts | 12 + vueJs/src/icons/components/api-gateway.ts | 12 + vueJs/src/icons/components/api.ts | 12 + vueJs/src/icons/components/back-top.ts | 2 +- vueJs/src/icons/components/bug.ts | 2 +- vueJs/src/icons/components/client.ts | 12 + vueJs/src/icons/components/clipboard.ts | 2 +- vueJs/src/icons/components/component.ts | 2 +- vueJs/src/icons/components/dashboard.ts | 2 +- vueJs/src/icons/components/edit.ts | 2 +- vueJs/src/icons/components/email.ts | 2 +- vueJs/src/icons/components/example.ts | 2 +- vueJs/src/icons/components/exit-fullscreen.ts | 2 +- vueJs/src/icons/components/eye-off.ts | 2 +- vueJs/src/icons/components/file-manager.ts | 12 + vueJs/src/icons/components/file-storage.ts | 12 + vueJs/src/icons/components/file.ts | 12 + vueJs/src/icons/components/folder.ts | 12 + vueJs/src/icons/components/form.ts | 2 +- vueJs/src/icons/components/global-setting.ts | 12 + vueJs/src/icons/components/group.ts | 12 + vueJs/src/icons/components/guide-2.ts | 2 +- vueJs/src/icons/components/hamburger.ts | 2 +- vueJs/src/icons/components/icon.ts | 2 +- vueJs/src/icons/components/identity-server.ts | 12 + vueJs/src/icons/components/identity.ts | 12 + vueJs/src/icons/components/index.ts | 20 +- vueJs/src/icons/components/international.ts | 2 +- vueJs/src/icons/components/language.ts | 2 +- vueJs/src/icons/components/like.ts | 2 +- vueJs/src/icons/components/manager.ts | 4 +- vueJs/src/icons/components/nested.ts | 2 +- .../src/icons/components/organization-unit.ts | 12 + vueJs/src/icons/components/pdf.ts | 2 +- vueJs/src/icons/components/people.ts | 2 +- vueJs/src/icons/components/peoples.ts | 2 +- vueJs/src/icons/components/role.ts | 4 +- vueJs/src/icons/components/route.ts | 12 + vueJs/src/icons/components/search.ts | 2 +- vueJs/src/icons/components/shopping.ts | 2 +- vueJs/src/icons/components/skill.ts | 2 +- vueJs/src/icons/components/star.ts | 2 +- vueJs/src/icons/components/tab.ts | 2 +- vueJs/src/icons/components/tenant.ts | 12 + vueJs/src/icons/components/theme.ts | 2 +- vueJs/src/icons/components/tree.ts | 2 +- vueJs/src/icons/components/wechat.ts | 2 +- vueJs/src/icons/components/zip.ts | 2 +- vueJs/src/icons/svg/admin.svg | 1 + vueJs/src/icons/svg/aggregate.svg | 1 + vueJs/src/icons/svg/api-gateway.svg | 1 + vueJs/src/icons/svg/api.svg | 1 + vueJs/src/icons/svg/client.svg | 1 + vueJs/src/icons/svg/file-manager.svg | 1 + vueJs/src/icons/svg/file-storage.svg | 1 + vueJs/src/icons/svg/file.svg | 1 + vueJs/src/icons/svg/folder.svg | 1 + vueJs/src/icons/svg/global-setting.svg | 1 + vueJs/src/icons/svg/group.svg | 1 + vueJs/src/icons/svg/identity-server.svg | 124 ++++++++ vueJs/src/icons/svg/identity.svg | 1 + vueJs/src/icons/svg/organization-unit.svg | 1 + vueJs/src/icons/svg/route.svg | 1 + vueJs/src/icons/svg/tenant.svg | 1 + vueJs/src/lang/zh.ts | 10 +- vueJs/src/permission.ts | 1 - vueJs/src/router/modules/admin.ts | 6 +- vueJs/src/router/modules/apigateway.ts | 6 +- vueJs/src/router/modules/file-management.ts | 8 +- vueJs/src/router/modules/identityServer.ts | 8 +- vueJs/src/store/index.ts | 4 +- vueJs/src/store/modules/abp.ts | 27 +- vueJs/src/store/modules/permission.ts | 4 +- vueJs/src/store/modules/user.ts | 13 +- vueJs/src/utils/request.ts | 69 +++-- .../settings/components/SettingEditForm.vue | 4 +- vueJs/src/views/admin/settings/index.vue | 7 +- vueJs/src/views/file-management/index.vue | 277 ++++++++++++++++-- vueJs/src/views/login/index.vue | 6 +- vueJs/src/views/register/index.vue | 4 +- vueJs/src/views/reset-password/index.vue | 4 +- 99 files changed, 950 insertions(+), 242 deletions(-) create mode 100644 aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDownloadDto.cs create mode 100644 vueJs/src/icons/components/admin.ts create mode 100644 vueJs/src/icons/components/aggregate.ts create mode 100644 vueJs/src/icons/components/api-gateway.ts create mode 100644 vueJs/src/icons/components/api.ts create mode 100644 vueJs/src/icons/components/client.ts create mode 100644 vueJs/src/icons/components/file-manager.ts create mode 100644 vueJs/src/icons/components/file-storage.ts create mode 100644 vueJs/src/icons/components/file.ts create mode 100644 vueJs/src/icons/components/folder.ts create mode 100644 vueJs/src/icons/components/global-setting.ts create mode 100644 vueJs/src/icons/components/group.ts create mode 100644 vueJs/src/icons/components/identity-server.ts create mode 100644 vueJs/src/icons/components/identity.ts create mode 100644 vueJs/src/icons/components/organization-unit.ts create mode 100644 vueJs/src/icons/components/route.ts create mode 100644 vueJs/src/icons/components/tenant.ts create mode 100644 vueJs/src/icons/svg/admin.svg create mode 100644 vueJs/src/icons/svg/aggregate.svg create mode 100644 vueJs/src/icons/svg/api-gateway.svg create mode 100644 vueJs/src/icons/svg/api.svg create mode 100644 vueJs/src/icons/svg/client.svg create mode 100644 vueJs/src/icons/svg/file-manager.svg create mode 100644 vueJs/src/icons/svg/file-storage.svg create mode 100644 vueJs/src/icons/svg/file.svg create mode 100644 vueJs/src/icons/svg/folder.svg create mode 100644 vueJs/src/icons/svg/global-setting.svg create mode 100644 vueJs/src/icons/svg/group.svg create mode 100644 vueJs/src/icons/svg/identity-server.svg create mode 100644 vueJs/src/icons/svg/identity.svg create mode 100644 vueJs/src/icons/svg/organization-unit.svg create mode 100644 vueJs/src/icons/svg/route.svg create mode 100644 vueJs/src/icons/svg/tenant.svg diff --git a/aspnet-core/database/ApiGateway-Init.sql b/aspnet-core/database/ApiGateway-Init.sql index 878518b50..18927c432 100644 --- a/aspnet-core/database/ApiGateway-Init.sql +++ b/aspnet-core/database/ApiGateway-Init.sql @@ -11,7 +11,7 @@ Target Server Version : 80020 File Encoding : 65001 - Date: 07/08/2020 08:04:44 + Date: 10/08/2020 09:45:50 */ SET NAMES utf8mb4; @@ -89,7 +89,7 @@ CREATE TABLE `appapigatewayauthoptions` ( PRIMARY KEY (`Id`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayAuthOptions_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewayAuthOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 114 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewayauthoptions @@ -174,6 +174,14 @@ INSERT INTO `appapigatewayauthoptions` VALUES (102, 1290849628051124224, '', '') INSERT INTO `appapigatewayauthoptions` VALUES (103, 1290849798553776128, '', ''); INSERT INTO `appapigatewayauthoptions` VALUES (104, 1290849978032238592, '', ''); INSERT INTO `appapigatewayauthoptions` VALUES (105, 1291259822512693248, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (106, 1292620505149145088, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (107, 1292620665505775616, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (108, 1292620843398791168, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (109, 1292621027574874112, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (110, 1292621363161137152, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (111, 1292621494837116928, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (112, 1292621629260365824, '', ''); +INSERT INTO `appapigatewayauthoptions` VALUES (113, 1292622526073864192, '', ''); -- ---------------------------- -- Table structure for appapigatewaybalanceroptions @@ -191,7 +199,7 @@ CREATE TABLE `appapigatewaybalanceroptions` ( UNIQUE INDEX `IX_AppApiGatewayBalancerOptions_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayGlobalConfiguratio~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayBalancerOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 117 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewaybalanceroptions @@ -277,6 +285,14 @@ INSERT INTO `appapigatewaybalanceroptions` VALUES (105, NULL, 129084962805112422 INSERT INTO `appapigatewaybalanceroptions` VALUES (106, NULL, 1290849798553776128, '', '', 0); INSERT INTO `appapigatewaybalanceroptions` VALUES (107, NULL, 1290849978032238592, '', '', 0); INSERT INTO `appapigatewaybalanceroptions` VALUES (108, NULL, 1291259822512693248, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (109, NULL, 1292620505149145088, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (110, NULL, 1292620665505775616, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (111, NULL, 1292620843398791168, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (112, NULL, 1292621027574874112, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (113, NULL, 1292621363161137152, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (114, NULL, 1292621494837116928, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (115, NULL, 1292621629260365824, '', '', 0); +INSERT INTO `appapigatewaybalanceroptions` VALUES (116, NULL, 1292622526073864192, '', '', 0); -- ---------------------------- -- Table structure for appapigatewaycacheoptions @@ -290,7 +306,7 @@ CREATE TABLE `appapigatewaycacheoptions` ( PRIMARY KEY (`Id`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayCacheOptions_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewayCacheOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 114 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewaycacheoptions @@ -375,6 +391,14 @@ INSERT INTO `appapigatewaycacheoptions` VALUES (102, 1290849628051124224, 0, '') INSERT INTO `appapigatewaycacheoptions` VALUES (103, 1290849798553776128, 0, ''); INSERT INTO `appapigatewaycacheoptions` VALUES (104, 1290849978032238592, 0, ''); INSERT INTO `appapigatewaycacheoptions` VALUES (105, 1291259822512693248, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (106, 1292620505149145088, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (107, 1292620665505775616, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (108, 1292620843398791168, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (109, 1292621027574874112, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (110, 1292621363161137152, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (111, 1292621494837116928, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (112, 1292621629260365824, 0, ''); +INSERT INTO `appapigatewaycacheoptions` VALUES (113, 1292622526073864192, 0, ''); -- ---------------------------- -- Table structure for appapigatewaydiscovery @@ -484,7 +508,7 @@ CREATE TABLE `appapigatewayhttpoptions` ( UNIQUE INDEX `IX_AppApiGatewayHttpOptions_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayGlobalConfiguration_It~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayHttpOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 117 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewayhttpoptions @@ -570,6 +594,14 @@ INSERT INTO `appapigatewayhttpoptions` VALUES (105, NULL, 1290849628051124224, 0 INSERT INTO `appapigatewayhttpoptions` VALUES (106, NULL, 1290849798553776128, 0, 0, 0, 0, 0); INSERT INTO `appapigatewayhttpoptions` VALUES (107, NULL, 1290849978032238592, 0, 0, 0, 0, 0); INSERT INTO `appapigatewayhttpoptions` VALUES (108, NULL, 1291259822512693248, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (109, NULL, 1292620505149145088, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (110, NULL, 1292620665505775616, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (111, NULL, 1292620843398791168, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (112, NULL, 1292621027574874112, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (113, NULL, 1292621363161137152, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (114, NULL, 1292621494837116928, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (115, NULL, 1292621629260365824, 0, 0, 0, 0, 0); +INSERT INTO `appapigatewayhttpoptions` VALUES (116, NULL, 1292622526073864192, 0, 0, 0, 0, 0); -- ---------------------------- -- Table structure for appapigatewayqosoptions @@ -587,7 +619,7 @@ CREATE TABLE `appapigatewayqosoptions` ( UNIQUE INDEX `IX_AppApiGatewayQoSOptions_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayGlobalConfiguration_Ite~` FOREIGN KEY (`ItemId`) REFERENCES `appapigatewayglobalconfiguration` (`ItemId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayQoSOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 117 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewayqosoptions @@ -673,6 +705,14 @@ INSERT INTO `appapigatewayqosoptions` VALUES (105, NULL, 1290849628051124224, 50 INSERT INTO `appapigatewayqosoptions` VALUES (106, NULL, 1290849798553776128, 50, 60000, 30000); INSERT INTO `appapigatewayqosoptions` VALUES (107, NULL, 1290849978032238592, 50, 60000, 30000); INSERT INTO `appapigatewayqosoptions` VALUES (108, NULL, 1291259822512693248, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (109, NULL, 1292620505149145088, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (110, NULL, 1292620665505775616, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (111, NULL, 1292620843398791168, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (112, NULL, 1292621027574874112, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (113, NULL, 1292621363161137152, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (114, NULL, 1292621494837116928, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (115, NULL, 1292621629260365824, 50, 60000, 30000); +INSERT INTO `appapigatewayqosoptions` VALUES (116, NULL, 1292622526073864192, 50, 60000, 30000); -- ---------------------------- -- Table structure for appapigatewayratelimitoptions @@ -714,7 +754,7 @@ CREATE TABLE `appapigatewayratelimitrule` ( UNIQUE INDEX `IX_AppApiGatewayRateLimitRule_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayDynamicReRoute_Dynam~` FOREIGN KEY (`DynamicReRouteId`) REFERENCES `appapigatewaydynamicreroute` (`DynamicReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT, CONSTRAINT `FK_AppApiGatewayRateLimitRule_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 114 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewayratelimitrule @@ -799,6 +839,14 @@ INSERT INTO `appapigatewayratelimitrule` VALUES (102, 1290849628051124224, NULL, INSERT INTO `appapigatewayratelimitrule` VALUES (103, 1290849798553776128, NULL, '', 0, NULL, NULL, NULL); INSERT INTO `appapigatewayratelimitrule` VALUES (104, 1290849978032238592, NULL, '', 0, NULL, NULL, NULL); INSERT INTO `appapigatewayratelimitrule` VALUES (105, 1291259822512693248, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (106, 1292620505149145088, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (107, 1292620665505775616, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (108, 1292620843398791168, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (109, 1292621027574874112, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (110, 1292621363161137152, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (111, 1292621494837116928, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (112, 1292621629260365824, NULL, '', 0, NULL, NULL, NULL); +INSERT INTO `appapigatewayratelimitrule` VALUES (113, 1292622526073864192, NULL, '', 0, NULL, NULL, NULL); -- ---------------------------- -- Table structure for appapigatewayreroute @@ -838,7 +886,7 @@ CREATE TABLE `appapigatewayreroute` ( PRIMARY KEY (`Id`) USING BTREE, UNIQUE INDEX `AK_AppApiGatewayReRoute_ReRouteId`(`ReRouteId`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewayReRoute_AppId_DownstreamPathTemplate_UpstreamPa~`(`AppId`, `DownstreamPathTemplate`, `UpstreamPathTemplate`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 113 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 121 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewayreroute @@ -923,6 +971,14 @@ INSERT INTO `appapigatewayreroute` VALUES (109, '{}', 'e937ff4ea11e4f0ca39d079c7 INSERT INTO `appapigatewayreroute` VALUES (110, '{}', '22212bc751b743678d9c2f095d05ce25', 1290849798553776128, '【平台服务】- 当前用户配置', '/api/settings/by-current-user', '', '', '/api/settings/by-current-user', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30010,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (111, '{}', '8dfa430d752a4b4a869ad401b3802a62', 1290849978032238592, '【平台服务】- 配置管理', '/api/settings', '', '', '/api/settings', 'GET,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30010,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); INSERT INTO `appapigatewayreroute` VALUES (112, '{}', '9844fed6507844f2ac64bd08649bd3a6', 1291259822512693248, '【身份认证服务】- 查询组织机构根节点', '/api/identity/organization-units/root-node', '', '', '/api/identity/organization-units/root-node', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30010,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (113, '{}', '24d8794cf8f943b4ac45d2bcccf7c128', 1292620505149145088, '【平台服务】- 文件系统', '/api/file-management/file-system', '', '', '/api/file-management/file-system', 'GET,PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (114, '{}', '0acf6762d3af43efb655107e0039f5fc', 1292620665505775616, '【平台服务】- 文件系统 - 目录管理', '/api/file-management/file-system/folders', '', '', '/api/file-management/file-system/folders', 'POST,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (115, '{}', '5442138c816542bbb8b2c7fa51f10a5f', 1292620843398791168, '【平台服务】- 文件系统 - 文件管理', '/api/file-management/file-system/files', '', '', '/api/file-management/file-system/files', 'GET,POST,DELETE,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (116, '{}', '7eb315567bbc470bbbfd26923c5d0aba', 1292621027574874112, '【平台服务】- 文件系统 - 复制目录', '/api/file-management/file-system/folders/copy', '', '', '/api/file-management/file-system/folders/copy', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (117, '{}', 'af5853680cff454fa66ff6022f18da23', 1292621363161137152, '【平台服务】- 文件系统 - 移动目录', '/api/file-management/file-system/folders/move', '', '', '/api/file-management/file-system/folders/move', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (118, '{}', '6daa6d8c8adb466899988fd8181c29a8', 1292621494837116928, '【平台服务】- 文件系统 - 复制文件', '/api/file-management/file-system/files/copy', '', '', '/api/file-management/file-system/files/copy', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (119, '{}', '9560caaa3bd9424984c44724aa54bfe9', 1292621629260365824, '【平台服务】- 文件系统 - 移动文件', '/api/file-management/file-system/files/move', '', '', '/api/file-management/file-system/files/move', 'PUT,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); +INSERT INTO `appapigatewayreroute` VALUES (120, '{}', 'fc2aaa6035484201b9014912930fb7cb', 1292622526073864192, '【平台服务】- 文件系统 - 详情页', '/api/file-management/file-system/profile', '', '', '/api/file-management/file-system/profile', 'GET,', '', '', '', '', '', '', '', 1, '', '', 'HTTP', '127.0.0.1:30025,', '', '', '', 0, 30000, 1, '', 'TEST-APP'); -- ---------------------------- -- Table structure for appapigatewayroutegroup @@ -966,7 +1022,7 @@ CREATE TABLE `appapigatewaysecurityoptions` ( PRIMARY KEY (`Id`) USING BTREE, UNIQUE INDEX `IX_AppApiGatewaySecurityOptions_ReRouteId`(`ReRouteId`) USING BTREE, CONSTRAINT `FK_AppApiGatewaySecurityOptions_AppApiGatewayReRoute_ReRouteId` FOREIGN KEY (`ReRouteId`) REFERENCES `appapigatewayreroute` (`ReRouteId`) ON DELETE CASCADE ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 114 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of appapigatewaysecurityoptions @@ -1051,6 +1107,14 @@ INSERT INTO `appapigatewaysecurityoptions` VALUES (102, 1290849628051124224, '', INSERT INTO `appapigatewaysecurityoptions` VALUES (103, 1290849798553776128, '', ''); INSERT INTO `appapigatewaysecurityoptions` VALUES (104, 1290849978032238592, '', ''); INSERT INTO `appapigatewaysecurityoptions` VALUES (105, 1291259822512693248, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (106, 1292620505149145088, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (107, 1292620665505775616, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (108, 1292620843398791168, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (109, 1292621027574874112, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (110, 1292621363161137152, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (111, 1292621494837116928, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (112, 1292621629260365824, '', ''); +INSERT INTO `appapigatewaysecurityoptions` VALUES (113, 1292622526073864192, '', ''); -- ---------------------------- -- Table structure for cap.published @@ -1069,11 +1133,6 @@ CREATE TABLE `cap.published` ( INDEX `IX_ExpiresAt`(`ExpiresAt`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; --- ---------------------------- --- Records of cap.published --- ---------------------------- -INSERT INTO `cap.published` VALUES (1291259823775178752, 'v1', 'LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData', '{\"Headers\":{\"cap-callback-name\":null,\"cap-msg-id\":\"1291259823775178752\",\"cap-msg-name\":\"LINGYUN.ApiGateway.EventBus.ApigatewayConfigChangeEventData\",\"cap-msg-type\":\"Object\",\"cap-senttime\":\"2020/8/6 14:28:27 +08:00\",\"cap-corr-id\":\"1291259823775178752\",\"cap-corr-seq\":\"0\"},\"Value\":{\"DateTime\":\"2020-08-06T14:28:27.0879956+08:00\",\"AppId\":\"TEST-APP\",\"Method\":\"Create\",\"Object\":\"ReRoute\"}}', 0, '2020-08-06 14:28:27', '2020-08-07 14:28:27', 'Succeeded'); - -- ---------------------------- -- Table structure for cap.received -- ---------------------------- diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs index 891ac26a2..b4a0cd686 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/AbpFileManagementApplicationContractsModule.cs @@ -4,6 +4,7 @@ using Volo.Abp.Modularity; namespace LINGYUN.Abp.FileManagement { [DependsOn( + typeof(AbpFileManagementDomainSharedModule), typeof(AbpDddApplicationModule))] public class AbpFileManagementApplicationContractsModule : AbpModule { diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs index bbda957fe..d399c5571 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCopyOrMoveDto.cs @@ -4,7 +4,6 @@ namespace LINGYUN.Abp.FileManagement { public class FileCopyOrMoveDto { - [Required] [StringLength(255)] public string Path { get; set; } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs index 5a5096e58..a0d87c28a 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileCreateDto.cs @@ -8,7 +8,6 @@ namespace LINGYUN.Abp.FileManagement /// /// 文件名 /// - [Required] [StringLength(255)] public string Name { get; set; } /// diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs index f74c4d823..a12f6ff3c 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileDeleteDto.cs @@ -4,7 +4,6 @@ namespace LINGYUN.Abp.FileManagement { public class FileDeleteDto { - [Required] [StringLength(255)] public string Path { get; set; } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDownloadDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDownloadDto.cs new file mode 100644 index 000000000..b421dda4a --- /dev/null +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemDownloadDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Text; + +namespace LINGYUN.Abp.FileManagement +{ + public class FileSystemDownloadDto : FileSystemGetDto + { + /// + /// 当前字节数 + /// + public int CurrentByte { get; set; } + } +} diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs index 421ae1803..8c9619ba6 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/FileSystemGetDto.cs @@ -4,7 +4,6 @@ namespace LINGYUN.Abp.FileManagement { public class FileSystemGetDto { - [Required] [StringLength(255)] public string Path { get; set; } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs index 0b415358f..6f33e940b 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application.Contracts/LINGYUN/Abp/FileManagement/Permissions/AbpFileManagementPermissions.cs @@ -2,7 +2,7 @@ { public class AbpFileManagementPermissions { - public const string GroupName = "Abp.FileManagement"; + public const string GroupName = "AbpFileManagement"; /// /// 文件系统 diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs index 68e3b603c..7a9fd2076 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.Application/LINGYUN/Abp/FileManagement/FileSystemAppService.cs @@ -126,7 +126,8 @@ namespace LINGYUN.Abp.FileManagement var fileSystemPath = GetFileSystemPath(input.Path); fileSystemPath = Path.Combine(fileSystemPath, input.Name); var blobName = GetFileSystemRelativePath(fileSystemPath); - + // 去除第一个路径标识符 + blobName = blobName.RemovePreFix("/", "\\"); return await BlobContainer.GetAsync(blobName); } @@ -181,10 +182,14 @@ namespace LINGYUN.Abp.FileManagement fileSystemPath = GetFileSystemPath(input.Parent); } var directoryInfo = new DirectoryInfo(fileSystemPath); - // 查询全部 + if (!directoryInfo.Exists) + { + return Task.FromResult(new PagedResultDto(0, fileSystems)); + } + // 查询全部文件系统 var fileSystemInfos = directoryInfo.GetFileSystemInfos(); // 指定搜索条件查询目录 - FileSystemInfo[] fileSystemInfoSearchChildren;// = directoryInfo.GetDirectories(input.Filter ?? "*", SearchOption.TopDirectoryOnly); + FileSystemInfo[] fileSystemInfoSearchChildren; if (!input.Filter.IsNullOrWhiteSpace()) { var searchPattern = $"*{input.Filter}*"; @@ -341,20 +346,22 @@ namespace LINGYUN.Abp.FileManagement // 去除完整路径中的文件系统根目录 var fileSystemConfiguration = GetFileSystemBlobProviderConfiguration(); var blobPath = fileSystemConfiguration.BasePath; - path = path.Replace(blobPath, ""); // 去除租户或宿主目录 if (CurrentTenant.Id == null) { - path = path.Replace("\\host", ""); + blobPath = Path.Combine(blobPath, "host"); } else { - path = path.Replace($"\\tenants\\{CurrentTenant.Id.Value.ToString("D")}", ""); + blobPath = Path.Combine(blobPath, "tenants", CurrentTenant.Id.Value.ToString("D")); } // 去除完整路径中的容器根目录 var containerName = BlobContainerNameAttribute.GetContainerName(); - path = path.Replace($"\\{containerName}", ""); - + if (path.Contains(containerName)) + { + blobPath = Path.Combine(blobPath, containerName); + } + path = path.Replace(blobPath, ""); return path; } @@ -363,8 +370,10 @@ namespace LINGYUN.Abp.FileManagement var fileSystemConfiguration = GetFileSystemBlobProviderConfiguration(); var blobPath = GetFileSystemBashPath(); - if (fileSystemConfiguration.AppendContainerNameToBasePath) + if (!path.IsNullOrWhiteSpace() && fileSystemConfiguration.AppendContainerNameToBasePath) { + // 去除第一个路径标识符 + path = path.RemovePreFix("/", "\\"); blobPath = Path.Combine(blobPath, path); } diff --git a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs index de8205cf7..8deebdb75 100644 --- a/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs +++ b/aspnet-core/modules/file-management/LINGYUN.Abp.FileManagement.HttpApi/LINGYUN/Abp/FileManagement/FileSystemController.cs @@ -1,4 +1,5 @@ using LINGYUN.Abp.FileManagement.Settings; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.StaticFiles; using System; @@ -47,7 +48,7 @@ namespace LINGYUN.Abp.FileManagement [HttpPost] [Route("files")] - public virtual async Task CreateFileAsync(FileCreateDto input) + public virtual async Task CreateFileAsync([FromQuery] FileCreateDto input, IFormFile file) { // 检查文件大小 var fileSizeLimited = await SettingProvider @@ -76,17 +77,15 @@ namespace LINGYUN.Abp.FileManagement { throw new UserFriendlyException(L["NotAllowedFileExtensionName", fileExtensionName]); } - // 当前计算机临时目录 - var tempFilePath = Environment.GetFolderPath(Environment.SpecialFolder.Templates); // 以上传的文件名创建一个临时目录 - tempFilePath = Path.Combine(tempFilePath, "lingyun-abp-file-management", Path.GetFileNameWithoutExtension(fileName)); + var tempFilePath = Path.Combine( + Path.GetTempPath(), + "lingyun-abp-file-management", + "upload", + string.Concat(input.Path ?? "", input.Name).ToMd5()); + DirectoryHelper.CreateIfNotExists(tempFilePath); // 以上传的分片索引创建临时文件 var tempSavedFile = Path.Combine(tempFilePath, $"{input.CurrentByte}.{fileExtensionName}"); - if (!Directory.Exists(tempFilePath)) - { - // 临时目录不存在则创建 - Directory.CreateDirectory(tempFilePath); - } try { if (HttpContext.RequestAborted.IsCancellationRequested) @@ -99,7 +98,7 @@ namespace LINGYUN.Abp.FileManagement using (var fs = new FileStream(tempSavedFile, FileMode.Create, FileAccess.Write)) { // 写入当前分片文件 - await Request.Body.CopyToAsync(fs); + await file.CopyToAsync(fs); } if (input.CurrentByte == input.TotalByte) @@ -160,46 +159,66 @@ namespace LINGYUN.Abp.FileManagement [HttpGet] [Route("files")] - public virtual async Task DownloadFileAsync(FileSystemGetDto input) + public virtual async Task DownloadFileAsync(FileSystemDownloadDto input) { - var fileStream = await FileSystemAppService.DownloadFileAsync(input); - - // 得到文件扩展名 - var fileExt = Path.GetExtension(input.Name); - var provider = new FileExtensionContentTypeProvider(); - // Http响应标头的文件类型 - string memi = provider.Mappings[fileExt]; - using (Response.Body) + var tempFileName = string.Concat(input.Path ?? "", input.Name); + tempFileName = tempFileName.ToMd5() + Path.GetExtension(input.Name); + // 以上传的文件名创建一个临时目录 + var tempFilePath = Path.Combine( + Path.GetTempPath(), + "lingyun-abp-file-management", + "download"); + DirectoryHelper.CreateIfNotExists(tempFilePath); + tempFilePath = Path.Combine(tempFilePath, tempFileName); + long contentLength = 0L; + // 单个分块大小 2MB + int bufferSize = 2 * 1024 * 1024; + using (new DisposeAction(() => + { + // 最终下载完毕后,删除临时文件 + if (bufferSize + input.CurrentByte > contentLength) + { + FileHelper.DeleteIfExists(tempFilePath); + } + })) { + if (!System.IO.File.Exists(tempFilePath)) + { + var blobStream = await FileSystemAppService.DownloadFileAsync(input); + using (var tempFileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write)) + { + blobStream.Position = 0; + await blobStream.CopyToAsync(tempFileStream); + } + } + // 读取缓存文件 + using var fileStream = new FileStream(tempFilePath, FileMode.Open, FileAccess.Read); + // 得到文件扩展名 + var fileExt = Path.GetExtension(input.Name); + var provider = new FileExtensionContentTypeProvider(); // Http响应标头的文件类型 - Response.ContentType = memi; + string memi = provider.Mappings[fileExt]; // 文件大小 - byte[] contentBytes = await fileStream.GetAllBytesAsync(); - long contentLength = contentBytes.Length; - // 指定响应内容大小 - Response.ContentLength = contentLength; - // 单个分块大小 2MB - int bufferSize = 2 * 1024 * 1024; - // 分块总数 - int contentByteCount = Math.DivRem(contentBytes.Length, bufferSize, out int modResult); - for (int index = 0; index < contentByteCount; index++) + contentLength = fileStream.Length; + if (bufferSize > contentLength) + { + var currentTransferBytes = await fileStream.GetAllBytesAsync(); + // 写入响应流 + return File(currentTransferBytes, memi, input.Name); + } + else { // 当前分页传输字节 byte[] currentTransferBytes = new byte[bufferSize]; - if (index == contentByteCount - 1) + if (input.CurrentByte + bufferSize >= contentLength) { - // 最后一个分块和余数大小一起传输 - if (modResult > 0) - { - currentTransferBytes = new byte[bufferSize + modResult]; - } + currentTransferBytes = new byte[contentLength - input.CurrentByte]; } - // 复制文件流中的当前分块区段 - Array.Copy(contentBytes, index * bufferSize, currentTransferBytes, 0, currentTransferBytes.Length); + // 读取文件流中的当前分块区段 + fileStream.Seek(input.CurrentByte, SeekOrigin.Begin); + await fileStream.ReadAsync(currentTransferBytes, 0, currentTransferBytes.Length); // 写入响应流 - await Response.Body.WriteAsync(currentTransferBytes, 0, currentTransferBytes.Length); - // 清空缓冲区 - await Response.Body.FlushAsync(); + return File(currentTransferBytes, memi, input.Name); } } } diff --git a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs index 931a5b941..fbccd7cc5 100644 --- a/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs +++ b/aspnet-core/services/admin/LINGYUN.BackendAdminApp.Host/BackendAdminHostModule.cs @@ -198,6 +198,16 @@ namespace LINGYUN.BackendAdmin options.Resources .Get() .AddVirtualJson("/LINGYUN/BackendAdmin/Identity/Localization"); + options + .AddLanguagesMapOrUpdate( + "vue-admin-element-ui", + new NameValue("zh-Hans", "zh"), + new NameValue("en", "en")); + options + .AddLanguageFilesMapOrUpdate( + "vue-admin-element-ui", + new NameValue("zh-Hans", "zh"), + new NameValue("en", "en")); }); context.Services.AddAuthentication("Bearer") diff --git a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs index 5fb3e6d81..f1a4587ff 100644 --- a/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs +++ b/aspnet-core/services/platform/LINGYUN.Platform.HttpApi.Host/AppPlatformHttpApiHostModule.cs @@ -165,6 +165,17 @@ namespace LINGYUN.Platform { options.Languages.Add(new LanguageInfo("en", "en", "English")); options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + + options + .AddLanguagesMapOrUpdate( + "vue-admin-element-ui", + new NameValue("zh-Hans", "zh"), + new NameValue("en", "en")); + options + .AddLanguageFilesMapOrUpdate( + "vue-admin-element-ui", + new NameValue("zh-Hans", "zh"), + new NameValue("en", "en")); }); context.Services.AddAuthentication("Bearer") diff --git a/vueJs/src/App.vue b/vueJs/src/App.vue index fa8146b67..2d7738f0e 100644 --- a/vueJs/src/App.vue +++ b/vueJs/src/App.vue @@ -6,7 +6,7 @@ diff --git a/vueJs/src/api/filemanagement.ts b/vueJs/src/api/filemanagement.ts index 83a38a4a3..1063f3e6b 100644 --- a/vueJs/src/api/filemanagement.ts +++ b/vueJs/src/api/filemanagement.ts @@ -73,6 +73,19 @@ export default class FileManagementService { const _url = baseUrl + '/files/copy' return ApiService.Put(_url, payload, serviceUrl) } + + public static downlodFle(name: string, path: string | undefined, currentByte: number | undefined) { + let _url = baseUrl + '/files?name=' + name + if (path) { + _url += '&path=' + path + } + _url += '¤tByte=' + currentByte + return ApiService.HttpRequestWithOriginResponse(({ + url: _url, + method: 'GET', + responseType: 'blob' + })) + } } export enum FileSystemType { diff --git a/vueJs/src/api/users.ts b/vueJs/src/api/users.ts index f7555d49e..f7d018e10 100644 --- a/vueJs/src/api/users.ts +++ b/vueJs/src/api/users.ts @@ -158,11 +158,11 @@ export default class UserApiService { }) } - public static refreshToken(token: string) { + public static refreshToken(token: string, refreshToken: string) { const _url = '/connect/token' const refresh = { grant_type: 'refresh_token', - refresh_token: token, + refresh_token: refreshToken, client_id: process.env.VUE_APP_CLIENT_ID, client_secret: process.env.VUE_APP_CLIENT_SECRET } @@ -172,7 +172,8 @@ export default class UserApiService { method: 'POST', data: qs.stringify(refresh), headers: { - 'Content-Type': 'application/x-www-form-urlencoded' + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': token } }) } diff --git a/vueJs/src/components/LangSelect/index.vue b/vueJs/src/components/LangSelect/index.vue index 7ecc4778b..1701a5dd2 100644 --- a/vueJs/src/components/LangSelect/index.vue +++ b/vueJs/src/components/LangSelect/index.vue @@ -28,9 +28,9 @@ + + diff --git a/vueJs/src/views/login/index.vue b/vueJs/src/views/login/index.vue index d38dbb28f..14566a788 100644 --- a/vueJs/src/views/login/index.vue +++ b/vueJs/src/views/login/index.vue @@ -158,7 +158,7 @@ import TenantBox from '@/components/TenantBox/index.vue' import LangSelect from '@/components/LangSelect/index.vue' import { Component, Vue, Watch } from 'vue-property-decorator' import UserService, { PhoneVerify, VerifyType } from '@/api/users' -import { AbpConfigurationModule } from '@/store/modules/abp' +import { AbpModule } from '@/store/modules/abp' @Component({ name: 'Login', @@ -185,11 +185,11 @@ export default class extends Vue { } get isMultiEnabled() { - return AbpConfigurationModule.configuration?.multiTenancy?.isEnabled + return AbpModule.configuration?.multiTenancy?.isEnabled } get selfRegistration() { - const selfRegister = AbpConfigurationModule.configuration.setting.values['Abp.Account.IsSelfRegistrationEnabled'] + const selfRegister = AbpModule.configuration.setting.values['Abp.Account.IsSelfRegistrationEnabled'] if (selfRegister) { return selfRegister === 'true' } diff --git a/vueJs/src/views/register/index.vue b/vueJs/src/views/register/index.vue index aff866bbd..fc6229b62 100644 --- a/vueJs/src/views/register/index.vue +++ b/vueJs/src/views/register/index.vue @@ -125,7 +125,7 @@ import TenantBox from '@/components/TenantBox/index.vue' import LangSelect from '@/components/LangSelect/index.vue' import { Component, Vue, Watch } from 'vue-property-decorator' import UserService, { PhoneVerify, VerifyType, UserRegisterData } from '@/api/users' -import { AbpConfigurationModule } from '@/store/modules/abp' +import { AbpModule } from '@/store/modules/abp' @Component({ name: 'Register', @@ -151,7 +151,7 @@ export default class extends Vue { } get isMultiEnabled() { - return AbpConfigurationModule.configuration?.multiTenancy?.isEnabled + return AbpModule.configuration?.multiTenancy?.isEnabled } private validatePhoneNumberValue = (rule: any, value: string, callback: any) => { diff --git a/vueJs/src/views/reset-password/index.vue b/vueJs/src/views/reset-password/index.vue index 65e422f23..cd5030340 100644 --- a/vueJs/src/views/reset-password/index.vue +++ b/vueJs/src/views/reset-password/index.vue @@ -113,7 +113,7 @@ import TenantBox from '@/components/TenantBox/index.vue' import LangSelect from '@/components/LangSelect/index.vue' import { Component, Vue, Watch } from 'vue-property-decorator' import UserService, { PhoneVerify, VerifyType, UserResetPasswordData } from '@/api/users' -import { AbpConfigurationModule } from '@/store/modules/abp' +import { AbpModule } from '@/store/modules/abp' @Component({ name: 'Register', @@ -138,7 +138,7 @@ export default class extends Vue { } get isMultiEnabled() { - return AbpConfigurationModule.configuration?.multiTenancy?.isEnabled + return AbpModule.configuration?.multiTenancy?.isEnabled } private validatePhoneNumberValue = (rule: any, value: string, callback: any) => {