Sfoglia il codice sorgente

feat:走秀视频和视频换脸

chenjiaxin 1 giorno fa
parent
commit
772fa6b091

+ 17 - 19
src/utils/downloadUtil.js

@@ -1,39 +1,37 @@
-import { Message } from 'element-ui'
+import { Message } from "element-ui";
 
 export default {
-  // 新增视频下载方法
-  async videoDownload(url, fileName) {
+  // 通用文件下载方法
+  async fileDownload(url, fileName) {
     try {
       // 检查URL是否合法
       if (!url) {
-        Message.error('下载地址不能为空');
+        Message.error("下载地址不能为空");
         return false;
       }
-
       // 检查文件类型
-      const fileType = url.toLowerCase().split('.').pop();
-      if (!['mp4', 'mov'].includes(fileType)) {
-        Message.error('只支持下载 MP4 或 MOV 格式的文件');
+      const fileType = url
+        .toLowerCase()
+        .split(".")
+        .pop();
+      if (!["jpg", "jpeg", "png", "gif", "webp",'map4','mov','mp3'].includes(fileType)) {
+        Message.error("该文件的格式不支持下载");
         return false;
       }
-
       const response = await fetch(url, {
-        method: 'GET',
-        credentials: 'include', // 包含 cookies
-        headers: {
-          'Content-Type': 'application/json',
-        }
+        method: "GET",
+        credentials: "include" // 包含 cookies
       });
-      
+
       if (!response.ok) {
-        Message.error('下载失败');
+        Message.error("下载失败");
         return false;
       }
 
       const blob = await response.blob();
-      const $link = document.createElement('a');
+      const $link = document.createElement("a");
       $link.href = URL.createObjectURL(blob);
-      $link.download = fileName || 'video.mp4';
+      $link.download = fileName || url.split("/").pop() || "download";
       document.body.appendChild($link);
       $link.click();
       document.body.removeChild($link);
@@ -44,4 +42,4 @@ export default {
       return false;
     }
   }
-}
+};

+ 31 - 38
src/views/catwalk-video/index.vue

@@ -1,25 +1,8 @@
 <template>
   <div class="app-container">
-    <div class="filter-container">
-      <div class="filter-container-lt">
-        <el-input placeholder="视频标题" class="filter-item" style="width: 200px;" clearable
-          v-model="listQuery.videoTitle" />
-        <!-- <el-input placeholder="SKU" class="filter-item" style="width: 200px;" clearable v-model="listQuery.sku" /> -->
-        <el-button v-waves class="filter-btn" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button>
-      </div>
-      <!-- <div class="filter-container-rt">
-        <excel-import :upload-url="'/api/upload-excel'" :headers="{ token: 'your-token' }"
-          :upload-data="{ type: 'import' }" @on-success="handleImportSuccess">
-          <template slot="upload-text">
-            导入话题
-          </template>
-</excel-import>
-</div> -->
-    </div>
-
     <div class="table-container">
-      <el-table  height="80vh" style="width: 100%" v-loading="listLoading" :key="tableKey" :data="list" row-key="id" stripe border fit
-        highlight-current-row>
+      <el-table height="80vh" style="width: 100%" v-loading="listLoading" :key="tableKey" :data="list" row-key="id"
+        stripe border fit highlight-current-row>
         <el-table-column label="序号" type="index" width="60" align="center" />
         <el-table-column label="视频ID" min-width="100" align="center" prop="id" />
 
@@ -27,25 +10,31 @@
         <el-table-column label="视频封面" min-width="130" align="center" prop="videoCoverImageUrl">
           <template slot-scope="scope">
             <div v-if="scope.row.videoCoverImageUrl" class="video" @click="handlePlay(scope.row)">
-              <img :src="scope.row.videoCoverImageUrl" class="video-img" />
+              <video :src="scope.row.videoUrl" class="video-img" />
               <i class="el-icon-video-play" />
             </div>
           </template>
         </el-table-column>
-        <el-table-column label="视频末帧" min-width="130" align="center" prop="videoDesc">
+        <el-table-column label="视频末帧" min-width="130" align="center" prop="videoEndFrameUrl">
           <template slot-scope="scope">
-            <el-image class="video-last-img" :src="scope.row.videoCoverImageUrl"
-              :preview-src-list="[scope.row.videoCoverImageUrl]">
-            </el-image>
+            <div class="video">
+              <el-image  class="video-last-img video" :src="scope.row.videoEndFrameUrl"
+                :preview-src-list="[scope.row.videoEndFrameUrl]" />
+              <i class="el-icon-zoom-in" />
+            </div>
           </template>
         </el-table-column>
-        <el-table-column label="使用音乐" min-width="110" align="center" prop="videoMusic" />
-        <el-table-column label="拼接视频个数" min-width="100" align="center" prop="publishTime" />
+        <el-table-column label="使用音乐" min-width="110" align="center" prop="videoMusic">
+          <template slot-scope="scope">
+            <span>{{ scope.row.musicClass}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="拼接视频个数" min-width="120" align="center" prop="numVideo" />
         <el-table-column label="SKU" min-width="100" align="center" prop="sku" />
-        <!-- <el-table-column label="操作人" min-width="100" align="center" prop="creator" /> -->
+        <el-table-column label="店铺名称" min-width="100" align="center" prop="storeName" />
         <el-table-column label="创建时间" min-width="100" align="center" prop="createTime" />
-        <el-table-column label="下载次数" min-width="100" align="center" prop="createTime" />
-        <el-table-column label="优化建议" min-width="100" align="center" prop="createTime">
+        <el-table-column label="下载次数" min-width="100" align="center" prop="downloadCount" />
+        <!-- <el-table-column label="优化建议" min-width="100" align="center" prop="createTime">
           <template slot-scope="scope">
             <p v-if="roles.includes('superAdmin')">
               <span class="desc">优化</span>
@@ -56,17 +45,16 @@
                   class="el-icon-edit" /></a>
             </p>
           </template>
-        </el-table-column>
-        <el-table-column v-permission="['superAdmin']" label="使用账号" width="100" align="center" prop="createTime">
+        </el-table-column> -->
+        <!-- <el-table-column v-permission="['superAdmin']" label="使用账号" width="100" align="center" prop="createTime">
           <template slot-scope="scope">
             <el-popover placement="top-start" width="200" trigger="hover" :content="scope.row.videoDesc">
               <span class="desc" slot="reference"></span>
             </el-popover>
           </template>
-        </el-table-column>
+        </el-table-column> -->
         <!-- <el-table-column label="生成账号" min-width="100" align="center" prop="createTime" /> -->
-        <el-table-column label="操作" align="center" width="160"
-          v-bind="device !== 'mobile' ? { fixed: 'right' } : {}">
+        <el-table-column label="操作" align="center" width="160" v-bind="device !== 'mobile' ? { fixed: 'right' } : {}">
           <template slot-scope="scope">
             <el-tooltip class="item" effect="dark" content="下载" placement="top">
               <el-button type="primary" :loading="scope.row && scope.row.id
@@ -120,12 +108,14 @@ import { fetchOralVideoList, deleteOralVideoList } from "@/api/video";
 import downloadUtil from "@/utils/downloadUtil";
 import VideoPlayer from "@/components/VideoPlayer";
 import { mapGetters } from "vuex";
+import permission from "@/directive/permission";
 
 
 export default {
-  name: "oralVideoIndex",
+  name: "catwalkVideoIndex",
   directives: {
-    waves
+    waves,
+    permission
   },
   components: {
     swPage,
@@ -136,7 +126,7 @@ export default {
     // changeTopic
   },
   computed: {
-    ...mapGetters(["device","roles"]) // 从 vuex 中获取设备类型
+    ...mapGetters(["device", "roles"]) // 从 vuex 中获取设备类型
   },
   data() {
     return {
@@ -150,6 +140,7 @@ export default {
         currentPage: 1,
         pageSize: 10,
         videoTitle: null,
+        type:2
         // sku: null,
       },
       currentVideoUrl: null,
@@ -187,7 +178,7 @@ export default {
       this.$set(this.downloadingRows, id, true);
       try {
         const title = sku ? videoTitle + "_" + sku : videoTitle;
-        const res = await downloadUtil.videoDownload(videoUrl, title);
+        const res = await downloadUtil.fileDownload(videoUrl, title);
         if (res) {
           this.$message.success("下载成功");
         }
@@ -279,6 +270,7 @@ export default {
     height: 80px;
     border: 1px solid #eee;
     object-fit: cover;
+    object-position: top;
     cursor: pointer;
   }
 
@@ -305,6 +297,7 @@ export default {
     height: 80px;
     border: 1px solid #eee;
     object-fit: cover;
+    object-position: top;
     cursor: pointer;
   }
 

+ 67 - 0
src/views/face-swap-video/component/editSuggestion.vue

@@ -0,0 +1,67 @@
+<template>
+  <el-dialog :title="'优化建议 - ' + rows.videoTitle" width="540px" :visible.sync="dialogVisible">
+    <el-form :model="form" :rules="rules" ref="suggestionForm" >
+      <el-form-item>
+        <el-input type="textarea" :autosize="{ minRows: 6, maxRows: 10 }" placeholder="请输入内容" v-model="form.suggestion">
+        </el-input>
+      </el-form-item>
+    </el-form>
+
+    <span slot="footer" class="dialog-footer">
+      <el-button @click="dialogVisible = false">取消</el-button>
+      <el-button type="primary" :loading="comfirmLoading" @click="handleConfirm">确定</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+import { editSuggestion } from "@/api/video";
+export default {
+  name: "EditSuggestion",
+  props: {
+    rows: {
+      type: Object,
+      required: true
+    }
+  },
+  data() {
+    return {
+      form: {
+        suggestion: null
+      },
+      dialogVisible: false,
+      comfirmLoading: false,
+      rules: {
+        suggestion: [
+          { required: true, message: "请输入建议", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  methods: {
+    show() {
+      this.dialogVisible = !this.dialogVisible;
+    },
+    handleConfirm() {
+      this.$refs.suggestionForm.validate(valid => {
+        if (valid) {
+          this.comfirmLoading = true;
+          editSuggestion(this.form).then(res =>{
+            if(res.code == 200){
+              this.$message.success("修改成功");
+              this.$emit("confirm");
+            }
+          }).finally(()=>{
+            this.comfirmLoading = false;
+          })
+        } else {
+          return false;
+        }
+      });
+      this.dialogVisible = false;
+    }
+  }
+};
+</script>
+
+

+ 71 - 0
src/views/face-swap-video/component/suggestionTable.vue

@@ -0,0 +1,71 @@
+<template>
+  <el-dialog
+    title="查看优化建议"
+    width="700px"
+    :visible.sync="dialogVisible"
+  >
+  <el-table style="width: 100%" v-loading="listLoading" :key="tableKey" :data="list" row-key="id" stripe border fit
+  highlight-current-row>
+  <el-table-column label="序号" type="index" width="60" align="center" />
+  <el-table-column label="优化建议" min-width="100" align="center" prop="suggestion" />
+  <el-table-column label="建议人" min-width="100" align="center" prop="name" />
+  </el-table>
+    <!-- 分页 -->
+    <swPage v-if="total > 0" key="2" :listQuery="listQuery" :total="total" pos="btmRight" @retPage="retPage" />
+  </el-dialog>
+</template>
+
+<script>
+import { fetchSuggestionList } from "@/api/catwalkVideo";
+import swPage from "@/views/common/swPage";
+export default {
+  name: "SuggestionTable",
+  props: {
+    rows: {
+      type: Object,
+      required: true
+    }
+  },
+  components: {
+    swPage,
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      listLoading: false,
+      tableKey: 0,
+      list: [],
+      total:0,
+      listQuery: {
+        currentPage: 1,
+        pageSize: 10,
+      },
+    };
+  },
+  methods: {
+    show() {
+      this.dialogVisible = !this.dialogVisible;
+    },
+    getList() {
+      this.listLoading = true;
+      fetchSuggestionList(this.listQuery).then(res => {
+        if (200 == res.code) {
+          this.total = res.data.total;
+          this.list = res.data.rows;
+        }
+        this.listLoading = false;
+      });
+    },
+    retPage() {
+      //分页
+      this.getList();
+    },
+  }
+};
+</script>
+
+<style scoped>
+.el-select {
+  width: 100%;
+}
+</style>

+ 160 - 108
src/views/face-swap-video/index.vue

@@ -4,7 +4,13 @@
       <div class="filter-container-lt">
         <el-input placeholder="视频标题" class="filter-item" style="width: 200px;" clearable
           v-model="listQuery.videoTitle" />
-        <!-- <el-input placeholder="SKU" class="filter-item" style="width: 200px;" clearable v-model="listQuery.sku" /> -->
+        <!-- <el-input
+          placeholder="SKU"
+          class="filter-item"
+          style="width: 200px;"
+          clearable
+          v-model="listQuery.sku"
+        /> -->
         <el-button v-waves class="filter-btn" type="primary" icon="el-icon-search" @click="handleFilter">搜索</el-button>
       </div>
       <!-- <div class="filter-container-rt">
@@ -13,102 +19,92 @@
           <template slot="upload-text">
             导入话题
           </template>
-        </excel-import>
-      </div> -->
+</excel-import>
+</div> -->
     </div>
 
     <div class="table-container">
-      <el-table height="80vh" style="width: 100%" v-loading="listLoading" :key="tableKey" :data="list" row-key="id" stripe border fit
-        highlight-current-row>
+      <el-table height="80vh" style="width: 100%" v-loading="listLoading" :key="tableKey" :data="list" row-key="id"
+        stripe border fit highlight-current-row>
         <el-table-column label="序号" type="index" width="60" align="center" />
         <el-table-column label="视频ID" min-width="100" align="center" prop="id" />
-
         <el-table-column label="视频标题" min-width="150" align="center" prop="videoTitle" />
-        <el-table-column label="视频封面" min-width="110" align="center" prop="videoCoverImageUrl">
+        <el-table-column label="原图片/视频" min-width="130" align="center" prop="videoUrl">
           <template slot-scope="scope">
-            <div v-if="scope.row.videoCoverImageUrl" class="video" @click="handlePlay(scope.row)">
-              <img :src="scope.row.videoCoverImageUrl" class="video-img" />
+            <div v-if="isVideoFormat(scope.row.rawVideoUrl)" class="video"
+              @click="handlePlay(scope.row, scope.row.rawVideoUrl)">
+              <video :src="scope.row.rawVideoUrl" class="video-img" />
               <i class="el-icon-video-play" />
             </div>
+            <div class="video" v-else>
+              <el-image  class="video-last-img video" :src="scope.row.rawVideoUrl"
+                :preview-src-list="[scope.row.rawVideoUrl]" />
+              <i class="el-icon-zoom-in" />
+            </div>
           </template>
         </el-table-column>
-        <el-table-column label="视频描述" min-width="150" align="center" prop="videoDesc">
+        <el-table-column label="处理后图片/视频" min-width="130" align="center" prop="videoUrl">
           <template slot-scope="scope">
-            <el-popover placement="top-start" width="200" trigger="hover" :content="scope.row.videoDesc">
-              <span class="desc"
-                slot="reference">{{ scope.row.videoDesc }}</span>
-            </el-popover>
+            <div v-if="isVideoFormat(scope.row.videoUrl)" class="video"
+              @click="handlePlay(scope.row, scope.row.videoUrl)">
+              <!-- <img :src="scope.row.videoCoverImageUrl" class="video-img" /> -->
+              <video :src="scope.row.videoUrl" class="video-img" />
+              <i class="el-icon-video-play" />
+            </div>
+            <div class="video" v-else>
+              <el-image  class="video-last-img video" :src="scope.row.videoUrl"
+                :preview-src-list="[scope.row.videoUrl]" />
+              <i class="el-icon-zoom-in" />
+            </div>
           </template>
         </el-table-column>
-        <el-table-column label="SKU" min-width="100" align="center" prop="sku" />
-
-        <el-table-column label="SKUID" min-width="100" align="center" prop="skuId" />
-        <el-table-column label="审核状态" min-width="100" align="center" prop="reviewStatus">
+        <el-table-column label="换脸所用模特" min-width="130" align="center" prop="swapModelUrl">
           <template slot-scope="scope">
-            <span class="status-tag" :class="{
-              'status-pending': scope.row.reviewStatus === 0,
-              'status-success': scope.row.reviewStatus === 1,
-              'status-error': scope.row.reviewStatus === 2
-            }"></span>
-            {{ getValueByKey(scope.row.reviewStatus, auditStatus) }}
+            <div class="video">
+              <el-image  class="video-last-img video" :src="scope.row.swapModelUrl"
+                :preview-src-list="[scope.row.swapModelUrl]" />
+              <i class="el-icon-zoom-in" />
+            </div>
           </template>
         </el-table-column>
-
-        <el-table-column label="审核时间" min-width="100" align="center" prop="reviewTime" />
-        <el-table-column label="审核人" min-width="100" align="center" prop="reviewer" />
-        <el-table-column label="发布状态" min-width="100" align="center" prop="publishStatus">
+        <!-- <el-table-column label="操作人" min-width="100" align="center" prop="creator" /> -->
+        <el-table-column label="创建时间" min-width="100" align="center" prop="createTime" />
+        <el-table-column label="下载次数" min-width="100" align="center" prop="downlaodCount" />
+        <!-- <el-table-column label="优化建议" min-width="100" align="center" prop="remark">
           <template slot-scope="scope">
-            <span class="status-tag" :class="{
-              'status-pending': scope.row.publishStatus === 0,
-              'status-success': scope.row.publishStatus === 1,
-              'status-error': scope.row.publishStatus === 2
-            }"></span>
-            {{ getValueByKey(scope.row.publishStatus, auditStatus) }}
+            <p v-if="roles.includes('superAdmin')">
+              <span class="desc">{{remark}}</span>
+              <a class="look-more" href="javascript:void(0);" @click="handleViewSuggestions(scope.row)">更多&nbsp;>></a>
+            </p>
+            <p v-else>
+              <a class="edit" href="javascript:void(0);" @click="handleEditSuggestions(scope.row)"><i
+                  class="el-icon-edit" /></a>
+            </p>
+          </template>
+        </el-table-column> -->
+        <!-- <el-table-column v-permission="['superAdmin']" label="使用账号" width="100" align="center" prop="createTime">
+          <template slot-scope="scope">
+            <el-popover placement="top-start" width="200" trigger="hover" :content="scope.row.videoDesc">
+              <span class="desc" slot="reference"></span>
+            </el-popover>
           </template>
         </el-table-column>
-        <el-table-column label="发布时间" min-width="100" align="center" prop="publishTime" />
-        <el-table-column label="发布人" min-width="100" align="center" prop="publisher" />
-        <el-table-column label="关联话题" min-width="100" align="center" prop="hotWords" />
-
-        <el-table-column label="直播时间" min-width="100" align="center" prop="liveTime" />
-        <!-- <el-table-column
-          label="直播场次"
-          min-width="100"
-          align="center"
-          prop="liveSession"
-        /> -->
-        <el-table-column label="直播中控" min-width="120" align="center" prop="liveController">
-        </el-table-column>
-
-        <el-table-column label="直播间号" min-width="100" align="center" prop="liveRoomId" />
-        <el-table-column label="操作人" min-width="100" align="center" prop="creator" />
-
-        <el-table-column label="创建时间" min-width="100" align="center" prop="createTime" />
-        <el-table-column label="操作" align="center" min-width="160"
-          v-bind="device !== 'mobile' ? { fixed: 'right' } : {}">
+        <el-table-column label="生成账号" min-width="100" align="center" prop="createTime" /> -->
+        <el-table-column label="操作" align="center" width="160" v-bind="device !== 'mobile' ? { fixed: 'right' } : {}">
           <template slot-scope="scope">
             <el-tooltip class="item" effect="dark" content="下载" placement="top">
               <el-button type="primary" :loading="scope.row && scope.row.id
-                ? downloadingRows[scope.row.id]
-                : false
+                  ? downloadingRows[scope.row.id]
+                  : false
                 " size="mini" icon="el-icon-download" circle @click="handleDownload(scope.row)" />
             </el-tooltip>
             <el-tooltip class="item" effect="dark" content="播放" placement="top">
-              <el-button type="success" size="mini" icon="el-icon-caret-right" circle @click="handlePlay(scope.row)" />
+              <el-button type="success" size="mini" icon="el-icon-caret-right" circle
+                @click="handlePlay(scope.row, scope.row.videoUrl)" />
             </el-tooltip>
-            <el-tooltip
-              class="more"
-              effect="dark"
-              content="删除"
-              placement="top"
-            >
-              <el-button
-                type="danger"
-                size="mini"
-                icon="el-icon-delete-solid"
-                circle
-                @click="handleDelete(scope.row)"
-              />
+            <el-tooltip class="more" effect="dark" content="删除" placement="top">
+              <el-button type="danger" size="mini" icon="el-icon-delete-solid" circle
+                @click="handleDelete(scope.row)" />
             </el-tooltip>
             <!-- <el-tooltip class="more" effect="dark" content="更多" placement="top">
               <el-dropdown trigger="click" @command="command => handleMore(command, scope.row)">
@@ -129,8 +125,12 @@
     <!-- 视频播放 -->
     <video-player ref="videoPlayer" :video-url="currentVideoUrl" :video-title="currentVideoTitle"
       @close="handlePlayerClose" />
-    <!-- 修改话题-->
-     <change-topic ref="changeTopicRef" :rows="currentVideo" @confirm="handleTopicChange" />
+    <!-- 优化建议 -->
+    <suggestion-table ref="suggestionTable" :rows="currentVideo" />
+    <!-- 编辑优化建议 -->
+    <edit-suggestion ref="editSuggestion" :rows="currentVideo" @confirm="handleCofirmSuggestion" />
+    <el-image ref="elImage" style="width: 0; height: 0;" :src="imageUrl" :preview-src-list="[imageUrl]">
+    </el-image>
   </div>
 </template>
 
@@ -139,28 +139,30 @@ import waves from "@/directive/waves";
 import swPage from "@/views/common/swPage";
 import { auditStatus } from "@/constants/index";
 import { getValueByKey } from "@/utils/index";
-import ExcelImport from "@/components/ExcelImport";
-import changeTopic from "@/views/oral-video/component/changeTopic";
+// import ExcelImport from "@/components/ExcelImport";
+import EditSuggestion from "./component/editSuggestion";
+import SuggestionTable from "./component/suggestionTable";
 
 import { fetchOralVideoList, deleteOralVideoList } from "@/api/video";
 import downloadUtil from "@/utils/downloadUtil";
 import VideoPlayer from "@/components/VideoPlayer";
 import { mapGetters } from "vuex";
 
-
 export default {
-  name: "oralVideoIndex",
+  name: "faceswapVideoIndex",
   directives: {
     waves
   },
   components: {
     swPage,
     VideoPlayer,
-    ExcelImport,
-    changeTopic
+    SuggestionTable,
+    EditSuggestion
+    // ExcelImport,
+    // changeTopic
   },
   computed: {
-    ...mapGetters(["device"]) // 从 vuex 中获取设备类型
+    ...mapGetters(["device", "roles"]) // 从 vuex 中获取设备类型
   },
   data() {
     return {
@@ -174,11 +176,13 @@ export default {
         currentPage: 1,
         pageSize: 10,
         videoTitle: null,
+        type: 3
         // sku: null,
       },
       currentVideoUrl: null,
       currentVideoTitle: null,
-      currentVideo:{},
+      currentVideo: {},
+      imageUrl: null
     };
   },
   //页面创建的时候执行
@@ -187,6 +191,18 @@ export default {
   },
   methods: {
     getValueByKey,
+    isVideoFormat(url) {
+      if (!url) return false;
+      return url.toLowerCase().endsWith(".mp4");
+    },
+    // 新增图片格式检测方法
+    isImageFormat(url) {
+      const extension = url
+        .toLowerCase()
+        .split(".")
+        .pop();
+      return ["jpg", "jpeg", "png", "gif", "webp"].includes(extension);
+    },
     getList() {
       this.listLoading = true;
       fetchOralVideoList(this.listQuery).then(res => {
@@ -211,7 +227,7 @@ export default {
       this.$set(this.downloadingRows, id, true);
       try {
         const title = sku ? videoTitle + "_" + sku : videoTitle;
-        const res = await downloadUtil.videoDownload(videoUrl, title);
+        const res = await downloadUtil.fileDownload(videoUrl, title);
         if (res) {
           this.$message.success("下载成功");
         }
@@ -221,25 +237,36 @@ export default {
         this.$set(this.downloadingRows, id, false);
       }
     },
-    // 视频播放
-    handlePlay(row) {
-      const { videoUrl, videoTitle } = row;
-      ``;
-      if (!videoUrl) {
-        this.$message.error("视频地址不存在");
+    handlePlay(row, url) {
+      const { videoTitle } = row;
+      if (!url) {
+        this.$message.error("媒体地址不存在");
         return;
       }
-      this.currentVideoUrl = videoUrl;
-      this.currentVideoTitle = videoTitle;
-      this.$refs.videoPlayer.show();
+
+      if (this.isVideoFormat(url)) {
+        // 视频播放逻辑
+        this.currentVideoUrl = url;
+        this.currentVideoTitle = videoTitle;
+        this.$refs.videoPlayer.show();
+      } else if (this.isImageFormat(url)) {
+        // 新增图片格式判断
+        this.$nextTick(() => {
+          this.imageUrl = url;
+          this.$refs.elImage.clickHandler();
+        });
+      } else {
+        this.$message.error("不支持的文件格式");
+      }
     },
+
     handlePlayerClose() {
       this.currentVideoUrl = "";
       this.currentVideoTitle = "";
     },
     handleDelete(row) {
       //删除
-      this.$confirm("是否删除该视频?", "提示", {
+      this.$confirm("是否删除该图片/视频?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning"
@@ -257,13 +284,6 @@ export default {
         });
       });
     },
-    // 导入话题回调
-    handleImportSuccess({ data, header, file }) {
-      console.log("导入的数据:", data);
-      console.log("表头:", header);
-      console.log("原始文件:", file);
-      // 处理导入的数据
-    },
     //更多
     handleMore(command, row) {
       if (command === "delete") {
@@ -272,14 +292,16 @@ export default {
         this.changeTopic(row); // 修改话题
       }
     },
-    // 修改话题
-    changeTopic(row) {
+    handleViewSuggestions(row) {
+      this.currentVideo = row;
+      this.$refs.suggestionTable.show();
+    },
+    handleEditSuggestions(row) {
       this.currentVideo = row;
-      this.$refs.changeTopicRef.show();
+      this.$refs.editSuggestion.show();
     },
-    handleTopicChange() {
-      this.$refs.changeTopicRef.show();
-      this.retPage()
+    handleCofirmSuggestion() {
+      this.retPage();
     }
   }
 };
@@ -298,6 +320,22 @@ export default {
   }
 }
 
+.video-last-img {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-top: 5px;
+
+  /deep/.el-image__preview {
+    width: 80px;
+    height: 80px;
+    border: 1px solid #eee;
+    object-fit: cover;
+    object-position: top;
+    cursor: pointer;
+  }
+}
+
 .video {
   position: relative;
   display: flex;
@@ -307,6 +345,7 @@ export default {
   &:hover {
     i {
       opacity: 1;
+      pointer-events: none;
     }
 
     .video-img {
@@ -315,16 +354,18 @@ export default {
   }
 
   &-img {
-    width: 60px;
-    height: 60px;
+    width: 80px;
+    height: 80px;
     border: 1px solid #eee;
+    vertical-align: top;
     object-fit: cover;
+    object-position: top;
     cursor: pointer;
   }
 
   i {
-    width: 60px;
-    height: 60px;
+    width: 80px;
+    height: 80px;
     position: absolute;
     top: 85%;
     left: 50%;
@@ -374,4 +415,15 @@ export default {
 .more {
   margin-left: 10px;
 }
+
+.look-more {
+  font-size: 12px;
+  color: #ae8877;
+  text-decoration: underline;
+}
+
+.edit {
+  font-size: 16px;
+  color: #ae8877;
+}
 </style>

+ 2 - 1
src/views/oral-video/index.vue

@@ -174,6 +174,7 @@ export default {
         currentPage: 1,
         pageSize: 10,
         videoTitle: null,
+        type:1
         // sku:null
       },
       currentVideoUrl: null,
@@ -211,7 +212,7 @@ export default {
       this.$set(this.downloadingRows, id, true);
       try {
         const title = sku ? videoTitle + "_" + sku : videoTitle;
-        const res = await downloadUtil.videoDownload(videoUrl, title);
+        const res = await downloadUtil.fileDownload(videoUrl, title);
         if (res) {
           this.$message.success("下载成功");
         }

+ 1 - 1
src/views/product/product.vue

@@ -209,7 +209,7 @@
         this.$set(this.downloadingRows, id, true);
         try {
           const title = sku ? videoTitle + "_" + sku : videoTitle;
-          const res = await downloadUtil.videoDownload(videoUrl, title);
+          const res = await downloadUtil.fileDownload(videoUrl, title);
           if (res) {
             this.$message.success("下载成功");
           }

+ 2 - 2
vue.config.js

@@ -34,8 +34,8 @@ module.exports = {
       //   }
       // },
       "/app": {
-        // target: "http://10.41.3.106:9093",
-        target: "https://portal.gloria.com.cn",
+         target: "http://10.41.3.106:9093",
+        // target: "https://portal.gloria.com.cn",
         changeOrigin: true
       }
     }