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