<template>
|
<div class="logo-upload-simple">
|
<div class="page-card">
|
<h3 class="card-title">Logo上传到腾讯云COS测试</h3>
|
|
<!-- 说明 -->
|
<el-alert
|
title="测试说明"
|
type="info"
|
:closable="false"
|
show-icon
|
style="margin-bottom: 20px;"
|
>
|
<p>此页面用于测试将UI目录下的logo.jpg文件上传到腾讯云COS存储桶。</p>
|
<p>上传过程会通过后端API获取临时密钥,然后直接上传到COS。</p>
|
</el-alert>
|
|
<!-- Logo预览 -->
|
<el-card shadow="never" style="margin-bottom: 20px;">
|
<template #header>
|
<span>Logo文件预览</span>
|
</template>
|
<div class="logo-preview">
|
<img
|
src="/UI/logo.jpg"
|
alt="Logo"
|
class="logo-image"
|
@load="logoLoaded = true"
|
@error="logoError = true"
|
/>
|
<div class="logo-info">
|
<p><strong>文件路径:</strong> UI/logo.jpg</p>
|
<p><strong>状态:</strong>
|
<el-tag :type="logoLoaded ? 'success' : logoError ? 'danger' : 'info'">
|
{{ logoLoaded ? '加载成功' : logoError ? '加载失败' : '加载中' }}
|
</el-tag>
|
</p>
|
</div>
|
</div>
|
</el-card>
|
|
<!-- COS配置信息 -->
|
<el-card shadow="never" style="margin-bottom: 20px;">
|
<template #header>
|
<div class="card-header">
|
<span>COS配置信息</span>
|
<el-button type="primary" size="small" @click="loadCOSConfig">
|
刷新配置
|
</el-button>
|
</div>
|
</template>
|
<div v-if="cosConfig" class="config-info">
|
<p><strong>存储桶:</strong> {{ cosConfig.bucket }}</p>
|
<p><strong>地域:</strong> {{ cosConfig.region }}</p>
|
<p><strong>域名:</strong> {{ cosConfig.domain || '默认域名' }}</p>
|
</div>
|
<div v-else-if="configError" class="config-error">
|
<el-alert type="error" :title="configError" :closable="false" />
|
</div>
|
<div v-else>
|
<el-skeleton :rows="3" animated />
|
</div>
|
</el-card>
|
|
<!-- 上传操作 -->
|
<el-card shadow="never" style="margin-bottom: 20px;">
|
<template #header>
|
<span>上传操作</span>
|
</template>
|
|
<div class="upload-section">
|
<el-button
|
type="success"
|
size="large"
|
:loading="uploading"
|
@click="uploadLogo"
|
:disabled="!logoLoaded || !cosConfig"
|
>
|
<el-icon><Upload /></el-icon>
|
{{ uploading ? '上传中...' : '开始上传Logo' }}
|
</el-button>
|
|
<p class="upload-tip">
|
点击按钮将自动获取logo文件并上传到腾讯云COS存储桶的avatars目录下
|
</p>
|
</div>
|
</el-card>
|
|
<!-- 上传进度 -->
|
<el-card v-if="uploadProgress.show" shadow="never" style="margin-bottom: 20px;">
|
<template #header>
|
<span>上传进度</span>
|
</template>
|
<div class="progress-section">
|
<div class="progress-info">
|
<span>{{ uploadProgress.fileName }}</span>
|
<span>{{ uploadProgress.status }}</span>
|
</div>
|
<el-progress
|
:percentage="uploadProgress.percent"
|
:status="uploadProgress.type"
|
/>
|
<div v-if="uploadProgress.details" class="progress-details">
|
<p>{{ uploadProgress.details }}</p>
|
</div>
|
</div>
|
</el-card>
|
|
<!-- 上传结果 -->
|
<el-card v-if="uploadResult.show" shadow="never">
|
<template #header>
|
<span>上传结果</span>
|
</template>
|
<div class="result-section">
|
<el-alert
|
:title="uploadResult.success ? '上传成功!' : '上传失败!'"
|
:type="uploadResult.success ? 'success' : 'error'"
|
:closable="false"
|
show-icon
|
>
|
<div v-if="uploadResult.success">
|
<p><strong>Logo已成功上传到腾讯云COS!</strong></p>
|
<div class="result-url">
|
<p><strong>访问URL:</strong></p>
|
<el-input
|
v-model="uploadResult.url"
|
readonly
|
style="margin: 8px 0;"
|
>
|
<template #append>
|
<el-button @click="copyUrl">复制</el-button>
|
</template>
|
</el-input>
|
</div>
|
<div class="result-actions">
|
<el-button type="primary" @click="previewLogo">
|
<el-icon><View /></el-icon>
|
预览Logo
|
</el-button>
|
<el-button type="success" @click="saveToDatabase">
|
<el-icon><Document /></el-icon>
|
保存到数据库
|
</el-button>
|
</div>
|
</div>
|
<div v-else>
|
<p><strong>错误信息:</strong> {{ uploadResult.error }}</p>
|
<div class="error-details" v-if="uploadResult.details">
|
<p><strong>详细信息:</strong></p>
|
<pre>{{ uploadResult.details }}</pre>
|
</div>
|
</div>
|
</el-alert>
|
</div>
|
</el-card>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, reactive, onMounted } from 'vue'
|
import { ElMessage } from 'element-plus'
|
import { uploadToCOS } from '@/utils/cos-simple'
|
|
// 组件状态
|
const logoLoaded = ref(false)
|
const logoError = ref(false)
|
const uploading = ref(false)
|
const cosConfig = ref<any>(null)
|
const configError = ref('')
|
|
// 上传进度
|
const uploadProgress = reactive({
|
show: false,
|
fileName: '',
|
percent: 0,
|
status: '',
|
type: undefined as 'success' | 'exception' | undefined,
|
details: ''
|
})
|
|
// 上传结果
|
const uploadResult = reactive({
|
show: false,
|
success: false,
|
url: '',
|
error: '',
|
details: ''
|
})
|
|
// 加载COS配置
|
const loadCOSConfig = async () => {
|
try {
|
configError.value = ''
|
console.log('模拟COS配置...')
|
|
// 模拟配置信息
|
cosConfig.value = {
|
bucket: 'ryc-media-1234567890',
|
region: 'ap-chengdu',
|
domain: 'https://ryc-media-1234567890.cos.ap-chengdu.myqcloud.com'
|
}
|
|
console.log('COS配置设置成功:', cosConfig.value)
|
ElMessage.success('COS配置加载成功')
|
|
} catch (error: any) {
|
console.error('获取COS配置失败:', error)
|
configError.value = `获取COS配置失败: ${error.message}`
|
ElMessage.error('获取COS配置失败')
|
}
|
}
|
|
// 获取Logo文件
|
const fetchLogoFile = async (): Promise<File> => {
|
console.log('正在获取Logo文件...')
|
|
const response = await fetch('/UI/logo.jpg')
|
if (!response.ok) {
|
throw new Error(`获取Logo文件失败: HTTP ${response.status}`)
|
}
|
|
const blob = await response.blob()
|
const file = new File([blob], 'logo.jpg', { type: 'image/jpeg' })
|
|
console.log('Logo文件获取成功:', {
|
name: file.name,
|
size: file.size,
|
type: file.type
|
})
|
|
return file
|
}
|
|
// 上传Logo
|
const uploadLogo = async () => {
|
if (!cosConfig.value) {
|
ElMessage.error('请先加载COS配置')
|
return
|
}
|
|
uploading.value = true
|
uploadProgress.show = true
|
uploadProgress.fileName = 'logo.jpg'
|
uploadProgress.percent = 0
|
uploadProgress.status = '准备上传...'
|
uploadProgress.type = undefined
|
uploadProgress.details = ''
|
uploadResult.show = false
|
|
try {
|
// 1. 获取Logo文件
|
uploadProgress.status = '获取Logo文件...'
|
uploadProgress.details = '正在从 /UI/logo.jpg 获取文件'
|
const logoFile = await fetchLogoFile()
|
|
// 2. 开始上传
|
uploadProgress.status = '连接COS服务...'
|
uploadProgress.details = `准备上传到存储桶: ${cosConfig.value.bucket}`
|
|
// 模拟进度更新
|
const progressInterval = setInterval(() => {
|
if (uploadProgress.percent < 90) {
|
uploadProgress.percent += Math.random() * 15
|
uploadProgress.status = `上传中... ${Math.round(uploadProgress.percent)}%`
|
}
|
}, 300)
|
|
// 执行上传
|
const uploadUrl = await uploadToCOS(logoFile)
|
|
// 清除进度定时器
|
clearInterval(progressInterval)
|
|
// 更新进度为完成
|
uploadProgress.percent = 100
|
uploadProgress.status = '上传完成'
|
uploadProgress.type = 'success'
|
uploadProgress.details = `文件已上传到: ${uploadUrl}`
|
|
// 显示结果
|
uploadResult.show = true
|
uploadResult.success = true
|
uploadResult.url = uploadUrl
|
|
console.log('Logo上传成功:', uploadUrl)
|
ElMessage.success('Logo上传成功!')
|
|
} catch (error: any) {
|
console.error('Logo上传失败:', error)
|
|
uploadProgress.percent = 0
|
uploadProgress.status = '上传失败'
|
uploadProgress.type = 'exception'
|
uploadProgress.details = error.message
|
|
uploadResult.show = true
|
uploadResult.success = false
|
uploadResult.error = error.message || '上传失败'
|
uploadResult.details = error.stack || JSON.stringify(error, null, 2)
|
|
ElMessage.error('Logo上传失败')
|
} finally {
|
uploading.value = false
|
}
|
}
|
|
// 复制URL
|
const copyUrl = async () => {
|
try {
|
await navigator.clipboard.writeText(uploadResult.url)
|
ElMessage.success('URL已复制到剪贴板')
|
} catch (error) {
|
ElMessage.error('复制失败')
|
}
|
}
|
|
// 预览Logo
|
const previewLogo = () => {
|
window.open(uploadResult.url, '_blank')
|
}
|
|
// 保存到数据库
|
const saveToDatabase = async () => {
|
try {
|
// 这里应该调用后端API保存媒体信息到数据库
|
// 模拟保存过程
|
ElMessage.info('正在保存到数据库...')
|
|
// 模拟API调用
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
ElMessage.success('Logo信息已保存到数据库')
|
|
// 可以保存到localStorage供后续使用
|
localStorage.setItem('uploaded_logo_url', uploadResult.url)
|
|
} catch (error) {
|
ElMessage.error('保存到数据库失败')
|
}
|
}
|
|
// 页面加载时自动获取COS配置
|
onMounted(() => {
|
loadCOSConfig()
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.logo-upload-simple {
|
.card-title {
|
margin-bottom: 20px;
|
color: #303133;
|
font-size: 18px;
|
font-weight: 600;
|
}
|
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.logo-preview {
|
display: flex;
|
gap: 20px;
|
align-items: center;
|
|
.logo-image {
|
width: 100px;
|
height: 100px;
|
object-fit: contain;
|
border: 2px solid #e4e7ed;
|
border-radius: 8px;
|
background-color: #f5f7fa;
|
}
|
|
.logo-info {
|
flex: 1;
|
|
p {
|
margin: 8px 0;
|
|
strong {
|
color: #606266;
|
margin-right: 8px;
|
}
|
}
|
}
|
}
|
|
.config-info {
|
p {
|
margin: 8px 0;
|
|
strong {
|
color: #606266;
|
margin-right: 8px;
|
}
|
}
|
}
|
|
.upload-section {
|
text-align: center;
|
|
.upload-tip {
|
margin-top: 16px;
|
color: #909399;
|
font-size: 14px;
|
}
|
}
|
|
.progress-section {
|
.progress-info {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 8px;
|
font-size: 14px;
|
color: #606266;
|
}
|
|
.progress-details {
|
margin-top: 8px;
|
padding: 8px;
|
background-color: #f5f7fa;
|
border-radius: 4px;
|
font-size: 12px;
|
color: #909399;
|
}
|
}
|
|
.result-section {
|
.result-url {
|
margin: 16px 0;
|
}
|
|
.result-actions {
|
margin-top: 16px;
|
display: flex;
|
gap: 8px;
|
flex-wrap: wrap;
|
}
|
|
.error-details {
|
margin-top: 16px;
|
|
pre {
|
background-color: #f5f7fa;
|
padding: 12px;
|
border-radius: 4px;
|
font-size: 12px;
|
color: #606266;
|
white-space: pre-wrap;
|
word-break: break-all;
|
max-height: 200px;
|
overflow-y: auto;
|
}
|
}
|
}
|
}
|
</style>
|