lrj
2 天以前 7ad9c3c93f0cc103347ae2e2429e0122fb512e24
web/src/views/carousel/index.vue
@@ -7,26 +7,26 @@
    <!-- 搜索区域 -->
    <div class="search-section">
      <el-form :model="searchForm" inline>
        <el-form-item label="标题">
          <el-input
            v-model="searchForm.title"
            placeholder="请输入标题关键词"
            clearable
            @keyup.enter="handleSearch"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="success" @click="handleAdd">
            <el-icon><Plus /></el-icon>
            新增轮播图
          </el-button>
          <el-button @click="updateSortOrders">设置顺序</el-button>
        </el-form-item>
      </el-form>
      <div class="search-toolbar">
        <el-input
          v-model="searchForm.title"
          placeholder="请输入标题关键词"
          style="width: 200px"
          clearable
        />
        <el-button type="primary" @click="handleSearch">
          <el-icon><Search /></el-icon>
          查询
        </el-button>
        <el-button type="primary" @click="handleSetOrder">
          <el-icon><Sort /></el-icon>
          设置顺序
        </el-button>
        <el-button type="primary" @click="handleAdd">
          <el-icon><Plus /></el-icon>
          新增轮播图
        </el-button>
      </div>
    </div>
    <!-- 数据表格 -->
@@ -58,10 +58,10 @@
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180" />
        <el-table-column label="操作" width="200" fixed="right">
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
            <el-button type="danger" size="small" @click="handleDelete(row)">删除</el-button>
            <el-button type="primary" size="small" @click="handleEdit(row)" :icon="Edit" circle title="编辑"></el-button>
            <el-button type="danger" size="small" @click="handleDelete(row)" :icon="Delete" circle title="删除"></el-button>
          </template>
        </el-table-column>
      </el-table>
@@ -156,7 +156,7 @@
        <!-- 已上传的媒体列表 -->
        <div v-if="mediaList.length > 0">
          <h5>已上传媒体:</h5>
          <el-table :data="mediaList" size="small" style="width: 100%;">
          <el-table :data="mediaList" size="small" style="width: 100%;" v-loading="uploadingMedia">
            <el-table-column prop="name" label="文件名" min-width="200" />
            <el-table-column prop="mediaType" label="类型" width="100">
              <template #default="{ row }">
@@ -168,8 +168,19 @@
                <div v-if="row.mediaType === 1" class="media-preview" @click="openMediaInNewTab(row.fullUrl)">
                  <img :src="row.fullUrl" class="preview-image clickable" />
                </div>
                <div v-else-if="row.mediaType === 2" class="media-preview" @click="openMediaInNewTab(row.fullUrl)">
                  <video :src="row.fullUrl" class="preview-video clickable" muted></video>
                <div v-else-if="row.mediaType === 2" class="video-thumbnail-container" @click="openMediaInNewTab(row.fullUrl)">
                  <img v-if="row.thumbUrl || row.fullThumbUrl"
                       :src="row.thumbUrl || row.fullThumbUrl"
                       class="video-thumbnail" />
                  <div v-else class="video-placeholder">
                    <i class="el-icon-video-camera"></i>
                    <span>视频缩略图</span>
                  </div>
                  <div class="video-play-overlay">
                    <div class="video-play-button">
                      <i class="el-icon-video-play"></i>
                    </div>
                  </div>
                </div>
              </template>
            </el-table-column>
@@ -193,7 +204,7 @@
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { Plus, Sort, Edit, Delete } from '@element-plus/icons-vue'
import { CarouselApi } from '@/api/carousel'
import { uploadFile, getMediasByTarget, saveMedia, deleteMedia } from '@/api/media'
import { MediaTargetType } from '@/constants/mediaTargetType'
@@ -419,8 +430,8 @@
      ElMessage.error('只能上传图片或视频文件!')
      continue
    }
    if (file.size / 1024 / 1024 > 50) {
      ElMessage.error('文件大小不能超过 50MB!')
    if (file.size / 1024 / 1024 > 300) {
      ElMessage.error('文件大小不能超过 300MB!')
      continue
    }
    
@@ -650,6 +661,13 @@
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }
  
  .search-toolbar {
    display: flex;
    gap: 12px;
    align-items: center;
    justify-content: flex-end;
  }
  .table-section {
    background: #fff;
    padding: 20px;
@@ -692,6 +710,79 @@
  border-radius: 4px;
}
.video-thumbnail-container {
  position: relative;
  width: 80px;
  height: 60px;
  cursor: pointer;
  border-radius: 4px;
  overflow: hidden;
}
.video-thumbnail {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
}
.video-placeholder {
  width: 100%;
  height: 100%;
  background: #f0f0f0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  color: #999;
  font-size: 10px;
}
.video-placeholder i {
  font-size: 16px;
  margin-bottom: 2px;
}
.video-play-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.video-thumbnail-container:hover .video-play-overlay {
  opacity: 1;
}
.video-play-button {
  width: 24px;
  height: 24px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #333;
  transition: all 0.3s ease;
}
.video-play-button:hover {
  background: rgba(255, 255, 255, 1);
  transform: scale(1.1);
}
.video-play-button i {
  font-size: 12px;
}
.clickable {
  cursor: pointer;
  transition: opacity 0.3s;