From 93eb6b470773bc49ea6e1a9d4cbd914eb95d525b Mon Sep 17 00:00:00 2001 From: lrj <owen.stl@gmail.com> Date: 星期二, 30 九月 2025 17:38:04 +0800 Subject: [PATCH] feat: 完善比赛晋级功能并清理测试文件 --- web/src/components/SubmissionFiles.vue | 130 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 105 insertions(+), 25 deletions(-) diff --git a/web/src/components/SubmissionFiles.vue b/web/src/components/SubmissionFiles.vue index a3e9c38..be768b9 100644 --- a/web/src/components/SubmissionFiles.vue +++ b/web/src/components/SubmissionFiles.vue @@ -25,15 +25,20 @@ </div> <!-- 瑙嗛棰勮 --> - <div v-else-if="isVideo(file)" class="video-preview"> - <video - :src="file.url" - controls - preload="metadata" - class="preview-video" - > - 鎮ㄧ殑娴忚鍣ㄤ笉鏀寔瑙嗛鎾斁 - </video> + <div v-else-if="isVideo(file)" class="video-preview" @click="playVideo(file)"> + <div class="video-thumbnail"> + <el-image + :src="file.thumbUrl || file.url" + :alt="file.name" + fit="cover" + class="preview-image" + /> + <div class="play-overlay"> + <el-icon :size="40" class="play-icon"> + <VideoPlay /> + </el-icon> + </div> + </div> <div class="file-info"> <span class="file-name">{{ file.name }}</span> <span class="file-size">{{ formatFileSize(file.fileSize) }}</span> @@ -54,10 +59,10 @@ <el-button type="primary" size="small" - @click="downloadFile(file)" + @click="previewOrDownloadFile(file)" class="download-btn" > - 涓嬭浇 + {{ isImage(file) || isVideo(file) ? '棰勮' : '涓嬭浇' }} </el-button> </div> </div> @@ -67,13 +72,33 @@ <div v-else class="no-files"> <el-empty description="鏆傛棤鎻愪氦璧勬枡" :image-size="80" /> </div> + + <!-- 瑙嗛鎾斁瀵硅瘽妗� --> + <el-dialog + v-model="videoDialogVisible" + :title="currentVideoFile?.name || '瑙嗛鎾斁'" + width="80%" + center + > + <div class="video-player-container"> + <video + v-if="currentVideoFile" + :src="currentVideoFile.url" + controls + autoplay + class="video-player" + > + 鎮ㄧ殑娴忚鍣ㄤ笉鏀寔瑙嗛鎾斁 + </video> + </div> + </el-dialog> </div> </template> <script setup> -import { computed } from 'vue' -import { ElImage, ElButton, ElIcon, ElEmpty } from 'element-plus' -import { Document, Files } from '@element-plus/icons-vue' +import { computed, ref } from 'vue' +import { ElImage, ElButton, ElIcon, ElEmpty, ElDialog } from 'element-plus' +import { Document, Files, VideoPlay } from '@element-plus/icons-vue' const props = defineProps({ files: { @@ -81,6 +106,10 @@ default: () => [] } }) + +// 瑙嗛鎾斁瀵硅瘽妗� +const videoDialogVisible = ref(false) +const currentVideoFile = ref(null) // 鍥剧墖鏂囦欢URL鍒楄〃锛堢敤浜庨瑙堬級 const imageUrls = computed(() => { @@ -123,15 +152,27 @@ return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i] } -// 涓嬭浇鏂囦欢 -const downloadFile = (file) => { - const link = document.createElement('a') - link.href = file.url - link.download = file.name - link.target = '_blank' - document.body.appendChild(link) - link.click() - document.body.removeChild(link) +// 鎾斁瑙嗛 +const playVideo = (file) => { + currentVideoFile.value = file + videoDialogVisible.value = true +} + +// 棰勮鎴栦笅杞芥枃浠� +const previewOrDownloadFile = (file) => { + if (isImage(file) || isVideo(file)) { + // 鍥剧墖鍜岃棰戝湪鏂扮獥鍙d腑棰勮 + window.open(file.url, '_blank') + } else { + // 鍏朵粬鏂囦欢绫诲瀷涓嬭浇 + const link = document.createElement('a') + link.href = file.url + link.download = file.name + link.target = '_blank' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + } } </script> @@ -172,11 +213,37 @@ flex-direction: column; } -.preview-image, -.preview-video { +.preview-image { width: 100%; height: 120px; object-fit: cover; +} + +.video-thumbnail { + position: relative; + width: 100%; + height: 120px; + cursor: pointer; +} + +.play-overlay { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(0, 0, 0, 0.6); + border-radius: 50%; + padding: 12px; + transition: all 0.3s; +} + +.play-overlay:hover { + background: rgba(0, 0, 0, 0.8); + transform: translate(-50%, -50%) scale(1.1); +} + +.play-icon { + color: white; } .document-preview { @@ -235,4 +302,17 @@ .file-document { border-color: #E6A23C; } + +.video-player-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 300px; +} + +.video-player { + width: 100%; + max-width: 800px; + height: auto; +} </style> \ No newline at end of file -- Gitblit v1.8.0