13 changed files with 438 additions and 0 deletions
@ -0,0 +1,14 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public class GetPublicFileInput |
|||
{ |
|||
[Required] |
|||
public string Name { get; set; } |
|||
|
|||
public string Path { get; set; } |
|||
|
|||
public string Process { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public interface IFileAppService : IApplicationService |
|||
{ |
|||
Task<OssObjectDto> UploadAsync(UploadPublicFileInput input); |
|||
|
|||
Task<Stream> GetAsync(GetPublicFileInput input); |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public interface IFileValidater |
|||
{ |
|||
Task ValidationAsync(UploadFile input); |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public interface IPrivateFileAppService : IFileAppService |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public interface IPublicFileAppService : IFileAppService |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public class UploadFile |
|||
{ |
|||
/// <summary>
|
|||
/// 总文件大小
|
|||
/// </summary>
|
|||
[Required] |
|||
public long TotalSize { get; set; } |
|||
/// <summary>
|
|||
/// 文件名
|
|||
/// </summary>
|
|||
[Required] |
|||
public string FileName { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.IO; |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public class UploadPublicFileInput |
|||
{ |
|||
public string Path { get; set; } |
|||
public string Object { get; set; } |
|||
public bool Overwrite { get; set; } = true; |
|||
|
|||
[Required] |
|||
[DisableAuditing] |
|||
[DisableValidation] |
|||
public Stream Content { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
using LINGYUN.Abp.Features.LimitValidation; |
|||
using LINGYUN.Abp.OssManagement.Features; |
|||
using System; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using System.Web; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public abstract class FileAppServiceBase : OssManagementApplicationServiceBase, IFileAppService |
|||
{ |
|||
private readonly IFileValidater _fileValidater; |
|||
private readonly IOssContainerFactory _ossContainerFactory; |
|||
|
|||
protected FileAppServiceBase( |
|||
IFileValidater fileValidater, |
|||
IOssContainerFactory ossContainerFactory) |
|||
{ |
|||
_fileValidater = fileValidater; |
|||
_ossContainerFactory = ossContainerFactory; |
|||
} |
|||
|
|||
[RequiresFeature(AbpOssManagementFeatureNames.OssObject.UploadFile)] |
|||
[RequiresLimitFeature( |
|||
AbpOssManagementFeatureNames.OssObject.UploadLimit, |
|||
AbpOssManagementFeatureNames.OssObject.UploadInterval, |
|||
LimitPolicy.Month)] |
|||
public virtual async Task<OssObjectDto> UploadAsync(UploadPublicFileInput input) |
|||
{ |
|||
await _fileValidater.ValidationAsync(new UploadFile |
|||
{ |
|||
TotalSize = input.Content.Length, |
|||
FileName = input.Object |
|||
}); |
|||
|
|||
var oss = _ossContainerFactory.Create(); |
|||
|
|||
var createOssObjectRequest = new CreateOssObjectRequest( |
|||
GetCurrentBucket(), |
|||
HttpUtility.UrlDecode(input.Object), |
|||
input.Content, |
|||
GetCurrentPath(HttpUtility.UrlDecode(input.Path))) |
|||
{ |
|||
Overwrite = input.Overwrite |
|||
}; |
|||
|
|||
var ossObject = await oss.CreateObjectAsync(createOssObjectRequest); |
|||
|
|||
return ObjectMapper.Map<OssObject, OssObjectDto>(ossObject); |
|||
} |
|||
|
|||
[RequiresFeature(AbpOssManagementFeatureNames.OssObject.DownloadFile)] |
|||
[RequiresLimitFeature( |
|||
AbpOssManagementFeatureNames.OssObject.DownloadLimit, |
|||
AbpOssManagementFeatureNames.OssObject.DownloadInterval, |
|||
LimitPolicy.Month)] |
|||
public virtual async Task<Stream> GetAsync(GetPublicFileInput input) |
|||
{ |
|||
var ossObjectRequest = new GetOssObjectRequest( |
|||
GetCurrentBucket(), |
|||
// 需要处理特殊字符
|
|||
HttpUtility.UrlDecode(input.Name), |
|||
GetCurrentPath(HttpUtility.UrlDecode(input.Path)), |
|||
HttpUtility.UrlDecode(input.Process)); |
|||
|
|||
var ossContainer = _ossContainerFactory.Create(); |
|||
var ossObject = await ossContainer.GetObjectAsync(ossObjectRequest); |
|||
|
|||
return ossObject.Content; |
|||
} |
|||
|
|||
protected virtual string GetCurrentBucket() |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
protected virtual string GetCurrentPath(string path) |
|||
{ |
|||
path = path.RemovePreFix(".").RemovePreFix("/"); |
|||
return path; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
/// <summary>
|
|||
/// 所有登录用户访问私有文件服务接口
|
|||
/// bucket限制在users
|
|||
/// path限制在用户id
|
|||
/// </summary>
|
|||
[Authorize] |
|||
// 不对外公开,仅通过控制器调用
|
|||
//[RemoteService(IsMetadataEnabled = false)]
|
|||
public class PrivateFileAppService : FileAppServiceBase, IPrivateFileAppService |
|||
{ |
|||
public PrivateFileAppService( |
|||
IFileValidater fileValidater, |
|||
IOssContainerFactory ossContainerFactory) |
|||
: base(fileValidater, ossContainerFactory) |
|||
{ |
|||
} |
|||
protected override string GetCurrentBucket() |
|||
{ |
|||
return "users"; |
|||
} |
|||
|
|||
protected override string GetCurrentPath(string path) |
|||
{ |
|||
path = base.GetCurrentPath(path); |
|||
var userId = CurrentUser.GetId().ToString("N"); |
|||
return path.StartsWith(userId) ? path : $"{userId}/{path}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Volo.Abp; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public class AbpOssManagementOptions |
|||
{ |
|||
/// <summary>
|
|||
/// 静态容器
|
|||
/// 不允许被删除
|
|||
/// </summary>
|
|||
public List<string> StaticBuckets { get; } |
|||
|
|||
public AbpOssManagementOptions() |
|||
{ |
|||
StaticBuckets = new List<string> |
|||
{ |
|||
"public", |
|||
"users", |
|||
"system", |
|||
}; |
|||
} |
|||
|
|||
public void AddStaticBucket(string bucket) |
|||
{ |
|||
Check.NotNullOrWhiteSpace(bucket, nameof(bucket)); |
|||
|
|||
StaticBuckets.AddIfNotContains(bucket); |
|||
} |
|||
|
|||
public bool CheckStaticBucket(string bucket) |
|||
{ |
|||
return StaticBuckets.Any(bck => bck.Equals(bucket)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
using LINGYUN.Abp.OssManagement.Localization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Http; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
[Area("oss-management")] |
|||
[Route("api/files/private")] |
|||
[RemoteService(false)] |
|||
[ApiExplorerSettings(IgnoreApi = true)] |
|||
public class PrivateFilesController : AbpController |
|||
{ |
|||
private readonly IPrivateFileAppService _privateFileAppService; |
|||
|
|||
public PrivateFilesController( |
|||
IPrivateFileAppService privateFileAppService) |
|||
{ |
|||
_privateFileAppService = privateFileAppService; |
|||
|
|||
LocalizationResource = typeof(AbpOssManagementResource); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("{path}")] |
|||
[Route("{path}/{name}")] |
|||
public virtual async Task<OssObjectDto> UploadAsync(string path, string name) |
|||
{ |
|||
if (Request.ContentLength <= 0) |
|||
{ |
|||
ThrowValidationException(L["FileNotBeNullOrEmpty"], "File"); |
|||
} |
|||
|
|||
var file = Request.Form.Files[0]; |
|||
var fileName = name ?? file.FileName; |
|||
|
|||
var createOssObjectInput = new UploadPublicFileInput |
|||
{ |
|||
Path = path, |
|||
Object = fileName, |
|||
Content = file.OpenReadStream(), |
|||
Overwrite = true |
|||
}; |
|||
|
|||
return await _privateFileAppService.UploadAsync(createOssObjectInput); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{name}")] |
|||
[Route("{name}/{process}")] |
|||
[Route("p/{path}/{name}")] |
|||
[Route("p/{path}/{name}/{process}")] |
|||
public virtual async Task<IActionResult> GetAsync(string path, string name, string process) |
|||
{ |
|||
var input = new GetPublicFileInput |
|||
{ |
|||
Name = name, |
|||
Path = path, |
|||
Process = process |
|||
}; |
|||
var fileStream = await _privateFileAppService.GetAsync(input); |
|||
|
|||
if (fileStream.IsNullOrEmpty()) |
|||
{ |
|||
return NotFound(); |
|||
} |
|||
|
|||
return File( |
|||
fileStream, |
|||
MimeTypes.GetByExtension(Path.GetExtension(input.Name)) |
|||
); |
|||
} |
|||
|
|||
private static void ThrowValidationException(string message, string memberName) |
|||
{ |
|||
throw new AbpValidationException(message, |
|||
new List<ValidationResult> |
|||
{ |
|||
new ValidationResult(message, new[] {memberName}) |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
using LINGYUN.Abp.OssManagement.Localization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Http; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
[Area("oss-management")] |
|||
[Route("api/files/public")] |
|||
[RemoteService(false)] |
|||
[ApiExplorerSettings(IgnoreApi = true)] |
|||
public class PublicFilesController : AbpController |
|||
{ |
|||
private readonly IPublicFileAppService _publicFileAppService; |
|||
|
|||
public PublicFilesController( |
|||
IPublicFileAppService publicFileAppService) |
|||
{ |
|||
_publicFileAppService = publicFileAppService; |
|||
|
|||
LocalizationResource = typeof(AbpOssManagementResource); |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Route("{path}")] |
|||
[Route("{path}/{name}")] |
|||
public virtual async Task<OssObjectDto> UploadAsync(string path, string name) |
|||
{ |
|||
if (Request.ContentLength <= 0) |
|||
{ |
|||
ThrowValidationException(L["FileNotBeNullOrEmpty"], "File"); |
|||
} |
|||
|
|||
var file = Request.Form.Files[0]; |
|||
var fileName = name ?? file.FileName; |
|||
|
|||
var createOssObjectInput = new UploadPublicFileInput |
|||
{ |
|||
Path = path, |
|||
Object = fileName, |
|||
Content = file.OpenReadStream(), |
|||
Overwrite = true |
|||
}; |
|||
|
|||
return await _publicFileAppService.UploadAsync(createOssObjectInput); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{name}")] |
|||
[Route("{name}/{process}")] |
|||
[Route("p/{path}/{name}")] |
|||
[Route("p/{path}/{name}/{process}")] |
|||
public virtual async Task<IActionResult> GetAsync(string path, string name, string process) |
|||
{ |
|||
var input = new GetPublicFileInput |
|||
{ |
|||
Name = name, |
|||
Path = path, |
|||
Process = process |
|||
}; |
|||
var fileStream = await _publicFileAppService.GetAsync(input); |
|||
|
|||
if (fileStream.IsNullOrEmpty()) |
|||
{ |
|||
return NotFound(); |
|||
} |
|||
|
|||
return File( |
|||
fileStream, |
|||
MimeTypes.GetByExtension(Path.GetExtension(input.Name)) |
|||
); |
|||
} |
|||
|
|||
private static void ThrowValidationException(string message, string memberName) |
|||
{ |
|||
throw new AbpValidationException(message, |
|||
new List<ValidationResult> |
|||
{ |
|||
new ValidationResult(message, new[] {memberName}) |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement.SettingManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpOssManagementApplicationContractsModule), |
|||
typeof(AbpAspNetCoreMvcModule))] |
|||
public class AbpOssManagementSettingManagementModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpOssManagementSettingManagementModule).Assembly); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue