Explorar el Código

feat:增加批量协作的功能

tremble hace 4 años
padre
commit
3974216b19

+ 1 - 1
pc/index.html

@@ -14,7 +14,7 @@
     <meta name="description" content="世界上首款消费级3D相机—四维看看(4DKanKan)。技术核心三要素:易操作;自动化;高精度。主要应用领域为数字文博、数字地产、数字电商、数字餐饮、数字家居等。">
     <link rel="shortcut icon" href="//4dkk.4dage.com/FDKKIMG/icon/kankan_icon.ico">
     <link rel="icon" type="image/png" href="//4dkk.4dage.com/FDKKIMG/icon/kankan_icon192.png" sizes="192x192">
-    <link rel="stylesheet" href="//at.alicdn.com/t/font_941679_px081tlqkur.css">
+    <link rel="stylesheet" href="//at.alicdn.com/t/font_941679_7vwx5e680s5.css">
     <link rel="apple-touch-icon" sizes="180x180" href="//4dkk.4dage.com/FDKKIMG/icon/kankan_icon180.png">
     <title>四维看看</title>
     <script>

+ 2 - 2
pc/src/apis/index.js

@@ -7,7 +7,7 @@ export default {
   getEmailAuthCode (data) {
     return axios.post('sso/user/getEmailAuthCode', data)
   },
-  
+
   // 地址模块
   getReceiverList () {
     return axios.post('user/getReceiverList')
@@ -21,4 +21,4 @@ export default {
   deleteAddress (id) {
     return axios.post('user/deleteAddress', {id})
   }
-}
+}

+ 345 - 0
pc/src/assets/font/demo_index.html

@@ -31,6 +31,96 @@
           <ul class="icon_lists dib-box">
           
             <li class="dib">
+              <span class="icon iconfont">&#xe737;</span>
+                <div class="name">main_list</div>
+                <div class="code-name">&amp;#xe737;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe738;</span>
+                <div class="name">main_grid</div>
+                <div class="code-name">&amp;#xe738;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe6a4;</span>
+                <div class="name">横标EN</div>
+                <div class="code-name">&amp;#xe6a4;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe695;</span>
+                <div class="name">确认</div>
+                <div class="code-name">&amp;#xe695;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe693;</span>
+                <div class="name">警示</div>
+                <div class="code-name">&amp;#xe693;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe691;</span>
+                <div class="name">密码不可见</div>
+                <div class="code-name">&amp;#xe691;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe690;</span>
+                <div class="name">密码可见</div>
+                <div class="code-name">&amp;#xe690;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68f;</span>
+                <div class="name">回顶页尖嘴</div>
+                <div class="code-name">&amp;#xe68f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe71f;</span>
+                <div class="name">logo</div>
+                <div class="code-name">&amp;#xe71f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68e;</span>
+                <div class="name">新购物车</div>
+                <div class="code-name">&amp;#xe68e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68d;</span>
+                <div class="name">对号</div>
+                <div class="code-name">&amp;#xe68d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68c;</span>
+                <div class="name">叹号</div>
+                <div class="code-name">&amp;#xe68c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68b;</span>
+                <div class="name">购物车</div>
+                <div class="code-name">&amp;#xe68b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe68a;</span>
+                <div class="name">首页公仔</div>
+                <div class="code-name">&amp;#xe68a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe709;</span>
+                <div class="name">case_teamwork</div>
+                <div class="code-name">&amp;#xe709;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe704;</span>
                 <div class="name">case_hot</div>
                 <div class="code-name">&amp;#xe704;</div>
@@ -663,6 +753,141 @@
         <ul class="icon_lists dib-box">
           
           <li class="dib">
+            <span class="icon iconfont icon-main_list"></span>
+            <div class="name">
+              main_list
+            </div>
+            <div class="code-name">.icon-main_list
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-main_grid"></span>
+            <div class="name">
+              main_grid
+            </div>
+            <div class="code-name">.icon-main_grid
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-hengbiaoEN"></span>
+            <div class="name">
+              横标EN
+            </div>
+            <div class="code-name">.icon-hengbiaoEN
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-queren"></span>
+            <div class="name">
+              确认
+            </div>
+            <div class="code-name">.icon-queren
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-jingshi"></span>
+            <div class="name">
+              警示
+            </div>
+            <div class="code-name">.icon-jingshi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-mimabukejian"></span>
+            <div class="name">
+              密码不可见
+            </div>
+            <div class="code-name">.icon-mimabukejian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-mimakejian"></span>
+            <div class="name">
+              密码可见
+            </div>
+            <div class="code-name">.icon-mimakejian
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-huidingyejianzui"></span>
+            <div class="name">
+              回顶页尖嘴
+            </div>
+            <div class="code-name">.icon-huidingyejianzui
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-logo"></span>
+            <div class="name">
+              logo
+            </div>
+            <div class="code-name">.icon-logo
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-xingouwuche"></span>
+            <div class="name">
+              新购物车
+            </div>
+            <div class="code-name">.icon-xingouwuche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-duihao"></span>
+            <div class="name">
+              对号
+            </div>
+            <div class="code-name">.icon-duihao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-tanhao"></span>
+            <div class="name">
+              叹号
+            </div>
+            <div class="code-name">.icon-tanhao
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-gouwuche"></span>
+            <div class="name">
+              购物车
+            </div>
+            <div class="code-name">.icon-gouwuche
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-shouyegongzi"></span>
+            <div class="name">
+              首页公仔
+            </div>
+            <div class="code-name">.icon-shouyegongzi
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-case_teamwork"></span>
+            <div class="name">
+              case_teamwork
+            </div>
+            <div class="code-name">.icon-case_teamwork
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-case_hot"></span>
             <div class="name">
               case_hot
@@ -1566,6 +1791,126 @@
           
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-main_list"></use>
+                </svg>
+                <div class="name">main_list</div>
+                <div class="code-name">#icon-main_list</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-main_grid"></use>
+                </svg>
+                <div class="name">main_grid</div>
+                <div class="code-name">#icon-main_grid</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-hengbiaoEN"></use>
+                </svg>
+                <div class="name">横标EN</div>
+                <div class="code-name">#icon-hengbiaoEN</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-queren"></use>
+                </svg>
+                <div class="name">确认</div>
+                <div class="code-name">#icon-queren</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-jingshi"></use>
+                </svg>
+                <div class="name">警示</div>
+                <div class="code-name">#icon-jingshi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-mimabukejian"></use>
+                </svg>
+                <div class="name">密码不可见</div>
+                <div class="code-name">#icon-mimabukejian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-mimakejian"></use>
+                </svg>
+                <div class="name">密码可见</div>
+                <div class="code-name">#icon-mimakejian</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-huidingyejianzui"></use>
+                </svg>
+                <div class="name">回顶页尖嘴</div>
+                <div class="code-name">#icon-huidingyejianzui</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-logo"></use>
+                </svg>
+                <div class="name">logo</div>
+                <div class="code-name">#icon-logo</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-xingouwuche"></use>
+                </svg>
+                <div class="name">新购物车</div>
+                <div class="code-name">#icon-xingouwuche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-duihao"></use>
+                </svg>
+                <div class="name">对号</div>
+                <div class="code-name">#icon-duihao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-tanhao"></use>
+                </svg>
+                <div class="name">叹号</div>
+                <div class="code-name">#icon-tanhao</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-gouwuche"></use>
+                </svg>
+                <div class="name">购物车</div>
+                <div class="code-name">#icon-gouwuche</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-shouyegongzi"></use>
+                </svg>
+                <div class="name">首页公仔</div>
+                <div class="code-name">#icon-shouyegongzi</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-case_teamwork"></use>
+                </svg>
+                <div class="name">case_teamwork</div>
+                <div class="code-name">#icon-case_teamwork</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-case_hot"></use>
                 </svg>
                 <div class="name">case_hot</div>

BIN
pc/src/assets/font/download.zip


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 66 - 6
pc/src/assets/font/iconfont.css


BIN
pc/src/assets/font/iconfont.eot


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
pc/src/assets/font/iconfont.js


+ 105 - 0
pc/src/assets/font/iconfont.json

@@ -6,6 +6,111 @@
   "description": "",
   "glyphs": [
     {
+      "icon_id": "18585802",
+      "name": "main_list",
+      "font_class": "main_list",
+      "unicode": "e737",
+      "unicode_decimal": 59191
+    },
+    {
+      "icon_id": "18585803",
+      "name": "main_grid",
+      "font_class": "main_grid",
+      "unicode": "e738",
+      "unicode_decimal": 59192
+    },
+    {
+      "icon_id": "12324810",
+      "name": "横标EN",
+      "font_class": "hengbiaoEN",
+      "unicode": "e6a4",
+      "unicode_decimal": 59044
+    },
+    {
+      "icon_id": "17783073",
+      "name": "确认",
+      "font_class": "queren",
+      "unicode": "e695",
+      "unicode_decimal": 59029
+    },
+    {
+      "icon_id": "17783047",
+      "name": "警示",
+      "font_class": "jingshi",
+      "unicode": "e693",
+      "unicode_decimal": 59027
+    },
+    {
+      "icon_id": "17732978",
+      "name": "密码不可见",
+      "font_class": "mimabukejian",
+      "unicode": "e691",
+      "unicode_decimal": 59025
+    },
+    {
+      "icon_id": "17732965",
+      "name": "密码可见",
+      "font_class": "mimakejian",
+      "unicode": "e690",
+      "unicode_decimal": 59024
+    },
+    {
+      "icon_id": "17006990",
+      "name": "回顶页尖嘴",
+      "font_class": "huidingyejianzui",
+      "unicode": "e68f",
+      "unicode_decimal": 59023
+    },
+    {
+      "icon_id": "16930529",
+      "name": "logo",
+      "font_class": "logo",
+      "unicode": "e71f",
+      "unicode_decimal": 59167
+    },
+    {
+      "icon_id": "16779535",
+      "name": "新购物车",
+      "font_class": "xingouwuche",
+      "unicode": "e68e",
+      "unicode_decimal": 59022
+    },
+    {
+      "icon_id": "16338996",
+      "name": "对号",
+      "font_class": "duihao",
+      "unicode": "e68d",
+      "unicode_decimal": 59021
+    },
+    {
+      "icon_id": "16338993",
+      "name": "叹号",
+      "font_class": "tanhao",
+      "unicode": "e68c",
+      "unicode_decimal": 59020
+    },
+    {
+      "icon_id": "16336618",
+      "name": "购物车",
+      "font_class": "gouwuche",
+      "unicode": "e68b",
+      "unicode_decimal": 59019
+    },
+    {
+      "icon_id": "16297783",
+      "name": "首页公仔",
+      "font_class": "shouyegongzi",
+      "unicode": "e68a",
+      "unicode_decimal": 59018
+    },
+    {
+      "icon_id": "16170186",
+      "name": "case_teamwork",
+      "font_class": "case_teamwork",
+      "unicode": "e709",
+      "unicode_decimal": 59145
+    },
+    {
       "icon_id": "15926961",
       "name": "case_hot",
       "font_class": "case_hot",

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 45 - 0
pc/src/assets/font/iconfont.svg


BIN
pc/src/assets/font/iconfont.ttf


BIN
pc/src/assets/font/iconfont.woff


BIN
pc/src/assets/font/iconfont.woff2


+ 58 - 0
pc/src/assets/style/public.scss

@@ -264,6 +264,19 @@ body{
   margin-top: 30px;
 }
 
+.refreshing-sml-loader{
+  width: 10px;
+  height: 10px;
+  font-size: 8px;
+  border-radius: 5px;
+}
+
+.refreshing-sml-loader::after{
+  margin-top: 0;
+
+}
+
+
 .common-title {
   font-size: 40px;
   color: #202020;
@@ -283,6 +296,51 @@ body{
   }
 }
 
+.fdcheck{
+  position: relative;
+  cursor: pointer;
+  &::before{
+    content: '';
+    border: #CCCCCC 1px solid;
+    width: 14px;
+    height: 14px;
+    position: absolute;
+    left: -20px;
+    top: 50%;
+    transform: translateY(-50%);
+    display: inline-block;
+  }
+}
+
+.check_active{
+  &::before{
+    content: '';
+    background: #1fe4dc;
+    border: #1fe4dc 1px solid;
+  }
+  &::after{
+    left: -17px;
+    top: 50%;
+    position: absolute;
+    display: table;
+    border: 2px solid #000;
+    border-top: 0;
+    border-left: 0;
+    transform: rotate(45deg) translate(-50%, -50%);
+    opacity: 1;
+    transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
+    width: 6px;
+    height: 10px;
+    content: " ";
+  }
+}
+
+.edit{
+  color: $theme-color;
+  cursor: pointer;
+  margin-left: 8px;
+}
+
 @keyframes fadeUp {
   from {
     opacity: 0;

+ 67 - 5
pc/src/components/table/index.vue

@@ -1,25 +1,87 @@
 <template>
   <div class="table-layout">
-    <ul class="t-header">
+    <ul class="t-header" :class="{line:showLine}">
+      <li v-if="selection" class="check-cls"><span @click="lock=false,selectAll=!selectAll" class="fdcheck" :class="{check_active:selectAll}">全选</span></li>
       <li v-for="(item,i) in header" :key="i" :style="{width:item.width&&innerW>1500?item.width+'px':(100/header.length)+'%'}">
         <slot :data='item' name='header'></slot>
       </li>
     </ul>
     <div class="t-con">
-      <ul class="t-item" v-for="(item,i) in data" :key="i">
+      <ul class="t-item" :class="{line:showLine}" v-for="(item,i) in fixdata" :key="i">
+        <li v-if="selection" class="check-cls"><span @click="selectItem(item,i)" class="fdcheck" :class="{check_active:item.hasAuth}"></span></li>
         <li v-for="(sub,j) in header" :key='j' :style="{width:sub.width&&innerW>1500?sub.width+'px':(100/header.length)+'%'}">
-          <slot :data='item[sub.key]' :item='item' :canclick='sub.canclick' name='item'></slot>
+          <slot :data='item[sub.key]' :type="sub.type" :item='item' :canclick='sub.canclick' name='item'></slot>
         </li>
       </ul>
     </div>
   </div>
 </template>
 <script>
+import { mapState } from 'vuex'
+
 export default {
-  props: ['data', 'header'],
+  props: ['data', 'header', 'selection', 'showLine'],
   data () {
     return {
-      innerW: window.innerWidth
+      innerW: window.innerWidth,
+      selectAll: false,
+      lock: true
+    }
+  },
+  computed: {
+    ...mapState({
+      language: state => state.language.current,
+      fixdata () {
+        let data = this.data && this.data.map(item => {
+          item.hasAuth = false
+          return item
+        })
+        return data
+      }
+    })
+
+  },
+  watch: {
+    data () {
+      this.selectAll = false
+    },
+    selectAll: function (newVal) {
+      if (!this.lock) {
+        this.fixdata.forEach(item => {
+          item.hasAuth = newVal
+          if (item.status || item.status === 0) {
+            if (!(item.status === 1 || item.status === -2)) {
+              item.hasAuth = false
+            }
+          }
+        })
+        this.handleSelect()
+      }
+    }
+  },
+  methods: {
+    handleSelect () {
+      let arr = this.fixdata.filter(item => {
+        return item.hasAuth
+      })
+      this.$emit('selection-change', arr)
+    },
+    selectItem (item, i) {
+      if (item.status || item.status === 0) {
+        if (!(item.status === 1 || item.status === -2)) {
+          return this.$toast.show('warn', this.language === 'en' ? '该场景计算中或计算错误,无法进行勾选' : '该场景计算中或计算错误,无法进行勾选')
+        }
+      }
+      item.hasAuth = !item.hasAuth
+      this.$set(this.fixdata, i, item)
+      this.lock = true
+      this.selectAll = true
+      this.fixdata.forEach(sub => {
+        if (!sub.hasAuth) {
+          this.selectAll = false
+        }
+      })
+      this.handleSelect()
     }
   },
   mounted () {

+ 12 - 0
pc/src/components/table/style.scss

@@ -2,6 +2,11 @@
   width: 100%;
   color: #777;
   font-size: 12px;
+  .check-cls{
+    width:60px;
+    text-align:left!important; 
+    margin-left:20px;
+  }
   .t-header{
     display: flex;
     justify-content: space-around;
@@ -28,6 +33,13 @@
         }
       }
     }
+    .line{
+      min-height: 50px;
+      border-bottom: 1px solid rgba($color: #202020, $alpha: 0.1);
+      &:first-of-type{
+        border-top: 1px solid rgba($color: #202020, $alpha: 0.1);
+      }
+    }
   }
 }
 

+ 80 - 21
pc/src/components/toast/cooperation.vue

@@ -6,17 +6,26 @@
   >
     <div class="toast-con bind-con" :style="{minWidth:'600px'}">
       <div class="t-header ">
-        <span>{{lang==='en'?'Invite collaborator':'分配协作'}}</span>
+        <span>{{lang==='en'?'Invite collaborator':'协作设置'}}</span>
         <i class="iconfont icon-cuowu" @click="handleClick"></i>
       </div>
       <div class="binding-con" :style="{height:(Math.ceil(auth.length/4)*30 + 140)+'px'}">
         <div class="binding-body cooperation">
-          <div class="toclient">{{lang==='en'?'Add collaborator':`分配${cooType === 'scene'?'场景':'相机'}给用户`}}</div>
-          <div class="b-input" >
-            <input v-model="userName" :placeholder="lang==='en'?'User name':'请输入用户账号'" type="text">
-          </div>
+          <template v-if="!cooName">
+            <div class="toclient">{{lang==='en'?'Collaborator':`协作用户`}}</div>
+            <div class="b-input" >
+              <input v-model="userName" :placeholder="lang==='en'?'User name':'请输入用户账号'" type="text">
+            </div>
+          </template>
 
-          <div class="toclient"><span>{{lang==='en'?'Assign Permission':'分配权限'}}</span><div @click="lock=false,selectAll=!selectAll"><span :class="{check_active:selectAll}" class="fdcheck">{{lang==='en'?'All':'全选'}}</span></div></div>
+          <template v-else>
+            <div class="toclient">{{lang==='en'?'Collaborator':`协作用户`}}</div>
+            <div class="b-input" >
+              {{cooName}}
+            </div>
+          </template>
+
+          <div class="toclient"><span>{{lang==='en'?'Permission':'协作权限'}}</span><div @click="handleSelectAll" v-if="!cooName"><span :class="{check_active:selectAll}" class="fdcheck">{{lang==='en'?'All':'全选'}}</span></div></div>
           <ul class="auth-list">
             <li v-for="(item,i) in auth" :key="i"><span @click="selectItem(item,i)" class="fdcheck" :class="{check_active:item.hasAuth}">{{lang==='en'?item.keyWord:item.name}}</span></li>
           </ul>
@@ -24,9 +33,16 @@
       </div>
 
       <div class="bind-btn coo-btn" >
-        <span @click="addCooperation">{{lang==='en'?'OK':'确定'}}</span>
-        <span class="default" @click="handleClick">{{lang==='en'?'Cancel':'取消'}}</span>
+        <template v-if="!cooName">
+          <span @click="addCooperation">{{lang==='en'?'OK':'确定'}}</span>
+          <span class="default" @click="handleClick">{{lang==='en'?'Cancel':'取消'}}</span>
+        </template>
+
+        <template v-else>
+          <span class="default" @click="unbind">{{lang==='en'?'Cancel collaborator':'取消协作'}}</span>
+        </template>
       </div>
+
     </div>
 
   </div>
@@ -35,9 +51,11 @@
 <script>
 import toastZH from '@/store/language/cn/toast'
 import toastEN from '@/store/language/en/toast'
+import temp from '../../page/navs/temp.vue'
 
 export default {
-  props: ['sceneNum', 'visible', 'cooType'],
+  components: { temp },
+  props: ['sceneNum', 'ids', 'cooName', 'visible', 'cooType'],
   data () {
     return {
       lock: true,
@@ -61,9 +79,8 @@ export default {
     },
     visible: function (newVal) {
       if (newVal) {
-        this.selectAll = true
+        this.selectAll = !this.cooName
         this.getResoureList()
-        // this.getResoureByNum()
       }
       this.userName = ''
       this.lang = localStorage.getItem('language')
@@ -71,7 +88,44 @@ export default {
     }
   },
   methods: {
+    async unbind () {
+      let token = localStorage.getItem('token')
+      let url = this.cooType === 'scene' ? '/user/scene/cooperation/delete' : '/user/camera/deleteCooperationUser'
+      let params = this.cooType === 'scene' ? {
+        sceneNum: this.sceneNum
+      } : {
+        cameraId: this.sceneNum
+      }
+
+      let result = await this.$http({
+        method: 'post',
+        headers: {
+          token
+        },
+        data: params,
+        url: url
+      })
+
+      let data = result.data
+      if (data.code === 0) {
+        this.handleClick('getList')
+        this.$toast.show('success', this.toastCode['45'])
+      } else {
+        return this.$toast.show('warn', this.toastCode[data.code], () => {})
+      }
+    },
+
+    handleSelectAll () {
+      if (this.cooName) {
+        return
+      }
+      this.lock = false
+      this.selectAll = !this.selectAll
+    },
     selectItem (item, i) {
+      if (this.cooName) {
+        return
+      }
       item.hasAuth = !item.hasAuth
       this.$set(this.auth, i, item)
       this.lock = true
@@ -88,7 +142,7 @@ export default {
     },
     async getResoureByNum () {
       let token = localStorage.getItem('token')
-      let url = this.cooType === 'scene' ? '/user/scene/cooperation/sceneResourceBySceneNum' : '/user/camera/sceneResourceByCameraId'
+      let url = this.cooType === 'scene' ? '/user/scene/cooperation/findSceneResource' : '/user/camera/sceneResourceByCameraId'
       let params = this.cooType === 'scene' ? {
         sceneNum: this.sceneNum
       } : {
@@ -108,18 +162,18 @@ export default {
         return
       }
       let data = res.data.data || []
+
       setTimeout(() => {
+        let arr = data.map(sub => sub.id)
+        console.log(arr)
         let tmp = this.auth.map(item => {
           item.hasAuth = true
-          data.forEach(sub => {
-            if (item.id === sub.id) {
-              item.hasAuth = true
-            } else {
-              item.hasAuth = false
-            }
-          })
+          if (arr.length > 0) {
+            item.hasAuth = arr.indexOf(item.id) > -1
+          }
           return item
         })
+
         this.auth = tmp
       })
     },
@@ -141,6 +195,7 @@ export default {
         return item
       })
       this.auth = tmp
+      this.cooName && this.getResoureByNum()
     },
     async addCooperation () {
       let token = localStorage.getItem('token')
@@ -157,7 +212,7 @@ export default {
       })
 
       if (resourceIds.length <= 0) {
-        return this.$toast.show('error', `${this.lang === 'en' ? 'Please select at least one.' : '请至少勾选一项权限'}`)
+        return this.$toast.show('warn', `${this.lang === 'en' ? 'Please select at least one.' : '请至少勾选一项权限'}`)
       }
 
       let url = this.cooType === 'scene' ? '/user/scene/cooperation/save' : '/user/camera/saveCooperationUser'
@@ -166,7 +221,11 @@ export default {
         resourceIds: resourceIds.join(',')
       }
 
-      this.cooType === 'scene' ? (params['sceneNum'] = this.sceneNum) : (params['cameraId'] = this.sceneNum)
+      if (this.ids) {
+        this.cooType === 'scene' ? (params['sceneNum'] = this.ids) : (params['ids'] = this.ids)
+      } else {
+        this.cooType === 'scene' ? (params['sceneNum'] = this.sceneNum) : (params['cameraId'] = this.sceneNum)
+      }
 
       let result = await this.$http({
         method: 'post',

+ 3 - 1
pc/src/components/toast/index.vue

@@ -5,7 +5,7 @@
     <editInvoice :edititem=editItem :visible='editVisible' @closePoint="invoicehandle"/>
     <showInvoice :showitem=showItem :visible='showVisible' @closePoint="()=>{showVisible = false}"/>
     <binding :btype="bindingType" :visible='bindingVisible' @closePoint="()=>{bindingVisible = false,emitCallback()}"/>
-    <cooperation :sceneNum="sceneNum" :cooType="cooType" :visible='cooperationVisible' @closePoint="handleCooClose"/>
+    <cooperation :sceneNum="sceneNum" :cooName="cooName" :ids="ids" :cooType="cooType" :visible='cooperationVisible' @closePoint="handleCooClose"/>
 
     <div
       class="toast-layout"
@@ -75,6 +75,8 @@ export default {
       visible: false,
       bindingType: 1,
       sceneNum: '',
+      cooName: '',
+      ids: '',
       cooType: '',
       capacitytype: '',
       capacityvisible: false,

+ 4 - 1
pc/src/components/toast/toast.js

@@ -71,7 +71,10 @@ Toast.install = function (Vue) {
       }
     },
     showCooperation: (item, callback) => {
-      instance.sceneNum = item.num
+      instance.sceneNum = item.num || ''
+      instance.cooName = item.cooName || ''
+
+      instance.ids = item.ids
       instance.cooType = item.type || 'scene'
 
       instance.cooperationVisible = true

+ 0 - 58
pc/src/page/manage/index.vue

@@ -1,65 +1,7 @@
 <template>
   <div class="manage-layout">
-    <div class="manage-bg">
-      <div class="manage-con container">
-        <template v-if="!deviceLogin">
-          <div class="info">
-            <div class="member">
-              <p>{{info.nickName||content.nickName||'--'}}</p>
-              <p>{{langMain.sn}}
-                <span class="child-name" ref="selectMenu" :class="{sanjiao:isSelect,'tab-active':selectActive}" @click="selectChange">
-                  {{isSelect?(activeCamera.snCode||(activeCamera.childName&&activeCamera.childName.replace('4DKKPRO_',''))):'--'}}
-                  <ul v-if="isSelect">
-                    <li v-for="(item,i) in content.cameraList" @click="selectInId(item)" :key="i" >{{item.snCode||(item.childName&&item.childName.replace('4DKKPRO_',''))||'--'}}</li>
-                  </ul>
-                </span>
-                <!-- <span class="sanjiao" v-if="isSelect"></span> -->
-              </p>
-            </div>
-            <div class="capacity">
-              <div class="c-dec">
-                <span>{{langMain.used}}{{isSelect?(activeCamera.usedSpaceStr+' / '+activeCamera.totalSpaceStr):'--'}} </span>
-              </div>
-              <div class="c-line">
-                <div class="active" :style="{width:getBar(activeCamera.usedSpace,activeCamera.totalSpace),background:getColor(activeCamera.usedSpace,activeCamera.totalSpace)}"></div>
-              </div>
-              <div class="c-detail">
-                <span>{{langMain.space}}{{activeCamera.spaceStr||'--'}} &nbsp;&nbsp;&nbsp;{{langMain.expire}}{{activeCamera.spaceEndStr||'--'}}</span>
-              </div>
-            </div>
-          </div>
-          <div class="open-btn" v-if="isSelect" @click="$router.push({name:'introduce',params:{id:activeCamera.childName}})">{{langMain.btnType.buy.xufei}}</div>
-        </template>
-        <template v-else>
-          <div class="info deviceLogin">
-            <div class="member">
-              <p>{{language!=='en'?(detail.nickName||'--'):(detail.nickName==='Pro设备用户'?'4DKanKan Pro User':(detail.nickName||'--'))}}</p>
-              <p>
-                <span class="child-name">
-                  {{detail.snCode||(detail.childName&&detail.childName.replace('4DKKPRO_',''))||'--'}}
-                </span>
-              </p>
-            </div>
-            <div class="capacity">
-              <div class="c-dec">
-                <span>{{langMain.used}}{{detail.totalSpaceStr?(detail.usedSpaceStr+' / '+detail.totalSpaceStr):'--'}} </span>
-              </div>
-              <div class="c-line">
-                <div class="active" :style="{width:getBar(detail.usedSpace,detail.totalSpace),background:getColor(detail.usedSpace,detail.totalSpace)}"></div>
-              </div>
-              <div class="c-detail">
-                <span>{{langMain.space}}{{detail.spaceStr||'--'}} &nbsp;&nbsp;&nbsp;{{langMain.expire}}{{detail.spaceEndStr||'--'}}</span>
-              </div>
-            </div>
-          </div>
-          <div class="open-btn" :style="{backgroundColor:'#1fe4dc'}" @click="toastKR(detail.userId)">{{langMain.btnType.buy[detail.spaceId?'xufei':'name']}}</div>
-        </template>
-      </div>
-    </div>
     <div class="manage-body ">
       <div class="container">
-
-      
         <div class="mc-left">
           <div v-for="(item,index) in settings" :key="index">
             <ul class="list-items">

+ 1 - 1
pc/src/page/manage/style.scss

@@ -136,7 +136,7 @@
   }
   .manage-body{
     min-height: 676px;
-    
+    padding-top: 80px;
     background-color: #f4f4f6;
     .container {
       display: flex;

+ 1 - 1
pc/src/page/manage/temp/consumption.vue

@@ -336,7 +336,7 @@ export default {
       }
       let data = {
         params: {
-          childName: searchKey,
+          childName: searchKey.trim(),
           pageNum: searchKey ? 1 : this.currentPage,
           pageSize: this.pageSize
         },

+ 169 - 53
pc/src/page/manage/temp/device.vue

@@ -3,15 +3,26 @@
     <div class="d-header">
       <ul class="tab-list">
         <li @click="tabActive = item.id" :class="{active:tabActive === item.id}" v-for="(item,i) in langDevices.tabList" :key="i">
-          {{item.name}}
+          {{item.name}}({{i===0?allTotal:xiezuoNum}})
         </li>
       </ul>
-      <div class="tab-search" :style="{marginRight:isWide?'35px':'149px'}">
-        <input v-model="searchKey" @keyup.enter="getList(searchKey)" type="text" :placeholder="langDevices.placeholder.searchID">
-        <i class="iconfont icon-sousuo" @click="getList(searchKey)"></i>
+      <div class="rig-con">
+        <div class="btns" v-if="tabActive===4&&!isImgType">
+          <span class="button" @click="addDevice"><i class="iconfont icon-jiahao"></i>{{langDevices.add}}</span>
+          <span class="button" @click="multCop">{{langDevices.fenpei}}</span>
+          <span class="button default" @click="multDel">{{langDevices.unbind}}</span>
+        </div>
+        <div class="tab-search" :style="{marginRight:isWide?'0':'149px'}">
+          <input v-model="searchKey" @keyup.enter="getList(searchKey)" type="text" :placeholder="langDevices.placeholder.searchID">
+          <i class="iconfont icon-sousuo" @click="getList(searchKey)"></i>
+        </div>
+        <div class="main-list" v-if="tabActive===4">
+          <i @click="changeType(true)" class="iconfont icon-main_grid" :title="langDevices.pictle" :class="{active:isImgType}"></i>
+          <i @click="changeType(false)" class="iconfont icon-main_list" :title="langDevices.listtle" :class="{active:!isImgType}"></i>
+        </div>
       </div>
     </div>
-    <div class="d-con">
+    <div class="d-con" v-if="isImgType||tabActive===0">
       <div class="edit-item item" @click="addDevice">
         <div class="plus-con">
           <div class="iconplus">
@@ -31,7 +42,6 @@
           <div class="i-left" :style="{marginTop:tabActive===4?'15px':'25px'}">
             <template v-if="tabActive===4">
               <p class="d-id" :title="item.snCode||(item.childName&&item.childName.replace('4DKKPRO_',''))||'--'">S/N: {{item.snCode||(item.childName&&item.childName.replace('4DKKPRO_',''))||'--'}} </p>
-              <!-- item.spaceEndTime|| -->
               <p class="p-sub" style="padding-left: 26px;" :title="`${item.usedSpaceStr} / ${item.totalSpaceStr}`">
                 <img :src="`${$cdn}images/icon-cloud.png`" alt="">
                 {{item.usedSpaceStr}} / {{item.totalSpaceStr}}
@@ -55,7 +65,7 @@
                       {{langDevices.capacity}}
                     </li>
                     <li @click="unbind(item)">{{langDevices.unbind}}</li>
-                    <li v-if="item.status !== 0" @click="handleCooperation(item)">{{item.cooperationUser?langDevices.qxfp:langDevices.fenpei}}</li>
+                    <li v-if="item.status !== 0" @click="handleCooperation(item)">{{langDevices.fenpei}}</li>
                   </ul>
                 </div>
               </div>
@@ -65,7 +75,6 @@
               <p class="p-sub">剩余点数:{{item.balance}}</p>
               <div class="d-edit" :class="{'dtow-edit':tabActive!==4}">
               <router-link class="primary" :to="{name:'introtow',params:{id:item.childName}}"><span>{{langDevices.recharge}}</span></router-link>
-                <!-- <span @click="$router.push({name:'introtow',params:{id:item.childName}})">充值</span> -->
               <div>
                   <span @click="unbind(item)">{{langDevices.unbind}}</span>
               </div>
@@ -78,6 +87,21 @@
         </div>
       </template>
     </div>
+
+    <tableList v-else @selection-change="data=>{selectedArr=data}" :header='tabHeader' :showLine='true' :selection='true' :data='mydevice.list' class="table-list" >
+      <div slot-scope="{data}" slot="header">
+        {{language==='en'?data.en:data.name}}
+      </div>
+      <div slot-scope="{data,type,canclick,item}" slot="item" style="width:100%">
+        <template v-if="canclick">
+          <router-link class="edit" target="_blank" :to="{name:'introduce',params:{id:item.childName}}">{{langDevices.capacity}}</router-link>
+          <span class="edit" @click="handleCooperation(item)" v-if="item.status !== 0" >{{langDevices.fenpei}}</span>
+
+        </template>
+        <span v-else-if="type==='qingkuang'">{{item.usedSpaceStr}} / {{item.totalSpaceStr}}</span>
+        <span v-else>{{data||'-'}}</span>
+      </div>
+    </tableList>
     <div class="paging" v-if="total">
       <Paging @clickHandle="pageChange" :current="currentPage" :total="total" :equable="pageSize" />
     </div>
@@ -87,9 +111,11 @@
 <script>
 import { mapState } from 'vuex'
 import Paging from '@/components/Paging'
+import tableList from '@/components/table'
+import {device} from './idevice'
 
 export default {
-  components: {Paging},
+  components: {Paging, tableList},
   data () {
     let tabList = [
       {
@@ -100,11 +126,19 @@ export default {
         id: 0
       }
     ]
+    let isImgType = localStorage.getItem('isImgTypeForDevice') === '' ? true : (localStorage.getItem('isImgTypeForDevice') === 'true')
+
     return {
+      tabHeader: device,
+      lock: false,
+      selectedArr: [],
       tabList,
+      allTotal: 0,
+      xiezuoNum: 0,
       tabActive: 4,
       currentPage: 1,
       total: 0,
+      isImgType: isImgType,
       searchKey: '',
       pageSize: 8,
       isWide: window.innerWidth > 1300,
@@ -137,38 +171,70 @@ export default {
     }
   },
   mounted () {
+    this.getEMTotal()
+
     this.getList()
   },
   methods: {
-    async handleCooperation (item) {
-      if (item.cooperationUser) {
-        let result = await this.$http({
-          method: 'post',
-          data: {
-            cameraId: item.id
-          },
-          headers: {
-            token: this.token
-          },
-          url: '/user/camera/deleteCooperationUser'
+    changeType (status) {
+      this.isImgType = status
+      localStorage.setItem('isImgTypeForDevice', status)
+    },
+    checkSelect () {
+      let pass = this.selectedArr.length <= 0
+      if (pass) {
+        return this.$toast.show('warn', `${this.language === 'en' ? 'Please select at least one.' : '请至少勾选一项'}`)
+      }
+      return true
+    },
+    multCop () {
+      if (this.checkSelect()) {
+        let ids = this.selectedArr.map(item => {
+          return item.id
         })
-        let data = result.data
-        if (data.code === 0) {
-          this.$toast.show('success', this.langToast['45'], () => {
-            this.getList()
-          })
-        } else {
-          return this.$toast.show('warn', this.langToast[data.code], () => {})
-        }
-      } else {
+
         this.$toast.showCooperation({
-          num: item.id,
+          ids: ids.join(','),
           type: 'device'
         }, () => {
           this.getList()
         })
       }
     },
+    multDel () {
+      if (this.checkSelect()) {
+        let ids = this.selectedArr.map(item => {
+          return item.id
+        })
+
+        this.unbind(ids.join(','), true)
+      }
+    },
+    async getEMTotal () {
+      let res = await this.$http({
+        method: 'post',
+        data: {
+          cameraType: 0,
+          childName: '',
+          pageNum: this.currentPage,
+          pageSize: this.pageSize
+        },
+        headers: {
+          token: this.token
+        },
+        url: '/user/camera/list'
+      })
+      this.xiezuoNum = res.data.data.total
+    },
+    async handleCooperation (item) {
+      this.$toast.showCooperation({
+        num: item.id,
+        cooName: item.cooperationUserName,
+        type: 'device'
+      }, () => {
+        this.getList()
+      })
+    },
     gotoScene (item) {
       this.$router.push({
         name: 'scene',
@@ -202,11 +268,11 @@ export default {
       }
       return color
     },
-    async unbind (item) {
+    async unbind (item, multi = false) {
       this.$toast.showConfirm('warn', this.langToast['26'], async () => {
         let params = {
-          cameraId: item.id
         }
+        multi ? (params['ids'] = item) : (params['cameraId'] = item.id)
         let res = await this.$http({
           method: 'post',
           data: params,
@@ -238,7 +304,7 @@ export default {
 
       let params = {
         cameraType: this.tabActive,
-        childName: searchKey,
+        childName: searchKey.trim(),
         pageNum: searchKey ? 1 : this.currentPage,
         pageSize: this.pageSize
       }
@@ -252,6 +318,11 @@ export default {
       this.pageSize = this.mydevice.pageSize
       this.total = this.mydevice.total || 0
       this.loading = false
+
+      if (!this.lock && !this.allTotal) {
+        this.lock = true
+        this.allTotal = this.total
+      }
     }
   }
 }
@@ -282,30 +353,71 @@ $font-color: #2d2d2d;
         border-bottom: 1px solid $theme-color;
       }
     }
-    .tab-search{
+
+    .rig-con{
+      margin-right: 40px;
       float: right;
-      position: relative;
-      width: 230px;
-      padding-left: 10px;
-      margin-right: 35px;
-      border: 1px solid #ccc;
       display: flex;
-      .iconfont{
-        width: 28px;
-        height: 28px;
-        padding: 6px;
-        cursor: pointer;
-        background: #e4e4e4;
+      align-items: center;
+      .btns{
+        margin-right: 20px;
+        .button{
+          line-height: 30px;
+          height: 30px;
+          min-width: 80px;
+          padding: 0 10px;
+          text-align: center;
+          vertical-align: middle;
+          font-size: 14px;
+          color: #202020;
+          margin-left: 10px;
+          cursor: pointer;
+          .iconfont{
+            font-size: 14px;
+            margin-right: 4px;
+          }
+        }
+        .default{
+          background: #E4E4E4;
+        }
       }
-      input{
-        width: 100%;
-        font-size: 14px;
-        appearance: none;
-        line-height: 28px;
-        height: 28px;
-        border: 0;
+      .tab-search{
+        float: right;
+        position: relative;
+        width: 230px;
+        padding-left: 10px;
+        border: 1px solid #ccc;
+        display: flex;
+        .iconfont{
+          width: 28px;
+          height: 28px;
+          padding: 6px;
+          cursor: pointer;
+          background: #e4e4e4;
+        }
+        input{
+          width: 100%;
+          font-size: 14px;
+          appearance: none;
+          line-height: 28px;
+          height: 28px;
+          border: 0;
+        }
+      }
+      .main-list{
+        display: inline-block;
+        margin-left: 35px;
+        .iconfont{
+          cursor: pointer;
+          font-size: 20px;
+          margin-left: 5px;
+        }
+        .active{
+          color: #1fe4dc;
+        }
       }
     }
+
   }
   .d-con{
     margin-left: 40px;
@@ -562,6 +674,10 @@ $font-color: #2d2d2d;
       }
     }
   }
+  .table-list{
+    width: calc(100% - 80px);
+    margin: 30px auto;
+  }
   .scene-nothing{
     padding: 42px 0 150px 0;
     text-align: center;
@@ -584,7 +700,7 @@ $font-color: #2d2d2d;
     & /deep/ .layout {
       text-align: left;
       margin-top: 0;
-      margin-left: 15px;
+      margin-left: 30px;
     }
     & /deep/ .layout a:not(:last-child) {
       margin: 10px 8px;

+ 47 - 0
pc/src/page/manage/temp/idevice.js

@@ -0,0 +1,47 @@
+let device = [
+  {
+    key: 'snCode',
+    name: 'S/N',
+    en: 'Device',
+    width: 150,
+    type: 'image'
+  }, {
+    key: 'sceneName',
+    name: '云容量使用情况',
+    en: 'Expansion order number',
+    width: 200,
+    type: 'qingkuang'
+  }, {
+    key: 'spaceStr',
+    en: 'Access channel',
+    name: '套餐类型'
+  }, {
+    key: 'spaceEndStr',
+    en: 'Package capacity',
+    name: '套餐到期时间'
+  }, {
+    key: 'cooperationUserName',
+    en: 'Method of Payment',
+    name: '协作者'
+  }, {
+    key: 'sceneNum',
+    en: 'Paid amount',
+    name: '拍摄场景数量',
+    type: 'typefix'
+  },
+  {
+    key: 'lastTime',
+    en: 'Time spent',
+    name: '最后拍摄时间',
+    width: 180
+  }, {
+    key: 'detail',
+    name: '操作',
+    en: '操作',
+    canclick: true
+  }
+]
+
+export {
+  device
+}

+ 45 - 0
pc/src/page/manage/temp/iscene.js

@@ -0,0 +1,45 @@
+let scene = [
+  {
+    key: 'thumb',
+    name: '场景封面',
+    en: 'Device',
+    width: 64,
+    type: 'image'
+  }, {
+    key: 'sceneName',
+    name: '标题',
+    en: 'Expansion order number',
+    width: 200
+  }, {
+    key: 'snCode',
+    en: 'Access channel',
+    name: 'S/N'
+  }, {
+    key: 'cooperationUserName',
+    en: 'Package capacity',
+    name: '协作者'
+  }, {
+    key: 'viewCount',
+    en: 'Method of Payment',
+    name: '浏览数量'
+  }, {
+    key: 'sceneType',
+    en: 'Paid amount',
+    name: '分类',
+    type: 'typefix'
+  },
+  {
+    key: 'createTime',
+    en: 'Time spent',
+    name: '拍摄时间'
+  }, {
+    key: 'detail',
+    name: '操作',
+    en: '操作',
+    canclick: true
+  }
+]
+
+export {
+  scene
+}

+ 192 - 82
pc/src/page/manage/temp/scene.vue

@@ -3,27 +3,38 @@
     <div class="d-header">
         <ul class="tab-list" v-if="!deviceLogin">
           <li @click="tabActive = item.id" :class="{active:tabActive === item.id}" v-for="(item,i) in langScenes.tabList" :key="i">
-            {{item.name}}
+            {{item.name}}({{i===0?allTotal:xiezuoNum}})
           </li>
         </ul>
 
         <ul class="tab-list" v-else>
           <li class="active" v-for="(item,i) in [langScenes.tabList[0]]" :key="i">
-            {{item.name}}
+            {{item.name}}({{allTotal}})
           </li>
         </ul>
-      <div class="tab-search">
-        <input
-          v-model="searchKey"
-          @keyup.enter="gotoSearch(searchKey)"
-          type="text"
-          :placeholder="langScenes.placeholder.searchID"
-        />
-        <i class="iconfont icon-sousuo" @click="gotoSearch(searchKey)"></i>
+      <div class="rig-con">
+        <div class="btns" v-if="tabActive===1&&!isImgType">
+          <span class="button" @click="multCop">{{langScenes.fenpei}}</span>
+          <span class="button default" @click="multDel">{{langScenes.delete}}</span>
+        </div>
+        <div class="tab-search">
+          <input
+            v-model="searchKey"
+            @keyup.enter="gotoSearch(searchKey)"
+            type="text"
+            :placeholder="langScenes.placeholder.searchID"
+          />
+          <i class="iconfont icon-sousuo" @click="gotoSearch(searchKey)"></i>
+        </div>
+        <div class="main-list">
+          <i @click="changeType(true)" class="iconfont icon-main_grid" :title="langScenes.pictle" :class="{active:isImgType}"></i>
+          <i @click="changeType(false)" class="iconfont icon-main_list" :title="langScenes.listtle" :class="{active:!isImgType}"></i>
+        </div>
       </div>
     </div>
 
-    <ul v-if="total" ref="ulMenu">
+  <template v-if="total">
+     <ul v-if="isImgType" ref="ulMenu">
       <template>
         <li v-for="(item,index) in myscene.list" :key="index">
           <div @click="((item.status === 1||item.status===-2)&&item.payStatus !== -2) && goto(item.webSite)" class="a-tap">
@@ -52,7 +63,7 @@
                 </div>
                 <ul :style="{minWidth: language==='en'?'150px': '90px'}">
                   <li v-if="item.status === 1||item.status===-2" @click="gotoEdit(item)">{{langScenes.edit}}</li>
-                  <li @click="handleCooperation(item)" v-if="(item.status === 1||item.status===-2)&&!deviceLogin">{{item.cooperationUserId?langScenes.qxfp:langScenes.fenpei}}</li>
+                  <li @click="handleCooperation(item)" v-if="(item.status === 1||item.status===-2)&&!deviceLogin">{{langScenes.fenpei}}</li>
                   <li v-if="item.status !== 0" @click="del(item)">{{langScenes.delete}}</li>
                 </ul>
               </template>
@@ -78,10 +89,36 @@
         </li>
       </template>
     </ul>
+
+    <tableList v-else @selection-change="data=>{selectedArr=data}" :header='tabHeader' :showLine='true' :selection='true' :data='myscene.list' class="table-list" >
+      <div slot-scope="{data}" slot="header">
+        {{language==='en'?data.en:data.name}}
+      </div>
+      <div slot-scope="{data,canclick,type,item}" slot="item" style="width:100%">
+        <template v-if="canclick">
+          <span class="edit" v-if="item.status === 1||item.status===-2" @click="gotoEdit(item)">{{langScenes.edit}}</span>
+          <span class="edit" @click="handleCooperation(item)" v-if="(item.status === 1||item.status===-2)&&!deviceLogin&&tabActive===1" >{{langScenes.fenpei}}</span>
+        </template>
+        <div style="position:relative;" v-else-if="type === 'image'" >
+          <div :title="item.name" @click="((item.status === 1||item.status===-2)&&item.payStatus !== -2) && goto(item.webSite)" style="height:40px;" class="card-img" :style="{backgroundImage: `url(${getSceneImg(item)})`}"></div>
+          <div class="loading-hover" v-if="item.status === 0">
+              <div class="loading-icon" style="width:100%">
+                <p style="margin-top:0">{{langScenes.share.calcule}}</p>
+              </div>
+            </div>
+        </div>
+
+        <span v-else-if="type === 'typefix'">{{langScenes.typeObj[data]}}</span>
+        <span v-else>{{data||'-'}}</span>
+      </div>
+    </tableList>
+  </template>
+
     <div class="scene-nothing" v-else>
       <img :src="`${$cdn}images/nothing.png`" />
       <div>{{langScenes.noScenes}}</div>
     </div>
+
     <div class="paging" v-if="total">
       <Paging @clickHandle="pageChange" :current="currentPage" :total="total" :equable="pageSize" />
     </div>
@@ -135,9 +172,11 @@
 
 <script>
 import { mapState } from 'vuex'
+import tableList from '@/components/table'
+import {scene} from './iscene'
 import Paging from '@/components/Paging'
 export default {
-  components: { Paging },
+  components: { Paging, tableList },
   data () {
     let imgs = [
       {
@@ -153,15 +192,23 @@ export default {
         id: 2
       }
     ]
+
+    let isImgType = localStorage.getItem('isImgType') === '' ? true : (localStorage.getItem('isImgType') === 'true')
     return {
+      tabHeader: scene,
+      xiezuoNum: 0,
       pageSize: 12,
+      lock: false,
       currentPage: 1,
       searchKey: '',
+      selectedArr: [],
       total: 0,
+      allTotal: 0,
       showShare: false,
       imgs,
       num: '',
       rnd: Math.random(),
+      isImgType: isImgType,
       lwidth: 853,
       lheight: 480,
       url: 'https://www.4dkankan.com/showProPC.html?m=KcMeJlOr8',
@@ -237,39 +284,54 @@ export default {
         })
       })
     } else {
+      this.getCooTotal()
       this.getList()
     }
   },
   methods: {
-    async handleCooperation (item) {
-      if (item.cooperationUserId) {
-        let result = await this.$http({
-          method: 'post',
-          data: {
-            sceneNum: item.num
-          },
-          headers: {
-            token: this.token
-          },
-          url: '/user/scene/cooperation/delete'
+    changeType (status) {
+      this.isImgType = status
+      localStorage.setItem('isImgType', status)
+    },
+    checkSelect () {
+      let pass = this.selectedArr.length <= 0
+      if (pass) {
+        return this.$toast.show('warn', `${this.language === 'en' ? 'Please select at least one.' : '请至少勾选一项'}`)
+      }
+      return true
+    },
+    multCop () {
+      if (this.checkSelect()) {
+        let nums = this.selectedArr.map(item => {
+          return item.num
         })
-        let data = result.data
-        if (data.code === 0) {
-          this.$toast.show('success', this.langToast['45'], () => {
-            this.getList()
-          })
-        } else {
-          return this.$toast.show('warn', this.langToast[data.code], () => {})
-        }
-      } else {
+
         this.$toast.showCooperation({
-          num: item.num,
+          ids: nums.join(','),
           type: 'scene'
         }, () => {
           this.getList()
         })
       }
     },
+    multDel () {
+      if (this.checkSelect()) {
+        let nums = this.selectedArr.map(item => {
+          return item.num
+        })
+
+        this.del(nums.join(','), true)
+      }
+    },
+    async handleCooperation (item) {
+      this.$toast.showCooperation({
+        num: item.num,
+        cooName: item.cooperationUserName,
+        type: 'scene'
+      }, () => {
+        this.getList()
+      })
+    },
     handleMenu (index) {
       this.ulActive = index === this.ulActive ? '' : index
     },
@@ -352,10 +414,10 @@ export default {
 
       window.open(url.replace('http://', 'https://') + (this.language === 'en' ? '&lang=en' : ''), '_blank')
     },
-    async del (item) {
+    async del (item, multi = false) {
       this.$toast.showConfirm('warn', this.langScenes.delwarn, async () => {
         let params = {
-          sceneNum: item.num
+          sceneNum: multi ? item : item.num
         }
         let res = await this.$http({
           method: 'post',
@@ -385,6 +447,24 @@ export default {
         this.getList(searchKey)
       }
     },
+
+    async getCooTotal () {
+      let res = await this.$http({
+        method: 'post',
+        data: {
+          pageNum: this.currentPage,
+          pageSize: this.pageSize,
+          cameraId: null,
+          searchKey: this.searchKey,
+          cameraType: null
+        },
+        headers: {
+          token: this.token
+        },
+        url: '/user/scene/cooperation/cooperationSceneList'
+      })
+      this.xiezuoNum = res.data.data.total
+    },
     async getList (searchKey = null) {
       this.searchKey = searchKey || this.searchKey
       let { id: cameraId = null, type: cameraType = null } = this.cameradetail
@@ -393,7 +473,7 @@ export default {
         pageNum: this.currentPage,
         pageSize: this.pageSize,
         cameraId,
-        searchKey: this.searchKey,
+        searchKey: this.searchKey.trim(),
         cameraType
       }
       if (this.tabActive === 2) {
@@ -405,6 +485,11 @@ export default {
       }
       this.pageSize = this.myscene.pageSize
       this.total = this.myscene.total || 0
+
+      if (!this.lock && !this.allTotal) {
+        this.lock = true
+        this.allTotal = this.total
+      }
     },
     copyTextToClipboard (text) {
       var textArea = document.createElement('textarea')
@@ -471,30 +556,66 @@ $font-color: #2d2d2d;
         border-bottom: 1px solid $theme-color;
       }
     }
-    .tab-search{
+
+    .rig-con{
+      margin-right: 40px;
       float: right;
-      position: relative;
-      width: 230px;
-      padding-left: 10px;
-      margin-right: 120px;
-      border: 1px solid #ccc;
       display: flex;
-      .iconfont{
-        width: 28px;
-        height: 28px;
-        padding: 6px;
-        cursor: pointer;
-        background: #e4e4e4;
+      align-items: center;
+      .btns{
+        margin-right: 20px;
+        .button{
+          line-height: 30px;
+          height: 30px;
+          min-width: 80px;
+          padding: 0 10px;
+          text-align: center;
+          vertical-align: middle;
+          font-size: 14px;
+          color: #202020;
+          cursor: pointer;
+        }
+        .default{
+          background: #E4E4E4;
+          margin-left: 10px;
+        }
       }
-      input{
-        width: 100%;
-        font-size: 14px;
-        appearance: none;
-        line-height: 28px;
-        height: 28px;
-        border: 0;
+      .tab-search{
+        position: relative;
+        width: 230px;
+        border: 1px solid #ccc;
+        display: flex;
+        .iconfont{
+          width: 28px;
+          height: 28px;
+          padding: 6px;
+          cursor: pointer;
+          background: #e4e4e4;
+        }
+        input{
+          width: 100%;
+          font-size: 14px;
+          appearance: none;
+          padding-left: 10px;
+          line-height: 28px;
+          height: 28px;
+          border: 0;
+        }
+      }
+      .main-list{
+        display: inline-block;
+        margin-left: 20px;
+        .iconfont{
+          cursor: pointer;
+          font-size: 20px;
+          margin-left: 5px;
+        }
+        .active{
+          color: #1fe4dc;
+        }
       }
     }
+
   }
   > ul {
     padding: 30px 0 0 40px;
@@ -657,31 +778,20 @@ $font-color: #2d2d2d;
       }
     }
   }
-  // .tab-search {
-  //   float: right;
-  //   position: relative;
-  //   width: 230px;
-  //   padding-left: 10px;
-  //   border: 1px solid #ccc;
-  //   top: -30px;
-  //   right: 6vw;
-  //   display: flex;
-  //   .iconfont {
-  //     width: 28px;
-  //     height: 28px;
-  //     padding: 6px;
-  //     background: #e4e4e4;
-  //     cursor: pointer;
-  //   }
-  //   input {
-  //     width: 100%;
-  //     font-size: 14px;
-  //     appearance: none;
-  //     line-height: 28px;
-  //     height: 28px;
-  //     border: 0;
-  //   }
-  // }
+
+  .table-list{
+    width: calc(100% - 80px);
+    margin: 30px auto;
+    .card-img {
+        width: 100%;
+        height: 100%;
+        cursor: pointer;
+        background-position: center;
+        background-size: auto 100%;
+        background-repeat: no-repeat;
+    }
+  }
+
   .scene-nothing {
     width: 75%;
     padding: 42px 0 210px 0;
@@ -701,7 +811,7 @@ $font-color: #2d2d2d;
     & /deep/ .layout {
       text-align: left;
       margin-top: 0;
-      margin-left: 15px;
+      margin-left: 30px;
     }
     & /deep/ .layout a:not(:last-child) {
       margin: 10px 8px;

+ 15 - 3
pc/src/store/language/cn/manage.js

@@ -107,11 +107,21 @@ export default{
   myScenes: {
     edit: '编辑',
     delete: '删除',
-    fenpei: '分配协作',
+    fenpei: '协作',
     user: '协作者',
     qxfp: '取消协作',
+    listtle: '列表式',
+    pictle: '卡片式',
     shooting: '拍摄时间:',
     id: 'S/N:',
+    typeObj: {
+      2: '房地产',
+      1: '博物馆',
+      5: '家居',
+      4: '餐饮',
+      0: '其他',
+      3: '电商'
+    },
     tabList: [
       {
         name: '我的场景',
@@ -186,7 +196,7 @@ export default{
 
   },
   myDevices: {
-    add: '添加新设备',
+    add: '新增相机',
     tabList: [
       {
         name: '四维看看Pro',
@@ -196,6 +206,8 @@ export default{
         id: 0
       }
     ],
+    listtle: '列表式',
+    pictle: '卡片式',
     placeholder: {
       searchID: '搜索设备S/N或协作者手机'
     },
@@ -204,7 +216,7 @@ export default{
     upgrade: '升级',
     capacity: '扩容',
     unbind: '解绑',
-    fenpei: '分配协作',
+    fenpei: '协作',
     qxfp: '取消协作',
     recharge: '充值',
     expire: '到期:',

+ 3 - 0
pc/src/store/language/cn/toast.js

@@ -79,6 +79,7 @@ export default{
   '3020': '邮箱地址已存在',
   '3021': '账号不存在,请核对后重新输入',
   '3022': '该场景已添加协作者,请先取消协作后再添加',
+  '3026': '有部分场景已存在协作者,请先取消协作后再添加。',
 
   '3023': '手机验证码获取验证码次数过多,请明天再试',
   '3024': '不能将场景协作给自己',
@@ -86,6 +87,8 @@ export default{
   '6013': '必须输入需迁相机所绑定用户的验证码',
   '6014': '必须输入目标相机所绑定用户的验证码',
   '6015': '该相机已添加协作者,请先取消协作后再添加',
+  '6016': '有部分相机已存在协作者,请先取消协作后再添加。',
+
   '3025': '不能将相机分配给自己',
 
   '3019': '邮箱格式不正确',

+ 12 - 0
pc/src/store/language/en/manage.js

@@ -109,6 +109,8 @@ export default{
     delete: 'Delete',
     fenpei: 'Invite collaborator',
     qxfp: 'Cancel collaborator',
+    listtle: '列表式',
+    pictle: '卡片式',
     user: 'Collaborator',
     placeholder: {
       searchID: 'Search scene'
@@ -122,6 +124,14 @@ export default{
         id: 2
       }
     ],
+    typeObj: {
+      2: 'Real estate',
+      1: 'Museum',
+      5: 'Home',
+      4: 'Catering',
+      0: 'Others',
+      3: 'E-commerce'
+    },
     id: 'S/N: ',
     shooting: 'Shooting date: ',
     noScenes: 'No Records',
@@ -197,6 +207,8 @@ export default{
         id: 0
       }
     ],
+    listtle: '列表式',
+    pictle: '卡片式',
     placeholder: {
       searchID: 'Search S/N or Tel No.'
     },

+ 3 - 0
pc/src/store/language/en/toast.js

@@ -80,6 +80,7 @@ export default{
   '3020': 'Email already exists.',
   '3021': 'Invalid user name, please check and give a valid one.',
   '3022': 'There is already a collaborator for this scene. Please cancel the previous collaboration first.',
+  '3026': '有部分场景已存在协作者,请先取消协作后再添加。',
 
   '3023': 'The verification code has been obtained too many times, please try again tomorrow.',
   '3024': 'Can’t assign scene to yourself.',
@@ -87,6 +88,8 @@ export default{
   '6013': '必须输入需迁相机所绑定用户的验证码',
   '6014': '必须输入目标相机所绑定用户的验证码',
   '6015': 'Please cancel the collaborator first then to add another one.',
+  '6016': '有部分相机已存在协作者,请先取消协作后再添加。',
+
   '3025': 'Can’t assign camera to yourself.',
 
   '8001': 'Order doesn\'t exist.',

+ 2 - 2
pc/src/store/user.js

@@ -14,7 +14,7 @@ let vue = new Vue()
 let token = (localStorage && localStorage.getItem('token')) || ''
 
 let fdkankantoken = Cookies.get('4dkankantoken') || ''
-let cart = (localStorage && localStorage.getItem('cart')) || "[]"
+let cart = (localStorage && localStorage.getItem('cart')) || '[]'
 let invoice2 = (localStorage && localStorage.getItem('invoice2')) || []
 let invoice3 = (localStorage && localStorage.getItem('invoice3')) || []
 let deviceLogin = (localStorage && localStorage.getItem('deviceLogin')) || ''
@@ -187,7 +187,7 @@ export default {
       let data = res.data
       if (data.code !== 0) {
         vue.$toast.show('warn', toastCode[data.code])
-        return 
+        return
       }
       let token = data.data.token
       context.commit('saveToken', token)