增加同步配置
continuous-integration/drone/push Build is running Details

Uat_IRC_Net8
hang 2026-05-18 16:53:26 +08:00
parent ad5c36930e
commit 592de4deb4
3 changed files with 130 additions and 36 deletions

View File

@ -194,7 +194,7 @@ public interface IOSSService
List<string> GetRootFolderNames(); List<string> GetRootFolderNames();
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null); public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null);
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true); public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
@ -1856,23 +1856,39 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null) public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null)
{ {
//如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置 string objectStoreUse = string.Empty;
if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty()) //使用指定配置
if (objectUse != null)
{ {
var userDomain = domain?.Trim(); objectStoreUse = objectUse?.Trim() ?? string.Empty;
}
var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == userDomain); //根据域名动态判断
if (find != null) else
{
//如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty() && ObjectStoreServiceOptions.SyncConfigList.Any(t => t.Domain == domain))
{ {
ObjectStoreServiceOptions.ObjectStoreUse = find.Primary;
var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == domain);
if (find != null)
{
objectStoreUse = find.Primary;
}
}
else
{
//兜底,如果是本地测试环境,那就使用部署默认配置
objectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse;
} }
} }
var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS" || isGetAllTempToken == true) var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = objectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
if (objectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
{ {
var ossOptions = ObjectStoreServiceOptions.AliyunOSS; var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
@ -1920,11 +1936,11 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
objectStoreDTO.AliyunOSS = tempToken; objectStoreDTO.AliyunOSS = tempToken;
} }
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO") if (objectStoreUse == "MinIO")
{ {
objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO; objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO;
} }
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS" || isGetAllTempToken == true) if (objectStoreUse == "AWS" || isGetAllTempToken == true)
{ {
var awsOptions = ObjectStoreServiceOptions.AWS; var awsOptions = ObjectStoreServiceOptions.AWS;
@ -1969,7 +1985,8 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
objectStoreDTO.AWS = tempToken; objectStoreDTO.AWS = tempToken;
} }
else
if (objectStoreUse.IsNullOrEmpty())
{ {
throw new BusinessValidationFailedException("未定义的存储介质类型"); throw new BusinessValidationFailedException("未定义的存储介质类型");
} }
@ -1980,7 +1997,7 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
public async Task SyncFileAsync(string objectKey, ObjectStoreUse source, ObjectStoreUse destination, CancellationToken ct = default) public async Task SyncFileAsync(string objectKey, ObjectStoreUse source, ObjectStoreUse destination, CancellationToken ct = default)
{ {
GetObjectStoreTempToken(isGetAllTempToken: true); var tempConfig = GetObjectStoreTempToken(isGetAllTempToken: true);
var aliConfig = ObjectStoreServiceOptions.AliyunOSS; var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
@ -1999,36 +2016,76 @@ public class OSSService(IOptionsMonitor<ObjectStoreServiceOptions> options,
var amazonS3Client = new AmazonS3Client(credentials, clientConfig); var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
// ⭐ 关键变量
IDisposable? owner = null;
Stream sourceStream;
long contentLength;
// 根据源选择流式下载 // ========= 获取流 + 长度 =========
Stream sourceStream = source switch switch (source)
{ {
ObjectStoreUse.AliyunOSS => _ossClient.GetObject(aliConfig.BucketName, objectKey).Content, case ObjectStoreUse.AliyunOSS:
ObjectStoreUse.AWS => (await amazonS3Client.GetObjectAsync(awsConfig.BucketName, objectKey, ct)).ResponseStream, {
_ => throw new BusinessValidationFailedException("未定义的同步类型")
};
if (source == ObjectStoreUse.AliyunOSS) var obj = _ossClient.GetObject(
aliConfig.BucketName,
objectKey);
owner = obj;
sourceStream = obj.Content;
contentLength = obj.ContentLength;
break;
}
case ObjectStoreUse.AWS:
{
var response = await amazonS3Client.GetObjectAsync(
awsConfig.BucketName,
objectKey,
ct);
owner = response;
sourceStream = response.ResponseStream;
contentLength = response.Headers.ContentLength;
break;
}
default:
throw new BusinessValidationFailedException("未定义的同步类型");
}
try
{ {
var putRequest = new Amazon.S3.Model.PutObjectRequest // ========= 上传 =========
if (destination == ObjectStoreUse.AWS)
{ {
BucketName = awsConfig.BucketName, var putRequest = new Amazon.S3.Model.PutObjectRequest
Key = objectKey, {
InputStream = sourceStream BucketName = awsConfig.BucketName,
}; Key = objectKey,
InputStream = sourceStream,
Headers = { ContentLength = contentLength }
};
await amazonS3Client.PutObjectAsync(putRequest, ct); await amazonS3Client.PutObjectAsync(putRequest, ct);
}
else if (destination == ObjectStoreUse.AliyunOSS)
{
_ossClient.PutObject(
aliConfig.BucketName,
objectKey,
sourceStream);
}
else
{
throw new BusinessValidationFailedException("未定义的同步类型");
}
} }
else if (source == ObjectStoreUse.AWS) finally
{ {
_ossClient.PutObject(aliConfig.BucketName, objectKey, sourceStream); // ⭐⭐⭐ 真正释放 HTTP 连接
owner?.Dispose();
} }
else
{
throw new BusinessValidationFailedException("未定义的同步类型");
}
await sourceStream.DisposeAsync(); // 释放流
} }
} }

View File

@ -0,0 +1,16 @@
using AutoMapper;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.SCP.Service;
namespace IRaCIS.Core.Application.Service
{
public class CommonConfig : Profile
{
public CommonConfig()
{
CreateMap<FileUploadRecordAddOrEdit, FileUploadRecord>().ReverseMap();
}
}
}

View File

@ -50,6 +50,27 @@
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy", "secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "hir-test", "bucketName": "hir-test",
"viewEndpoint": "http://106.14.89.110:9001/hir-test/" "viewEndpoint": "http://106.14.89.110:9001/hir-test/"
},
// AWS S3
"AWS": {
// AWS S3 Region
"Region": "us-east-1",
// AWS S3 访
"EndPoint": "s3.us-east-1.amazonaws.com",
// 使 SSL
"UseSSL": true,
// AWS S3 ARN
"RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
// AWS S3 访 ID
"AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
// AWS S3 访 Secret
"SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
// AWS S3 Bucket
"BucketName": "ei-med-s3-lili-uat-store",
// AWS S3 访
"ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
// AWS S3
"DurationSeconds": 7200
} }
}, },