阿里云OSS设置
This commit is contained in:
@@ -165,7 +165,7 @@ const uploadFile = async (file: File) => {
|
||||
if (props.categoryId) {
|
||||
formData.append('categoryId', props.categoryId.toString())
|
||||
}
|
||||
formData.append('storageType', 'local')
|
||||
formData.append('storageType', 'aliyun')
|
||||
|
||||
const result = await parseApiResponse<{ fileUrl: string }>(await authFetch(`${API_BASE}/admin/attachments/upload`, {
|
||||
method: 'POST',
|
||||
|
||||
@@ -366,7 +366,7 @@ const uploadSingleFile = async (file: File): Promise<string | null> => {
|
||||
if (props.categoryId) {
|
||||
formData.append('categoryId', props.categoryId.toString())
|
||||
}
|
||||
formData.append('storageType', 'local')
|
||||
formData.append('storageType', 'aliyun')
|
||||
|
||||
const result = await parseApiResponse<{ fileUrl: string }>(await authFetch(`${API_BASE}/admin/attachments/upload`, {
|
||||
method: 'POST',
|
||||
|
||||
@@ -46,7 +46,7 @@ const uploadFile = async (file: File) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
if (props.categoryId) formData.append('categoryId', props.categoryId.toString())
|
||||
formData.append('storageType', 'local')
|
||||
formData.append('storageType', 'aliyun')
|
||||
const result = await parseApiResponse<{ fileUrl: string }>(
|
||||
await authFetch(`${API_BASE}/admin/attachments/upload`, { method: 'POST', headers: {}, body: formData })
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ export function useMdMediaUpload(editorRef: Ref<ExposeParam | undefined>) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('categoryId', '1')
|
||||
formData.append('storageType', 'local')
|
||||
formData.append('storageType', 'aliyun')
|
||||
|
||||
const response = await authFetch('/api/admin/attachments/upload', {
|
||||
method: 'POST',
|
||||
|
||||
@@ -293,7 +293,7 @@ const uploadFileWithFile = async (file: File) => {
|
||||
if (uploadCategoryId.value > 0) {
|
||||
formData.append('categoryId', uploadCategoryId.value.toString())
|
||||
}
|
||||
formData.append('storageType', 'local')
|
||||
formData.append('storageType', 'aliyun')
|
||||
|
||||
await parseApiResponse(await authFetch(`${API_BASE}/admin/attachments/upload`, {
|
||||
method: 'POST',
|
||||
|
||||
@@ -59,9 +59,9 @@
|
||||
type="text"
|
||||
id="ossAccessKeyId"
|
||||
v-model="ossForm.ossAccessKeyId"
|
||||
required
|
||||
:required="!currentConfig"
|
||||
class="admin-input font-mono"
|
||||
placeholder="OSS Access Key ID"
|
||||
placeholder="留空则保持原密钥;新建时必填"
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -73,9 +73,9 @@
|
||||
type="password"
|
||||
id="ossAccessKeySecret"
|
||||
v-model="ossForm.ossAccessKeySecret"
|
||||
required
|
||||
:required="!currentConfig"
|
||||
class="admin-input font-mono"
|
||||
placeholder="OSS Access Key Secret"
|
||||
placeholder="留空则保持原密钥;新建时必填"
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -285,6 +285,15 @@
|
||||
</button>
|
||||
<div v-else></div>
|
||||
<div class="flex gap-3">
|
||||
<button
|
||||
v-if="currentConfig && currentConfig.id > 0"
|
||||
type="button"
|
||||
class="admin-btn-secondary"
|
||||
:disabled="isTesting || isSubmitting"
|
||||
@click="testConnection"
|
||||
>
|
||||
{{ isTesting ? '测试中...' : '测试连接' }}
|
||||
</button>
|
||||
<button type="submit" class="admin-btn-primary" :disabled="isSubmitting">
|
||||
{{ isSubmitting ? '保存中...' : (currentConfig ? '保存' : '创建') }}
|
||||
</button>
|
||||
@@ -297,7 +306,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { getOSSConfigs, createOSSConfig, updateOSSConfig, deleteOSSConfig as deleteOSSConfigApi, OSSConfig } from '../../services/api'
|
||||
import { getOSSConfigs, createOSSConfig, updateOSSConfig, deleteOSSConfig as deleteOSSConfigApi, testOSSConfig, OSSConfig } from '../../services/api'
|
||||
import { useToast } from '../../composables/useToast'
|
||||
|
||||
const toast = useToast()
|
||||
@@ -314,6 +323,7 @@ const tabs = [
|
||||
// OSS配置管理
|
||||
const ossConfigs = ref<OSSConfig[]>([])
|
||||
const isSubmitting = ref(false)
|
||||
const isTesting = ref(false)
|
||||
|
||||
const ossForm = ref({
|
||||
id: 0,
|
||||
@@ -455,23 +465,32 @@ const fetchOSSConfigs = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const secretOrKeep = (value: string, isUpdate: boolean) => {
|
||||
if (value) return value
|
||||
return isUpdate ? '***' : ''
|
||||
}
|
||||
|
||||
const saveOSSConfig = async () => {
|
||||
// 设置存储类型
|
||||
ossForm.value.storageType = activeTab.value
|
||||
|
||||
// 验证必填字段
|
||||
const isUpdate = ossForm.value.id > 0
|
||||
|
||||
// 验证必填字段(更新时密钥可留空表示保持原值)
|
||||
if (activeTab.value === 'aliyun') {
|
||||
if (!ossForm.value.ossAccessKeyId || !ossForm.value.ossAccessKeySecret || !ossForm.value.ossEndpoint || !ossForm.value.ossBucket) {
|
||||
if ((!isUpdate && (!ossForm.value.ossAccessKeyId || !ossForm.value.ossAccessKeySecret)) ||
|
||||
!ossForm.value.ossEndpoint || !ossForm.value.ossBucket) {
|
||||
toast.showToast('请填写所有必填字段', 'error')
|
||||
return
|
||||
}
|
||||
} else if (activeTab.value === 'qcloud') {
|
||||
if (!ossForm.value.qcloudSecretId || !ossForm.value.qcloudSecretKey || !ossForm.value.qcloudRegion || !ossForm.value.qcloudBucket) {
|
||||
if ((!isUpdate && (!ossForm.value.qcloudSecretId || !ossForm.value.qcloudSecretKey)) ||
|
||||
!ossForm.value.qcloudRegion || !ossForm.value.qcloudBucket) {
|
||||
toast.showToast('请填写所有必填字段', 'error')
|
||||
return
|
||||
}
|
||||
} else if (activeTab.value === 'qiniu') {
|
||||
if (!ossForm.value.qiniuAccessKey || !ossForm.value.qiniuSecretKey || !ossForm.value.qiniuBucket) {
|
||||
if ((!isUpdate && (!ossForm.value.qiniuAccessKey || !ossForm.value.qiniuSecretKey)) ||
|
||||
!ossForm.value.qiniuBucket) {
|
||||
toast.showToast('请填写所有必填字段', 'error')
|
||||
return
|
||||
}
|
||||
@@ -487,31 +506,29 @@ const saveOSSConfig = async () => {
|
||||
|
||||
// 根据存储类型设置对应字段
|
||||
if (activeTab.value === 'aliyun') {
|
||||
updateData.ossAccessKeyId = ossForm.value.ossAccessKeyId
|
||||
updateData.ossAccessKeySecret = ossForm.value.ossAccessKeySecret
|
||||
updateData.ossAccessKeyId = secretOrKeep(ossForm.value.ossAccessKeyId, isUpdate)
|
||||
updateData.ossAccessKeySecret = secretOrKeep(ossForm.value.ossAccessKeySecret, isUpdate)
|
||||
updateData.ossEndpoint = ossForm.value.ossEndpoint
|
||||
updateData.ossBucket = ossForm.value.ossBucket
|
||||
updateData.ossDomain = ossForm.value.ossDomain || ''
|
||||
} else if (activeTab.value === 'qcloud') {
|
||||
updateData.qcloudSecretId = ossForm.value.qcloudSecretId
|
||||
updateData.qcloudSecretKey = ossForm.value.qcloudSecretKey
|
||||
updateData.qcloudSecretId = secretOrKeep(ossForm.value.qcloudSecretId, isUpdate)
|
||||
updateData.qcloudSecretKey = secretOrKeep(ossForm.value.qcloudSecretKey, isUpdate)
|
||||
updateData.qcloudRegion = ossForm.value.qcloudRegion
|
||||
updateData.qcloudBucket = ossForm.value.qcloudBucket
|
||||
updateData.qcloudDomain = ossForm.value.qcloudDomain || ''
|
||||
} else if (activeTab.value === 'qiniu') {
|
||||
updateData.qiniuAccessKey = ossForm.value.qiniuAccessKey
|
||||
updateData.qiniuSecretKey = ossForm.value.qiniuSecretKey
|
||||
updateData.qiniuAccessKey = secretOrKeep(ossForm.value.qiniuAccessKey, isUpdate)
|
||||
updateData.qiniuSecretKey = secretOrKeep(ossForm.value.qiniuSecretKey, isUpdate)
|
||||
updateData.qiniuBucket = ossForm.value.qiniuBucket
|
||||
updateData.qiniuRegion = ossForm.value.qiniuRegion || ''
|
||||
updateData.qiniuDomain = ossForm.value.qiniuDomain || ''
|
||||
}
|
||||
|
||||
if (ossForm.value.id > 0) {
|
||||
// 更新
|
||||
if (isUpdate) {
|
||||
await updateOSSConfig(ossForm.value.id, updateData)
|
||||
toast.showToast('OSS配置更新成功', 'success')
|
||||
} else {
|
||||
// 创建
|
||||
await createOSSConfig({
|
||||
...updateData,
|
||||
createdAt: '',
|
||||
@@ -529,6 +546,24 @@ const saveOSSConfig = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const testConnection = async () => {
|
||||
if (!currentConfig.value?.id) {
|
||||
toast.showToast('请先保存配置再测试连接', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
isTesting.value = true
|
||||
try {
|
||||
await testOSSConfig(currentConfig.value.id)
|
||||
toast.showToast('连接测试成功', 'success')
|
||||
} catch (error: any) {
|
||||
console.error('Error testing OSS config:', error)
|
||||
toast.showToast(error.message || '连接测试失败', 'error')
|
||||
} finally {
|
||||
isTesting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const deleteOSSConfig = async () => {
|
||||
if (!currentConfig.value) return
|
||||
|
||||
|
||||
@@ -549,7 +549,7 @@ const uploadMediaFile = async (file: File): Promise<string | null> => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('categoryId', '1')
|
||||
formData.append('storageType', 'local')
|
||||
formData.append('storageType', 'aliyun')
|
||||
|
||||
const response = await authFetch('/api/admin/attachments/upload', {
|
||||
method: 'POST',
|
||||
|
||||
@@ -2001,6 +2001,19 @@ export const deleteOSSConfig = async (id: number): Promise<void> => {
|
||||
}
|
||||
}
|
||||
|
||||
export const testOSSConfig = async (id: number): Promise<{ storageType: string; name: string }> => {
|
||||
try {
|
||||
const response = await authFetch(`${API_BASE}/admin/oss-configs/${id}/test`, {
|
||||
method: 'POST',
|
||||
headers: getAuthHeaders()
|
||||
})
|
||||
return await parseApiResponse<{ storageType: string; name: string }>(response)
|
||||
} catch (error) {
|
||||
console.error('Test OSS config error:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 附件相关类型
|
||||
export interface Attachment {
|
||||
id: number
|
||||
|
||||
Reference in New Issue
Block a user