tremble 4 лет назад
Родитель
Сommit
5557a21491
40 измененных файлов с 3439 добавлено и 474 удалено
  1. 2 0
      public/showMobile.html
  2. 903 1
      public/static/template/plugins/webvr.xml
  3. 904 1
      public/static/template/plugins/webvr/webvr.xml
  4. 1 1
      public/static/template/skin/vtourskin.xml
  5. 4 4
      src/api/index.js
  6. BIN
      src/assets/images/default/img_logoshow@2x.png
  7. BIN
      src/assets/images/icons/logo_zh.png
  8. BIN
      src/assets/images/icons/show_more.png
  9. 12 2
      src/assets/style/component.less
  10. 27 9
      src/components/audio/index.vue
  11. 76 0
      src/components/rollName/index.vue
  12. 1 1
      src/components/shared/popup/index.vue
  13. 9 5
      src/components/tableSelect.vue
  14. 1 1
      src/framework/Head.vue
  15. 30 6
      src/framework/Toolbar.vue
  16. 11 1
      src/framework/core/index.vue
  17. 17 5
      src/framework/show/index.vue
  18. 41 18
      src/framework/show/list.vue
  19. 18 1
      src/framework/show/popup/password.vue
  20. 1 1
      src/framework/show/popup/preview.vue
  21. 17 2
      src/framework/showMobile/iframe.vue
  22. 108 45
      src/framework/showMobile/index.vue
  23. 95 62
      src/framework/showMobile/list.vue
  24. 1 1
      src/framework/showMobile/popup/index.vue
  25. 17 1
      src/framework/showMobile/popup/password.vue
  26. 647 0
      src/framework/showMobile/ui/Show.Header.vue
  27. 10 0
      src/mixins/index.js
  28. 20 10
      src/router/index.js
  29. 1 2
      src/utils/request.js
  30. 26 4
      src/views/base/Toolbar.vue
  31. 1 1
      src/views/hotspot/EditPanel.vue
  32. 28 9
      src/views/information/Toolbar.vue
  33. 21 8
      src/views/information/index.vue
  34. 61 48
      src/views/material/audio/index.vue
  35. 44 0
      src/views/material/components/uploadList.vue
  36. 210 153
      src/views/material/image/index.vue
  37. 28 34
      src/views/material/pano/index.vue
  38. 1 1
      src/views/material/popup/rename.vue
  39. 44 35
      src/views/material/video/index.vue
  40. 1 1
      src/views/material/works/index.vue

+ 2 - 0
public/showMobile.html

@@ -9,6 +9,8 @@
     <link rel="stylesheet" href="<%= VUE_APP_STATIC_DIR %>/lib/iconfontQJ/iconfont.css"/>
     <link rel="stylesheet" href="<%= VUE_APP_STATIC_DIR %>/lib/iconfontVR/iconfont.css"/>
     <link rel="stylesheet" href="//at.alicdn.com/t/font_2410347_4htx35g8w1b.css"/>
+    <link rel="stylesheet" href="//at.alicdn.com/t/font_1064953_6ikt2gc1snb.css"/>
+    <link rel="stylesheet" href="<%= VUE_APP_STATIC_DIR %>/lib/animate/animate.min.css" />
     <link rel="icon" href="./favicon.ico" />
     <title>VR楼盘</title>
   </head>

Разница между файлами не показана из-за своего большого размера
+ 903 - 1
public/static/template/plugins/webvr.xml


Разница между файлами не показана из-за своего большого размера
+ 904 - 1
public/static/template/plugins/webvr/webvr.xml


+ 1 - 1
public/static/template/skin/vtourskin.xml

@@ -514,7 +514,7 @@
     <cursors standard="default" dragging="move" moving="move"/>
     <include url="%SWFPATH%/plugins/webvr.xml" devices="html5"/>
                          
-     <plugin name="WebVR" keep="true" devices="html5" pluginurl="%SWFPATH%/plugins/webvr.js" url=""
+     <plugin name="WebVR" keep="true" devices="html5" pluginurl="%SWFPATH%/plugins/webvr.js" url="%SWFPATH%/plugins/webvr.js"
             multireslock.desktop="true" multireslock.mobile.or.tablet="false" mobilevr_support="true"
             mobilevr_fake_support="true"
             onavailable="removelayer(webvr_enterbutton); skin_arrange_buttons(); webvr_onavailable();"

+ 4 - 4
src/api/index.js

@@ -29,7 +29,7 @@ const URL_FILL =  config.urlFill
  */
  export function getPanoInfo(data, ok, no) {
     let ossUrl = `https://ossxiaoan.4dage.com/720yun_fd_manage`
-    return http.get(`${ossUrl}/${data||number()}/someData.json`, {}, ok, no)
+    return http.get(`${ossUrl}/${data||number()}/someData.json?_=${Math.random()}`, {}, ok, no)
 }
 
 
@@ -291,7 +291,7 @@ export function checkLogin() {
  * 检测素材状态
  */
  export function checkMStatus(data, ok, no) {
-    return http.get(`${URL_FILL}/manage/fodder/checkStatus/${data.ids.join(',')}`, data, ok, no)
+    return http.get(`${URL_FILL}/manage/fodder/checkStatus/${data.ids.join(',')}`, {islongpolling:data.islongpolling}, ok, no)
 }
 
 
@@ -493,8 +493,8 @@ export function setListSort(data, ok, no) {
  * @param {*} ok 
  * @param {*} no 
  */
- export function uploadMaterial(data, type, ok, no) {
-    return http.uploadFile(`${URL_FILL}/manage/fodder/upload/${type}`, data, ok, no)
+ export function uploadMaterial(data, subdata, ok, no) {
+    return http.uploadFile(`${URL_FILL}/manage/fodder/upload/${subdata.type}/${subdata.uid}`, data, ok, no)
 }
 
 /**

BIN
src/assets/images/default/img_logoshow@2x.png


BIN
src/assets/images/icons/logo_zh.png


BIN
src/assets/images/icons/show_more.png


+ 12 - 2
src/assets/style/component.less

@@ -305,8 +305,8 @@ textarea:-ms-input-placeholder {
     > li {
       position: relative;
       margin: @gap @gap @gap*3;
-      width: 172px;
-      height: 172px;
+      width: 170px;
+      height: 170px;
       border: 2px solid rgba(0, 0, 0, 0);
       .ui-title {
         width: 100%;
@@ -758,6 +758,16 @@ textarea:-ms-input-placeholder {
   animation-duration: 0.2s;
 }
 
+@keyframes word-scroll {
+  0% {
+    transform: translateX(0);
+  }
+
+  100% {
+    transform: translateX(calc(-100% + 60px));
+  }
+}
+
 @keyframes warn-flash {
   0% {
     background-color: rgba(2, 200, 174, 0);

+ 27 - 9
src/components/audio/index.vue

@@ -1,7 +1,7 @@
 <template>
-  <div class="audio-wrapper">
-    <audio ref="audio">
-      <source :src="myAudioUrl" type="audio/mp3" />
+  <div class="audio-wrapper" :key="vkey">
+    <audio ref="audio" :key="vkey">
+      <source :src="myAudioUrl+`?_=${idleft}`" type="audio/mp3" />
     </audio>
     <div class="block" @click="myPlay">
       <div :id="idleft" class="left"></div>
@@ -25,7 +25,7 @@
 <script>
 export default {
   name: "myAudio",
-  props: ["myAudioUrl", "showTime","name", "idleft", "idright"],
+  props: ["myAudioUrl","autoplay", "showTime","name", "idleft", "idright","vkey",'bofang'],
   data() {
     return {
       audio: "",
@@ -69,10 +69,9 @@ export default {
         if (this.audio == data) {
           this.myPlayTemp = true;
         }
-    })
+      })
     },
-    // 点击播放/暂停图片时,控制音乐的播放与暂停
-    myPlay() {
+    stopAllAudio(){
       Array.from($("audio")).forEach((item) => {
         if (this.audio != item) {
           if (!item.paused) {
@@ -81,7 +80,10 @@ export default {
           }
         }
       });
-
+    },
+    // 点击播放/暂停图片时,控制音乐的播放与暂停
+    myPlay() {
+      this.stopAllAudio()
       setTimeout(() => {
         if (this.audio.paused) {
           // 开始播放当前点击的音频
@@ -97,7 +99,7 @@ export default {
     // 更新进度条与当前播放时间
     updateProgress() {
       let value = this.audio.currentTime / this.audio.duration;
-      this.progress = value * 100;
+      this.progress = value * 60;
       // 初始时间
       this.$refs.audioCurTime &&
         (this.$refs.audioCurTime.innerHTML = this.transTime(
@@ -119,6 +121,7 @@ export default {
     audioEnded() {
       this.progress = 0;
       this.myPlayTemp = true;
+      this.$emit('audioEnded')
       this.loadCircle();
     },
     // 播放时间换算
@@ -160,6 +163,21 @@ export default {
     },
   },
   watch: {
+    autoplay:{
+      deep:true,
+      immediate:true,
+      handler:function (newVal) {
+        if (newVal) {
+          this.myPlay()
+        }
+      }
+    },
+    bofang:{
+      deep:true,
+      handler:function () {
+        this.myPlay()
+      }
+    },
     audio: {
       deep: true,
       handler: function () {

+ 76 - 0
src/components/rollName/index.vue

@@ -0,0 +1,76 @@
+<template>
+  <div class="rollcon" :ref="'r_'+myref">
+    <span :class="{shenglv:(parentW < childW && !active)}" :ref="myref" :style="`transform: translateX(${translate}px);
+    ${`width: ${(parentW < childW && !active)?`calc(100% - ${mgin||10}px)`:'auto'}`}`">{{name}}</span>
+  </div>
+</template>
+<script>
+export default {
+  props:['name','myref','active','offset','mgin'],
+
+  data(){
+    return {
+      translate: 0,
+      parentW:0,
+      childW:0,
+    }
+  },
+  watch:{
+    active:{
+      immediate:true,
+      handler:function (newVal) {
+        if (newVal) {
+          this.start()
+        }
+      }
+    }
+  },
+  methods:{
+    start(){
+      let fn = ()=>{
+        this.translate -= 0.4
+        if ((this.parentW - this.translate - this.offset - (this.mgin || 0))>this.childW) {
+          this.translate = this.offset 
+        }
+        if (!this.active) {
+          this.translate = 0
+          return
+        }
+        requestAnimationFrame(fn)
+      }
+      if (this.parentW < this.childW) {
+        fn()
+      }
+    }
+  },
+  mounted(){
+    this.$nextTick(() => {
+      this.parentW = this.$refs['r_'+this.myref].offsetWidth
+      this.childW =this.$refs[this.myref].offsetWidth
+      this.start()
+    })
+  },
+  beforeDestroy(){
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.rollcon{
+  width: 100%;
+  display: inline-block;
+  >span{
+    width: auto;
+    display: inline-block;
+    transition: 0.3s transform ease;
+    vertical-align:unset;
+  }
+  .shenglv{
+    text-overflow: ellipsis;
+    overflow: hidden;
+    white-space: nowrap;
+    line-height: 100%;
+    vertical-align: baseline;
+  }
+}
+</style>

+ 1 - 1
src/components/shared/popup/index.vue

@@ -31,7 +31,7 @@ export default {
     left: 0;
     right: 0;
     bottom: 0;
-    background-color: rgba(0, 0, 0, 0.3);
+    background-color: rgba(0, 0, 0, 0.6);
     overflow: hidden;
     color: #000;
     display: flex;

+ 9 - 5
src/components/tableSelect.vue

@@ -22,7 +22,7 @@
               <input
                 type="checkbox"
                 v-model="allSelect"
-                @click="e => selectAll(e.target.checked)">
+                @click="e => selectAll(e.target)">
               <span></span>
             </div>
           </th>
@@ -32,9 +32,8 @@
           <td>
             <div class="checkbox">
               <input
-                :disabled="item.isUse == '1'"
                 type="checkbox"
-                @change="e => selectItem(item, e.target.checked)"
+                @change="e => selectItem(item, e.target)"
                 :checked="select.some(i => i[primaryKey] === item[primaryKey])"
               >
               <span></span>
@@ -45,7 +44,7 @@
               <img :src="item[sub.key]" alt="">
             </div>
             <div class="audio" v-else-if="sub.type=='audio'" >
-              <v-audio :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="item[sub.key]"></v-audio>
+              <v-audio :vkey="item.id" :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="item[sub.key]"></v-audio>
           </div>
             <span v-else>{{item[sub.key]}}</span>
           </td>
@@ -164,8 +163,13 @@ props:{
         this.selectItem(item, isSelect)
       })
     },
-    selectItem(item, isSelect) {
+    selectItem(item, e) {
+      let isSelect = e.checked
       if (this.hideAll) {
+        if (item.isUse == '1') {
+          e.checked = false
+          return this.$alert({content:'选中素材不能超过600kb'})
+        }
         this.select = [item]
       }
       else{

+ 1 - 1
src/framework/Head.vue

@@ -17,7 +17,7 @@
       v-if="info"
       :name="info.name"
       :show="showPreview"
-      :ifr="`./show.html?id=${info.id}&vr=${info.firstScene?info.firstScene.sceneCode:info.scenes[0].sceneCode}`"
+      :ifr="`./show.html?id=${info.id}&vr=${info.firstScene?info.firstScene.sceneCode:(info.scenes[0]?info.scenes[0].sceneCode:'')}`"
       @close="showPreview = false"
     />
   </header>

+ 30 - 6
src/framework/Toolbar.vue

@@ -26,7 +26,7 @@
               ></i>
             </div>
             <div class="img">
-              <img :src="item.icon+`?${Math.random()}`" alt="" />
+              <img v-if="item.icon" :src="item.icon+`?${Math.random()}`" alt="" />
             </div>
             <div class="ui-title">
               <span>{{ item.sceneTitle }}</span>
@@ -68,10 +68,24 @@ export default {
     })
   },
   methods: {
-    
+    updateInfo(){
+      let iidx = this.info.scenes.findIndex(item=>this.activeItem.sceneCode == item.sceneCode)
+      if (iidx>-1) {
+        this.info.scenes[iidx] = {
+          ...this.activeItem
+        }
+      }
+      this.$store.commit("SetInfo", this.info);
+    }
   },
   created() {},
   watch: {
+    'info.scenes':{
+      deep:true,
+      handler: function (newVal) {
+        console.log(newVal);
+      }
+    },
     taboneActive: {
       deep:true,
       handler: function (newVal,oldVal) {
@@ -95,9 +109,11 @@ export default {
         if (!newVal) {
           this.tabtowActive = this.childTab[0]
         } else{
-          this.scenes = this.info.scenes.filter(item=>{
+
+          let arr = this.info.scenes.filter(item=>{
             return newVal.id == item.category && item.type!='4dkk'
           })
+          this.scenes = arr.sort((a,b)=>a.weight-b.weight)
           this.activeItem = this.scenes[0]
         }
       }
@@ -108,8 +124,11 @@ export default {
       handler: function (newVal) {
         if (newVal) {
           if (this.loadList) {
-              this.taboneActive = this.info.catalogRoot[0] || { children: [] };
-              this.loadList = false
+              this.taboneActive = { children: [] };
+              setTimeout(() => {
+                this.taboneActive = this.info.catalogRoot[0] || { children: [] };
+                this.loadList = false 
+              });
           }
         }
       }
@@ -119,8 +138,9 @@ export default {
       handler: function(newVal) {
         this.$bus.emit("currentPcode", newVal);
         this.$store.commit("SetActiveItem", newVal || "");
+        this.updateInfo()
         if (newVal) {
-          this.$bus.emit("initView", newVal.icon);
+          this.$bus.emit("initView", newVal.icon||'');
         }
       },
     },
@@ -148,6 +168,10 @@ export default {
     this.$bus.on("canEdit", (data) => {
       this.canEdit = data;
     });
+
+    this.$bus.on("scenesChange", ()=> {
+      this.loadList = true;
+    });
   },
 };
 </script>

+ 11 - 1
src/framework/core/index.vue

@@ -12,7 +12,7 @@
 
 <script>
 import * as krfn from "@/core/index.js";
-import { uploadCover,savePosition,saveInitScreen } from "@/api";
+import { uploadCover } from "@/api";
 import { $waiting } from '@/components/shared/loading'
 import { mapGetters } from "vuex";
 
@@ -42,6 +42,15 @@ export default {
     },
   },
   methods: {
+    updateInfo(){
+      let iidx = this.info.scenes.findIndex(item=>this.activeItem.sceneCode == item.sceneCode)
+      if (iidx>-1) {
+        this.info.scenes[iidx] = {
+          ...this.activeItem
+        }
+      }
+      this.$store.commit("SetInfo", this.info);
+    },
     onClick() {
       this.$bus.emit('toggleFlash',true)
       let canvas = $("#krpanoSWFObject canvas")[0];
@@ -59,6 +68,7 @@ export default {
             }
             this.$bus.emit('toggleFlash',false)
             this.$bus.emit("initView", res.data);
+            this.updateInfo()
             this.$tips({ content: "设置成功",icon:'ok' });
             this.$store.commit("SetInfo", this.info);
           }

+ 17 - 5
src/framework/show/index.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="panocon">
     <template v-if="showInfo">
-      <iframe  v-if="activeItem.type=='4dkk'" 
+      <iframe allowfullscreen="true" v-if="activeItem.type=='4dkk'" 
       :src="`https://test.4dkankan.com/spc.html?m=${activeItem.sceneCode}`" frameborder="0"></iframe>
       <div v-show="activeItem.type!='4dkk'" id="pano"></div>
 
-      <div class="pano-logo" v-if="showInfo.isLogo">
-        <img :src="showInfo.logo||require('@/assets/images/icons/img_logo.png')" alt="" />
+      <div class="pano-logo" v-if="showInfo.isLogo&&activeItem.type!='4dkk'">
+        <img :src="showInfo.logo||require('@/assets/images/default/img_logoshow@2x.png')" alt="" />
       </div>
 
       <div
@@ -68,6 +68,7 @@ import { getPanoInfo, checkPassword,checkWork } from "@/api";
 import password from "./popup/password";
 import preview from "./popup/preview";
 
+
 import popup from "./popup/";
 import { mapGetters } from "vuex";
 
@@ -108,6 +109,10 @@ export default {
           icon: "icontool_about",
         },
         {
+          id: "vr",
+          icon: "icontool_vr",
+        },
+        {
           id: "full",
           icon: "icontool_full",
         },
@@ -148,6 +153,12 @@ export default {
       if (data.id == "full") {
         this.onFullScreen()
       }
+      if (data.id == "vr") {
+        var krpano = document.getElementById("krpanoSWFObject");
+        var webvr = krpano.get("webvr");
+        webvr.entervr();
+        // window.webvr.enterVR()
+      }
     },
     handlePassword(data) {
       checkPassword(
@@ -214,6 +225,7 @@ export default {
       immediate: true,
       handler: function (newVal) {
         if (newVal) {
+          document.title = newVal.name || '未命名'
           let locoR = "localRemind"+newVal.id
           if (!newVal.description) {
             this.aside.shift()
@@ -255,8 +267,8 @@ export default {
         if (newVal) {
           removepano("#pano");
           embedpano({
-            // xml: "%HTMLPATH%/static/template/tour.xml",
-            xml: `${this.$cdn}/720yun_fd_manage/${newVal.sceneCode}/vtour/tour.xml`,
+            xml: "%HTMLPATH%/static/template/tour.xml",
+            // xml: `${this.$cdn}/720yun_fd_manage/${newVal.sceneCode}/vtour/tour.xml`,
             swf: "%HTMLPATH%/static/template/tour.swf",
             target: "pano",
             html5: "auto",

+ 41 - 18
src/framework/show/list.vue

@@ -2,12 +2,12 @@
   <div class="list">
      <div class="l-con" :class="showList?'active':''">
        <div class="clip-scroller">
-        <ul class="pic-list" v-if="scenes.length>0">
-          <li @click="handleVR(item)" v-for="(item,i) in scenes" :key="i">
+        <ul class="pic-list" v-if="scenes.length>0" ref="pic">
+          <li :title="item.sceneTitle" @click="handleVR(item)" v-for="(item,i) in scenes" :key="i">
             <div :class="{active:selected.sceneCode==item.sceneCode}">
               <img :src="item.icon+`?${Math.random()}`" alt="" />
               <i class="iconfont iconscene_map_3d" :class="{'iconjump':item.type!=='4dkk'}"></i>
-              <span>{{item.sceneTitle}}</span>
+              <rollName :offset="20" :active="selected.sceneCode==item.sceneCode" class="pic-name" :myref="'subw'+item.id" :name="item.sceneTitle"/>
             </div>
           </li>
         </ul>
@@ -16,7 +16,7 @@
       <div class="clip-scroller" v-if="childTab.length > 1">
         <ul class="tap">
           <li @click="tabtowActive = item" v-for="(item,i) in childTab" :key="i">
-            <span :title="item.name" :class="{active:item.id == tabtowActive.id}" class="btn rect">{{item.name}}</span>
+            <rollName :offset="30" :mgin="20" :active="item.id == tabtowActive.id" class="btn rect" :class="{active:item.id == tabtowActive.id}" :myref="'ww'+item.id" :name="item.name"/>
           </li>
         </ul>
       </div>
@@ -24,7 +24,7 @@
       <div class="clip-scroller" v-if="showInfo.catalogRoot.length > 0 && showInfo.catalogs.length>1">
        <ul class="tap">
         <li @click="taboneActive = item" v-for="(item,i) in showInfo.catalogRoot" :key="i">
-          <span :title="item.name" :class="{active:item.id == taboneActive.id}" class="btn rect">{{item.name}}</span>
+          <rollName :offset="30" :mgin="20" :active="item.id == taboneActive.id" class="btn rect" :class="{active:item.id == taboneActive.id}" :myref="'zw'+item.id" :name="item.name"/>
         </li>
       </ul>
       </div>
@@ -38,11 +38,13 @@
 <script>
 import { mapGetters } from "vuex";
 import config from "@/config";
+import rollName from "@/components/rollName";
 
 let $scroll = null;
 
 export default {
   props:['select'],
+  components:{rollName},
   
   data(){
     return{
@@ -66,6 +68,11 @@ export default {
   },
 
   methods:{
+    getCWidth(ref){
+      if (this.$refs[ref]) {
+        return this.$refs[ref][0].clientWidth
+      }
+    },
     handleVR(item){
       history.replaceState(null, null, "".concat(window.location.pathname, "?").concat(`id=${this.showInfo.id}&vr=${item.sceneCode}`));
       this.sceneNum = item.sceneCode
@@ -111,9 +118,10 @@ export default {
         if (!newVal) {
           this.tabtowActive = this.childTab[0]
         } else{
-          this.scenes = this.showInfo.scenes.filter(item=>{
+          let arr = this.showInfo.scenes.filter(item=>{
             return newVal.id == item.category
           })
+          this.scenes = arr.sort((a,b)=>a.weight-b.weight)
         }
       }
     },
@@ -122,6 +130,10 @@ export default {
       deep:true,
       immediate:true,
       handler:function (newVal) {
+          if (!newVal) {
+            this.handleVR(this.showInfo.scenes[0])
+            return
+          }
           let val = this.showInfo.scenes.find(item=>item.sceneCode==newVal)
           let tmp = this.showInfo.catalogs.find(item=>item.id==val.category)
           let rootTmp = this.showInfo.catalogRoot.find(item => {
@@ -174,9 +186,13 @@ export default {
 }
 
 .rect{
-    border-radius: 4px;
-    height: 24px;
-    line-height: 24px;
+  border-radius: 4px;
+  height: 24px;
+  line-height: 24px;
+  padding: 0;
+  & /deep/ span{
+    margin: 0 20px;
+  }
 }
 
 .line{
@@ -224,6 +240,16 @@ export default {
       li{
         margin: 0 5px;
         display: inline-block;
+        
+      }
+    }
+    .tap{
+      padding: 12px 0;
+    }
+    .pic-list{
+      padding: 12px 0;
+      >li{
+        cursor: pointer;
         >div{
           width: 72px;
           height: 72px;
@@ -233,6 +259,12 @@ export default {
           overflow: hidden;
           position: relative;
           cursor: pointer;
+          .pic-name{
+            background: rgba(0, 0, 0, 0.5);
+            position: absolute;
+            left: 0;
+            bottom: 0;
+          }
           >img{
             position: absolute;
             top: 50%;
@@ -262,15 +294,6 @@ export default {
         }
       }
     }
-    .tap{
-      padding: 12px 0;
-    }
-    .pic-list{
-      padding: 12px 0;
-      >li{
-        cursor: pointer;
-      }
-    }
 
     .onecls{
       background: rgba(0, 0, 0, 0.3);

+ 18 - 1
src/framework/show/popup/password.vue

@@ -18,6 +18,7 @@
               placeholder="请输入访问密码"
               v-model="key"
             />
+            <i v-if="key" class="iconfont icon_close" @click="key=''"></i>
           </div>
         </div>
         <div class="ma-line"></div>
@@ -47,7 +48,7 @@ export default {
   },
   methods:{
     emitname(){
-      if (!this.key) {
+      if (!this.key.trim()) {
         return this.$alert({ content: "请输入访问密码" });
       }
       this.$emit('submit',this.key)
@@ -76,11 +77,27 @@ export default {
     width: 330px;
     margin: 20px auto;
     background: #fff;
+    >div{
+      position: relative;
+      >i{
+        position: absolute;
+        right: 10px;
+        top: 50%;
+        transform: translateY(-50%);
+        background: #ebebeb;
+        color: #fff;
+        border-radius: 50%;
+        padding: 2px;
+        cursor: pointer;
+        font-size: 14px;
+      }
+    }
     .ui-input{
       background-color: #fff;
       border: 1px solid rgba(#909090,0.5);
       color: #909090;
     }
+    
   }
   .ui-message-footer{
     width: 100%;

+ 1 - 1
src/framework/show/popup/preview.vue

@@ -19,7 +19,7 @@
           </template>
           <template v-else-if="item.hotspotType=='audio'">
             <div class="v-audio">
-              <v-audio :showTime=true :name="item.audio.name" :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="item.audio.ossPath"></v-audio>
+              <v-audio :vkey="item.id" :showTime=true :name="item.audio.name" :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="item.audio.ossPath"></v-audio>
             </div>
           </template>
           <video :poster="item.video.icon" v-else controls autoplay :src="item.video.ossPath"></video>

+ 17 - 2
src/framework/showMobile/iframe.vue

@@ -1,12 +1,21 @@
 <template>
   <div class="ifrcon">
-    <iframe ref="iframe" id="showifr" :src="url" frameborder="0" @load="onIframLoad"></iframe>
+    <Header :params="params" :title="'111'" />
+    <iframe allowfullscreen="true" ref="iframe" id="showifr" :src="url" frameborder="0" @load="onIframLoad"></iframe>
   </div>
 </template>
 
 <script>
+import Header from "./ui/Show.Header";
+
 export default {
   props:['url'],
+  components:{Header},
+  data(){
+    return {
+      params:''
+    }
+  },
   methods:{
     onIframLoad(){
       window.onmessage = e =>{
@@ -18,9 +27,15 @@ export default {
           this.$bus.emit('guideRoomsData',e.data.params)
         }
 
+        // if (e.data.event == "guide-status") {
+        // }
+
+        if (e.data.event == "action") {
+          this.$bus.emit('currentMode',e.data.params)
+        }
 
         if (e.data.event == "loaded") {
-          this.$bus.emit('sceneData',e.data.params)
+          this.params = e.data.params
           this.$refs.iframe.contentWindow.postMessage({
               source: "mingyuan",
               event: 'guide-rooms'

+ 108 - 45
src/framework/showMobile/index.vue

@@ -1,11 +1,11 @@
 <template>
   <div class="panocon">
-    <template v-if="showInfo&&showInfo.firstScene">
+    <template v-if="showInfo">
       <v-ifr v-if="activeItem.type=='4dkk'" :url="`https://test.4dkankan.com/embed.html?from=mingyuan&m=${activeItem.sceneCode}`" />
       <div v-show="activeItem.type!='4dkk'" id="pano"></div>
 
-      <div class="pano-logo" v-if="showInfo.isLogo">
-        <img :src="showInfo.logo||require('@/assets/images/icons/img_logo.png')" alt="" />
+      <div class="pano-logo" v-if="showInfo.isLogo&&activeItem.type!='4dkk'">
+        <img :src="showInfo.logo||require('@/assets/images/default/img_logoshow@2x.png')" alt="" />
       </div>
 
       <ul class="aside" v-show="activeItem.type!='4dkk'">
@@ -30,7 +30,7 @@
       >
         <img
           :src="
-            showInfo.pcIcon ||
+            showInfo.appIcon ||
             require('@/assets/images/default/show/img_tipsmb_default.png')
           "
           alt=""
@@ -44,7 +44,7 @@
       />
       <popup :title="'简介'" :show="showIntro" @close="showIntro = false">
         <div slot="content" class="introcon">
-          {{ showInfo.description }}
+          {{ showInfo.description || "暂无简介" }}
         </div>
       </popup>
       <imgview
@@ -69,6 +69,10 @@
         </div>
       </popup>
 
+      <div v-if="audioUrl" class="audio-btn" @click="bofang=!bofang">
+        {{bofang?'继续':'停止'}}播放
+        <v-audio :vkey="audioUrl.id" @audioEnded="handleEnded" :autoplay="true" :bofang="bofang" :v-show="false" :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="audioUrl.audio.ossPath"></v-audio>
+      </div>
       
     </template>
 
@@ -97,6 +101,7 @@ import vIfr from "./iframe";
 
 import popup from "./popup/";
 import { mapGetters } from "vuex";
+import vAudio from '@/components/audio'
 
 import list from "./list";
 
@@ -109,7 +114,8 @@ export default {
     popup,
     preview,
     imgview,
-    vIfr
+    vIfr,
+    vAudio
   },
   computed: {
     ...mapGetters({
@@ -119,8 +125,11 @@ export default {
   data() {
     return {
       showPreview: false,
+      audioUrl:'',
+      bofang:false,
       showTips: true,
       showImage: false,
+      showAudio:false,
       canLoad: false,
       showPassword: false,
       showIntro: false,
@@ -145,11 +154,21 @@ export default {
     };
   },
   methods: {
+    handleEnded(){
+      this.audioUrl = ''
+    },
     handleItem(data) {
       if (data.id == "about") {
         this.showIntro = true;
       }
+      if (data.id == "vr") {
+        var krpano = document.getElementById("krpanoSWFObject");
+        var webvr = krpano.get("webvr");
+        webvr.entervr();
+        // window.webvr.enterVR()
+      }
     },
+    
     handlePassword(data) {
       checkPassword(
         {
@@ -167,7 +186,7 @@ export default {
       this.canLoad = true;
     },
     handleSelect(data) {
-      this.activeItem = data;
+        this.activeItem = data;
     },
     
     getSceneInfo() {
@@ -190,8 +209,8 @@ export default {
     currentHotspot: {
       deep: true,
       handler: function (newVal) {
-        console.log(newVal);
         if (newVal) {
+          this.audioUrl = ''
           if (newVal.hotspotType == "link") {
             window.open(newVal.hyperlink, "_blank");
             return;
@@ -208,9 +227,14 @@ export default {
             this.showTextarea = true;
             return;
           }
+          if (newVal.hotspotType == "audio") {
+            this.audioUrl = newVal;
+            return;
+          }
+          
           this.showPreview = true;
         }
-      },
+      }
     },
     canLoad(newVal) {
       if (newVal) {
@@ -224,7 +248,8 @@ export default {
       immediate: true,
       handler: function (newVal) {
         if (newVal) {
-        let locoR = "localRemind"+newVal.id
+          document.title = newVal.name || '未命名'
+          let locoR = "localRemind"+newVal.id
 
           if (!newVal.description) {
             this.aside.shift()
@@ -243,40 +268,45 @@ export default {
     },
     activeItem: {
       handler(newVal) {
-        $("#pano").empty();
-        window.vrInitFn = () => {
-          var krpano = document.getElementById("krpanoSWFObject");
-          __krfn.utils.initHotspot(krpano, newVal && newVal.someData, false);
-        };
-        window.vrViewFn = () => {
-          try {
-            let tmp = newVal.initVisual||{};
-            var krpano = document.getElementById("krpanoSWFObject");
-            krpano.set("view.vlookat", tmp.vlookat||0);
-            krpano.set("view.hlookat", tmp.hlookat||0);
-            krpano.set("autorotate.enabled", Boolean(this.showInfo.isAuto));
-          } catch (error) {
-            error;
-          }
-        };
-        var settings = {
-          "events[skin_events].onxmlcomplete": "js(window.vrViewFn());",
-          "events[skin_events].onloadcomplete": "js(window.vrInitFn());",
-        };
-        if (newVal) {
-          removepano("#pano");
-          embedpano({
-            // xml: "%HTMLPATH%/static/template/tour.xml",
-            xml: `${this.$cdn}/720yun_fd_manage/${newVal.sceneCode}/vtour/tour.xml`,
-            swf: "%HTMLPATH%/static/template/tour.swf",
-            target: "pano",
-            html5: "auto",
-            mobilescale: 0.7,
-            vars: settings,
-            passQueryParameters: true,
-          });
-        }
+        this.$nextTick(()=>{
+            removepano("#pano");
+            $("#pano").empty();
+            window.vrInitFn = () => {
+              var krpano = document.getElementById("krpanoSWFObject");
+              __krfn.utils.initHotspot(krpano, newVal && newVal.someData, false);
+            };
+            window.vrViewFn = () => {
+              try {
+                let tmp = newVal.initVisual||{};
+                var krpano = document.getElementById("krpanoSWFObject");
+                krpano.set("view.vlookat", tmp.vlookat||0);
+                krpano.set("view.hlookat", tmp.hlookat||0);
+                krpano.set("autorotate.enabled", Boolean(this.showInfo.isAuto));
+              } catch (error) {
+                error;
+              }
+            };
+            var settings = {
+              "events[skin_events].onxmlcomplete": "js(window.vrViewFn());",
+              "events[skin_events].onloadcomplete": "js(window.vrInitFn());",
+            };
+            if (newVal) {
+              removepano("#pano");
+              embedpano({
+                // xml: "%HTMLPATH%/static/template/tour.xml",
+                xml: `${this.$cdn}/720yun_fd_manage/${newVal.sceneCode}/vtour/tour.xml`,
+                swf: "%HTMLPATH%/static/template/tour.swf",
+                target: "pano",
+                html5: "auto",
+                mobilescale: 0.7,
+                vars: settings,
+                passQueryParameters: true,
+              });
+            }
+        })
+
       },
+      
     },
   },
   mounted() {
@@ -322,6 +352,36 @@ export default {
     height: 100%;
   }
 
+  .audio-btn{
+    display: inline-block;
+    margin: 0 auto;
+    height: 36px;
+    line-height: 36px;
+    min-width: 78px;
+    cursor: pointer;
+    text-overflow: ellipsis;
+    text-align: center;
+    overflow: hidden;
+    white-space: nowrap;
+    position: fixed;
+    left: 50%;
+    transform: translateX(-50%);
+    bottom: 12px;
+    z-index: 9999;
+    border-radius: 18px;
+    background: rgba(0, 0, 0, 0.3);
+    border-radius: 18px;
+    border: 1px solid rgba(255, 255, 255, 0.2);
+    margin-top: 10px;
+    margin-left: 10px;
+    padding: 0 10px;
+    &.active{
+      background: rgba(0, 0, 0, 0.3);
+      border: 1px solid #1FE4DC;
+      color: #1FE4DC;
+    }
+}
+
   .pano-logo {
     position: absolute;
     top: 10px;
@@ -347,9 +407,9 @@ export default {
   }
   .aside {
     position: fixed;
-    z-index: 999;
+    z-index: 1001;
     right: 10px;
-    bottom: 0;
+    bottom: 4px;
     display: flex;
     > li {
       margin: 0 0 5px 5px;
@@ -375,6 +435,9 @@ export default {
   .introcon {
     line-height: 20px;
     color: #909090;
+    margin: 0 auto;
+    width: 90%;
+
   }
 }
 </style>

+ 95 - 62
src/framework/showMobile/list.vue

@@ -6,19 +6,20 @@
           <div :class="{active:selected.sceneCode==item.sceneCode}">
             <img :src="item.icon+`?${Math.random()}`" alt="" />
             <i class="iconfont iconscene_map_3d" :class="{'iconjump':item.type!=='4dkk'}"></i>
-            <span>{{item.sceneTitle}}</span>
+            <rollName :offset="20" :active="selected.sceneCode==item.sceneCode" class="pic-name" :myref="'subw'+item.id" :name="item.sceneTitle"/>
           </div>
         </li>
       </ul>
       
       <ul class="tap" v-if="childTab.length > 1" >
         <li  @click="tabtowActive = item" v-for="(item,i) in childTab" :key="i">
-          <span :title="item.name" :class="{active:item.id == tabtowActive.id}" class="btn rect">{{item.name}}</span>
+            <rollName :offset="30" :mgin="20" :active="item.id == tabtowActive.id" class="btn rect" :class="{active:item.id == tabtowActive.id}" :myref="'ww'+item.id" :name="item.name"/>
         </li>
       </ul>
        <ul class="tap" v-if="showInfo.catalogRoot.length > 1">
         <li @click="taboneActive = item" v-for="(item,i) in showInfo.catalogRoot" :key="i">
           <span :title="item.name"  :class="{active:item.id == taboneActive.id}" class="btn rect">{{item.name}}</span>
+            <rollName :offset="30" :mgin="20" :active="item.id == taboneActive.id" class="btn rect" :class="{active:item.id == taboneActive.id}" :myref="'zw'+item.id" :name="item.name"/>
         </li>
       </ul>
     </div>
@@ -30,6 +31,10 @@
 
         <li class="licon">
           <ul>
+            <li @click="handleDL" v-if="isShowDL">
+              <i class="iconfont" :class="isDaolan?'iconshow_suspension':'iconshow_playback'"></i>
+              <span title="导览" >导览</span>
+            </li>
             <li v-for="(item,i) in menu" @click="handleMenu(item)" :key="i">
               <i class="iconfont" :class="currentActive==item.id?item.active:item.icon"></i>
               <span :title="item.name" >{{item.name}}</span>
@@ -51,37 +56,36 @@
 <script>
 import { mapGetters } from "vuex";
 import config from "@/config";
+import rollName from "@/components/rollName";
 
 export default {
   props:['select'],
+  components:{rollName},
   
   data(){
     let menu = [{
-      id:'daolan',
-      name:'导览',
-      icon:'iconshow_playback',
-      active:'iconshow_suspension'
-    },{
-      id:'manyou',
+      id:'pano',
       name:'漫游',
       icon:'iconshow_roaming_normal',
       active:'iconshow_roaming_selected',
       params:'pano'
     },{
-      id:'pingmian',
+      id:'2d',
       name:'平面',
       icon:'iconshow_plane_normal',
       active:'iconshow_plane_selected',
       params:'2d'
     },{
-      id:'sanwei',
+      id:'3d',
       name:'三维',
       icon:'iconshow_3d_normal',
       active:'iconshow_3d_selected',
       params:'3d'
     }]
     return{
-      currentActive:'manyou',
+      isDaolan:false,
+      isShowDL:'',
+      currentActive:'pano',
       taboneActive:{children:[]},
       tabtowActive:'',
       childTab:[],
@@ -90,7 +94,8 @@ export default {
       menu,
       showList:true,
       loadFirst: true,
-      shouqi:false
+      shouqi:false,
+      canClick:true
     }
   },
   computed: {
@@ -104,41 +109,45 @@ export default {
 
   mounted(){
       this.$bus.on('guideRoomsData',data=>{
-        if (data.length<0) {
-          this.menu.shift()
+        if (data.length>0) {
+          this.isShowDL = true
         }
       })
-  },
-  methods:{
-    handleMenu(data){
-      if (this.currentActive == data.id) {
-        this.currentActive = ''
-      }
-      else{
-        this.currentActive = data.id
-      }
 
-      if (data.id=='manyou') {
-        this.currentActive = data.id
-      }
+      this.$bus.on('currentMode',data=>{
+        this.delHandle()
+        this.currentActive = data.data.mode || 'pano'
+        // this.menu.findItem(item=>item.params == data.data.mode)
+      })
       
-
+  },
+  methods:{
+    handleDL(){
+      this.isDaolan = !this.isDaolan
       let ele = document.getElementById('showifr');
-      let event = ''
-      let params = null
-      if (data.id=='daolan') {
-        this.currentActive?(event='guide-start'):(event='guide-pause')
-      }
-      else{
-        event = 'mode'
-        params = data.params
-      }
       ele.contentWindow.postMessage({
           source: "mingyuan",
-          event: event,
-          params: params,
+          event: this.isDaolan?'guide-start':'guide-pause',
       },"*")
     },
+    delHandle(){
+      this.canClick = false
+      setTimeout(() => {
+        this.canClick = true
+      }, 1800);
+    },
+    handleMenu(data){
+      if (this.canClick) {
+        this.currentActive = data.id
+        let ele = document.getElementById('showifr');
+        ele.contentWindow.postMessage({
+            source: "mingyuan",
+            event: 'mode',
+            params: data.params,
+        },"*")
+        this.delHandle()
+      }
+    },
     handleVR(item){
       history.replaceState(null, null, "".concat(window.location.pathname, "?").concat(`id=${this.showInfo.id}&vr=${item.sceneCode}`));
       this.sceneNum = item.sceneCode
@@ -166,9 +175,10 @@ export default {
         if (!newVal) {
           this.tabtowActive = this.childTab[0]
         } else{
-          this.scenes = this.showInfo.scenes.filter(item=>{
+          let arr = this.showInfo.scenes.filter(item=>{
             return newVal.id == item.category
           })
+          this.scenes = arr.sort((a,b)=>a.weight-b.weight)
         }
       }
     },
@@ -177,6 +187,10 @@ export default {
       deep:true,
       immediate:true,
       handler:function (newVal) {
+          if (!newVal) {
+            this.handleVR(this.showInfo.scenes[0])
+            return
+          }
           let val = this.showInfo.scenes.find(item=>item.sceneCode==newVal)
           let tmp = this.showInfo.catalogs.find(item=>item.id==val.category)
           let rootTmp = this.showInfo.catalogRoot.find(item => {
@@ -215,6 +229,7 @@ export default {
     background: rgba(0, 0, 0, 0.1);
     border: 1px solid rgba(255, 255, 255, 0.2);
     min-width: 78px;
+    max-width: 200px;
     cursor: pointer;
     text-overflow: ellipsis;
     overflow: hidden;
@@ -227,9 +242,14 @@ export default {
 }
 
 .rect{
-    border-radius: 4px;
-    height: 24px;
-    line-height: 24px;
+  border-radius: 4px;
+  height: 24px;
+  line-height: 24px;
+  padding: 0;
+  & /deep/ span{
+    line-height: 100%;
+    margin: 0 20px;
+  }
 }
 
 .line{
@@ -298,6 +318,9 @@ export default {
         }
       }
 
+      .licon{
+        max-width: none;
+      }
 
       &.shouqi{
         .licon{
@@ -333,6 +356,27 @@ export default {
       li{
         margin: 0 5px;
         text-align: center;
+        
+      }
+    }
+    .tap{
+      padding: 12px 10px;
+      background: rgba(0, 0, 0, 0.3);
+      margin-top: 1px;
+      overflow-x: auto;
+      &::-webkit-scrollbar{
+        display: none;
+      }
+    }
+    .pic-list{
+      background: rgba(0, 0, 0, 0.3);
+      padding: 12px 0;
+      overflow-x: auto;
+      &::-webkit-scrollbar {
+        display: none;
+      }
+      >li{
+        cursor: pointer;
         >div{
           width: 72px;
           height: 72px;
@@ -369,26 +413,15 @@ export default {
               border: 2px solid #1FE4DC;
           }
         }
-      }
-    }
-    .tap{
-      padding: 12px 10px;
-      background: rgba(0, 0, 0, 0.3);
-      margin-top: 1px;
-      overflow-x: auto;
-      &::-webkit-scrollbar{
-        display: none;
-      }
-    }
-    .pic-list{
-      background: rgba(0, 0, 0, 0.3);
-      padding: 12px 0;
-      overflow-x: auto;
-      &::-webkit-scrollbar {
-        display: none;
-      }
-      >li{
-        cursor: pointer;
+        .pic-name{
+          background: rgba(0, 0, 0, 0.5);
+          position: absolute;
+          left: 0;
+          bottom: 0;
+          /deep/ span{
+            word-break: keep-all;
+          }
+        }
       }
     }
     &.active{

+ 1 - 1
src/framework/showMobile/popup/index.vue

@@ -7,7 +7,7 @@
             <i class="iconfont icon_close"></i>
           </span>
         </div>
-        <div class="ui-message-main re-name">
+        <div class="ui-message-main">
           <slot name="content" />
         </div>
       </div>

+ 17 - 1
src/framework/showMobile/popup/password.vue

@@ -18,6 +18,7 @@
               placeholder="请输入访问密码"
               v-model="key"
             />
+            <i v-if="key" class="iconfont icon_close" @click="key=''"></i>
           </div>
         </div>
         <div class="ma-line"></div>
@@ -47,7 +48,7 @@ export default {
   },
   methods:{
     emitname(){
-      if (!this.key) {
+      if (!this.key.trim()) {
         return this.$alert({ content: "请输入访问密码" });
       }
       this.$emit('submit',this.key)
@@ -81,6 +82,21 @@ export default {
       border: 1px solid rgba(#909090,0.5);
       color: #909090;
     }
+    >div{
+      position: relative;
+      >i{
+        position: absolute;
+        right: 10px;
+        top: 50%;
+        transform: translateY(-50%);
+        background: #ebebeb;
+        color: #fff;
+        border-radius: 50%;
+        padding: 2px;
+        cursor: pointer;
+        font-size: 14px;
+      }
+    }
   }
   .ui-message-footer{
     width: 100%;

+ 647 - 0
src/framework/showMobile/ui/Show.Header.vue

@@ -0,0 +1,647 @@
+<template>
+    <div class="header app" v-if="params.title" @touchmove.prevent>
+        <div class="left show" >
+        </div>
+        <div
+            
+            class="title"
+            :class="{up:showDescription,empty: false}"
+            @click="onShowDescription"
+        >
+            <div>
+                <span>
+                    {{params.title}}
+                </span>
+                <i class="iconfont iconshow_drop-down"></i>
+            </div>
+        </div>
+        <div
+            class="right"
+            :class="{ more: showMore}"
+            @click="onShowMore"
+        >
+            <i class="iconfont iconshow_more"></i>
+            <keep-alive>
+                <transition
+                    appear
+                    name="custom-classes-transition"
+                    enter-active-class="animated fadeInUp short faster"
+                    leave-active-class="animated fadeOutDown short faster"
+                >
+                    <div v-if="showMore">
+                        <ul>
+                            <!-- <li>
+                                <i class="iconfont iconshow_more_ruler"></i>
+                                <span>菜单</span>
+                            </li> -->
+                            <li @click="handleVR">
+                                <i class="iconfont iconshow_more_vr"></i>
+                                <span>VR模式</span>
+                            </li>
+                            <li v-if="false">
+                                <i class="iconfont iconshow_more_music"></i>
+                                <b>
+                                    <i class="iconfont iconshow_more_finish"></i>
+                                </b>
+                                <span
+                                    v-html="
+                                        '音乐'
+                                    "
+                                ></span>
+                            </li>
+                            <!-- <li @click.stop="onMenuClick('share')">
+                                <i class="iconfont iconshow_more_share"></i>
+                                <span>分享链接</span>
+                            </li> -->
+                        </ul>
+                        <template>
+                            <div class="home">
+                                <a href="/">
+                                    <img
+                                        :src="require('@/assets/images/icons/logo_zh.png')"
+                                        alt=""
+                                    />
+                                </a>
+                            </div>
+                        </template>
+                    </div>
+                </transition>
+            </keep-alive>
+        </div>
+        <transition
+            appear
+            name="custom-classes-transition"
+            enter-active-class="animated fadeInUp short faster"
+            leave-active-class="animated fadeOutDown short faster"
+        >
+            <div
+                class="content"
+                v-if="showDescription"
+                @click="onShowDescription"
+            >
+                <div>
+                    <div v-html="params.description||'四维看看,让空间说故事'"></div>
+                </div>
+            </div>
+        </transition>
+        <template v-if="true">
+            <transition
+                appear
+                name="custom-classes-transition"
+                enter-active-class="animated slideInUp faster"
+                leave-active-class="animated slideOutDown faster"
+            >
+                <div class="app-share" v-if="false">
+                    <ul>
+                        <li @click="onShare('weixin')">
+                            <i class="iconfont icon_wechat"></i>
+                            <div>微信</div>
+                        </li>
+                        <li @click="onShare('weixinFriend')">
+                            <i class="iconfont icon_friend"></i>
+                            <div>朋友圈</div>
+                        </li>
+                        <li @click="onShare('qq')">
+                            <i class="iconfont icon_qq"></i>
+                            <div>QQ</div>
+                        </li>
+                        <li @click="onShare('copy')">
+                            <i class="iconfont iconlink"></i>
+                            <div>复制链接</div>
+                        </li>
+                    </ul>
+                    <div @click="showShare = false">取消</div>
+                </div>
+            </transition>
+        </template>
+        <div class="url-share" v-show="false">
+            <div>
+                <div class="tips">
+                    <h4>分享</h4>
+                    <i class="iconfont iconshow_cancel" @click="showCopy = false"></i>
+                </div>
+                <div class="url">分享链接</div>
+                <div class="btns">
+                    <button class="ui-button cancel" @click="showCopy = false">
+                        取消
+                    </button>
+                    <button class="ui-button submit btn-share-copy" :data-clipboard-text="shareURL">
+                        分享
+                    </button>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+
+export default {
+    props:['title','description','params'],
+    data() {
+        return {
+           showDescription:false,
+           showMore:false,
+           shareURL:''
+        }
+    },
+
+    methods: {
+      onShowDescription(){
+          this.showDescription = !this.showDescription
+          this.showMore = false
+      },
+      onShowMore(){
+          this.showMore = !this.showMore
+          this.showDescription = false
+      },
+      handleVR(){
+        let ele = document.getElementById('showifr');
+        ele.contentWindow.postMessage({
+            source: "mingyuan",
+            event: 'vr-in',
+        },"*")
+      }
+    },
+
+    mounted(){
+    }
+}
+</script>
+<style lang="less" scoped>
+.disable{
+    opacity: 1;
+}
+.header {
+    font-size: 16px;
+    position: absolute;
+    top: 12px;
+    left: 0;
+    height: 44px;
+    width: 100%;
+    z-index: 101;
+    color: #fff;
+    display: flex;
+    align-items: center;
+    text-shadow: 0px 0px 4px rgba(0, 0, 0, 0.4);
+    &.app {
+        top: 1rem;
+    }
+    .left {
+        width: 1.28rem;
+        height: 100%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        &.show {
+            visibility: visible;
+            pointer-events: auto;
+            .back {
+                visibility: visible;
+            }
+        }
+        .back {
+            width: 0.78rem;
+            height: 0.78rem;
+            border-radius: 50%;
+            background-color: rgba(0, 0, 0, 0.3);
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            visibility: hidden;
+            i {
+                font-size: 0.3rem;
+            }
+        }
+        .back-pano {
+            width: 100%;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            padding-left: 15px;
+            i {
+                font-size: 0.6rem;
+            }
+        }
+    }
+    .right {
+        position: relative;
+        width: 1.28rem;
+        height: 100%;
+        padding-right: 15px;
+        display: flex;
+        align-items: center;
+        justify-content: flex-end;
+        > i {
+            font-size: 20px;
+        }
+        > div {
+            position: absolute;
+            display: flex;
+            flex-direction: column;
+            right: 10px;
+            top: 50px;
+            padding: 4px 16px;
+            background-color: rgba(0, 0, 0, 0.5);
+            border-radius: 5px;
+            &::after {
+                content: "";
+                position: absolute;
+                top: -5px;
+                right: 10px;
+                width: 0;
+                height: 0;
+                border-width: 0 5px 5px;
+                border-style: solid;
+                border-color: transparent transparent rgba(0, 0, 0, 0.5);
+            }
+            &.flex {
+                li {
+                    span {
+                        flex: 1;
+                        width: auto;
+                        // min-width: 2.8rem;
+                    }
+                }
+            }
+            li {
+                position: relative;
+                display: flex;
+                align-items: flex-start;
+                margin-top: 0.3rem;
+                font-size: 0;
+                i {
+                    position: absolute;
+                    left: 0;
+                    top: 0;
+                    font-size: 16px;
+                }
+                b {
+                    position: absolute;
+                    left: 0.32rem;
+                    top: 0.33rem;
+                    width: 7px;
+                    height: 7px;
+                    border-radius: 50%;
+                    background-color: #00c2c4;
+                    i {
+                        color: #fff;
+                        font-size: 12px;
+                        transform: scale(0.3, 0.3);
+                        top: -4px;
+                        left: -3px;
+                    }
+                }
+                span {
+                    width: 72px;
+                    white-space: nowrap;
+                    text-align: left;
+                    padding-bottom: 12px;
+                    margin-left: 28px;
+                    font-size: 14px;
+                    text-indent: 8px;
+                    padding-right: 8px;
+                }
+            }
+
+            .home {
+                border-top: solid 1px rgba(255, 255, 255, 0.4);
+                a {
+                    width: 72px;
+                    margin-top: 12px;
+                    margin-bottom: 0;
+                    margin-left: auto;
+                    margin-right: auto;
+                    display: block;
+                    text-decoration: none;
+                    overflow: hidden;
+
+                    img {
+                        width: 100%;
+                        outline: none;
+                        border: none;
+                    }
+                }
+            }
+        }
+    }
+    .title {
+        display: flex;
+        flex: 1;
+        width: 100%;
+        height: 100%;
+        font-size: 14px;
+        letter-spacing: 1px;
+        align-items: center;
+        justify-content: center;
+        > div {
+            display: flex;
+            transition: background 0.3s ease, min-width 0.3s ease, border-radius 0.3s ease;
+            align-items: center;
+            justify-content: center;
+            padding-right: 12px;
+            padding-left: 12px;
+            white-space: nowrap;
+            position: absolute;
+            height: 100%;
+            min-width: 100%;
+            overflow: visible;
+            pointer-events: none;
+            background: linear-gradient(
+                90deg,
+                rgba(0, 0, 0, 0) 0%,
+                rgba(0, 0, 0, 0.15) 50%,
+                rgba(0, 0, 0, 0) 100%
+            );
+        }
+        span {
+            display: inline-block;
+            position: relative;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            max-width: 7rem;
+        }
+        i {
+            transition: all 0.3s;
+            position: absolute;
+            left: 50%;
+            bottom: 0;
+            font-size: 0.2rem;
+            transform:  translateX(-50%);
+            margin-bottom: 0.07rem;
+        }
+
+        &.up {
+            i {
+                transform:  translateX(-50%) rotate(180deg);
+            }
+            > div {
+                min-width: 0;
+                //position: static;
+                flex-shrink: 0;
+                background-color: rgba(0, 0, 0, 0.5);
+                border-radius: 44px;
+            }
+            &.drak {
+                > div {
+                    background-color: rgba(0, 0, 0, 0.8);
+                }
+            }
+        }
+
+        &.empty {
+            i {
+                display: none;
+            }
+        }
+    }
+    .content {
+        position: absolute;
+        top: 60px;
+        left: 30px;
+        right: 30px;
+        padding: 10px;
+        background: rgba(0, 0, 0, 0.5);
+        border-radius: 5px;
+        font-size: 14px;
+        text-align: center;
+        &.drak {
+            background: rgba(0, 0, 0, 0.8);
+        }
+        > div {
+            display: inline-block;
+            text-align: left;
+            letter-spacing: 1px;
+            word-break: break-all;
+            white-space: normal;
+            line-height: 1.5;
+            // h4 {
+            //     margin: 0;
+            //     padding: 0;
+            //     margin-bottom: 0.28rem;
+            //     font-size: 0.43rem;
+            //     padding-left: 0.18789rem;
+            //     width: 100%;
+            //     position: relative;
+            //     &::before {
+            //         content: "";
+            //         position: absolute;
+            //         left: 0;
+            //         top: 50%;
+            //         height: 80%;
+            //         transform: translateY(-50%);
+            //         width: 2px;
+            //         background-color: @color;
+            //     }
+            // }
+            /deep/ p {
+                word-break: break-word;
+            }
+
+            /deep/ a {
+                color: @color;
+            }
+        }
+        // &::after {
+        //     content: "";
+        //     position: absolute;
+        //     top: -6px;
+        //     left: 50%;
+        //     margin-left: -3px;
+        //     width: 0;
+        //     height: 0;
+        //     border-width: 0 7px 6px;
+        //     border-style: solid;
+        //     border-color: transparent transparent rgba(0, 0, 0, 0.5);
+        // }
+    }
+
+    .url-share {
+        position: fixed;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        background-color: rgba(0, 0, 0, 0.1);
+        > div {
+            position: absolute;
+            left: 0.6rem;
+            right: 0.6rem;
+            top: 50%;
+            transform: translateY(-50%);
+            border-radius: 4px;
+            background-color: rgba(0, 0, 0, 0.5);
+            padding: 0.31579rem;
+            font-size: 0.36842rem;
+            .tips {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                h4 {
+                    margin: 0;
+                    font-size: 0.42105rem;
+                }
+                i {
+                    font-size: 0.6rem;
+                }
+            }
+            .url {
+                display: -webkit-box;
+                color: #fff;
+                text-align: center;
+                padding: 0.26316rem;
+                width: 100%;
+                height: 1.8rem;
+                margin: 0.7rem 0rem;
+                border-radius: 0.07rem;
+                line-height: 1.99;
+                font-size: 0.36842rem;
+                background-color: rgba(0, 0, 0, 0.35);
+                overflow: hidden;
+                text-overflow: ellipsis;
+                word-break: break-all;
+                word-wrap: break-word;
+                -webkit-line-clamp: 2; //在第几行加省略号
+                -webkit-box-orient: vertical;
+            }
+            .btns {
+                display: flex;
+                justify-content: space-between;
+                button {
+                    font-size: 0.36842rem;
+                    width: 47%;
+                    height: 1.05263rem;
+                    border-radius: 1.05263rem;
+                    &.submit {
+                        background: #00c2c4;
+                    }
+                }
+            }
+        }
+    }
+
+    .app-share {
+        position: fixed;
+        left: 0;
+        bottom: 0;
+        width: 100%;
+        background-color: #fff;
+        color: @color;
+        text-shadow: none;
+        i {
+            font-size: 2rem;
+        }
+        ul {
+            display: flex;
+            justify-content: space-around;
+            div {
+                text-align: center;
+                margin-top: -0.3rem;
+                font-size: 0.34rem;
+            }
+            li {
+                padding-bottom: 0.5rem;
+            }
+        }
+        > div {
+            font-size: 16px;
+            text-align: center;
+            padding: 0.5rem;
+            border-top: solid 1px #eeeeee;
+        }
+    }
+}
+
+@media (orientation: landscape) {
+    .header {
+        top: 0.2rem;
+        height: 0.7rem;
+        &.app {
+            top: 0.2rem;
+        }
+        .left {
+            .back-pano {
+                i {
+                    font-size: 0.5rem;
+                }
+            }
+        }
+        .right {
+            > i {
+                font-size: 20px;
+            }
+            > div {
+                right: 10px;
+                top: 0.75rem;
+                padding: 4px 0.2rem;
+                &::after {
+                    right: 0.23rem;
+                }
+                li {
+                    margin-top: 0.15rem;
+                    i {
+                        font-size: 0.3rem;
+                    }
+                    b {
+                        left: 0.2rem;
+                        top: 0.15rem;
+                    }
+                    span {
+                        padding-bottom: 0.15rem;
+                        margin-left: 0.5rem;
+                        font-size: 0.25rem;
+                    }
+                }
+
+                .home {
+                    a {
+                        margin-top: 0.15rem;
+                        margin-bottom: 0rem;
+                    }
+                }
+            }
+        }
+        .title {
+            font-size: 0.3rem;
+        }
+        .content {
+            top: 1rem;
+            left: 2rem;
+            right: 2rem;
+            padding: 10px;
+
+            > div {
+                max-height: 3rem;
+                font-size: 0.25rem;
+                line-height: 1.5;
+            }
+        }
+    }
+}
+</style>
+<style lang="less">
+.animated.short {
+    &.faster {
+        animation-duration: 0.3s;
+    }
+    @keyframes fadeInUp {
+        0% {
+            opacity: 0;
+            transform: translate3d(0, 1rem, 0);
+        }
+        to {
+            opacity: 1;
+            transform: translateZ(0);
+        }
+    }
+    @keyframes fadeOutDown {
+        0% {
+            opacity: 1;
+        }
+        to {
+            opacity: 0;
+            transform: translate3d(0, 1rem, 0);
+        }
+    }
+}
+</style>

+ 10 - 0
src/mixins/index.js

@@ -23,6 +23,14 @@ const MARERIALSTR = {
   video: "视频",
 };
 
+let STRSTATUS = {
+  1: "制作中",
+  2: "制作失败",
+  3: "制作成功",
+  4: "上传中",
+  5: "上传失败"
+};
+
 Vue.prototype.$bus = bus;
 Vue.prototype.$api = api;
 Vue.prototype.$intranet = config.intranet;
@@ -32,6 +40,8 @@ Vue.prototype.$thumb = config.thumb;
 Vue.prototype.$noresult = config.noresult;
 Vue.prototype.$MAPTABLEHEADER = MAPTABLEHEADER;
 Vue.prototype.$MARERIALSTR = MARERIALSTR;
+Vue.prototype.$STRSTATUS = STRSTATUS;
+
 
 Vue.prototype.$videoImg =
   "?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast,ar_auto";

+ 20 - 10
src/router/index.js

@@ -1,7 +1,7 @@
 import Vue from 'vue'
 import Router from 'vue-router'
 import { PCMenu } from "../config/menu";
-import { checkLogin,getPanoInfo } from '@/api'
+import { checkWork, checkLogin,getPanoInfo } from '@/api'
 import { $alert } from '@/components/shared/message'
 import store from '../Store'
 
@@ -38,16 +38,26 @@ OnlineDetector.register(
 );
 
 //检验是不是该用户作品
-checkLogin().then(response => {
-  if (response.code == 3005) {
-    store.commit('UpdateIsShowState', false)
-    vue.$bus.emit('canLoad',false) 
-    return vue.$alert({content: '不是该用户作品'});
-  } else{
-    vue.$bus.emit('canLoad',true) 
-    LoginDetector.valid();
+
+
+checkWork().then(res=>{
+  if (res.data) {
+    checkLogin().then(response => {
+      if (response.code == 3005) {
+        store.commit('UpdateIsShowState', false)
+        vue.$bus.emit('canLoad',false) 
+        return vue.$alert({content: '不是该用户作品'});
+      } else{
+        vue.$bus.emit('canLoad',true) 
+        LoginDetector.valid();
+      }
+    });
+  } 
+  else{
+    return vue.$alert({content: '该作品已被删除'});
   }
-});
+  
+})
 
 getPanoInfo().then(response => {
   if(response&&response.status == 1){

+ 1 - 2
src/utils/request.js

@@ -16,8 +16,6 @@ import { $alert, $loginTips } from '@/components/shared/message'
 import { $waiting } from '@/components/shared/loading'
 
 
-let vue = new Vue()
-
 
 // 空函数
 const noop = function() {}
@@ -77,6 +75,7 @@ const showLoginTips = () => {
                     postQueue.length && postQueue.forEach(item => item())
                     postQueue = []
                     LoginDetector.valid();
+                    window.location.reload()
                 } else if (response.code === statusCode.FAILURE_CODE_5001) {
                     showLoginTips()
                 }

+ 26 - 4
src/views/base/Toolbar.vue

@@ -10,7 +10,7 @@
           </div>
           <div class="upload-btn">
             <button class="ui-button submit" @click="selectHandle('image')">选择图片</button>
-            <button class="ui-button submit" @click="selectHandle('pano')">全景封面
+            <button class="ui-button submit" @click="addScene">全景封面
               <div>
                 <div class="remark">
                   选择全景图封面做为作品封面
@@ -72,6 +72,15 @@
       >
     </Table>
     </div>
+
+    <div class="dialog" style="z-index: 2000" v-if="showScene">
+      <Select
+        @cancle="showScene = false"
+        :title="'选择素材'"
+        @submit="handleSelect"
+      >
+      </Select>
+    </div>
   </div>
 </template>
 
@@ -82,11 +91,13 @@ import Table from "@/components/tableSelect";
 import { changeByteUnit } from '@/utils/file'
 
 import { mapGetters } from "vuex";
+import Select from "@/components/select";
 
 export default {
   components: {
     EidtPanel,
-    Table
+    Table,
+    Select
   },
   data() {
     return {
@@ -104,6 +115,7 @@ export default {
         name:"自动巡游",
         id:"xy"
       }],
+      showScene:false,
       activeSetting:'',
       dataURL: "",
       isShowSelect:false,
@@ -143,6 +155,10 @@ export default {
     handleOpen(){
       this.selectHandle('image','editpanel')
     },
+    addScene(){
+      this.clickFrom = 'scene'
+      this.showScene = true
+    },
     changeCurrent(data){
       this.paging.pageNum = data;
     },
@@ -151,8 +167,14 @@ export default {
       this.getMaterialList();
     },
     handleSelect(data){
-      this.clickFrom == 'editpanel'?  this.select = data[0].icon :this.info.icon = data[0].icon
-      this.isShowSelect = false
+      if (this.clickFrom == 'scene') {
+        this.info.icon = data.icon
+        this.showScene = false
+      }
+      else{
+        this.clickFrom == 'editpanel'?  this.select = data[0].icon :this.info.icon = data[0].icon
+        this.isShowSelect = false
+      }
       setTimeout(() => {
         this.select = ''
       });

+ 1 - 1
src/views/hotspot/EditPanel.vue

@@ -348,7 +348,7 @@ export default {
         });
       }
 
-       if (!hotspotTitle) {
+       if (!hotspotTitle.trim()) {
         return this.$alert({
           content: "请输入热点标题",
         });

+ 28 - 9
src/views/information/Toolbar.vue

@@ -124,7 +124,6 @@
 </template>
 
 <script>
-import { delPano, setListSort } from "@/api";
 import tabList from "@/components/tablist";
 import browser from "@/utils/browser";
 
@@ -163,9 +162,10 @@ export default {
     "info.scenes": {
       deep: true,
       handler: function (newVal) {
-        this.scenes = newVal.filter((item) => {
+        let arr = newVal.filter((item) => {
           return this.tabtowActive.id == item.category;
         });
+        this.scenes = arr.sort((a,b)=>a.weight-b.weight)
       },
     },
     "info.catalogs": {
@@ -219,9 +219,10 @@ export default {
           this.tabtowActive = this.childTab[0];
         } else {
           this.$emit("catalog", newVal);
-          this.scenes = this.info.scenes.filter((item) => {
+          let arr = this.info.scenes.filter((item) => {
             return newVal.id == item.category;
           });
+          this.scenes = arr.sort((a,b)=>a.weight-b.weight)
         }
       },
     },
@@ -234,11 +235,20 @@ export default {
     },
     
     uploadListSort() {
-      let tmp = {};
-      this.list.forEach((item, i) => {
-        tmp[item["id"]] = i + 1;
+      this.scenes.forEach((item, i) => {
+        item.weight = i+1
       });
-      setListSort(tmp);
+
+      this.info.scenes.forEach((item)=>{
+        this.scenes.forEach((sub, idx) => {
+          sub.weight = idx+1
+          if (item.sceneCode == sub.sceneCode) {
+            item = sub
+          }
+        });
+      })
+
+      this.$store.commit("SetInfo", this.info);
     },
 
     delTree(data, type) {
@@ -279,7 +289,7 @@ export default {
 
 
       this.delFirstScene()
-
+      this.$bus.emit('scenesChange')
       this.$store.commit("SetInfo", this.info);
     },
 
@@ -317,6 +327,7 @@ export default {
           this.delFirstScene()
           let idx = this.info.scenes.findIndex(ele=>ele.id==item.id)
           this.info.scenes.splice(idx,1)
+          this.$bus.emit('scenesChange')
           this.$store.commit("SetInfo", this.info);
           this.$tips({ content: "删除成功", icon: "ok" });
         },
@@ -324,7 +335,15 @@ export default {
     },
   },
 
-  mounted() {},
+  mounted() {
+    this.$bus.on('getActive',data=>{
+      if (data.type == 1) {
+        this.taboneActive = data.willActive
+      } else{
+        this.tabtowActive = data.willActive
+      }
+    })
+  },
   components: {
     draggable,
     tabList,

+ 21 - 8
src/views/information/index.vue

@@ -206,12 +206,13 @@ export default {
       params.forEach(item => {
         let temp = this.info.scenes.find(sub=>sub.sceneCode == item.sceneCode)
         if (temp) {
-            this.$tips({ content: `已添加${item.type=='4dkk'?'场景':'全景图'}${item.sceneTitle},无法重复添加`, icon: "ok" });
+            this.$tips({ content: `${item.type=='4dkk'?'场景':'全景图'}${item.sceneTitle}已存在,不可重复添加`, icon: "ok" });
             return
         }
         !temp&&this.info.scenes.push(item)
       });
 
+      this.$bus.emit('scenesChange')
       this.$store.commit("SetInfo", this.info);
       this.showList = false;
     },
@@ -233,11 +234,12 @@ export default {
 
     handleRenameClose(){
       this.showRename = false
+      this.$bus.emit('scenesChange')
       this.$store.commit("SetInfo", this.backupInfo);
     },
 
     handleRename() {
-      if (!this.reNameItem) {
+      if (!this.reNameItem.sceneTitle.trim()) {
         return this.$alert({ content: "请输入名字" });
       }
       this.$tips({ content: "重命名成功", icon: "ok" });
@@ -250,20 +252,22 @@ export default {
     },
 
     handleAddGroup() {
-      if (!this.currentTabAtri.name) {
+      if (!this.currentTabAtri.name.trim()) {
         return this.$alert({ content: "请输入名字" });
       }
+      let willActive = ''
       let tmp = this.currentTabAtri.item;
       if (this.currentTabAtri.oper == "edit") {
         tmp.name = this.currentTabAtri.name;
       } else {
         if (this.currentTabAtri.type == 1) {
           let id = 'c_'+this.$randomWord(true,8,8)
-          this.info.catalogRoot.push({
+          willActive = {
             id: 'r_'+this.$randomWord(true,8,8),
             name: this.currentTabAtri.name,
             children: [id],
-          });
+          }
+          this.info.catalogRoot.push(willActive);
           this.info.catalogs.push({
             id,
             name: '默认二级分组',
@@ -276,17 +280,26 @@ export default {
             (item) => item.id == tmp.parentId
           );
           item.children.push(id);
-          this.info.catalogs.push({
+          willActive = {
             id,
             name: this.currentTabAtri.name,
-          });
+          }
+
+          this.info.catalogs.push(willActive);
         }
       }
 
-
+      this.$bus.emit('scenesChange')
       this.$store.commit("SetInfo", this.info);
       this.$tips({ content: "操作成功", icon: "ok" });
       this.showAddGroup = false;
+
+      if (this.currentTabAtri.oper != "edit") {
+        this.$bus.emit('getActive',{
+          type:this.currentTabAtri.type,
+          willActive
+        })
+      }
     },
 
     onAddScene() {

+ 61 - 48
src/views/material/audio/index.vue

@@ -16,33 +16,26 @@
       </div>
     </div>
     <div class="btn">
-                
-
       <button @mouseover.stop="showList=true"  @click="$refs.uploadFile.click();" class="ui-button ui-button-rect submit"><span>上传素材</span><i class="iconfont iconbs_upload"></i>
         <upload ref="uploadFile"
           :failString="'格式错误,请上传20MB以内、mp3格式的音频'"
           :limitFailStr="'过大,请上传20MB以内、mp3格式的音频'"
          accept-type="audio/mp3" media-type="audio" :limit="20"  @file-change="onFileChange"></upload>
-        <div @click.stop class="upload-list" v-if="showList">
-          <div class="top">
-            <span>上传列表({{uploadList.length}})</span>
-            <i class="iconfont icon_close" @click="showList=false"></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.indexOf('失败')>-1?'error':''">{{item.status}}</span>
-              <i @click="delUploadItem(i)" class="iconfont icon_close"></i>
-            </li>
-          </ul>
-          <div class="nouploaddata" v-else>
-              暂无正在上传的素材
-          </div>
-        </div>
+        <template v-if="showList">
+          <UploadList
+            @close="
+              () => {
+                showList = false;
+              }
+            "
+            :list="uploadList"
+            @del="delUploadItem"
+          />
+        </template>
       </button>
     </div>
     <div class="list">
-      <tableList @selection-change="data=>{selectedArr=data}" :header='tabHeader' :showLine='true' :selection='false' :data='list' class="table-list" >
+      <tableList v-if="list.length>0" @selection-change="data=>{selectedArr=data}" :header='tabHeader' :showLine='true' :selection='false' :data='list' class="table-list" >
         <div slot-scope="{data}" slot="header">
           {{data.name}}
         </div>
@@ -63,7 +56,7 @@
             </i>
           </div>
           <div class="audio" v-else-if="sub.type=='audio'" >
-              <v-audio :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="data"></v-audio>
+            <v-audio :vkey="item.id" :idleft="`_${$randomWord(true,8,8)}`" :idright="`_${$randomWord(true,8,8)}`" :myAudioUrl="data"></v-audio>
           </div>
           <span v-else @click="sub.fontweight&&($bus.emit('toggleAudio',item.ossPath))" :style="{fontWeight:sub.fontweight,color:'#202020'}">{{data||'-'}}</span>
         </div>
@@ -97,6 +90,7 @@ import vAudio from '@/components/audio'
 
 import Upload from "@/components/shared/uploads/UploadMultiple";
 import { changeByteUnit } from '@/utils/file'
+import UploadList from "../components/uploadList";
 
 const TYPE = 'audio'
 
@@ -114,7 +108,9 @@ export default {
     rename,
     Paging,
     Upload,
-    vAudio
+    vAudio,
+    UploadList
+
   },
   data(){
     return {
@@ -180,9 +176,11 @@ export default {
       for (let i = 0; i < file.files.length; i++) {
         let item = file.files[i];
         let tmp = {
-          status:'上传中',
-          name:item.name
-        }
+          statusStr: "上传中",
+          status: 4,
+          uid: `u_${this.$randomWord(true, 8, 8)}`,
+          name: item.name,
+        };
 
         if (item.name.toLowerCase().indexOf("mp3") <= -1) {
           return this.$alert({
@@ -199,14 +197,17 @@ export default {
         }
         
         this.uploadList.push(tmp)
-        canUploadList.push(item)
+        canUploadList.push({
+          file: item,
+          list: { ...tmp },
+        });
       }
 
 
       let p = []
       canUploadList.forEach(i => {
         let promise = new Promise((resolve)=>{
-            resolve({file:i})
+          resolve(i);
         })
         p.push(promise)
       })
@@ -217,7 +218,10 @@ export default {
               let params = {}
               params['file'] = data.file
               let promise = new Promise((resolve, reject) => {
-                uploadMaterial(params, TYPE, response => {
+                uploadMaterial(params, {
+                  type: TYPE,
+                  uid: data.list.uid,
+                }, response => {
                   resolve(response);
                 },(err)=>{
                   reject(err)
@@ -225,19 +229,25 @@ export default {
               }) 
               pp.push(promise)
         });
-        pp.length>0&& Promise.all(pp).then(response=>{
-          if (response.length > 0) {
-              response.forEach((item,i)=>{
-                if (item.code!=0) {
-                  this.uploadList[i].status = '上传失败'
-                }
-                else {
-                  this.uploadList.splice(i,1)
+        pp.length>0&& Promise.all(pp).then((response) => {
+            if (response.length > 0) {
+              this.uploadList.forEach(item=>{
+                item.status = 5
+              }) 
+
+              response.forEach((item) => {
+                let idx = this.uploadList.findIndex(
+                  (sub) => sub.uid == item.data.tempId
+                );
+                if (item.code == 0) {
+                  if (idx > -1) {
+                    this.uploadList.splice(idx,1)
+                  }
                 }
-              })
-            this.getMaterialList();
-         }
-        })
+              });
+              this.getMaterialList();
+            }
+          });
       })
     },
     changeCurrent(data){
@@ -253,15 +263,18 @@ export default {
           type:TYPE
         },
         (data) => {
-          
-          this.list = data.data.list.map(i=>{
-            i.fileSize = changeByteUnit(Number(i.fileSize))
-            return i
-          })
-          
-          this.paging.pageNum = data.data.pageNum;
-          this.paging.pageSize = data.data.pageSize;
-          this.paging.total = data.data.total;
+          this.list = []
+          setTimeout(() => {
+            this.list = data.data.list.map(i=>{
+              i.fileSize = changeByteUnit(Number(i.fileSize))
+              return i
+            })
+            
+            this.paging.pageNum = data.data.pageNum;
+            this.paging.pageSize = data.data.pageSize;
+            this.paging.total = data.data.total;
+          });
+
         }
       );
     }

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

@@ -0,0 +1,44 @@
+<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>

+ 210 - 153
src/views/material/image/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="panorama con">
     <div class="top">
-      <crumbs :list="tablist"/>
+      <crumbs :list="tablist" />
       <div class="filter">
         <div>
           <input
@@ -9,43 +9,60 @@
             v-model="searchKey"
             @keyup.enter="(paging.current = 1) && getMaterialList()"
             placeholder="搜索素材"
-          >
-          <i @click="(paging.current = 1) && getMaterialList()" class="iconfont iconbs_search"></i>
+          />
+          <i
+            @click="(paging.current = 1) && getMaterialList()"
+            class="iconfont iconbs_search"
+          ></i>
         </div>
       </div>
     </div>
     <div class="btn">
-                
-
-      <button @mouseover.stop="showList=true"  @click="$refs.uploadFile.click();" class="ui-button ui-button-rect submit"><span>上传素材</span><i class="iconfont iconbs_upload"></i>
-        <upload ref="uploadFile"
-        :failString="'格式错误,请上传10MB以内、jpg/png格式的图片'"
-        :limitFailStr="'过大,请上传10MB以内、jpg/png格式的图片'"
-         accept-type="image/png,image/jpeg" media-type="image" :limit="10"  @file-change="onFileChange"></upload>
-        <div @click.stop class="upload-list" v-if="showList">
-          <div class="top">
-            <span>上传列表({{uploadList.length}})</span>
-            <i class="iconfont icon_close" @click="showList=false"></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.indexOf('失败')>-1?'error':''">{{item.status}}</span>
-              <i @click="delUploadItem(i)" class="iconfont icon_close"></i>
-            </li>
-          </ul>
-          <div class="nouploaddata" v-else>
-              暂无正在上传的素材
-          </div>
-        </div>
+      <button
+        @mouseover.stop="showList = true"
+        @click="$refs.uploadFile.click()"
+        class="ui-button ui-button-rect submit"
+      >
+        <span>上传素材</span><i class="iconfont iconbs_upload"></i>
+        <upload
+          ref="uploadFile"
+          :failString="'格式错误,请上传10MB以内、jpg/png格式的图片'"
+          :limitFailStr="'过大,请上传10MB以内、jpg/png格式的图片'"
+          accept-type="image/png,image/jpeg"
+          media-type="image"
+          :limit="10"
+          @file-change="onFileChange"
+        ></upload>
+        <template v-if="showList">
+          <UploadList
+            @close="
+              () => {
+                showList = false;
+              }
+            "
+            :list="uploadList"
+            @del="delUploadItem"
+          />
+        </template>
       </button>
     </div>
     <div class="list">
-      <tableList @selection-change="data=>{selectedArr=data}" :header='tabHeader' :showLine='true' :selection='false' :data='list' class="table-list" >
-        <div slot-scope="{data}" slot="header">
-          {{data.name}}
+      <tableList
+        @selection-change="
+          (data) => {
+            selectedArr = data;
+          }
+        "
+        :header="tabHeader"
+        :showLine="true"
+        :selection="false"
+        :data="list"
+        class="table-list"
+      >
+        <div slot-scope="{ data }" slot="header">
+          {{ data.name }}
         </div>
-        <div slot-scope="{data,item,sub}" slot="item" style="width:100%">
+        <div slot-scope="{ data, item, sub }" slot="item" style="width: 100%">
           <div class="handle" v-if="sub.canclick">
             <i
               class="iconfont iconbs_list_edit hover-tips"
@@ -61,26 +78,43 @@
               </div>
             </i>
           </div>
-          <div class="img" v-else-if="sub.type=='image'">
-            <img :id="'img'+item.id" v-viewer :src="data+`?${Math.random()}`" alt="">
+          <div class="img" v-else-if="sub.type == 'image'">
+            <img
+              :id="'img' + item.id"
+              v-viewer
+              :src="data + `?${Math.random()}`"
+              alt=""
+            />
           </div>
-          <span v-else @click="sub.fontweight&&(viewImg('img'+item.id))" :style="{fontWeight:sub.fontweight,color:'#202020'}">{{data||'-'}}</span>
+          <span
+            v-else
+            @click="sub.fontweight && viewImg('img' + item.id)"
+            :style="{ fontWeight: sub.fontweight, color: '#202020' }"
+            >{{ data || "-" }}</span
+          >
         </div>
       </tableList>
       <div class="nodata" v-if="list.length == 0">
-        <img :src="$noresult" alt="">
-        <span>{{isClickSearch?'未搜索到结果':'暂无素材,快去上传吧'}}</span>
+        <img :src="$noresult" alt="" />
+        <span>{{
+          isClickSearch ? "未搜索到结果" : "暂无素材,快去上传吧"
+        }}</span>
       </div>
     </div>
     <div class="paging">
       <Paging
-        v-if="paging.total>0"
+        v-if="paging.total > 0"
         :paging="paging"
         @changeCurrent="changeCurrent"
       />
     </div>
 
-    <rename :item="popupItem" :show='showRename' @rename="handleRename" @close="showRename=false" />
+    <rename
+      :item="popupItem"
+      :show="showRename"
+      @rename="handleRename"
+      @close="showRename = false"
+    />
     <preview
       :item="popupItem"
       :show="showPreview"
@@ -90,195 +124,218 @@
 </template>
 
 <script>
-import tableList from '@/components/table'
-import crumbs from '@/components/crumbs'
-import {data} from './image'
-import rename from '../popup/rename'
-import Paging from '../components/paging'
+import tableList from "@/components/table";
+import crumbs from "@/components/crumbs";
+import { data } from "./image";
+import rename from "../popup/rename";
+import Paging from "../components/paging";
+import UploadList from "../components/uploadList";
+
 import Upload from "@/components/shared/uploads/UploadMultiple";
-import { changeByteUnit } from '@/utils/file'
+import { changeByteUnit } from "@/utils/file";
 import preview from "../popup/preview";
 
 import {
   getMaterialList,
   uploadMaterial,
   editMaterial,
-  delMaterial
+  delMaterial,
 } from "@/api";
 
+const TYPE = "image";
 
-const TYPE = 'image'
 
 export default {
-  components:{
+  components: {
     tableList,
     crumbs,
     rename,
     Paging,
     Upload,
-    preview
+    preview,
+    UploadList,
   },
-  data(){
+  data() {
     return {
-      showPreview:false,
-      showRename:false,
-      showList:false,
-      isClickSearch:'',
-      popupItem:'',
+      showPreview: false,
+      showRename: false,
+      showList: false,
+      isClickSearch: "",
+      popupItem: "",
       tabHeader: data,
       selectedArr: [],
-      searchKey:'',
-      tablist:[{
-        name:'图片',
-        id:TYPE
-      }],
-      list:[],
-      uploadList:[],
+      searchKey: "",
+      tablist: [
+        {
+          name: "图片",
+          id: TYPE,
+        },
+      ],
+      list: [],
+      uploadList: [],
       paging: {
         pageSize: 12,
         pageNum: 1,
         total: 0,
         showSize: 4,
-        current: 1
-      }
-    }
+        current: 1,
+      },
+    };
   },
   mounted() {
     this.getMaterialList();
   },
-  watch:{
-    'paging.pageNum':function () {
-      this.getMaterialList()
+  watch: {
+    "paging.pageNum": function () {
+      this.getMaterialList();
     }
   },
-  methods:{
-    viewImg(id){
-      const viewer = this.$el.querySelector('#'+id).$viewer
-      viewer.show()
+  methods: {
+    viewImg(id) {
+      const viewer = this.$el.querySelector("#" + id).$viewer;
+      viewer.show();
     },
-    handleRename(data){
-      editMaterial({
-          id:this.popupItem.id,
-          name:data
-        },()=>{
-          this.$tips({ content: "修改成功",icon:'ok'});
-          this.showRename = false
-          this.popupItem = ''
+    handleRename(data) {
+      editMaterial(
+        {
+          id: this.popupItem.id,
+          name: data,
+        },
+        () => {
+          this.$tips({ content: "修改成功", icon: "ok" });
+          this.showRename = false;
+          this.popupItem = "";
           this.getMaterialList();
-        });
+        }
+      );
     },
-    delUploadItem(index){
-      ~index && this.uploadList.splice(index, 1)
+    
+    delUploadItem(index) {
+      ~index && this.uploadList.splice(index, 1);
     },
-    del(item){
+    del(item) {
       this.$confirm({
-          content: "是否删除?",
-          ok: () => {
-              delMaterial(item.id,()=>{
-                this.$tips({ content: "删除成功",icon:'ok' });
-                this.getMaterialList();
-              });
-          }
+        content: "是否删除?",
+        ok: () => {
+          delMaterial(item.id, () => {
+            this.$tips({ content: "删除成功", icon: "ok" });
+            this.getMaterialList();
+          });
+        },
       });
     },
     onFileChange(file) {
-      let canUploadList = []
+      let canUploadList = [];
       for (let i = 0; i < file.files.length; i++) {
         let item = file.files[i];
         let tmp = {
-          status:'上传中',
-          name:item.name
-        }
-        if (item.type.indexOf("jpeg") <= -1&&item.type.indexOf('png')<=-1) {
+          statusStr: "上传中",
+          status: 4,
+          uid: `u_${this.$randomWord(true, 8, 8)}`,
+          name: item.name,
+        };
+        if (item.type.indexOf("jpeg") <= -1 && item.type.indexOf("png") <= -1) {
           return this.$alert({
-              content: `“${item.name}”格式错误,请上传10MB以内、jpg/png格式的图片`
+            content: `“${item.name}”格式错误,请上传10MB以内、jpg/png格式的图片`,
           });
         }
-        let tname= item.name.substring(0, item.name.lastIndexOf("."));
-         if (tname.length > 50) {
+        let tname = item.name.substring(0, item.name.lastIndexOf("."));
+        if (tname.length > 50) {
           return this.$alert({
-              content: `“${item.name}”名称过长,请上传标题在50字以内的图片`
-            });
+            content: `“${item.name}”名称过长,请上传标题在50字以内的图片`,
+          });
         }
-        this.uploadList.push(tmp)
-        canUploadList.push(item)
+        this.uploadList.push(tmp);
+        canUploadList.push({
+          file: item,
+          list: { ...tmp },
+        });
       }
 
+      let p = [];
+      canUploadList.forEach((i) => {
+        let promise = new Promise((resolve) => {
+          resolve(i);
+        });
+        p.push(promise);
+      });
 
-      let p = []
-      canUploadList.forEach(i => {
-        let promise = new Promise((resolve)=>{
-            resolve({file:i})
-        })
-        p.push(promise)
-      })
-
-    Promise.all(p).then(result=>{
-        let pp = []
-        p.length>0&&result.forEach((data,i) => {
-              let params = {}
-              params['file'] = data.file
-              if (data.file.name.length>50) {
-                this.uploadList[i].status = '上传失败'
-              }
-              let promise = new Promise((resolve, reject) => {
-                uploadMaterial(params, TYPE, response => {
+      Promise.all(p).then((result) => {
+        let pp = [];
+        p.length > 0 &&
+          result.forEach((data) => {
+            let params = {};
+            params["file"] = data.file;
+            let promise = new Promise((resolve, reject) => {
+              uploadMaterial(
+                params,
+                {
+                  type: TYPE,
+                  uid: data.list.uid,
+                },
+                (response) => {
                   resolve(response);
-                },(err)=>{
-                  reject(err)
-                })
-              }) 
-              pp.push(promise)
-        });
-        pp.length>0&& Promise.all(pp).then(response=>{
-            if (response.length > 0) {
-              response.forEach((item,i)=>{
-                if (item.code!=0) {
-                  this.uploadList[i].status = '上传失败'
+                },
+                (err) => {
+                  reject(err);
                 }
-                else {
-                  this.uploadList.splice(i,1)
+              );
+            });
+            pp.push(promise);
+          });
+        pp.length > 0 &&
+          Promise.all(pp).then((response) => {
+            if (response.length > 0) {
+              this.uploadList.forEach(item=>{
+                item.status = 5
+              }) 
+              response.forEach((item) => {
+                let idx = this.uploadList.findIndex(
+                  (sub) => sub.uid == item.data.tempId
+                );
+                if (item.code == 0) {
+                  if (idx > -1) {
+                    this.uploadList.splice(idx,1)
+                  }
                 }
-              })
-            this.getMaterialList();
-          }
-        })
-      })
+              });
+              this.getMaterialList();
+            }
+          });
+      });
     },
-    changeCurrent(data){
-      this.paging.pageNum = data
+    changeCurrent(data) {
+      this.paging.pageNum = data;
     },
     getMaterialList() {
-      this.isClickSearch = !!this.searchKey
+      this.isClickSearch = !!this.searchKey;
       getMaterialList(
         {
           pageNum: this.paging.pageNum,
           pageSize: this.paging.pageSize,
           searchKey: this.searchKey,
-          type:TYPE
+          type: TYPE,
         },
         (data) => {
-          
-          this.list = data.data.list.map(i=>{
-            i.fileSize = changeByteUnit(Number(i.fileSize))
-            return i
-          })
-          
+          this.list = data.data.list.map((i) => {
+            i.fileSize = changeByteUnit(Number(i.fileSize));
+            return i;
+          });
+
           this.paging.pageNum = data.data.pageNum;
           this.paging.pageSize = data.data.pageSize;
           this.paging.total = data.data.total;
         }
       );
-    }
-  }
-}
+    },
+  },
+};
 </script>
 
 <style lang="less" scoped>
-.panorama{
-  
+.panorama {
 }
 </style>
 <style lang="less" scoped>
-@import '../style.less';
+@import "../style.less";
 </style>

+ 28 - 34
src/views/material/pano/index.vue

@@ -33,24 +33,17 @@
           :limit="120"
           @file-change="onFileChange"
         ></upload>
-        <div @click.stop class="upload-list" v-if="showList">
-          <div class="top">
-            <span>上传列表({{ uploadList.length }})</span>
-            <i class="iconfont icon_close" @click="showList = false"></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="delUploadItem(i)" class="iconfont icon_close"></i>
-            </li>
-          </ul>
-          <div class="nouploaddata" v-else>暂无正在上传的素材</div>
-        </div>
+        <template v-if="showList">
+          <UploadList
+            @close="
+              () => {
+                showList = false;
+              }
+            "
+            :list="uploadList"
+            @del="delUploadItem"
+          />
+        </template>
       </button>
     </div>
     <div class="list">
@@ -156,6 +149,7 @@ import cover from "../popup/cover";
 import Paging from "../components/paging";
 import Upload from "@/components/shared/uploads/UploadMultiple";
 import { getImgWH, changeByteUnit } from "@/utils/file";
+import UploadList from "../components/uploadList";
 
 import {
   getMaterialList,
@@ -170,13 +164,7 @@ import {
 
 const TYPE = "pano";
 const LONGPOLLINGTIME = 10;
-let StrStatus = {
-  1: "制作中",
-  2: "制作失败",
-  3: "制作成功",
-  4: "上传中",
-  5: "上传失败",
-};
+
 export default {
   components: {
     tableList,
@@ -186,10 +174,10 @@ export default {
     Paging,
     preview,
     Upload,
+    UploadList
   },
   data() {
     return {
-      StrStatus,
       isLongPolling: false,
       showRename: false,
       showPreview: false,
@@ -227,6 +215,7 @@ export default {
     isLongPolling: {
       handler: function (newVal) {
         if (!newVal) {
+          this.getMaterialList(true);
           this.clearinter();
         } else {
           this.Longpolling();
@@ -287,7 +276,7 @@ export default {
     },
 
     _checkMStatus(islongpolling = null) {
-      let ids = this.uploadList.filter((item) => item.id);
+      let ids = this.uploadList.filter((item) => !!item.id);
       if (ids.length > 0) {
         checkMStatus(
           {
@@ -305,7 +294,10 @@ export default {
               }
             });
             this.uploadList = tmp;
-            if (!tmp.some((item) => item == 1)) {
+            if (tmp.some((item) => item.status == 3)) {
+              this.getMaterialList(true)
+            }
+            if (!tmp.some((item) => item.status == 1)) {
               this.isLongPolling = false;
             }
           }
@@ -333,7 +325,6 @@ export default {
           uid: `u_${this.$randomWord(true, 8, 8)}`,
           name: item.name,
         };
-        item.uid = tmp.uid;
         if (item.type.indexOf("jpeg") <= -1) {
           return this.$alert({
             content: `“${item.name}”格式错误,请上传2:1、120MB以内、jpg格式的全景图片`,
@@ -377,7 +368,10 @@ export default {
             let promise = new Promise((resolve, reject) => {
               uploadMaterial(
                 params,
-                TYPE,
+                {
+                  type: TYPE,
+                  uid: data.list.uid,
+                },
                 (response) => {
                   resolve(response);
                 },
@@ -392,7 +386,8 @@ export default {
           Promise.all(pp).then((response) => {
             if (response.length > 0) {
               response.forEach((item, i) => {
-                let idx = this.uploadList.findIndex(sub=>sub.name == item.name)
+                this.uploadList[i].status = 5;
+                let idx = this.uploadList.findIndex(sub=>sub.uid == item.data.tempId)
                 if (idx>-1) {
                   if (item.code != 0) {
                     this.uploadList[idx].status = 5;
@@ -404,9 +399,7 @@ export default {
                     this.isLongPolling = true;
                   }
                 }
-                
               });
-              this.getMaterialList();
             }
           });
       });
@@ -414,7 +407,7 @@ export default {
     changeCurrent(data) {
       this.paging.pageNum = data;
     },
-    getMaterialList() {
+    getMaterialList(islongpolling = null) {
       this.isClickSearch = !!this.searchKey;
 
       getMaterialList(
@@ -423,6 +416,7 @@ export default {
           pageSize: this.paging.pageSize,
           searchKey: this.searchKey,
           type: TYPE,
+          islongpolling
         },
         (data) => {
           this.list = data.data.list.map((i) => {

+ 1 - 1
src/views/material/popup/rename.vue

@@ -50,7 +50,7 @@ export default {
   },
   methods:{
     emitname(){
-      if (!this.key) {
+      if (!this.key.trim()) {
         return this.$alert({ content: "请输入名字" });
       }
       this.$emit('rename',this.key)

+ 44 - 35
src/views/material/video/index.vue

@@ -22,22 +22,17 @@
         :failString="'格式错误,请上传200MB以内、mp4格式的视频'"
         :limitFailStr="'过大,请上传200MB以内、mp4格式的视频'"
          accept-type="video/mp4" media-type="video" :limit="200"  @file-change="onFileChange"></upload>
-        <div @click.stop class="upload-list" v-if="showList">
-          <div class="top">
-            <span>上传列表({{uploadList.length}})</span>
-            <i class="iconfont icon_close" @click="showList=false"></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.indexOf('失败')>-1?'error':''">{{item.status}}</span>
-              <i @click="delUploadItem(i)" class="iconfont icon_close"></i>
-            </li>
-          </ul>
-          <div class="nouploaddata" v-else>
-              暂无正在上传的素材
-          </div>
-        </div>
+        <template v-if="showList">
+          <UploadList
+            @close="
+              () => {
+                showList = false;
+              }
+            "
+            :list="uploadList"
+            @del="delUploadItem"
+          />
+        </template>
       </button>
     </div>
     <div class="list">
@@ -100,6 +95,7 @@ import Paging from '../components/paging'
 import Upload from "@/components/shared/uploads/UploadMultiple";
 import { changeByteUnit } from '@/utils/file'
 import preview from "../popup/preview";
+import UploadList from "../components/uploadList";
 
 
 import {
@@ -119,6 +115,7 @@ export default {
     crumbs,
     rename,
     Paging,
+    UploadList,
     Upload
   },
   data(){
@@ -185,9 +182,11 @@ export default {
       for (let i = 0; i < file.files.length; i++) {
         let item = file.files[i];
         let tmp = {
-          status:'上传中',
-          name:item.name
-        }
+          statusStr: "上传中",
+          status: 4,
+          uid: `u_${this.$randomWord(true, 8, 8)}`,
+          name: item.name,
+        };
         if (item.type.indexOf("mp4") <= -1) {
           return this.$alert({
               content: `“${item.name}”格式错误,请上传200MB以内、mp4格式的视频`
@@ -200,14 +199,17 @@ export default {
             });
         }
         this.uploadList.push(tmp)
-        canUploadList.push(item)
+        canUploadList.push({
+          file: item,
+          list: { ...tmp },
+        });
       }
 
 
       let p = []
       canUploadList.forEach(i => {
         let promise = new Promise((resolve)=>{
-            resolve({file:i})
+            resolve(i)
         })
         p.push(promise)
       })
@@ -217,9 +219,11 @@ export default {
         p.length>0&&result.forEach(data => {
               let params = {}
               params['file'] = data.file
-              console.log('params',params);
               let promise = new Promise((resolve, reject) => {
-                uploadMaterial(params, TYPE, response => {
+                uploadMaterial(params, {
+                  type: TYPE,
+                  uid: data.list.uid,
+                }, response => {
                   resolve(response);
                 },(err)=>{
                   reject(err)
@@ -227,19 +231,24 @@ export default {
               }) 
               pp.push(promise)
         });
-        pp.length>0&& Promise.all(pp).then(response=>{
-         if (response.length > 0) {
-              response.forEach((item,i)=>{
-                if (item.code!=0) {
-                  this.uploadList[i].status = '上传失败'
-                }
-                else {
-                  this.uploadList.splice(i,1)
+        pp.length>0&& Promise.all(pp).then((response) => {
+            if (response.length > 0) {
+              this.uploadList.forEach(item=>{
+                item.status = 5
+              }) 
+              response.forEach((item, i) => {
+                let idx = this.uploadList.findIndex(
+                  (sub) => sub.uid == item.data.tempId
+                );
+                if (item.code == 0) {
+                  if (idx > -1) {
+                    this.uploadList.splice(idx,1)
+                  }
                 }
-              })
-            this.getMaterialList();
-         }
-        })
+              });
+              this.getMaterialList();
+            }
+          });
       })
     },
     changeCurrent(data){

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

@@ -56,7 +56,7 @@
       v-if="showItem"
       :name="showItem.name"
       :show="showPreview"
-      :ifr="`./show.html?id=${showItem.id}&vr=${showItem.firstScene?showItem.firstScene.sceneCode:showItem.scenes[0].sceneCode}`"
+      :ifr="`./show.html?id=${showItem.id}&vr=${showItem.firstScene?showItem.firstScene.sceneCode:(showItem.scenes[0]?showItem.scenes[0].sceneCode:'')}`"
       @close="showPreview = false"
     />
   </div>