Forráskód Böngészése

Merge branch 'master' of http://192.168.0.115:3000/chenzhiguang/FD_Pano

tremble 4 éve
szülő
commit
c08a6e72b5

+ 12 - 2
src/Store/index.js

@@ -20,7 +20,12 @@ const store = new Vuex.Store({
     sceneList:[],
     activeItem:'',
     isEditing:false,
-    isShow: false
+    isShow: false,
+
+    uploadStatusListAudio: [],
+    uploadStatusListImage: [],
+    uploadStatusListPano: [],
+    uploadStatusListVideo: [],
   },
   getters: {
     isEditing:state=>state.isEditing,
@@ -36,7 +41,12 @@ const store = new Vuex.Store({
     temptablist:state=>state.temptablist,
     sceneList:state=>state.sceneList,
     isShow:state=>state.isShow,
-    allVrlist:state=>state.allVrlist
+    allVrlist:state=>state.allVrlist,
+
+    uploadStatusListAudio: state => state.uploadStatusListAudio,
+    uploadStatusListImage: state => state.uploadStatusListImage,
+    uploadStatusListPano: state => state.uploadStatusListPano,
+    uploadStatusListVideo: state => state.uploadStatusListVideo,
   },
   mutations: {
     SetTabList(state, list) {

BIN
src/assets/images/icons/material_preview_close@2x.png


+ 1 - 1
src/components/tableSelect.vue

@@ -53,7 +53,7 @@
           <td colspan="10">
             <div class="nodata">
               <img :src="$noresult" alt="">
-              <span>{{isClickSearch?'未搜索到结果':'暂无素材,快去上传吧'}}</span>
+              <span>{{isClickSearch?'未搜索到结果~':'暂无素材,快去上传吧'}}</span>
             </div>
           </td>
         </tr>

+ 47 - 53
src/views/material/audio/index.vue

@@ -91,11 +91,11 @@
           >
         </div>
       </tableList>
-      <UploadTaskList class="upload-list-new" v-show="uploadTaskList.length != 0" fileType="AUDIO" :taskList="uploadTaskList" @cancel-task="onCancelTask"></UploadTaskList>
+      <UploadTaskList class="upload-list-new" fileType="AUDIO" :taskList="uploadListForUI" @cancel-task="onCancelTask"></UploadTaskList>
       <div class="total-number" v-if="list.length !== 0 || hasMoreData">已加载{{list.length}}条</div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && lastestUsedSearchKey">
         <img :src="$noresult" alt="" />
-        <span>未搜索到结果</span>
+        <span>未搜索到结果~</span>
       </div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && !lastestUsedSearchKey">
         <img :src="config.empty" alt="" />
@@ -125,6 +125,7 @@ import Upload from "@/components/shared/uploads/UploadMultiple";
 import { changeByteUnit } from "@/utils/file";
 import UploadTaskList from "../components/uploadList1.1.0.vue";
 import { debounce } from "@/utils/other.js"
+import { mapState } from 'vuex';
 
 import {
   getMaterialList,
@@ -167,10 +168,13 @@ export default {
       list: [],
       hasMoreData: true,
       isRequestingMoreData: false,
-      uploadTaskList: [],
-      uploadHandlerList: [],
     };
   },
+  computed: {
+    ...mapState({
+      uploadListForUI: 'uploadStatusListAudio',
+    })
+  },
   mounted() {
   },
   watch: {
@@ -269,8 +273,6 @@ export default {
       });
     },
     onFileChange(e) {
-      let uploadFileList = [];
-
       e.files.forEach((eachFile, i) => {
         if (eachFile.name.toLowerCase().indexOf("mp3") <= -1) {
           setTimeout(() => {
@@ -292,63 +294,55 @@ export default {
           return;
         }
 
-        let tmp = {
+        let itemInUploadList = {
           title: eachFile.name,
           ifKnowProgress: true,
           progress: 0,
           status: 'LOADING',
           statusStr: "正在上传素材",
           uid: `u_${this.$randomWord(true, 8, 8)}`,
+          abortHandler: null,
         };
-        this.uploadTaskList.push(tmp);
-        uploadFileList.push({
-          file: eachFile,
-          list: { ...tmp },
-        });
-      });
-
-      let uploadPromiseList = [];
-      uploadFileList.forEach((data, index) => {
-        let promise = new Promise((resolve, reject) => {
-          const handler = uploadMaterial(
-            {
-              file: data.file
-            },
-            {
-              type: TYPE,
-              uid: data.list.uid,
-            },
-            (response) => {
-              this.uploadTaskList[index].status = 'SUCCESS'
-              this.uploadTaskList[index].statusText = '素材上传成功'
-              resolve(response);
-            },
-            (err) => {
-              if (err.status === 0) { // 用户取消了上传任务。TODO:判断依据不够完美。
-                this.uploadTaskList[index].status = 'CANCELLED'
-                this.uploadTaskList[index].statusText = '已取消'
-              } else {
-                this.uploadTaskList[index].status = 'FAIL'
-                this.uploadTaskList[index].statusText = '素材上传失败'
-              }
-              reject(err);
-            },
-            (progress) => {
-              this.uploadTaskList[index].progress = progress
+        
+        itemInUploadList.abortHandler = uploadMaterial(
+          {
+            file: eachFile
+          },
+          {
+            type: TYPE,
+            uid: itemInUploadList.uid,
+          },
+          () => { // 上传成功
+            const index = this.uploadListForUI.findIndex((eachItem) => {
+              eachItem.uid === itemInUploadList.uid
+            })
+            this.uploadListForUI.splice(index, 1)
+            this.refreshListDebounced()
+          },
+          (err) => {
+            if (err.statusText === 'abort') { // 用户取消了上传任务。
+              const index = this.uploadListForUI.findIndex((eachItem) => {
+                eachItem.uid === itemInUploadList.uid
+              })
+              this.uploadListForUI.splice(index, 1)
+            } else {
+              itemInUploadList.status = 'FAIL'
+              itemInUploadList.statusText = '素材上传失败'
             }
-          );
-          this.uploadHandlerList.push(handler)
-        });
-        uploadPromiseList.push(promise);
-      });
-      Promise.allSettled(uploadPromiseList).then(() => {
-        this.uploadTaskList = []
-        this.uploadHandlerList = []
-        this.refreshListDebounced()
+          },
+          (progress) => {
+            itemInUploadList.progress = progress
+          }
+        );
+
+        this.uploadListForUI.push(itemInUploadList);
       });
     },
-    onCancelTask(index) {
-      this.uploadHandlerList[index].abort()
+    onCancelTask(uid) {
+      const index = this.uploadListForUI.findIndex((eachItem) => {
+        return eachItem.uid === uid
+      })
+      this.uploadListForUI[index].abortHandler.abort()
     },
     getMoreMaterialItem() {
       this.isRequestingMoreData = true

+ 0 - 44
src/views/material/components/uploadList.vue

@@ -1,44 +0,0 @@
-<template>
-  <div class="upload-list"  @click.stop>
-    <div class="top">
-      <span>上传列表({{uploadList.length}})</span>
-      <i class="iconfont icon_close" @click="$emit('close')"></i>
-    </div>
-    <ul v-if="uploadList.length > 0">
-      <li v-for="(item, i) in uploadList" :key="i">
-        <span>{{ item.name }}</span>
-        <span
-          class="success"
-          :class="item.status == 2 || item.status == 5 ? 'error' : ''"
-          >{{ $STRSTATUS[item.status] }}</span
-        >
-        <i @click="$emit('del',i)" class="iconfont icon_close"></i>
-      </li>
-    </ul>
-    <div class="nouploaddata" v-else>
-        暂无正在上传的素材
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  props:['list'],
-  computed:{
-    uploadList(){
-      return this.list.filter(item=>item.status != 3) || []
-    }
-  },
-  methods:{
-    
-  }
-}
-</script>
-
-<style lang="less" scoped>
-
-</style>
-
-<style lang="less" scoped>
-@import '../style.less';
-</style>

+ 9 - 6
src/views/material/components/uploadList1.1.0.vue

@@ -16,8 +16,8 @@
     <div class="content" v-show="expandSwitch">
       <div
         class="list-item" 
-        v-for="(taskItem, index) in taskList"
-        :key="index"
+        v-for="(taskItem) in taskList"
+        :key="taskItem.uid"
       >
         <div class="left">
           <img class="type-icon" :src="uploadFieIconUrl" alt=""/>
@@ -35,7 +35,7 @@
             v-show="(taskItem.status === 'LOADING' && taskItem.ifKnowProgress) || taskItem.status === 'FAIL'"
             class="cancel-btn"
             :src="require('@/assets/images/icons/material_preview_upload_cancel@2x.png')"
-            @click="onClickCancel(index)"
+            @click="onClickCancel(taskItem.uid)"
           />
         </div>
         <div class="progress-bar" v-if="taskItem.ifKnowProgress && taskItem.status === 'LOADING'" :style="{width: Math.round(taskItem.progress * 100) + '%'}"></div>
@@ -60,7 +60,8 @@ export default {
        *  ifKnowProgress: Boolean // false则进度条效果是loading而不是具体进度
        *  progress:Number // 进度,0到1之间。
        *  status: 'FAIL' | 'LOADING' // 将来可能还需要:'SUCCESS', 'CANCELLED'
-       *  statusText
+       *  statusText,
+       *  uid: String,
        * }
        */
       type: Array,
@@ -72,6 +73,7 @@ export default {
       //     progress: '0.3',
       //     status: 'LOADING',
       //     statusText: '上传中',
+      //     uid: 'a'
       //   },
       //   {
       //     title: '标题',
@@ -79,6 +81,7 @@ export default {
       //     progress: '0.3',
       //     status: 'LOADING',
       //     statusText: '后台处理中',
+      //     uid: 'b'
       //   },
       //   {
       //     title: '标题',
@@ -113,8 +116,8 @@ export default {
     onClickExpand() {
       this.expandSwitch = !this.expandSwitch
     },
-    onClickCancel(index) {
-      this.$emit('cancel-task', index)
+    onClickCancel(uid) {
+      this.$emit('cancel-task', uid)
     },
   }
 }

+ 68 - 69
src/views/material/image/index.vue

@@ -13,7 +13,7 @@
           <span>上传素材</span>
           <i class="iconfont icon-material_prompt hover-tips hover-tips-upload-icon">
             <div>
-              <div class="remark">请上传120MB以内、jpg/png格式的图片</div>
+              <div class="remark">请上传10MB以内、jpg/png格式的图片</div>
             </div>
           </i>
           <upload
@@ -59,7 +59,7 @@
           {{ data.name }}
         </div>
         <div slot-scope="{ data, item, sub }" slot="item" style="width: 100%">
-          <div class="handle" v-if="sub.canclick">
+          <div v-if="sub.canclick" class="handle">
             <i
               class="iconfont iconbs_list_edit hover-tips"
               @click="(showRename = true), (popupItem = item)"
@@ -74,27 +74,26 @@
               </div>
             </i>
           </div>
-          <div class="img" v-else-if="sub.type == 'image'">
+          <div v-else-if="sub.type == 'image'" class="img">
             <img
               :id="'img' + item.id"
-              v-viewer
               :src="data + `?${Math.random()}`"
               alt=""
+              @click="previewImage(item)"
             />
           </div>
           <span
             v-else
-            @click="sub.fontweight && viewImg('img' + item.id)"
             :style="{ fontWeight: sub.fontweight, color: '#202020' }"
             >{{ data || "-" }}</span
           >
         </div>
       </tableList>
-      <UploadTaskList class="upload-list-new" v-show="uploadTaskList.length != 0" fileType="AUDIO" :taskList="uploadTaskList" @cancel-task="onCancelTask"></UploadTaskList>
+      <UploadTaskList class="upload-list-new" fileType="AUDIO" :taskList="uploadListForUI" @cancel-task="onCancelTask"></UploadTaskList>
       <div class="total-number" v-if="list.length !== 0 || hasMoreData">已加载{{list.length}}条</div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && lastestUsedSearchKey">
         <img :src="$noresult" alt="" />
-        <span>未搜索到结果</span>
+        <span>未搜索到结果~</span>
       </div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && !lastestUsedSearchKey">
         <img :src="config.empty" alt="" />
@@ -110,9 +109,12 @@
       @close="showRename = false"
     />
     <preview
-      :item="popupItem"
-      :show="showPreview"
-      @close="showPreview = false"
+      ref="image-previewer"
+      :ifShow="showPreview"
+      :canFullScreen="false"
+      :imageList="list.map(item => item.icon)"
+      :imageTitleList="list.map(item => item.fileName)"
+      @click-delete="onClickDeleteInPreview"
     />
   </div>
 </template>
@@ -126,8 +128,9 @@ import rename from "../popup/rename";
 import UploadTaskList from "../components/uploadList1.1.0.vue";
 import Upload from "@/components/shared/uploads/UploadMultiple";
 import { changeByteUnit } from "@/utils/file";
-import preview from "../popup/preview";
+import preview from "../popup/imagePreviewer.vue";
 import { debounce } from "@/utils/other.js"
+import { mapState } from 'vuex';
 
 import {
   getMaterialList,
@@ -149,7 +152,7 @@ export default {
   },
   data() {
     return {
-      config,
+      config, // TODO: 没必要这么弄
       showPreview: false,
       showRename: false,
       showList: false,
@@ -170,10 +173,13 @@ export default {
       list: [],
       hasMoreData: true,
       isRequestingMoreData: false,
-      uploadTaskList: [],
-      uploadHandlerList: [],
     };
   },
+  computed: {
+    ...mapState({
+      uploadListForUI: 'uploadStatusListImage',
+    })
+  },
   mounted() {
   },
   watch: {
@@ -197,10 +203,6 @@ export default {
       this.hasMoreData = true
       this.$refs['table-list'].requestMoreData()
     }, 700, false),
-    viewImg(id) {
-      const viewer = this.$el.querySelector("#" + id).$viewer;
-      viewer.show();
-    },
     handleRename(newName) {
       editMaterial(
         {
@@ -268,9 +270,13 @@ export default {
         },
       });
     },
+    previewImage(targetItem) {
+      const index = this.list.findIndex((eachItem) => {
+        return eachItem.id === targetItem.id
+      })
+      this.$refs['image-previewer'].show(index)
+    },
     onFileChange(e) {
-      let uploadFileList = [];
-
       e.files.forEach((eachFile, i) => {
         if (
           eachFile.name.toLowerCase().indexOf("jpeg") <= -1 &&
@@ -296,65 +302,55 @@ export default {
           return;
         }
 
-        let tmp = {
+        let itemInUploadList = {
           title: eachFile.name,
           ifKnowProgress: true,
           progress: 0,
           status: 'LOADING',
           statusStr: "正在上传素材",
           uid: `u_${this.$randomWord(true, 8, 8)}`,
+          abortHandler: null,
         };
-        this.uploadTaskList.push(tmp);
-        uploadFileList.push({
-          file: eachFile,
-          list: { ...tmp },
-        });
-      });
-
-      let uploadPromiseList = [];
-      uploadFileList.forEach((data, index) => {
-        let promise = new Promise((resolve, reject) => {
-          const handler = uploadMaterial(
-            {
-              file: data.file
-            },
-            {
-              type: TYPE,
-              uid: data.list.uid,
-            },
-            (response) => {
-              this.uploadTaskList[index].status = 'SUCCESS'
-              this.uploadTaskList[index].statusText = '素材上传成功'
-              resolve(response);
-            },
-            (err) => {
-              if (err.status === 0) { // 用户取消了上传任务。TODO:判断依据不够完美。
-                this.uploadTaskList[index].status = 'CANCELLED'
-                this.uploadTaskList[index].statusText = '已取消'
-              } else {
-                this.uploadTaskList[index].status = 'FAIL'
-                this.uploadTaskList[index].statusText = '素材上传失败'
-              }
-              reject(err);
-            },
-            (progress) => {
-              this.uploadTaskList[index].progress = progress
+        
+        itemInUploadList.abortHandler = uploadMaterial(
+          {
+            file: eachFile
+          },
+          {
+            type: TYPE,
+            uid: itemInUploadList.uid,
+          },
+          () => { // 上传成功
+            const index = this.uploadListForUI.findIndex((eachItem) => {
+              eachItem.uid === itemInUploadList.uid
+            })
+            this.uploadListForUI.splice(index, 1)
+            this.refreshListDebounced()
+          },
+          (err) => {
+            if (err.statusText === 'abort') { // 用户取消了上传任务。
+              const index = this.uploadListForUI.findIndex((eachItem) => {
+                eachItem.uid === itemInUploadList.uid
+              })
+              this.uploadListForUI.splice(index, 1)
+            } else {
+              itemInUploadList.status = 'FAIL'
+              itemInUploadList.statusText = '素材上传失败'
             }
-          );
-          this.uploadHandlerList.push(handler)
-        });
-        uploadPromiseList.push(promise);
-      });
-      Promise.allSettled(uploadPromiseList).then(() => {
-        setTimeout(() => {
-          this.uploadTaskList = []
-          this.uploadHandlerList = []
-          this.refreshListDebounced()
-        }, 1000);
+          },
+          (progress) => {
+            itemInUploadList.progress = progress
+          }
+        );
+
+        this.uploadListForUI.push(itemInUploadList);
       });
     },
-    onCancelTask(index) {
-      this.uploadHandlerList[index].abort()
+    onCancelTask(uid) {
+      const index = this.uploadListForUI.findIndex((eachItem) => {
+        return eachItem.uid === uid
+      })
+      this.uploadListForUI[index].abortHandler.abort()
     },
     getMoreMaterialItem() {
       this.isRequestingMoreData = true
@@ -384,6 +380,9 @@ export default {
         }
       );
     },
+    onClickDeleteInPreview(index) {
+      this.del(this.list[index])
+    },
   },
 };
 </script>

+ 61 - 84
src/views/material/pano/index.vue

@@ -106,11 +106,11 @@
           </span>
         </div>
       </tableList>
-      <UploadTaskList class="upload-list-new" v-show="uploadTaskList.length != 0" fileType="AUDIO" :taskList="uploadTaskList" @cancel-task="onCancelTask"></UploadTaskList>
+      <UploadTaskList class="upload-list-new" fileType="IMAGE" :taskList="uploadListForUI" @cancel-task="onCancelTask"></UploadTaskList>
       <div class="total-number" v-if="list.length !== 0 || hasMoreData">已加载{{list.length}}条</div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && lastestUsedSearchKey">
         <img :src="$noresult" alt="" />
-        <span>未搜索到结果</span>
+        <span>未搜索到结果~</span>
       </div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && !lastestUsedSearchKey">
         <img :src="config.empty" alt="" />
@@ -151,6 +151,7 @@ import Upload from "@/components/shared/uploads/UploadMultiple";
 import { getImgWH, changeByteUnit } from "@/utils/file";
 import UploadTaskList from "../components/uploadList1.1.0.vue";
 import { debounce } from "@/utils/other.js"
+import { mapState } from 'vuex';
 
 import {
   getMaterialList,
@@ -178,7 +179,6 @@ export default {
   data() {
     return {
       config,
-      longPollingSwitch: false,
       showRename: false,
       showPreview: false,
       showCover: false,
@@ -202,14 +202,22 @@ export default {
       hasMoreData: true,
       isRequestingMoreData: false,
       uploadList: [],
-      uploadTaskList: [],
-      uploadHandlerList: [],
     };
   },
+  computed: {
+    ...mapState({
+      uploadListForUI: 'uploadStatusListPano',
+    }),
+    needLongPolling() {
+      return this.uploadListForUI.some((item) => {
+        return item.status === 'LOADING' && item.ifKnowProgress === false
+      })
+    }
+  },
   mounted() {
   },
   watch: {
-    longPollingSwitch: {
+    needLongPolling: {
       handler: function (newVal) {
         if (!newVal) {
           this.clearinter();
@@ -323,34 +331,26 @@ export default {
       });
     },
     _checkMStatus() {
-      let loadingTaskList = this.uploadTaskList.filter((item) => item.status === 'LOADING');
-      if (loadingTaskList.length > 0) {
+      let needPollingTaskList = this.uploadListForUI.filter((item) => item.status === 'LOADING' && item.ifKnowProgress === false);
+      if (needPollingTaskList.length > 0) {
         checkMStatus(
           {
-            ids: this.uploadTaskList.map((item) => item.backendId),
+            ids: needPollingTaskList.map((item) => item.backendId),
             islongpolling: true,
           },
           (res) => {
             // 1切图中,2失败,3成功
             res.data.forEach(eachRes => {
               if (eachRes.status === 2) {
-                const index = this.uploadTaskList.findIndex(eachTask => eachTask.backendId === eachRes.id)
-                index >= 0 && (this.uploadTaskList[index].status = 'FAIL')
-                index >= 0 && (this.uploadTaskList[index].statusText = '素材切图失败')
+                const index = this.uploadListForUI.findIndex(eachTask => eachTask.backendId === eachRes.id)
+                index >= 0 && (this.uploadListForUI[index].status = 'FAIL')
+                index >= 0 && (this.uploadListForUI[index].statusText = '素材切图失败')
               } else if (eachRes.status === 3) {
-                const index = this.uploadTaskList.findIndex(eachTask => eachTask.backendId === eachRes.id)
-                index >= 0 && (this.uploadTaskList[index].status = 'SUCCESS')
-                index >= 0 && (this.uploadTaskList[index].statusText = '切图成功')
+                const index = this.uploadListForUI.findIndex(eachTask => eachTask.backendId === eachRes.id)
+                index >= 0 && (this.uploadListForUI.splice(index, 1))
+                index >= 0 && this.refreshListDebounced()
               }
             });
-            if (!this.uploadTaskList.some((item) => item.status === 'LOADING')) {
-              this.longPollingSwitch = false;
-              setTimeout(() => {
-                this.uploadTaskList = []
-                this.uploadHandlerList = []
-                this.refreshListDebounced()
-              }, 1000);
-            }
           }
         );
       }
@@ -402,8 +402,6 @@ export default {
       });
     },
     onFileChange(e) {
-      let uploadFileList = [];
-
       e.files.forEach((eachFile, i) => {
         if (
           eachFile.name.toLowerCase().indexOf("jpeg") <= -1 &&
@@ -428,75 +426,54 @@ export default {
           return;
         }
 
-        let tmp = {
+        let itemInUploadList = {
           title: eachFile.name,
           ifKnowProgress: true,
           progress: 0,
           status: 'LOADING',
           statusStr: "正在上传素材",
           uid: `u_${this.$randomWord(true, 8, 8)}`,
+          abortHandler: null,
+          backendId: '',
         };
-        this.uploadTaskList.push(tmp);
-        uploadFileList.push({
-          file: eachFile,
-          list: { ...tmp },
-        });
-      });
 
-      let uploadPromiseList = [];
-      uploadFileList.forEach((data, index) => {
-        let promise = new Promise((resolve, reject) => {
-          const handler = uploadMaterial(
-            {
-              file: data.file
-            },
-            {
-              type: TYPE,
-              uid: data.list.uid,
-            },
-            (response) => {
-              if (response.data.id) {
-                this.uploadTaskList[index].statusText = '正在切图处理'
-                this.uploadTaskList[index].ifKnowProgress = false
-                this.uploadTaskList[index].backendId = response.data.id
-                resolve(response);
-              } else {
-                this.uploadTaskList[index].status = 'FAIL'
-                this.uploadTaskList[index].statusText = '素材上传失败'
-                reject('拿不到上传后文件id')
-              }
-            },
-            (err) => {
-              if (err.status === 0) { // 用户取消了上传任务。TODO:判断依据不够完美。
-                this.uploadTaskList[index].status = 'CANCELLED'
-                this.uploadTaskList[index].statusText = '已取消'
-              } else {
-                this.uploadTaskList[index].status = 'FAIL'
-                this.uploadTaskList[index].statusText = '素材上传失败'
-              }
-              reject(err);
-            },
-            (progress) => {
-              this.uploadTaskList[index].progress = progress
+        itemInUploadList.abortHandler = uploadMaterial(
+          {
+            file: eachFile
+          },
+          {
+            type: TYPE,
+            uid: itemInUploadList.uid,
+          },
+          (response) => { // 上传成功
+            itemInUploadList.statusText = '正在切图处理'
+            itemInUploadList.ifKnowProgress = false
+            itemInUploadList.backendId = response.data.id
+          },
+          (err) => {
+            if (err.statusText === 'abort') { // 用户取消了上传任务。
+              const index = this.uploadListForUI.findIndex((eachItem) => {
+                eachItem.uid === itemInUploadList.uid
+              })
+              this.uploadListForUI.splice(index, 1)
+            } else {
+              itemInUploadList.status = 'FAIL'
+              itemInUploadList.statusText = '素材上传失败'
             }
-          );
-          this.uploadHandlerList.push(handler)
-        });
-        uploadPromiseList.push(promise);
-      });
-      Promise.allSettled(uploadPromiseList).then(() => {
-        if (!this.uploadTaskList.some((item) => item.status === 'LOADING')) {
-          setTimeout(() => {
-            this.uploadTaskList = []
-            this.uploadHandlerList = []
-          }, 1000);
-        } else {
-          this.longPollingSwitch = true
-        }
-      });
+          },
+          (progress) => {
+            itemInUploadList.progress = progress
+          }
+        )
+
+        this.uploadListForUI.push(itemInUploadList);
+      })
     },
-    onCancelTask(index) {
-      this.uploadHandlerList[index].abort()
+    onCancelTask(uid) {
+      const index = this.uploadListForUI.findIndex((eachItem) => {
+        return eachItem.uid === uid
+      })
+      this.uploadListForUI[index].abortHandler.abort()
     },
     getMoreMaterialItem(islongpolling = null) {
       this.isRequestingMoreData = true

+ 234 - 0
src/views/material/popup/imagePreviewer.vue

@@ -0,0 +1,234 @@
+<template>
+  <popup v-if="ifShow">
+    <div class="preview-wrapper">
+      <div class="title">{{imageTitleList[currentIndex]}}</div>
+      <img class="close-btn" :src="require('@/assets/images/icons/material_preview_close@2x.png')" @click=onClickClose />
+      <img
+        class="image"
+        :src="imageList[currentIndex]"
+        :style="imageStyle"
+        @wheel.prevent="onImageWheel"
+      />
+      <div class="toolbar">
+        <i
+          class="iconfont icon-material_preview_previous hover-tips" @click="onClickPrevious()">
+          <div>
+            <div class="remark">上一张</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_next1 hover-tips append-splitter" @click="onClickNext()">
+          <div>
+            <div class="remark">下一张</div>
+          </div>
+        </i>
+        <i v-if="canScale" class="iconfont icon-material_preview_enlarge hover-tips" @click="onClickZoomIn()">
+          <div>
+            <div class="remark">放大</div>
+          </div>
+        </i>
+        <i v-if="canScale" class="iconfont icon-material_preview_narrow hover-tips" @click="onClickZoomOut()">
+          <div>
+            <div class="remark">缩小</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_next hover-tips-warn" @click="onClickDelete()">
+          <div>
+            <div class="remark">删除</div>
+          </div>
+        </i>
+        <i v-if="canFullScreen && objectFit === 'scale-down'" class="iconfont icon-material_preview_full_screen hover-tips" @click="onClickFullScreen()">
+          <div>
+            <div class="remark">全屏</div>
+          </div>
+        </i>
+        <i v-if="canFullScreen && objectFit === 'contain'" class="iconfont icon-material_preview_drop_out hover-tips" @click="onClickCancelFullScreen()">
+          <div>
+            <div class="remark">取消全屏</div>
+          </div>
+        </i>
+      </div>
+    </div>
+  </popup>
+</template>
+
+<script>
+import Popup from "@/components/shared/popup";
+
+export default {
+  props: {
+    imageTitleList: {
+      type: Array,
+      default: () => {
+        return [
+          'aaa',
+          'bbb'
+        ]
+      }
+    },
+    imageList: {
+      type: Array,
+      default: () => {
+        return [
+          'https://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fodder/20220125_114634855.jpg',
+          'https://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fodder/20220125_142545584.jpg',
+        ]
+      }
+    },
+    canScale: {
+      type: Boolean,
+      default: true
+    },
+    canFullScreen: {
+      type: Boolean,
+      default: true
+    },
+  },
+  components:{
+    Popup
+  },
+  data(){
+    return {
+      ifShow: false,
+      currentIndex: 0,
+      scaleRate: 1,
+      objectFit: 'scale-down',
+    }
+  },
+  computed: {
+    imageStyle() {
+      return {
+        transform: `scale(${this.scaleRate})`,
+        objectFit: this.objectFit,
+      }
+    }
+  },
+  watch: {
+    imageList: {
+      handler: function (newList) {
+        if (newList.length - 1 < this.currentIndex) {
+          this.currentIndex = newList.length - 1
+        }
+      }
+    }
+  },
+  methods:{
+    show(index) {
+      Number.isSafeInteger(index) && (this.currentIndex = index)
+      this.ifShow = true
+    },
+    onImageWheel(e) {
+      if (e.deltaY > 0) {
+        this.scaleRate = this.scaleRate * 1.1
+      } else {
+        this.scaleRate = this.scaleRate * 0.9
+      }
+    },
+    onClickPrevious() {
+      if (this.currentIndex > 0) {
+        this.currentIndex--
+      }
+    },
+    onClickNext() {
+      if (this.currentIndex < this.imageList.length - 1) {
+        this.currentIndex++
+      }
+    },
+    onClickZoomIn() {
+      this.scaleRate = this.scaleRate * 1.1
+    },
+    onClickZoomOut() {
+      this.scaleRate *= 0.9
+    },
+    onClickDelete() {
+      this.$emit('click-delete', this.currentIndex)
+    },
+    onClickFullScreen() {
+      this.scaleRate = 1
+      this.objectFit = 'contain'
+    },
+    onClickCancelFullScreen() {
+      this.scaleRate = 1
+      this.objectFit = 'scale-down'
+    },
+    onClickClose() {
+      this.ifShow = false
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+  .preview-wrapper {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    .title {
+      position: absolute;
+      top: 16px;
+      left: 30px;
+      z-index: 2;
+      height: 36px;
+      font-size: 14px;
+      color: #FFFFFF;
+      background: rgba(0, 0, 0, 0.6);
+      border-radius: 18px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding-left: 16px;
+      padding-right: 16px;
+    }
+    .close-btn {
+      position: absolute;
+      top: 16px;
+      right: 30px;
+      width: 36px;
+      height: 36px;
+      z-index: 2;
+      cursor: pointer;
+    }
+    .toolbar {
+      position: absolute;
+      bottom: 147px;
+      left: 50%;
+      transform: translateX(-50%);
+      height: 60px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding: 0 43px;
+      background: rgba(0, 0, 0, 0.6);
+      border-radius: 8px;
+      z-index: 2;
+      .iconfont {
+        cursor: pointer;
+        color: white;
+        margin-right: 36px;
+        font-size: 22px;
+        &:last-child {
+          margin-right: 0;
+        }
+      }
+      .append-splitter {
+        &::after {
+          content: "|";
+          position: absolute;
+          right: -18px;
+          top: -4px;
+          font-size: 20px;
+          color: rgba(255, 255, 255, 0.5);
+        }
+      }
+    }
+    .image {
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      z-index: 1;
+    }
+  }
+</style>

+ 234 - 0
src/views/material/popup/panoImagePreviewer.vue

@@ -0,0 +1,234 @@
+<template>
+  <popup v-if="ifShow">
+    <div class="preview-wrapper">
+      <div class="title">{{imageTitleList[currentIndex]}}</div>
+      <img class="close-btn" :src="require('@/assets/images/icons/material_preview_close@2x.png')" @click=onClickClose />
+      <img
+        class="image"
+        :src="imageList[currentIndex]"
+        :style="imageStyle"
+        @wheel.prevent="onImageWheel"
+      />
+      <div class="toolbar">
+        <i
+          class="iconfont icon-material_preview_previous hover-tips" @click="onClickPrevious()">
+          <div>
+            <div class="remark">上一张</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_next1 hover-tips append-splitter" @click="onClickNext()">
+          <div>
+            <div class="remark">下一张</div>
+          </div>
+        </i>
+        <i v-if="canScale" class="iconfont icon-material_preview_enlarge hover-tips" @click="onClickZoomIn()">
+          <div>
+            <div class="remark">放大</div>
+          </div>
+        </i>
+        <i v-if="canScale" class="iconfont icon-material_preview_narrow hover-tips" @click="onClickZoomOut()">
+          <div>
+            <div class="remark">缩小</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_next hover-tips-warn" @click="onClickDelete()">
+          <div>
+            <div class="remark">删除</div>
+          </div>
+        </i>
+        <i v-if="canFullScreen && objectFit === 'scale-down'" class="iconfont icon-material_preview_full_screen hover-tips" @click="onClickFullScreen()">
+          <div>
+            <div class="remark">全屏</div>
+          </div>
+        </i>
+        <i v-if="canFullScreen && objectFit === 'contain'" class="iconfont icon-material_preview_drop_out hover-tips" @click="onClickCancelFullScreen()">
+          <div>
+            <div class="remark">取消全屏</div>
+          </div>
+        </i>
+      </div>
+    </div>
+  </popup>
+</template>
+
+<script>
+import Popup from "@/components/shared/popup";
+
+export default {
+  props: {
+    imageTitleList: {
+      type: Array,
+      default: () => {
+        return [
+          'aaa',
+          'bbb'
+        ]
+      }
+    },
+    imageList: {
+      type: Array,
+      default: () => {
+        return [
+          'https://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fodder/20220125_114634855.jpg',
+          'https://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fodder/20220125_142545584.jpg',
+        ]
+      }
+    },
+    canScale: {
+      type: Boolean,
+      default: true
+    },
+    canFullScreen: {
+      type: Boolean,
+      default: true
+    },
+  },
+  components:{
+    Popup
+  },
+  data(){
+    return {
+      ifShow: false,
+      currentIndex: 0,
+      scaleRate: 1,
+      objectFit: 'scale-down',
+    }
+  },
+  computed: {
+    imageStyle() {
+      return {
+        transform: `scale(${this.scaleRate})`,
+        objectFit: this.objectFit,
+      }
+    }
+  },
+  watch: {
+    imageList: {
+      handler: function (newList) {
+        if (newList.length - 1 < this.currentIndex) {
+          this.currentIndex = newList.length - 1
+        }
+      }
+    }
+  },
+  methods:{
+    show(index) {
+      Number.isSafeInteger(index) && (this.currentIndex = index)
+      this.ifShow = true
+    },
+    onImageWheel(e) {
+      if (e.deltaY > 0) {
+        this.scaleRate = this.scaleRate * 1.1
+      } else {
+        this.scaleRate = this.scaleRate * 0.9
+      }
+    },
+    onClickPrevious() {
+      if (this.currentIndex > 0) {
+        this.currentIndex--
+      }
+    },
+    onClickNext() {
+      if (this.currentIndex < this.imageList.length - 1) {
+        this.currentIndex++
+      }
+    },
+    onClickZoomIn() {
+      this.scaleRate = this.scaleRate * 1.1
+    },
+    onClickZoomOut() {
+      this.scaleRate *= 0.9
+    },
+    onClickDelete() {
+      this.$emit('click-delete', this.currentIndex)
+    },
+    onClickFullScreen() {
+      this.scaleRate = 1
+      this.objectFit = 'contain'
+    },
+    onClickCancelFullScreen() {
+      this.scaleRate = 1
+      this.objectFit = 'scale-down'
+    },
+    onClickClose() {
+      this.ifShow = false
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+  .preview-wrapper {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    .title {
+      position: absolute;
+      top: 16px;
+      left: 30px;
+      z-index: 2;
+      height: 36px;
+      font-size: 14px;
+      color: #FFFFFF;
+      background: rgba(0, 0, 0, 0.6);
+      border-radius: 18px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding-left: 16px;
+      padding-right: 16px;
+    }
+    .close-btn {
+      position: absolute;
+      top: 16px;
+      right: 30px;
+      width: 36px;
+      height: 36px;
+      z-index: 2;
+      cursor: pointer;
+    }
+    .toolbar {
+      position: absolute;
+      bottom: 147px;
+      left: 50%;
+      transform: translateX(-50%);
+      height: 60px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding: 0 43px;
+      background: rgba(0, 0, 0, 0.6);
+      border-radius: 8px;
+      z-index: 2;
+      .iconfont {
+        cursor: pointer;
+        color: white;
+        margin-right: 36px;
+        font-size: 22px;
+        &:last-child {
+          margin-right: 0;
+        }
+      }
+      .append-splitter {
+        &::after {
+          content: "|";
+          position: absolute;
+          right: -18px;
+          top: -4px;
+          font-size: 20px;
+          color: rgba(255, 255, 255, 0.5);
+        }
+      }
+    }
+    .image {
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      z-index: 1;
+    }
+  }
+</style>

+ 48 - 56
src/views/material/video/index.vue

@@ -33,7 +33,7 @@
             <input
               type="text"
               v-model="searchKey"
-              placeholder="搜索文件或素材"
+              placeholder="搜索素材"
             />
             <i v-if="searchKey" @click="searchKey=''" class="iconfont icontoast_red del"></i>
           </div>
@@ -91,11 +91,11 @@
           >
         </div>
       </tableList>
-      <UploadTaskList class="upload-list-new" v-show="uploadTaskList.length != 0" fileType="AUDIO" :taskList="uploadTaskList" @cancel-task="onCancelTask"></UploadTaskList>
+      <UploadTaskList class="upload-list-new" fileType="VIDEO" :taskList="uploadListForUI" @cancel-task="onCancelTask"></UploadTaskList>
       <div class="total-number" v-if="list.length !== 0 || hasMoreData">已加载{{list.length}}条</div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && lastestUsedSearchKey">
         <img :src="$noresult" alt="" />
-        <span>未搜索到结果</span>
+        <span>未搜索到结果~</span>
       </div>
       <div class="nodata" v-if="list.length == 0 && !hasMoreData && !lastestUsedSearchKey">
         <img :src="config.empty" alt="" />
@@ -129,6 +129,7 @@ import { changeByteUnit } from "@/utils/file";
 import preview from "../popup/preview";
 import UploadTaskList from "../components/uploadList1.1.0.vue";
 import { debounce } from "@/utils/other.js"
+import { mapState } from 'vuex';
 
 import {
   getMaterialList,
@@ -172,10 +173,13 @@ export default {
       list: [],
       hasMoreData: true,
       isRequestingMoreData: false,
-      uploadTaskList: [],
-      uploadHandlerList: [],
     };
   },
+  computed: {
+    ...mapState({
+      uploadListForUI: 'uploadStatusListVideo',
+    })
+  },
   mounted() {
   },
   watch: {
@@ -267,8 +271,6 @@ export default {
       });
     },
     onFileChange(e) {
-      let uploadFileList = [];
-
       e.files.forEach((eachFile, i) => {
         if (eachFile.name.toLowerCase().indexOf("mp4") <= -1) {
           setTimeout(() => {
@@ -290,65 +292,55 @@ export default {
           return;
         }
 
-        let tmp = {
+        let itemInUploadList = {
           title: eachFile.name,
           ifKnowProgress: true,
           progress: 0,
           status: 'LOADING',
           statusStr: "正在上传素材",
           uid: `u_${this.$randomWord(true, 8, 8)}`,
+          abortHandler: null,
         };
-        this.uploadTaskList.push(tmp);
-        uploadFileList.push({
-          file: eachFile,
-          list: { ...tmp },
-        });
-      });
-
-      let uploadPromiseList = [];
-      uploadFileList.forEach((data, index) => {
-        let promise = new Promise((resolve, reject) => {
-          const handler = uploadMaterial(
-            {
-              file: data.file
-            },
-            {
-              type: TYPE,
-              uid: data.list.uid,
-            },
-            (response) => {
-              this.uploadTaskList[index].status = 'SUCCESS'
-              this.uploadTaskList[index].statusText = '素材上传成功'
-              resolve(response);
-            },
-            (err) => {
-              if (err.status === 0) { // 用户取消了上传任务。TODO:判断依据不够完美。
-                this.uploadTaskList[index].status = 'CANCELLED'
-                this.uploadTaskList[index].statusText = '已取消'
-              } else {
-                this.uploadTaskList[index].status = 'FAIL'
-                this.uploadTaskList[index].statusText = '素材上传失败'
-              }
-              reject(err);
-            },
-            (progress) => {
-              this.uploadTaskList[index].progress = progress
+        
+        itemInUploadList.abortHandler = uploadMaterial(
+          {
+            file: eachFile
+          },
+          {
+            type: TYPE,
+            uid: itemInUploadList.uid,
+          },
+          () => { // 上传成功
+            const index = this.uploadListForUI.findIndex((eachItem) => {
+              eachItem.uid === itemInUploadList.uid
+            })
+            this.uploadListForUI.splice(index, 1)
+            this.refreshListDebounced()
+          },
+          (err) => {
+            if (err.statusText === 'abort') { // 用户取消了上传任务。
+              const index = this.uploadListForUI.findIndex((eachItem) => {
+                eachItem.uid === itemInUploadList.uid
+              })
+              this.uploadListForUI.splice(index, 1)
+            } else {
+              itemInUploadList.status = 'FAIL'
+              itemInUploadList.statusText = '素材上传失败'
             }
-          );
-          this.uploadHandlerList.push(handler)
-        });
-        uploadPromiseList.push(promise);
-      });
-      Promise.allSettled(uploadPromiseList).then(() => {
-        setTimeout(() => {
-          this.uploadTaskList = []
-          this.uploadHandlerList = []
-          this.refreshListDebounced()
-        }, 1000);
+          },
+          (progress) => {
+            itemInUploadList.progress = progress
+          }
+        );
+
+        this.uploadListForUI.push(itemInUploadList);
       });
     },
-    onCancelTask(index) {
-      this.uploadHandlerList[index].abort()
+    onCancelTask(uid) {
+      const index = this.uploadListForUI.findIndex((eachItem) => {
+        return eachItem.uid === uid
+      })
+      this.uploadListForUI[index].abortHandler.abort()
     },
     getMoreMaterialItem() {
       this.isRequestingMoreData = true

+ 1 - 1
src/views/material/works/index.vue

@@ -63,7 +63,7 @@
     </ul>
     <div class="nodata" v-if="list.length == 0 && !hasMoreData && lastestUsedSearchKey">
       <img :src="$noresult" alt="" />
-      <span>未搜索到结果</span>
+      <span>未搜索到结果~</span>
     </div>
     <div class="nodata" v-if="list.length == 0 && !hasMoreData && !lastestUsedSearchKey">
       <img :src="config.empty" alt="" />