Pārlūkot izejas kodu

增加上传同步

gemercheung 2 gadi atpakaļ
vecāks
revīzija
ee2daa480c

+ 37 - 2
packages/qjkankan-editor/src/components/materialListInMaterialSelector.vue

@@ -182,7 +182,7 @@
         <!-- 本组件内的列表数据 -->
         <div
           class="table-body-row"
-          v-for="(item, i) in list"
+          v-for="(item, i) in showList"
           :key="i"
           @click="
             (e) => {
@@ -442,6 +442,9 @@ export default {
     };
   },
   computed: {
+    showList() {
+      return this.list.filter((i) => i.status === 3);
+    },
     materialTypeAlias() {
       if (this.materialType === "3D") {
         return "scene";
@@ -606,7 +609,7 @@ export default {
             this.materialItemCustomProcess(i);
             return i;
           });
-          this.list = this.list.concat(newData);
+          this.preProessData(newData);
           if (this.listRealLength === data.data.total) {
             this.hasMoreData = false;
           }
@@ -619,6 +622,38 @@ export default {
         }
       );
     },
+    preProessData(newData) {
+      this.list = this.list.concat(newData);
+
+      const uploadlist = this.list
+        .filter((i) => i.status < 3)
+        .map((item) => {
+          let itemInUploadList = {
+            title: item.name,
+            ifKnowProgress: false,
+            progress: 0,
+            status: "LOADING",
+            statusText: this.$i18n.t(`gather.cutting`),
+            uid: `u_${this.$randomWord(true, 8, 8)}`,
+            abortHandler: null,
+            backendId: item.id, // 只用于全景图上传
+            parentFolderId: item.dirId,
+          };
+          return itemInUploadList;
+        });
+
+      const res = new Map();
+
+      const latestUploadlist = this.uploadStatusList
+        .concat(uploadlist)
+        .filter((a) => !res.has(a.backendId) && res.set(a.backendId, 1));
+      console.log("latestUploadlist", latestUploadlist);
+      const capitalizedMaterialType = capitalize(this.materialType);
+      this.$store.commit(
+        `setUploadStatusList${capitalizedMaterialType}`,
+        latestUploadlist
+      );
+    },
     refreshMaterialList: debounce(
       function (type) {
         this.isRequestingMoreData = false;

+ 182 - 191
packages/qjkankan-editor/src/components/materialSelector.vue

@@ -1,10 +1,9 @@
 <template>
-  <div
-    class="table-select"
-    :class="isDarkTheme ? '' : 'bright'"
-  >
+  <div class="table-select" :class="isDarkTheme ? '' : 'bright'">
     <span class="title">{{ title }}</span>
-    <div class="close-btn"><i class="iconfont icon-pop-ups_shut-down" @click="$emit('cancle')"></i></div>
+    <div class="close-btn">
+      <i class="iconfont icon-pop-ups_shut-down" @click="$emit('cancle')"></i>
+    </div>
 
     <div class="material-tab">
       <a
@@ -58,11 +57,8 @@
         <div v-if="currentMaterialType === '3D'" class="bottom-line"></div>
       </a>
     </div>
-    
-    <div
-      class="filter"
-      :class="{active: isSearchKeyInputActive}"
-    >
+
+    <div class="filter" :class="{ active: isSearchKeyInputActive }">
       <input
         type="text"
         :placeholder="$i18n.t('gather.keywords')"
@@ -71,25 +67,23 @@
         @blur="isSearchKeyInputActive = false"
       />
       <i v-if="!searchKey" class="iconfont icon-editor_search search-icon" />
-      <i v-if="searchKey" @click="searchKey=''" class="iconfont icontoast_red clear-icon"></i>
+      <i
+        v-if="searchKey"
+        @click="searchKey = ''"
+        class="iconfont icontoast_red clear-icon"
+      ></i>
     </div>
 
     <MaterialList
       v-if="selectableType.includes('pano')"
       v-show="currentMaterialType === 'pano'"
-
       :isDarkTheme="isDarkTheme"
-      
       :currentMaterialType="currentMaterialType"
       :materialType="'pano'"
-      
       :tableHeaderKeyList="['icon', 'name']"
-
       :isMultiSelection="isMultiSelection"
       :select="select"
-
       :searchKey="searchKey"
-
       :canUpload="true"
       :fileInputCustomCheck="checkPanoFileInput"
       :fileUploadLongPollingCb="panoUploadLongPolling"
@@ -100,61 +94,59 @@
       :fileInputAcceptType="'image/png,image/jpeg,image/jpg'"
       :fileInputMediaType="'image'"
       :fileInputLimit="120"
-
-      @need-clear-filter="() => {searchKey = ''}"
+      @need-clear-filter="
+        () => {
+          searchKey = '';
+        }
+      "
     >
-      <template
-        v-slot:materialUploadSuccessIcon="slotProps"
-      >
+      <template v-slot:materialUploadSuccessIcon="slotProps">
         <img
-          :src="slotProps.uploadInfo.successInfo[slotProps.tableItemStructure.key] + $imgsuffix"
+          :src="
+            slotProps.uploadInfo.successInfo[slotProps.tableItemStructure.key] +
+            $imgsuffix
+          "
           alt=""
         />
       </template>
-      <template
-        v-slot:materialUploadingIcon
-      >
+      <template v-slot:materialUploadingIcon>
         <img
           src="@/assets/images/icons/upload-file-type-icon-image@2x.png"
-          style="object-fit: contain;"
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialUploadFailIcon
-      >
+      <template v-slot:materialUploadFailIcon>
         <img
           src="@/assets/images/icons/upload-file-type-icon-image@2x.png"
-          style="object-fit: contain;"
-        |  alt=""
-        >
+          style="object-fit: contain"
+          |
+          alt=""
+        />
       </template>
-      <template
-        v-slot:materialIcon="slotProps"
-      >
+      <template v-slot:materialIcon="slotProps">
         <img
-          :src="slotProps.materialInfo[slotProps.tableItemStructure.key] + $imgsuffix"
+          v-if="slotProps.materialInfo[slotProps.tableItemStructure.key]"
+          :src="
+            slotProps.materialInfo[slotProps.tableItemStructure.key] +
+            $imgsuffix
+          "
           alt=""
         />
+        <img v-else src="@/assets/img/list_placeholder.png" alt="" />
       </template>
     </MaterialList>
 
     <MaterialList
       v-if="selectableType.includes('image')"
       v-show="currentMaterialType === 'image'"
-
       :isDarkTheme="isDarkTheme"
-
       :currentMaterialType="currentMaterialType"
       :materialType="'image'"
-      
       :tableHeaderKeyList="['icon', 'name']"
-      
       :isMultiSelection="isMultiSelection"
       :select="select"
-
       :searchKey="searchKey"
-
       :canUpload="true"
       :fileInputBtnTip="$i18n.t(`gather.img_size`)"
       :fileInputFailString="$i18n.t(`gather.img_fail`)"
@@ -162,61 +154,58 @@
       :fileInputAcceptType="'image/png,image/jpeg,image/jpg'"
       :fileInputMediaType="'image'"
       :fileInputLimit="10"
-
-      @need-clear-filter="() => {searchKey = ''}"
+      @need-clear-filter="
+        () => {
+          searchKey = '';
+        }
+      "
     >
-      <template
-        v-slot:materialUploadSuccessIcon="slotProps"
-      >
+      <template v-slot:materialUploadSuccessIcon="slotProps">
         <img
-          :src="slotProps.uploadInfo.successInfo[slotProps.tableItemStructure.key] + $imgsuffix"
+          :src="
+            slotProps.uploadInfo.successInfo[slotProps.tableItemStructure.key] +
+            $imgsuffix
+          "
           alt=""
         />
       </template>
-      <template
-        v-slot:materialUploadingIcon
-      >
+      <template v-slot:materialUploadingIcon>
         <img
           src="@/assets/images/icons/upload-file-type-icon-image@2x.png"
-          style="object-fit: contain;"
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialUploadFailIcon
-      >
+      <template v-slot:materialUploadFailIcon>
         <img
           src="@/assets/images/icons/upload-file-type-icon-image@2x.png"
-          style="object-fit: contain;"
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialIcon="slotProps"
-      >
+      <template v-slot:materialIcon="slotProps">
         <img
-          :src="slotProps.materialInfo[slotProps.tableItemStructure.key] + $imgsuffix"
+          v-if="slotProps.materialInfo[slotProps.tableItemStructure.key]"
+          :src="
+            slotProps.materialInfo[slotProps.tableItemStructure.key] +
+            $imgsuffix
+          "
           alt=""
         />
+        <img v-else src="@/assets/img/list_placeholder.png" alt="" />
       </template>
     </MaterialList>
 
     <MaterialList
       v-if="selectableType.includes('audio')"
       v-show="currentMaterialType === 'audio'"
-
       :isDarkTheme="isDarkTheme"
-
       :currentMaterialType="currentMaterialType"
       :materialType="'audio'"
-      
       :tableHeaderKeyList="['ossPath', 'name']"
-      
       :isMultiSelection="isMultiSelection"
       :select="select"
-
       :searchKey="searchKey"
-
       :canUpload="true"
       :fileInputBtnTip="$i18n.t(`gather.audio_size`)"
       :fileInputFailString="$i18n.t(`gather.audio_fail`)"
@@ -224,12 +213,13 @@
       :fileInputAcceptType="'audio/mp3'"
       :fileInputMediaType="'audio'"
       :fileInputLimit="20"
-
-      @need-clear-filter="() => {searchKey = ''}"
+      @need-clear-filter="
+        () => {
+          searchKey = '';
+        }
+      "
     >
-      <template
-        v-slot:materialUploadSuccessIcon="slotProps"
-      >
+      <template v-slot:materialUploadSuccessIcon="slotProps">
         <AudioIconCanPlay
           class="audio-player"
           :vKey="slotProps.uploadInfo.successInfo.id"
@@ -238,27 +228,25 @@
           :myAudioUrl="slotProps.uploadInfo.successInfo.ossPath"
         />
       </template>
-      <template
-        v-slot:materialUploadingIcon
-      >
+      <template v-slot:materialUploadingIcon>
         <img
-          :src="require('@/assets/images/icons/upload-file-type-icon-audio@2x.png')"
-          style="object-fit: contain;"
+          :src="
+            require('@/assets/images/icons/upload-file-type-icon-audio@2x.png')
+          "
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialUploadFailIcon
-      >
+      <template v-slot:materialUploadFailIcon>
         <img
-          :src="require('@/assets/images/icons/upload-file-type-icon-audio@2x.png')"
-          style="object-fit: contain;"
+          :src="
+            require('@/assets/images/icons/upload-file-type-icon-audio@2x.png')
+          "
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialIcon="slotProps"
-      >
+      <template v-slot:materialIcon="slotProps">
         <AudioIconCanPlay
           class="audio-player"
           :vKey="slotProps.materialInfo.id"
@@ -272,20 +260,14 @@
     <MaterialList
       v-if="selectableType.includes('video')"
       v-show="currentMaterialType === 'video'"
-
       :isDarkTheme="isDarkTheme"
-
       :currentMaterialType="currentMaterialType"
       :materialType="'video'"
       :materialItemCustomProcess="videoMaterialItemCustomProcess"
-
       :tableHeaderKeyList="['icon', 'name']"
-      
       :isMultiSelection="isMultiSelection"
       :select="select"
-
       :searchKey="searchKey"
-
       :canUpload="true"
       :fileInputBtnTip="$i18n.t(`gather.video_size`)"
       :fileInputFailString="$i18n.t(`gather.video_fail`)"
@@ -293,70 +275,74 @@
       :fileInputAcceptType="'video/mp4'"
       :fileInputMediaType="'video'"
       :fileInputLimit="200"
-
-      @need-clear-filter="() => {searchKey = ''}"
+      @need-clear-filter="
+        () => {
+          searchKey = '';
+        }
+      "
     >
-      <template
-        v-slot:materialUploadSuccessIcon="slotProps"
-      >
+      <template v-slot:materialUploadSuccessIcon="slotProps">
         <img
-          :src="slotProps.uploadInfo.successInfo[slotProps.tableItemStructure.key]"
+          :src="
+            slotProps.uploadInfo.successInfo[slotProps.tableItemStructure.key]
+          "
           alt=""
         />
       </template>
-      <template
-        v-slot:materialUploadingIcon
-      >
+      <template v-slot:materialUploadingIcon>
         <img
           src="@/assets/images/icons/upload-file-type-icon-video@2x.png"
-          style="object-fit: contain;"
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialUploadFailIcon
-      >
+      <template v-slot:materialUploadFailIcon>
         <img
           src="@/assets/images/icons/upload-file-type-icon-video@2x.png"
-          style="object-fit: contain;"
+          style="object-fit: contain"
           alt=""
-        >
+        />
       </template>
-      <template
-        v-slot:materialIcon="slotProps"
-      >
+
+      <template v-slot:materialIcon="slotProps">
         <img
-          :src="slotProps.materialInfo[slotProps.tableItemStructure.key]"
+          v-if="slotProps.materialInfo[slotProps.tableItemStructure.key]"
+          :src="
+            slotProps.materialInfo[slotProps.tableItemStructure.key] +
+            $imgsuffix
+          "
           alt=""
         />
+        <img v-else src="@/assets/img/list_placeholder.png" alt="" />
       </template>
     </MaterialList>
 
     <MaterialList
       v-if="selectableType.includes('3D')"
       v-show="currentMaterialType === '3D'"
-
       :isDarkTheme="isDarkTheme"
-
       :currentMaterialType="currentMaterialType"
       :materialType="'3D'"
-
       :tableHeaderKeyList="['thumb', 'sceneName']"
-
       :isMultiSelection="isMultiSelection"
       :select="select"
-
       :searchKey="searchKey"
-
-      @need-clear-filter="() => {searchKey = ''}"
+      @need-clear-filter="
+        () => {
+          searchKey = '';
+        }
+      "
     >
-      <template
-        v-slot:materialIcon="slotProps"
-      >
+      <template v-slot:materialIcon="slotProps">
         <img
-          :src="slotProps.materialInfo[slotProps.tableItemStructure.key] + $imgsuffix"
+          v-if="slotProps.materialInfo[slotProps.tableItemStructure.key]"
+          :src="
+            slotProps.materialInfo[slotProps.tableItemStructure.key] +
+            $imgsuffix
+          "
           alt=""
         />
+        <img v-else src="@/assets/img/list_placeholder.png" alt="" />
       </template>
     </MaterialList>
 
@@ -365,8 +351,14 @@
         class="ui-button"
         :class="isDarkTheme ? 'deepcancel' : 'cancel'"
         @click="$emit('cancle')"
-      >{{ $i18n.t("gather.cancel") }}</button>
-      <button class="ui-button submit" :class="{ disable: !select.length }" @click="onClickComfirm">
+      >
+        {{ $i18n.t("gather.cancel") }}
+      </button>
+      <button
+        class="ui-button submit"
+        :class="{ disable: !select.length }"
+        @click="onClickComfirm"
+      >
         {{ $i18n.t("gather.comfirm"), }}
       </button>
     </div>
@@ -374,14 +366,12 @@
 </template>
 
 <script>
-import { mapMutations, } from "vuex";
+import { mapMutations } from "vuex";
 import MaterialList from "./materialListInMaterialSelector.vue";
 import AudioIconCanPlay from "@/components/audio/indexForEditor.vue";
 import { getImgWH, changeByteUnit } from "@/utils/file";
-import { debounce } from "@/utils/other.js"
-import {
-  checkMStatus,
-} from "@/api";
+import { debounce } from "@/utils/other.js";
+import { checkMStatus } from "@/api";
 
 export default {
   components: {
@@ -394,77 +384,70 @@ export default {
       default: true,
     },
     title: {
-      default: '',
-      type: String
+      default: "",
+      type: String,
     },
     selectableType: {
       type: Array,
-      default: function() {
-        return [
-          'image',
-          'pano',
-          'audio',
-          'video',
-          '3D',
-        ]
+      default: function () {
+        return ["image", "pano", "audio", "video", "3D"];
       },
     },
     initialMaterialType: {
       type: String,
-      default: 'image',
+      default: "image",
     },
     isMultiSelection: {
       type: Boolean,
       default: false,
     },
   },
-  data () {
+  data() {
     return {
       select: [],
       isSearchKeyInputActive: false,
-      searchKey: '', // 搜索关键词
-      latestUsedSearchKey: '',
+      searchKey: "", // 搜索关键词
+      latestUsedSearchKey: "",
 
       currentMaterialType: this.initialMaterialType,
-    }
-  },
-  watch: {
+    };
   },
+  watch: {},
   methods: {
-    ...mapMutations([
-      'clearUploadStatusLists',
-    ]),
+    ...mapMutations(["clearUploadStatusLists"]),
     async checkPanoFileInput(eachFile, i) {
-      let WHRate = null
+      let WHRate = null;
       try {
-        const { width, height } = await getImgWH(eachFile)
-        WHRate = width / height
+        const { width, height } = await getImgWH(eachFile);
+        WHRate = width / height;
       } catch (e) {
-        console.error('获取图像宽高失败:', e)
+        console.error("获取图像宽高失败:", e);
         setTimeout(() => {
           this.$msg({
             message: `“${eachFile.name}”${this.$i18n.t(`gather.pano_fail`)}`,
             type: "warning",
           });
         }, i * 100);
-        return false
+        return false;
       }
       if (WHRate !== 2) {
-        console.log('宽高比不对!');
+        console.log("宽高比不对!");
         setTimeout(() => {
           this.$msg({
             message: `“${eachFile.name}”${this.$i18n.t(`gather.pano_fail`)}`,
             type: "warning",
           });
         }, i * 100);
-        return false
+        return false;
       } else {
         console.log(WHRate);
-        return true
+        return true;
       }
     },
     panoUploadLongPolling(uploadStatusList) {
-      let needPollingTaskList = uploadStatusList.filter((item) => item.status === 'LOADING' && item.ifKnowProgress === false);
+      let needPollingTaskList = uploadStatusList.filter(
+        (item) => item.status === "LOADING" && item.ifKnowProgress === false
+      );
       if (needPollingTaskList.length > 0) {
         checkMStatus(
           {
@@ -473,26 +456,32 @@ export default {
           },
           (res) => {
             // 1切图中,2失败,3成功
-            res.data.forEach(eachRes => {
+            res.data.forEach((eachRes) => {
               if (eachRes.status === 2) {
-                const index = uploadStatusList.findIndex(eachTask => eachTask.backendId === eachRes.id)
+                const index = uploadStatusList.findIndex(
+                  (eachTask) => eachTask.backendId === eachRes.id
+                );
                 if (index >= 0) {
-                  const targetItem = uploadStatusList[index]
-                  targetItem.status = 'FAIL'
-                  targetItem.statusText = this.$i18n.t(`gather.material_cutting_fail`)
-                  targetItem.ifKnowProgress = true
+                  const targetItem = uploadStatusList[index];
+                  targetItem.status = "FAIL";
+                  targetItem.statusText = this.$i18n.t(
+                    `gather.material_cutting_fail`
+                  );
+                  targetItem.ifKnowProgress = true;
                 }
               } else if (eachRes.status === 3) {
-                const index = uploadStatusList.findIndex(eachTask => eachTask.backendId === eachRes.id)
+                const index = uploadStatusList.findIndex(
+                  (eachTask) => eachTask.backendId === eachRes.id
+                );
                 if (index >= 0) {
-                  const targetItem = uploadStatusList[index]
-                  targetItem.status = 'SUCCESS'
+                  const targetItem = uploadStatusList[index];
+                  targetItem.status = "SUCCESS";
                   if (eachRes.fileSize) {
                     eachRes.fileSize = changeByteUnit(Number(eachRes.fileSize));
                   } else {
-                    eachRes.fileSize = ''
+                    eachRes.fileSize = "";
                   }
-                  targetItem.successInfo = eachRes
+                  targetItem.successInfo = eachRes;
                 }
               }
             });
@@ -501,16 +490,19 @@ export default {
       }
     },
     videoMaterialItemCustomProcess(item) {
-      item.icon = process.env.VUE_APP_ORIGIN == 'aws' ? item.icon : (item.ossPath + this.$videoImg)
+      item.icon =
+        process.env.VUE_APP_ORIGIN == "aws"
+          ? item.icon
+          : item.ossPath + this.$videoImg;
     },
     onClickComfirm: debounce(function () {
-      this.$emit('submit', this.select)
+      this.$emit("submit", this.select);
     }, 250),
   },
   mounted() {
-    this.clearUploadStatusLists()
+    this.clearUploadStatusLists();
   },
-}
+};
 </script>
 
 <style lang="less" scoped>
@@ -522,7 +514,7 @@ export default {
   transform: translateX(-50%) translateY(-50%);
   width: 600px;
   height: 730px;
-  background: #1A1B1D;
+  background: #1a1b1d;
   border-radius: 4px;
   border: 1px solid #404040;
   padding: 26px;
@@ -545,7 +537,7 @@ export default {
   .material-tab {
     margin-top: 35px;
 
-      > .material-tab-item {
+    > .material-tab-item {
       display: inline-block;
       margin-right: 20px;
       position: relative;
@@ -567,7 +559,7 @@ export default {
         bottom: -4px;
         width: 16px;
         height: 2px;
-        background: #0076F6;
+        background: #0076f6;
         border-radius: 1px;
       }
     }
@@ -630,7 +622,7 @@ export default {
 }
 
 .table-select.bright {
-  border: 1px solid #EBEDF0;
+  border: 1px solid #ebedf0;
   background: #fff;
   .title {
     color: #323233;
@@ -639,8 +631,7 @@ export default {
   .close-btn {
   }
   .material-tab {
-
-      > .material-tab-item {
+    > .material-tab-item {
       > .text {
         color: #969799;
         &.active {
@@ -654,8 +645,8 @@ export default {
   }
 
   .filter {
-    background: #F7F8FA;
-    border: 1px solid #EBEDF0;
+    background: #f7f8fa;
+    border: 1px solid #ebedf0;
 
     > input {
       color: #323233;
@@ -663,18 +654,18 @@ export default {
     > input::placeholder,
     textarea::placeholder {
       font-size: 14px;
-      color: #C8C9CC !important;
+      color: #c8c9cc !important;
     }
-    
+
     > .search-icon {
-      color: #C8C9CC;
+      color: #c8c9cc;
     }
     > .clear-icon {
-      color: #C8C9CC;
+      color: #c8c9cc;
     }
   }
 
   .btns {
   }
 }
-</style>
+</style>

+ 1 - 1
packages/qjkankan-view/.env.testprod

@@ -6,5 +6,5 @@ VUE_APP_PROXY_URL='https://test.4dkankan.com/qjkankan/'
 VUE_APP_URL_FILL=/qjkankan
 # 接口请求地址
 VUE_APP_APIS_URL=https://test.4dkankan.com/
-VUE_APP_DEBBUG_FLAG=0516-03
+VUE_APP_DEBBUG_FLAG=0530-01
 VUE_APP_DEBBUG_NOTIFY=1