oss板块
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
|
||||
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
|
||||
|
||||
using Aliyun.OSS;
|
||||
|
||||
namespace SimpleAdmin.System;
|
||||
|
||||
/// <summary>
|
||||
@@ -95,6 +97,8 @@ public class FileService : DbRepository<SysFile>, IFileService
|
||||
return GetFileStreamResult(devFile.StoragePath, devFile.Name);
|
||||
if (devFile.Engine == SysDictConst.FILE_ENGINE_MINIO)
|
||||
return await GetFileStreamResultFromMinio(devFile.ObjName, devFile.Name);
|
||||
if (devFile.Engine == SysDictConst.FILE_ENGINE_ALIYUN_OSS)
|
||||
return await GetFileStreamResultFromAliyunOss(devFile);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
@@ -142,6 +146,9 @@ public class FileService : DbRepository<SysFile>, IFileService
|
||||
}
|
||||
break;
|
||||
|
||||
case SysDictConst.FILE_ENGINE_ALIYUN_OSS:
|
||||
(bucketName, objName, storageUrl) = await StorageAliyunOss(objectId, file);
|
||||
break;
|
||||
default:
|
||||
|
||||
throw Oops.Bah("不支持的文件引擎");
|
||||
@@ -154,13 +161,13 @@ public class FileService : DbRepository<SysFile>, IFileService
|
||||
Engine = engine,
|
||||
Bucket = bucketName,
|
||||
Name = file.FileName,
|
||||
Suffix = fileSuffix.Split(".")[1],
|
||||
Suffix = fileSuffix.TrimStart('.'),
|
||||
ObjName = objName,
|
||||
SizeKb = fileSizeKb,
|
||||
SizeInfo = GetSizeInfo(fileSizeKb),
|
||||
StoragePath = storageUrl
|
||||
};
|
||||
if (engine != CateGoryConst.CONFIG_FILE_LOCAL)//如果不是本地,设置下载地址
|
||||
if (engine != SysDictConst.FILE_ENGINE_LOCAL)//如果不是本地,设置下载地址
|
||||
{
|
||||
devFile.DownloadPath = storageUrl;
|
||||
}
|
||||
@@ -236,6 +243,111 @@ public class FileService : DbRepository<SysFile>, IFileService
|
||||
return (fileObjectName, downloadUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将入职业务文件存储到阿里云 OSS。
|
||||
/// </summary>
|
||||
private async Task<(string bucketName, string objName, string downloadUrl)> StorageAliyunOss(
|
||||
long fileId,
|
||||
IFormFile file)
|
||||
{
|
||||
var setting = GetOssSetting();
|
||||
var suffix = Path.GetExtension(file.FileName).ToLowerInvariant();
|
||||
var objectName = $"onboarding/{DateTime.Now:yyyy/MM/dd}/{fileId}{suffix}";
|
||||
var metadata = new ObjectMetadata();
|
||||
if (!string.IsNullOrWhiteSpace(file.ContentType))
|
||||
metadata.ContentType = file.ContentType;
|
||||
|
||||
await using var stream = file.OpenReadStream();
|
||||
var client = CreateOssClient(setting);
|
||||
client.PutObject(setting.Bucket, objectName, stream, metadata);
|
||||
|
||||
var downloadUrl = string.IsNullOrWhiteSpace(setting.OSSUrl)
|
||||
? $"https://{setting.Bucket}.{setting.EndPoint.Trim().TrimEnd('/')}/{objectName}"
|
||||
: $"{setting.OSSUrl.Trim().TrimEnd('/')}/{objectName}";
|
||||
|
||||
return (setting.Bucket, objectName, downloadUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从阿里云 OSS 读取业务文件并通过统一下载接口返回。
|
||||
/// </summary>
|
||||
private async Task<FileStreamResult> GetFileStreamResultFromAliyunOss(SysFile file)
|
||||
{
|
||||
var setting = GetOssSetting();
|
||||
var client = CreateOssClient(setting);
|
||||
var ossObject = client.GetObject(file.Bucket, file.ObjName);
|
||||
var memory = new MemoryStream();
|
||||
await using (ossObject.Content)
|
||||
{
|
||||
await ossObject.Content.CopyToAsync(memory);
|
||||
}
|
||||
|
||||
memory.Position = 0;
|
||||
var fileName = HttpUtility.UrlEncode(file.Name, Encoding.GetEncoding("UTF-8"));
|
||||
return new FileStreamResult(memory, "application/octet-stream")
|
||||
{
|
||||
FileDownloadName = fileName
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取并校验阿里云 OSS 配置。
|
||||
/// </summary>
|
||||
private static OssSettingOptions GetOssSetting()
|
||||
{
|
||||
var setting = App.GetConfig<OssSettingOptions>("OssSetting", true);
|
||||
var configurationIncomplete = setting == null
|
||||
|| string.IsNullOrWhiteSpace(setting.AccessKeyID)
|
||||
|| string.IsNullOrWhiteSpace(setting.AccessKeySecret)
|
||||
|| string.IsNullOrWhiteSpace(setting.Bucket)
|
||||
|| string.IsNullOrWhiteSpace(setting.EndPoint);
|
||||
if (configurationIncomplete)
|
||||
throw Oops.Bah("阿里云 OSS 配置不完整");
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过 STS 临时凭证创建阿里云 OSS 客户端。
|
||||
/// </summary>
|
||||
private static OssClient CreateOssClient(OssSettingOptions setting)
|
||||
{
|
||||
var endpoint = setting.EndPoint.Trim();
|
||||
if (!endpoint.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|
||||
&& !endpoint.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
endpoint = "https://" + endpoint;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(setting.RoleArn))
|
||||
return new OssClient(endpoint, setting.AccessKeyID, setting.AccessKeySecret);
|
||||
|
||||
var stsConfig = new AlibabaCloud.OpenApiClient.Models.Config
|
||||
{
|
||||
AccessKeyId = setting.AccessKeyID,
|
||||
AccessKeySecret = setting.AccessKeySecret,
|
||||
Endpoint = setting.StsEndpoint
|
||||
};
|
||||
var stsClient = new AlibabaCloud.SDK.Sts20150401.Client(stsConfig);
|
||||
var request = new AlibabaCloud.SDK.Sts20150401.Models.AssumeRoleRequest
|
||||
{
|
||||
RoleArn = setting.RoleArn,
|
||||
RoleSessionName = string.IsNullOrWhiteSpace(setting.RoleSessionName)
|
||||
? "onboardx-server"
|
||||
: setting.RoleSessionName,
|
||||
DurationSeconds = 3600
|
||||
};
|
||||
var credentials = stsClient.AssumeRole(request).Body.Credentials;
|
||||
if (credentials == null)
|
||||
throw Oops.Bah("获取阿里云 OSS 临时凭证失败");
|
||||
|
||||
return new OssClient(
|
||||
endpoint,
|
||||
credentials.AccessKeyId,
|
||||
credentials.AccessKeySecret,
|
||||
credentials.SecurityToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件大小
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user