using Aliyun.OSS; using IRaCIS.Core.Infrastructure; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using Minio.DataModel.Args; using Minio; using SharpCompress.Common; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Security.AccessControl; using System.Text; using System.Threading.Tasks; namespace IRaCIS.Core.SCP { public class MinIOOptions : AWSOptions { public int port { get; set; } } public class AWSOptions { public string endPoint { get; set; } public bool useSSL { get; set; } public string accessKey { get; set; } public string secretKey { get; set; } public string bucketName { get; set; } public string viewEndpoint { get; set; } } public class AliyunOSSOptions { public string regionId { get; set; } public string accessKeyId { get; set; } public string accessKeySecret { get; set; } public string endPoint { get; set; } public string bucketName { get; set; } public string roleArn { get; set; } public string region { get; set; } public string viewEndpoint { get; set; } } public class ObjectStoreServiceOptions { public string ObjectStoreUse { get; set; } public AliyunOSSOptions AliyunOSS { get; set; } public MinIOOptions MinIO { get; set; } public AWSOptions AWS { get; set; } } public class ObjectStoreDTO { public string ObjectStoreUse { get; set; } public AliyunOSSOptions AliyunOSS { get; set; } public MinIOOptions MinIO { get; set; } public AWSOptions AWS { get; set; } } public class AliyunOSSTempToken { public string AccessKeyId { get; set; } public string AccessKeySecret { get; set; } public string SecurityToken { get; set; } public string Expiration { get; set; } public string Region { get; set; } public string BucketName { get; set; } public string ViewEndpoint { get; set; } } public enum ObjectStoreUse { AliyunOSS = 0, MinIO = 1, AWS = 2, } public interface IOSSService { public Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName,bool isFileNameAddGuid=true); public Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true); public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath); public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; } public Task GetSignedUrl(string ossRelativePath); } public class OSSService : IOSSService { public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; } public OSSService(IOptionsMonitor options) { ObjectStoreServiceOptions = options.CurrentValue; } /// /// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder /// /// /// /// /// public async Task UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true) { var ossRelativePath = isFileNameAddGuid? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}": $"{oosFolderPath}/{fileRealName}"; //var ossRelativePath = oosFolderPath + "/" + fileRealName; try { using (var memoryStream = new MemoryStream()) { fileStream.Seek(0, SeekOrigin.Begin); fileStream.CopyTo(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, memoryStream); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") { var minIOConfig = ObjectStoreServiceOptions.MinIO; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); var putObjectArgs = new PutObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithStreamData(memoryStream) .WithObjectSize(memoryStream.Length); await minioClient.PutObjectAsync(putObjectArgs); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { var minIOConfig = ObjectStoreServiceOptions.AWS; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); var putObjectArgs = new PutObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithStreamData(memoryStream) .WithObjectSize(memoryStream.Length); await minioClient.PutObjectAsync(putObjectArgs); } else { throw new BusinessValidationFailedException("未定义的存储介质类型"); } } } catch (Exception ex) { throw new BusinessValidationFailedException($"上传发生异常:{ex.Message}"); ; } return "/" + ossRelativePath; } /// /// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder /// /// /// /// /// public async Task UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true) { var localFileName = Path.GetFileName(localFilePath); var ossRelativePath = isFileNameAddGuid? $"{oosFolderPath}/{Guid.NewGuid()}_{localFileName}" : $"{oosFolderPath}/{localFileName}"; //var ossRelativePath = oosFolderPath + "/" + localFileName; if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.PutObject(aliConfig.bucketName, ossRelativePath, localFilePath); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") { var minIOConfig = ObjectStoreServiceOptions.MinIO; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); var putObjectArgs = new PutObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithFileName(localFilePath); await minioClient.PutObjectAsync(putObjectArgs); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { var minIOConfig = ObjectStoreServiceOptions.AWS; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); var putObjectArgs = new PutObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithFileName(localFilePath); await minioClient.PutObjectAsync(putObjectArgs); } else { throw new BusinessValidationFailedException("未定义的存储介质类型"); } return "/" + ossRelativePath; } public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath) { ossRelativePath = ossRelativePath.TrimStart('/'); try { if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 上传文件 var result = _ossClient.GetObject(aliConfig.bucketName, ossRelativePath); // 将下载的文件流保存到本地文件 using (var fs = File.OpenWrite(localFilePath)) { result.Content.CopyTo(fs); fs.Close(); } } else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") { var minIOConfig = ObjectStoreServiceOptions.MinIO; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); var getObjectArgs = new GetObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithFile(localFilePath); await minioClient.GetObjectAsync(getObjectArgs); } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { var minIOConfig = ObjectStoreServiceOptions.AWS; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); var getObjectArgs = new GetObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithFile(localFilePath); await minioClient.GetObjectAsync(getObjectArgs); } else { throw new BusinessValidationFailedException("未定义的存储介质类型"); } } catch (Exception ex) { throw new BusinessValidationFailedException("oss下载失败!" + ex.Message); } } public async Task GetSignedUrl(string ossRelativePath) { ossRelativePath = ossRelativePath.TrimStart('/'); try { if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS") { var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var _ossClient = new OssClient(aliConfig.endPoint, aliConfig.accessKeyId, aliConfig.accessKeySecret); // 生成签名URL。 var req = new GeneratePresignedUriRequest(aliConfig.bucketName, ossRelativePath, SignHttpMethod.Get) { // 设置签名URL过期时间,默认值为3600秒。 Expiration = DateTime.Now.AddHours(1), }; var uri = _ossClient.GeneratePresignedUri(req); return uri.PathAndQuery; } else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") { var minIOConfig = ObjectStoreServiceOptions.MinIO; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}:{minIOConfig.port}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); //var reqParams = new Dictionary(StringComparer.Ordinal) // { // { "response-content-type", "application/json" } // }; var args = new PresignedGetObjectArgs() .WithBucket(minIOConfig.bucketName) .WithObject(ossRelativePath) .WithExpiry(3600) /*.WithHeaders(reqParams)*/; var presignedUrl = await minioClient.PresignedGetObjectAsync(args); Uri uri = new Uri(presignedUrl); string relativePath = uri.PathAndQuery; return relativePath; } else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS") { var minIOConfig = ObjectStoreServiceOptions.AWS; var minioClient = new MinioClient().WithEndpoint($"{minIOConfig.endPoint}") .WithCredentials(minIOConfig.accessKey, minIOConfig.secretKey).WithSSL(minIOConfig.useSSL) .Build(); return string.Empty; } else { throw new BusinessValidationFailedException("未定义的存储介质类型"); } } catch (Exception ex) { throw new BusinessValidationFailedException("oss授权url失败!" + ex.Message); } } } }