lrj
昨天 93eb6b470773bc49ea6e1a9d4cbd914eb95d525b
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)) {
    // 图片和视频在新窗口中预览
    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>