验证存储桶是否可访问
This commit is contained in:
parent
09f72d1132
commit
d098a7ff81
|
|
@ -1,3 +1,6 @@
|
||||||
|
using COSXML;
|
||||||
|
using COSXML.Auth;
|
||||||
|
using COSXML.Model.Bucket;
|
||||||
using MiAssessment.Admin.Filters;
|
using MiAssessment.Admin.Filters;
|
||||||
using MiAssessment.Admin.Models.Common;
|
using MiAssessment.Admin.Models.Common;
|
||||||
using MiAssessment.Admin.Models.Config;
|
using MiAssessment.Admin.Models.Config;
|
||||||
|
|
@ -93,4 +96,77 @@ public class ConfigController : ControllerBase
|
||||||
return ApiResponse<bool>.Error(AdminErrorCodes.InternalError, "更新上传配置失败");
|
return ApiResponse<bool>.Error(AdminErrorCodes.InternalError, "更新上传配置失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 测试腾讯云COS连接
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">上传配置</param>
|
||||||
|
/// <returns>测试结果</returns>
|
||||||
|
[HttpPost("upload/testConnection")]
|
||||||
|
public Task<ApiResponse<bool>> TestCosConnection([FromBody] UploadSetting request)
|
||||||
|
{
|
||||||
|
// 验证必填参数
|
||||||
|
if (request.Type != "3")
|
||||||
|
{
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Error(AdminErrorCodes.InvalidParameter, "仅支持测试腾讯云COS连接"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(request.AccessKeyId) ||
|
||||||
|
string.IsNullOrWhiteSpace(request.AccessKeySecret) ||
|
||||||
|
string.IsNullOrWhiteSpace(request.Bucket) ||
|
||||||
|
string.IsNullOrWhiteSpace(request.Region))
|
||||||
|
{
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Error(AdminErrorCodes.InvalidParameter, "请填写完整的COS配置信息"));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 创建COS客户端
|
||||||
|
var config = new CosXmlConfig.Builder()
|
||||||
|
.IsHttps(true)
|
||||||
|
.SetRegion(request.Region!)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var credentialProvider = new DefaultQCloudCredentialProvider(
|
||||||
|
request.AccessKeyId!,
|
||||||
|
request.AccessKeySecret!,
|
||||||
|
600);
|
||||||
|
|
||||||
|
var cosXml = new CosXmlServer(config, credentialProvider);
|
||||||
|
|
||||||
|
// 尝试 HeadBucket 验证连接
|
||||||
|
var headBucketRequest = new HeadBucketRequest(request.Bucket!);
|
||||||
|
var result = cosXml.HeadBucket(headBucketRequest);
|
||||||
|
|
||||||
|
if (result.IsSuccessful())
|
||||||
|
{
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Success(true, "连接成功"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Error(AdminErrorCodes.InternalError, $"连接失败: {result.httpMessage}"));
|
||||||
|
}
|
||||||
|
catch (COSXML.CosException.CosClientException clientEx)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(clientEx, "COS连接测试客户端错误");
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Error(AdminErrorCodes.InternalError, $"连接失败: {clientEx.Message}"));
|
||||||
|
}
|
||||||
|
catch (COSXML.CosException.CosServerException serverEx)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(serverEx, "COS连接测试服务端错误");
|
||||||
|
var message = serverEx.errorCode switch
|
||||||
|
{
|
||||||
|
"NoSuchBucket" => "存储桶不存在,请检查Bucket名称",
|
||||||
|
"AccessDenied" => "访问被拒绝,请检查SecretId和SecretKey",
|
||||||
|
"SignatureDoesNotMatch" => "签名不匹配,请检查SecretKey",
|
||||||
|
"InvalidAccessKeyId" => "SecretId无效,请检查配置",
|
||||||
|
_ => $"连接失败: {serverEx.errorCode} - {serverEx.errorMessage}"
|
||||||
|
};
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Error(AdminErrorCodes.InternalError, message));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "COS连接测试异常");
|
||||||
|
return Task.FromResult(ApiResponse<bool>.Error(AdminErrorCodes.InternalError, $"连接测试失败: {ex.Message}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,14 @@ export function updateUploadConfig(data: UploadSetting): Promise<ApiResponse<boo
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试腾讯云COS连接
|
||||||
|
*/
|
||||||
|
export function testCosConnection(data: UploadSetting): Promise<ApiResponse<boolean>> {
|
||||||
|
return request<boolean>({
|
||||||
|
url: '/admin/config/upload/testConnection',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@
|
||||||
<el-icon><Refresh /></el-icon>
|
<el-icon><Refresh /></el-icon>
|
||||||
重置
|
重置
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="state.formData.type === '3'" @click="handleTest">
|
<el-button v-if="state.formData.type === '3'" :loading="state.testing" @click="handleTest">
|
||||||
<el-icon><Connection /></el-icon>
|
<el-icon><Connection /></el-icon>
|
||||||
测试连接
|
测试连接
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
@ -153,13 +153,14 @@
|
||||||
import { reactive, ref, computed, onMounted } from 'vue'
|
import { reactive, ref, computed, onMounted } from 'vue'
|
||||||
import { FolderOpened, Cloudy, Check, Refresh, Connection } from '@element-plus/icons-vue'
|
import { FolderOpened, Cloudy, Check, Refresh, Connection } from '@element-plus/icons-vue'
|
||||||
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
|
||||||
import { getUploadConfig, updateUploadConfig, type UploadSetting } from '@/api/system/config'
|
import { getUploadConfig, updateUploadConfig, testCosConnection, type UploadSetting } from '@/api/system/config'
|
||||||
|
|
||||||
// ============ Types ============
|
// ============ Types ============
|
||||||
|
|
||||||
interface UploadConfigState {
|
interface UploadConfigState {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
saving: boolean
|
saving: boolean
|
||||||
|
testing: boolean
|
||||||
formData: UploadSetting
|
formData: UploadSetting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,6 +173,7 @@ const formRef = ref<FormInstance>()
|
||||||
const state = reactive<UploadConfigState>({
|
const state = reactive<UploadConfigState>({
|
||||||
loading: false,
|
loading: false,
|
||||||
saving: false,
|
saving: false,
|
||||||
|
testing: false,
|
||||||
formData: {
|
formData: {
|
||||||
type: '1',
|
type: '1',
|
||||||
appId: '',
|
appId: '',
|
||||||
|
|
@ -264,8 +266,28 @@ function handleReset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTest() {
|
function handleTest() {
|
||||||
// TODO: 实现连接测试
|
// 先验证必填字段
|
||||||
ElMessage.info('连接测试功能开发中')
|
if (!state.formData.accessKeyId || !state.formData.accessKeySecret ||
|
||||||
|
!state.formData.bucket || !state.formData.region) {
|
||||||
|
ElMessage.warning('请先填写完整的COS配置信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
state.testing = true
|
||||||
|
testCosConnection(state.formData)
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
ElMessage.success(res.message || '连接成功')
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.message || '连接失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
ElMessage.error('连接测试请求失败')
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
state.testing = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ Lifecycle ============
|
// ============ Lifecycle ============
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user