xzh 4 年之前
父节点
当前提交
f073d1817a
共有 31 个文件被更改,包括 715 次插入89 次删除
  1. 1 1
      mobile/src/components/citySelect/style.scss
  2. 36 12
      mobile/src/components/toast/cooperation.vue
  3. 13 7
      mobile/src/components/toast/index.vue
  4. 32 0
      mobile/src/components/toast/loadingicon.vue
  5. 4 3
      mobile/src/components/toast/toast.js
  6. 130 4
      mobile/src/pages/account/manage/device/index.vue
  7. 4 1
      mobile/src/pages/account/manage/myscene/index.vue
  8. 13 6
      mobile/src/pages/account/manage/order/index.vue
  9. 1 0
      mobile/src/pages/layout/footer.vue
  10. 5 1
      mobile/src/store/language/cn/manage.js
  11. 8 0
      mobile/src/store/language/cn/toast.js
  12. 5 1
      mobile/src/store/language/en/manage.js
  13. 8 0
      mobile/src/store/language/en/toast.js
  14. 2 0
      pc/src/components/citySelect/index.vue
  15. 122 14
      pc/src/components/toast/cooperation.vue
  16. 16 11
      pc/src/components/toast/index.vue
  17. 32 0
      pc/src/components/toast/loadingicon.vue
  18. 61 4
      pc/src/components/toast/style.scss
  19. 4 2
      pc/src/components/toast/toast.js
  20. 4 2
      pc/src/page/layout/aside/temp/ctemp/detail.vue
  21. 1 0
      pc/src/page/layout/aside/temp/ltemp/style.scss
  22. 3 0
      pc/src/page/layout/footer.vue
  23. 137 5
      pc/src/page/manage/temp/device.vue
  24. 3 2
      pc/src/page/manage/temp/information.vue
  25. 12 6
      pc/src/page/manage/temp/order.vue
  26. 25 5
      pc/src/page/manage/temp/scene.vue
  27. 7 1
      pc/src/store/language/cn/manage.js
  28. 9 0
      pc/src/store/language/cn/toast.js
  29. 7 1
      pc/src/store/language/en/manage.js
  30. 9 0
      pc/src/store/language/en/toast.js
  31. 1 0
      pc/src/util/http.js

+ 1 - 1
mobile/src/components/citySelect/style.scss

@@ -39,7 +39,7 @@
           z-index: 999;
           transition: all 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
           overflow: auto;
-          max-height: 300px;
+          max-height: 200px;
           li{
             padding: 0 11px;
             line-height: 30px;

+ 36 - 12
mobile/src/components/toast/cooperation.vue

@@ -11,7 +11,7 @@
       </div>
       <div class="binding-con">
         <div class="binding-body">
-          <div class="toclient">{{lang==='en'?'Add collaborator':'分配场景给用户'}}</div>
+          <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>
@@ -32,13 +32,13 @@ import toastZH from '@/store/language/cn/toast'
 import toastEN from '@/store/language/en/toast'
 
 export default {
-  props: ['sceneNum', 'visible'],
+  props: ['sceneNum', 'visible', 'cooType'],
   data () {
     return {
       userName: '',
       lang: localStorage.getItem('language'),
-      toastCode: localStorage.getItem('language') === 'en' ? toastEN : toastZH
-
+      toastCode: localStorage.getItem('language') === 'en' ? toastEN : toastZH,
+      auth: ''
     }
   },
   computed: {
@@ -46,34 +46,58 @@ export default {
   },
   watch: {
     visible: function (newVal) {
+      if (newVal) {
+        this.getResoureList()
+      }
       this.userName = ''
       this.lang = localStorage.getItem('language')
       this.toastCode = this.lang === 'en' ? toastEN : toastZH
     }
   },
+  mounted () {
+  },
   methods: {
-    handleClick () {
-      this.$emit('closePoint')
+    async getResoureList () {
+      let token = localStorage.getItem('token')
+
+      let res = await this.$http({
+        method: 'post',
+        headers: {
+          token
+        },
+        url: '/user/scene/cooperation/sceneResourceList'
+      })
+      this.auth = res.data.data
+    },
+    handleClick (type = '') {
+      this.$emit('closePoint', type)
     },
     async addCooperation () {
       let token = localStorage.getItem('token')
       if (!this.userName) {
         return this.$toast.show('error', `${this.lang === 'en' ? 'Please enter user name.' : '请输入用户账号'}`)
       }
+      let resourceIds = this.auth.map(item => item.id)
+      let url = this.cooType === 'scene' ? '/user/scene/cooperation/save' : '/user/camera/saveCooperationUser'
+
+      let params = {
+        userName: this.userName,
+        resourceIds: resourceIds.join(',')
+      }
+
+      this.cooType === 'scene' ? (params['sceneNum'] = this.sceneNum) : (params['cameraId'] = this.sceneNum)
+
       let result = await this.$http({
         method: 'post',
-        data: {
-          userName: this.userName,
-          sceneNum: this.sceneNum
-        },
+        data: params,
         headers: {
           token
         },
-        url: '/user/scene/cooperation/save'
+        url
       })
       let data = result.data
       if (data.code === 0) {
-        this.handleClick()
+        this.handleClick('getList')
         this.$toast.show('success', this.toastCode['50'])
       } else {
         return this.$toast.show('warn', this.toastCode[data.code], () => {})

+ 13 - 7
mobile/src/components/toast/index.vue

@@ -2,7 +2,7 @@
   <div>
     <binding :btype="bindingType" :visible='bindingVisible' @closePoint="()=>{bindingVisible = false,emitCallback()}"/>
     <addcart :visible='addcartVisible' :img='img' :msg='addcartmsg' :txt='addcarbtnTxt' @closePoint="handleAddCart" />
-    <cooperation :sceneNum="sceneNum" :visible='cooperationVisible' @closePoint="()=>{cooperationVisible = false,emitCallback()}"/>
+    <cooperation :sceneNum="sceneNum" :visible='cooperationVisible' :cooType="cooType" @closePoint="handleCooClose"/>
 
     <div
       class="toast-layout"
@@ -10,11 +10,7 @@
       :class="{'toast-active':isLoaing}"
     >
       <div class="loading">
-        <svg viewBox="0 0 28 19">
-          <path
-            d="M4 0l3 3C5.151 4.589 4.141 6.938 4 9c.141 2.994 1.18 5.374 3 7l-3 3c-2.512-2.51-4-5.919-4-10 0-3.134 1.446-6.499 4-9zm20 0c2.554 2.501 4 5.866 4 9 0 4.081-1.488 7.49-4 10l-3-3c1.82-1.626 2.859-4.006 3-7-.141-2.062-1.151-4.411-3-6l3-3z"
-          ></path>
-        </svg>
+        <loading/>
       </div>
     </div>
     <div
@@ -68,6 +64,7 @@
 import binding from './binding'
 import addcart from './addcart'
 import cooperation from './cooperation'
+import loading from './loadingicon'
 
 let types = {
   warn: '提示',
@@ -87,11 +84,12 @@ let typesEn = {
 }
 
 export default {
-  components: {binding, addcart, cooperation},
+  components: {binding, addcart, loading, cooperation},
   data () {
     return {
       bindingType: 1,
       sceneNum: '',
+      cooType: '',
       visible: false,
       bindingVisible: false,
       addcartVisible: false,
@@ -127,6 +125,14 @@ export default {
   },
   mounted () {},
   methods: {
+    handleCooClose (data) {
+      this.cooperationVisible = false
+      data === 'getList' && this.emitCooCallback()
+    },
+    emitCooCallback () {
+      this.cooCallback && this.cooCallback()
+      this.visible = false
+    },
     handleAddCart (data) {
       this.addcartVisible = false
       data && this.callback()

+ 32 - 0
mobile/src/components/toast/loadingicon.vue

@@ -0,0 +1,32 @@
+<template>
+  <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+    viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
+  <g>
+    <circle class="st0" cx="32" cy="5" r="5"/>
+    <circle class="st1" cx="32" cy="59" r="5"/>
+    <circle class="st2" cx="18.5" cy="8.6" r="5"/>
+    <circle class="st3" cx="45.5" cy="55.4" r="5"/>
+    <circle class="st4" cx="8.6" cy="18.5" r="5"/>
+    <circle class="st5" cx="5" cy="32" r="5"/>
+    <circle cx="59" cy="32" r="5"/>
+    <circle class="st6" cx="8.6" cy="45.5" r="5"/>
+    <circle class="st7" cx="55.4" cy="18.5" r="5"/>
+    <circle class="st8" cx="18.5" cy="55.4" r="5"/>
+    <circle class="st9" cx="45.5" cy="8.6" r="5"/>
+  </g>
+  </svg>
+
+</template>
+
+<style lang="scss" scoped>
+.st0{opacity:0.73;}
+.st1{opacity:0.19;}
+.st2{opacity:0.64;}
+.st3{opacity:0.1;}
+.st4{opacity:0.55;}
+.st5{opacity:0.46;}
+.st6{opacity:0.37;}
+.st7{opacity:0.91;}
+.st8{opacity:0.28;}
+.st9{opacity:0.82;}
+</style>

+ 4 - 3
mobile/src/components/toast/toast.js

@@ -51,10 +51,11 @@ Toast.install = function (Vue) {
       instance.callback = callback || function () {
       }
     },
-    showCooperation: (sceneNum, callback) => {
-      instance.sceneNum = sceneNum
+    showCooperation: (item, callback) => {
+      instance.sceneNum = item.num
+      instance.cooType = item.type || 'scene'
       instance.cooperationVisible = true
-      instance.callback = callback || function () {
+      instance.cooCallback = callback || function () {
       }
     },
     show: (type, msg, callback, submsg = '') => {

+ 130 - 4
mobile/src/pages/account/manage/device/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="device-layout">
-    <div class="plate">
+    <div class="plate"  ref="deviceMenu">
       <template v-if="Number(tabActive)===4">
         <div class="d-item eight-item" v-for="(item,i) in mydevice.list" :key="i" >
           <template v-if="Number(tabActive)===4">
@@ -20,13 +20,25 @@
             </div>
             <p class="i-dec">{{langDevices.expand}}{{item.spaceStr||'--'}}</p>
             <p class="i-dec">{{langDevices.expire}}{{item.spaceEndStr||'--'}}</p>
-            <div class="btn-con">
+            <div class="btm-opr">
+              <div @click.stop="handleMenu(i)">
+                  <span class="spot"></span>
+                </div>
+                <ul v-if="ulActive === i">
+                  <li @click="unbind(item)">{{langDevices.unbind}}</li>
+                  <!-- <li @click="$router.push({name:'introduce',params:{id:item.childName}})">{{item.cooperationUserId?langScenes.qxfp:langScenes.fenpei}}</li> -->
+                  <li @click="$router.push({name:'introduce',params:{id:item.childName}})">{{langDevices.capacity}}</li>
+                  <li @click="handleCooperation(item)">{{item.cooperationUser?langDevices.qxfp:langDevices.fenpei}}</li>
+
+                </ul>
+            </div>
+            <!-- <div class="btn-con">
               <span></span>
               <div>
                 <div class="btn" @click="unbind(item)"><span>{{langDevices.unbind}}</span></div>
                 <div class="btn primary" @click="$router.push({name:'introduce',params:{id:item.childName}})"><span>{{langDevices.capacity}}</span></div>
               </div>
-            </div>
+            </div> -->
           </div>
         </div>
       </template>
@@ -68,7 +80,8 @@ export default {
       currentPage: 1,
       total: 0,
       searchKey: '',
-      pageSize: 8
+      pageSize: 8,
+      ulActive: ''
     }
   },
   computed: {
@@ -91,6 +104,38 @@ export default {
     }
   },
   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'
+        })
+        let data = result.data
+        if (data.code === 0) {
+          this.$toast.show('success', this.langToast['51'], () => {
+            this.getList()
+          })
+        } else {
+          return this.$toast.show('warn', this.langToast[data.code], () => {})
+        }
+      } else {
+        this.$toast.showCooperation({
+          num: item.id,
+          type: 'device'
+        }, () => {
+          this.getList()
+        })
+      }
+    },
+    handleMenu (index) {
+      this.ulActive = index === this.ulActive ? '' : index
+    },
     gotoScene (item) {
       this.$router.push({
         name: 'scenesearch',
@@ -183,6 +228,9 @@ export default {
     }
   },
   mounted () {
+    document.addEventListener('click', (e) => {
+      this.ulActive = ''
+    })
     this.getList()
   },
   watch: {
@@ -225,6 +273,7 @@ $theme-color: #1fe4dc;
 .device-layout{
   background: #f6f9fd;
   .plate{
+    padding-bottom: 10px;
     .scene-nothing{
       background: #fff;
       text-align: center;
@@ -308,6 +357,83 @@ $theme-color: #1fe4dc;
           display: flex;
           width: 100%;
         }
+        .btm-opr{
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-top: 6px;
+        position: relative;
+        .spot{
+          width: 4px;
+          height: 4px;
+          display: inline-block;
+          background-color: #202020;
+          border-radius: 50%;
+          position: relative;
+          margin-left: 10px;
+          &::after,&::before{
+            content: '';
+            position: absolute;
+            width: 4px;
+            height: 4px;
+            display: inline-block;
+            background-color: #202020;
+            border-radius: 50%;
+            left: -8px;
+            top: 50%;
+            transform: translateY(-50%);
+          }
+          &::before{
+            right: -8px;
+            left: unset;
+          }
+        }
+        >ul{
+          position: absolute;
+          z-index: 9;
+          left: -32px;
+          top: 22px;
+          background: #F7F7F7;
+          min-width: 90px;
+          box-shadow:0px 1px 6px rgba(0,0,0,0.16);
+          >li{
+            text-align: left;
+            width: 100%;
+            line-height: 2.5;
+            padding: 0 10px;
+            color: #202020;
+            &:hover{
+              background-color: #EBEBEB;
+            }
+          }
+        }
+        .btmr-con{
+          .btm-right{
+            display: inline-block;
+            background: #fff;
+            border: 1px solid #777777;
+            border-radius: 2px;
+            font-size: 12px;
+            width: 52px;
+            height: 26px;
+            line-height: 26px;
+            text-align: center;
+            margin-right: 4px;
+            position: relative;
+            span{
+              position: absolute;
+              top: 50%;
+              left: 50%;
+              transform: translate(-50%,-50%);
+            }
+          }
+          .primary{
+            background: #1fe4dc;
+            border: 1px solid #1fe4dc;
+          }
+        }
+
+      }
       }
     }
 

+ 4 - 1
mobile/src/pages/account/manage/myscene/index.vue

@@ -179,7 +179,10 @@ export default {
           return this.$toast.show('warn', this.langToast[data.code], () => {})
         }
       } else {
-        this.$toast.showCooperation(item.num, () => {
+        this.$toast.showCooperation({
+          num: item.num,
+          type: 'scene'
+        }, () => {
           this.getList()
         })
       }

+ 13 - 6
mobile/src/pages/account/manage/order/index.vue

@@ -55,16 +55,21 @@
               <template v-else-if="getStatus(item) === 'received'">
                 <span class="expreeNum">{{langOrders.received}}:{{item.orderItems[0].expressNum}}</span>
               </template>
+              <template v-else-if="getStatus(item) === 'expire'">
+                <span class="expreeNum">{{langOrders.expire}}</span>
+              </template>
               <template v-else>
                 <span class="expreeNum">{{langOrders.hasCancal}}</span>
               </template>
             </div>
             <div class="to-pay">
-              <span class="cancel btns" @click="changeIvoiceStatus(i,item)">{{langOrders.invoice}}</span>
-              <template v-if="getStatus(item) === 'unpaid'">
-              <span class="cancel btns" @click="cancal(item)">{{langOrders.cancal}}</span>
-              <span class="pay btns" @click="goPay(item)">{{langOrders.pay}}</span>
-            </template>
+              <template v-if="getStatus(item) !== 'expire'">
+                <span class="cancel btns" @click="changeIvoiceStatus(i,item)">{{langOrders.invoice}}</span>
+                <template v-if="getStatus(item) === 'unpaid'">
+                  <span class="cancel btns" @click="cancal(item)">{{langOrders.cancal}}</span>
+                  <span class="pay btns" @click="goPay(item)">{{langOrders.pay}}</span>
+                </template>
+              </template>
             </div>
           </div>
         </div>
@@ -270,7 +275,9 @@ export default {
         case 'processed':
           sPay()
           break
-
+        case 'expire':
+          temp = 'expire'
+          break
         default:
           break
       }

+ 1 - 0
mobile/src/pages/layout/footer.vue

@@ -37,6 +37,7 @@
         <div class="copyright">
           <p>{{langFooter.copyright[0]}}</p>
           <p>{{langFooter.copyright[1]}}</p>
+          <p>珠海市四维时代网络科技有限公司</p>
         </div>
       </div>
       <!-- <div class="layout">

+ 5 - 1
mobile/src/store/language/cn/manage.js

@@ -172,6 +172,7 @@ export default{
     received: '已收货',
     partShipped: '部分发货',
     hasCancal: '已取消',
+    expire: '已失效',
     edit: '修改',
     editInfo: '发货后7天内可修改',
     dontneed: '发票类型:不需要发票',
@@ -200,15 +201,18 @@ export default{
       }
     ],
     placeholder: {
-      searchID: '搜索设备S/N'
+      searchID: '搜索设备S/N或协作者手机'
     },
     storage: '云容量:',
     renew: '续费',
     upgrade: '升级',
     capacity: '扩容',
     unbind: '解绑',
+    fenpei: '分配协作',
+    qxfp: '取消协作',
     recharge: '充值',
     expire: '到期:',
+    xiezuo: '协作:',
     expand: '套餐:',
     jijiang: '即将到期',
     rongliang: '容量已满',

+ 8 - 0
mobile/src/store/language/cn/toast.js

@@ -89,6 +89,14 @@ export default{
   '3021': '账号不存在,请核对后重新输入',
   '3022': '该场景已添加协作者,请先取消协作后再添加',
 
+  '3023': '手机验证码获取验证码次数过多,请明天再试',
+  '3024': '不能将场景协作给自己',
+  '6012': '相机未绑定用户',
+  '6013': '必须输入需迁相机所绑定用户的验证码',
+  '6014': '必须输入目标相机所绑定用户的验证码',
+  '6015': '该相机已添加协作者,请先取消协作后再添加',
+  '3025': '不能将相机分配给自己',
+
   '8001': '订单不存在',
   '8002': '支付失败',
   '5001': 'modeldata.json为空',

+ 5 - 1
mobile/src/store/language/en/manage.js

@@ -174,6 +174,7 @@ export default{
     partShipped: 'Partly dispatched',
     received: 'Received',
     hasCancal: 'Cancelled',
+    expire: 'Expired',
     edit: 'Edit',
     editInfo: 'Only within 7 days after delivery',
     dontneed: 'Invoice type: No invoice required',
@@ -203,7 +204,7 @@ export default{
       }
     ],
     placeholder: {
-      searchID: 'Search device S/N'
+      searchID: 'Search S/N or Tel No.'
     },
     storage: 'Storage: ',
     upgrade: 'Upgrade',
@@ -211,6 +212,9 @@ export default{
     capacity: 'Expand',
     unbind: 'Unbind',
     recharge: 'Top up',
+    fenpei: 'Invite collaborator',
+    qxfp: 'Cancel collaborator',
+    xiezuo: 'Collaborator:',
     expire: 'Expiry Date: ',
     expand: 'Package: ',
     jijiang: 'About to Expire',

+ 8 - 0
mobile/src/store/language/en/toast.js

@@ -88,6 +88,14 @@ export default{
   '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.',
 
+  '3023': 'The verification code has been obtained too many times, please try again tomorrow.',
+  '3024': 'Can’t assign scene to yourself.',
+  '6012': 'The camera has not bound to user.',
+  '6013': '必须输入需迁相机所绑定用户的验证码',
+  '6014': '必须输入目标相机所绑定用户的验证码',
+  '6015': 'Please cancel the collaborator first then to add another one.',
+  '3025': 'Can’t assign camera to yourself.',
+
   '8001': 'Order doesn\'t exist.',
   '8002': 'Payment failure',
   '5001': 'Empty modeldata.json',

+ 2 - 0
pc/src/components/citySelect/index.vue

@@ -63,6 +63,8 @@ export default {
   watch: {
     currentProv () {
       this.currentCID = 0
+    },
+    currentCID () {
       this.currentSID = 0
     }
   },

+ 122 - 14
pc/src/components/toast/cooperation.vue

@@ -4,17 +4,22 @@
     :style="{background:false?'none':'rgba(0, 0, 0, 0.3)'}"
     :class="{'toast-active':visible}"
   >
-    <div class="toast-con bind-con" :style="{minWidth:'505px'}">
+    <div class="toast-con bind-con" :style="{minWidth:'600px'}">
       <div class="t-header ">
         <span>{{lang==='en'?'Invite collaborator':'分配协作'}}</span>
         <i class="iconfont icon-cuowu" @click="handleClick"></i>
       </div>
-      <div class="binding-con" style="height:150px">
-        <div class="binding-body" style="width:450px;top:25px">
-          <div class="toclient">{{lang==='en'?'Add collaborator':'分配场景给用户'}}</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>
+
+          <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>
+          <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>
         </div>
       </div>
 
@@ -32,10 +37,13 @@ import toastZH from '@/store/language/cn/toast'
 import toastEN from '@/store/language/en/toast'
 
 export default {
-  props: ['sceneNum', 'visible'],
+  props: ['sceneNum', 'visible', 'cooType'],
   data () {
     return {
+      lock: true,
       userName: '',
+      selectAll: false,
+      auth: [],
       lang: localStorage.getItem('language'),
       toastCode: localStorage.getItem('language') === 'en' ? toastEN : toastZH
     }
@@ -44,15 +52,95 @@ export default {
 
   },
   watch: {
+    selectAll: function (newVal) {
+      if (!this.lock) {
+        this.auth.forEach(item => {
+          item.hasAuth = newVal
+        })
+      }
+    },
     visible: function (newVal) {
+      if (newVal) {
+        this.selectAll = true
+        this.getResoureList()
+        // this.getResoureByNum()
+      }
       this.userName = ''
       this.lang = localStorage.getItem('language')
       this.toastCode = this.lang === 'en' ? toastEN : toastZH
     }
   },
   methods: {
-    handleClick () {
-      this.$emit('closePoint')
+    selectItem (item, i) {
+      item.hasAuth = !item.hasAuth
+      this.$set(this.auth, i, item)
+      this.lock = true
+      this.selectAll = true
+
+      this.auth.forEach(sub => {
+        if (!sub.hasAuth) {
+          this.selectAll = false
+        }
+      })
+    },
+    handleClick (type = '') {
+      this.$emit('closePoint', type)
+    },
+    async getResoureByNum () {
+      let token = localStorage.getItem('token')
+      let url = this.cooType === 'scene' ? '/user/scene/cooperation/sceneResourceBySceneNum' : '/user/camera/sceneResourceByCameraId'
+      let params = this.cooType === 'scene' ? {
+        sceneNum: this.sceneNum
+      } : {
+        cameraId: this.sceneNum
+      }
+
+      let res = await this.$http({
+        method: 'post',
+        headers: {
+          token
+        },
+        data: params,
+        url: url
+      })
+
+      if (res.data.code !== 0) {
+        return
+      }
+      let data = res.data.data || []
+      setTimeout(() => {
+        let tmp = this.auth.map(item => {
+          item.hasAuth = true
+          data.forEach(sub => {
+            if (item.id === sub.id) {
+              item.hasAuth = true
+            } else {
+              item.hasAuth = false
+            }
+          })
+          return item
+        })
+        this.auth = tmp
+      })
+    },
+    async getResoureList () {
+      let token = localStorage.getItem('token')
+
+      let res = await this.$http({
+        method: 'post',
+        headers: {
+          token
+        },
+        url: '/user/scene/cooperation/sceneResourceList'
+      })
+      if (res.data.code !== 0) {
+        return this.handleClick()
+      }
+      let tmp = res.data.data.map(item => {
+        item.hasAuth = true
+        return item
+      })
+      this.auth = tmp
     },
     async addCooperation () {
       let token = localStorage.getItem('token')
@@ -60,24 +148,44 @@ export default {
       if (!this.userName) {
         return this.$toast.show('error', `${this.lang === 'en' ? 'Please enter user name.' : '请输入用户账号'}`)
       }
+      let resourceIds = []
+
+      this.auth.forEach(item => {
+        if (item.hasAuth) {
+          resourceIds.push(item.id)
+        }
+      })
+
+      if (resourceIds.length <= 0) {
+        return this.$toast.show('error', `${this.lang === 'en' ? 'Please select at least one.' : '请至少勾选一项权限'}`)
+      }
+
+      let url = this.cooType === 'scene' ? '/user/scene/cooperation/save' : '/user/camera/saveCooperationUser'
+      let params = {
+        userName: this.userName,
+        resourceIds: resourceIds.join(',')
+      }
+
+      this.cooType === 'scene' ? (params['sceneNum'] = this.sceneNum) : (params['cameraId'] = this.sceneNum)
 
       let result = await this.$http({
         method: 'post',
-        data: {
-          userName: this.userName,
-          sceneNum: this.sceneNum
-        },
+        data: params,
         headers: {
           token
         },
-        url: '/user/scene/cooperation/save'
+        url: url
       })
       let data = result.data
       if (data.code === 0) {
-        this.handleClick()
+        this.handleClick('getList')
         this.$toast.show('success', this.toastCode['44'])
+      } else if (data.code === 3004) {
+        this.handleClick()
       } else {
-        return this.$toast.show('warn', this.toastCode[data.code])
+        return this.$toast.show('warn', this.toastCode[data.code], () => {
+          return false
+        })
       }
     }
   }

+ 16 - 11
pc/src/components/toast/index.vue

@@ -5,24 +5,20 @@
     <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" :visible='cooperationVisible' @closePoint="()=>{cooperationVisible = false,emitCallback()}"/>
+    <cooperation :sceneNum="sceneNum" :cooType="cooType" :visible='cooperationVisible' @closePoint="handleCooClose"/>
 
     <div
       class="toast-layout"
-      :style="{background:isLoaing?'none':'rgba(0, 0, 0, 0.3)'}"
+      :style="{background:isLoaing?'none':'rgba(0, 0, 0, 0.3)',zIndex:988888988}"
       :class="{'toast-active':isLoaing}"
     >
       <div class="loading">
-        <svg viewBox="0 0 28 19">
-          <path
-            d="M4 0l3 3C5.151 4.589 4.141 6.938 4 9c.141 2.994 1.18 5.374 3 7l-3 3c-2.512-2.51-4-5.919-4-10 0-3.134 1.446-6.499 4-9zm20 0c2.554 2.501 4 5.866 4 9 0 4.081-1.488 7.49-4 10l-3-3c1.82-1.626 2.859-4.006 3-7-.141-2.062-1.151-4.411-3-6l3-3z"
-          ></path>
-        </svg>
+        <loading/>
       </div>
     </div>
     <div
       class="toast-layout"
-      :style="{background:isLoaing?'none':'rgba(0, 0, 0, 0.3)'}"
+      :style="{background:isLoaing?'none':'rgba(0, 0, 0, 0.3)',zIndex:998888988}"
       :class="{'toast-active':visible}"
     >
       <div class="toast-con" :style="{minWidth:toastType==='comfirm'?'403px':'403px'}">
@@ -59,6 +55,7 @@ import showInvoice from './showInvoice'
 import binding from './binding'
 import cooperation from './cooperation'
 import { mapState } from 'vuex'
+import loading from './loadingicon'
 
 let types = {
   warn: '提示',
@@ -72,12 +69,13 @@ let typesEn = {
   success: 'Success'
 }
 export default {
-  components: {pointRecharge, binding, cooperation, capacityRecharge, editInvoice, showInvoice},
+  components: {pointRecharge, binding, loading, cooperation, capacityRecharge, editInvoice, showInvoice},
   data () {
     return {
       visible: false,
       bindingType: 1,
       sceneNum: '',
+      cooType: '',
       capacitytype: '',
       capacityvisible: false,
       ponintVisible: false,
@@ -131,6 +129,10 @@ export default {
 
   },
   methods: {
+    handleCooClose (data) {
+      this.cooperationVisible = false
+      data === 'getList' && this.emitCooCallback()
+    },
     qixianHandle (data) {
       this.capacityitem.month = data
     },
@@ -158,10 +160,13 @@ export default {
       }
       this.ponintVisible = false
     },
-    emitCallback () {
-      this.callback()
+    emitCooCallback () {
       this.cooCallback && this.cooCallback()
       this.visible = false
+    },
+    emitCallback () {
+      this.callback && this.callback()
+      this.visible = false
     }
   }
 }

+ 32 - 0
pc/src/components/toast/loadingicon.vue

@@ -0,0 +1,32 @@
+<template>
+  <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+    viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
+  <g>
+    <circle class="st0" cx="32" cy="5" r="5"/>
+    <circle class="st1" cx="32" cy="59" r="5"/>
+    <circle class="st2" cx="18.5" cy="8.6" r="5"/>
+    <circle class="st3" cx="45.5" cy="55.4" r="5"/>
+    <circle class="st4" cx="8.6" cy="18.5" r="5"/>
+    <circle class="st5" cx="5" cy="32" r="5"/>
+    <circle cx="59" cy="32" r="5"/>
+    <circle class="st6" cx="8.6" cy="45.5" r="5"/>
+    <circle class="st7" cx="55.4" cy="18.5" r="5"/>
+    <circle class="st8" cx="18.5" cy="55.4" r="5"/>
+    <circle class="st9" cx="45.5" cy="8.6" r="5"/>
+  </g>
+  </svg>
+
+</template>
+
+<style lang="scss" scoped>
+.st0{opacity:0.73;}
+.st1{opacity:0.19;}
+.st2{opacity:0.64;}
+.st3{opacity:0.1;}
+.st4{opacity:0.55;}
+.st5{opacity:0.46;}
+.st6{opacity:0.37;}
+.st7{opacity:0.91;}
+.st8{opacity:0.28;}
+.st9{opacity:0.82;}
+</style>

+ 61 - 4
pc/src/components/toast/style.scss

@@ -4,6 +4,44 @@ $anima-time:0.2s;
 $anima-delay:0.15s;
 $border-color: #e7e7e7;
 
+.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: " ";
+  }
+}
 
 .btn {
   width: 88px;
@@ -42,10 +80,10 @@ $border-color: #e7e7e7;
       top: calc(50% - 14px);
       left: calc(50% - 14px);
       transform: translate(-50%, -50%);
-      height: 28px;
-      width: 28px;
-      max-height: 28px;
-      max-width: 28px;
+      height: 50px;
+      width: 50px;
+      max-height: 50px;
+      max-width: 50px;
       animation: rotateLoader 1s;
       animation-iteration-count: infinite;
     }
@@ -333,6 +371,25 @@ $border-color: #e7e7e7;
           line-height: 2;
         }
       }
+      .cooperation{
+        top: 0!important;
+        width: 550px;
+        .toclient{
+          margin-top: 15px;
+          margin-bottom: 7px;
+          display: flex;
+          justify-content: space-between;
+        }
+        .auth-list{
+          display: flex;
+          flex-wrap: wrap;
+          margin-left: 20px;
+          >li{
+            margin-bottom: 10px;
+            width: 25%;
+          }
+        }
+      }
       .binding-success{
         position: absolute;
         top: 50%;

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

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

+ 4 - 2
pc/src/page/layout/aside/temp/ctemp/detail.vue

@@ -399,10 +399,12 @@ export default {
         province,
         city,
         shipMobile,
-        shipName
+        shipName,
+        id: this.address.id
       }
+      let url = this.address.id ? 'updateAddress' : 'insertAddress'
       this.$http
-        .post('/user/updateAddress', params, {
+        .post(`/user/${url}`, params, {
           headers: {
             token: this.token
           }

+ 1 - 0
pc/src/page/layout/aside/temp/ltemp/style.scss

@@ -53,6 +53,7 @@ $lincolor:#d0d0d1;
   cursor: pointer;
   position: relative;
   top: -10px;
+  display: inline-block;
   &:hover{
     color: #1fe4dc;
   }

+ 3 - 0
pc/src/page/layout/footer.vue

@@ -48,6 +48,9 @@
           <p class="relevant-1">Copyright © 2020 4DAGE Co., Ltd. All rights reserved. </p>
           <p class="relevant-2"><a class="a_class">粤ICP备14078495号-3</a></p>
         </div>
+        <p>Copyright © 2020 4DAGE Co., Ltd. All rights reserved. </p>
+        <p><a class="a_class" href="http://www.beian.miit.gov.cn" target="_blank">粤ICP备14078495号-3</a></p>
+        <p>珠海市四维时代网络科技有限公司</p>
       </div>
     </div>
   </div>

+ 137 - 5
pc/src/page/manage/temp/device.vue

@@ -43,11 +43,20 @@
               </div>
               <p class="p-sub">{{langDevices.expand}}{{item.spaceStr||'--'}}</p>
               <p class="p-sub">{{langDevices.expire}}{{item.spaceEndStr||'--'}}</p>
+              <p class="p-sub" :title="item.cooperationUserName" v-if="item.cooperationUserName">{{langDevices.xiezuo}}{{item.cooperationUserName||'--'}}</p>
 
-              <div class="d-edit">
-                <router-link class="primary" :to="{name:'introduce',params:{id:item.childName}}"><span>{{langDevices.capacity}}</span></router-link>
-                <div>
-                  <span @click="unbind(item)">{{langDevices.unbind}}</span>
+              <div class="oper-con">
+                <div class="oper">
+                  <div>
+                    <span class="spot"></span>
+                  </div>
+                  <ul :style="{minWidth: language==='en'?'150px': '90px'}">
+                    <li @click="$router.push({name:'introduce',params:{id:item.childName}})">
+                      {{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>
+                  </ul>
                 </div>
               </div>
             </template>
@@ -131,6 +140,35 @@ export default {
     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'
+        })
+        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,
+          type: 'device'
+        }, () => {
+          this.getList()
+        })
+      }
+    },
     gotoScene (item) {
       this.$router.push({
         name: 'scene',
@@ -392,7 +430,7 @@ $font-color: #2d2d2d;
             border: 1px solid #777777;
             border-radius: 2px;
             font-size: 12px;
-            width: 52px;
+            width: 50px;
             height: 22px;
             line-height: 22px;
             text-align: center;
@@ -414,6 +452,100 @@ $font-color: #2d2d2d;
             border: 1px solid #1fe4dc;
           }
         }
+        .oper-con{
+          flex: 1;
+          .oper {
+            width: 26px;
+            cursor: pointer;
+            display: inline-block;
+            position: relative;
+            line-height: 30px;
+            height: 30px;
+            font-size: 14px;
+            &:hover{
+              >ul{
+                display: block;
+              }
+            }
+            >div {
+              text-align: right;
+              display: inline-block;
+              width: 100%;
+              .spot{
+                width: 4px;
+                height: 4px;
+                display: inline-block;
+                background-color: #202020;
+                border-radius: 50%;
+                position: relative;
+                margin-right: 10px;
+                &::after,&::before{
+                  content: '';
+                  position: absolute;
+                  width: 4px;
+                  height: 4px;
+                  display: inline-block;
+                  background-color: #202020;
+                  border-radius: 50%;
+                  left: -8px;
+                  top: 50%;
+                  transform: translateY(-50%);
+                }
+                &::before{
+                  right: -8px;
+                  left: unset;
+                }
+              }
+            }
+
+            >ul{
+              display: none;
+              position: absolute;
+              top: 30px;
+              z-index: 9;
+              left: 0;
+              background: #F7F7F7;
+              min-width: 90px;
+              box-shadow:0px 1px 6px rgba(0,0,0,0.16);
+              >li{
+                text-align: left;
+                width: 100%;
+                line-height: 2.5;
+                padding: 0 10px;
+                color: #202020;
+                &:hover{
+                  background-color: #EBEBEB;
+                }
+              }
+            }
+            .b_default{
+                display: inline-block;
+                background: #fff;
+                color: #000;
+                border: 1px solid #777;
+                border-radius: 2px;
+                font-size: 12px;
+                width: 52px;
+                height: 22px;
+                line-height: 22px;
+                text-align: center;
+                vertical-align: middle;
+                margin-left: 4px;
+                -webkit-box-sizing: border-box;
+                box-sizing: border-box;
+                cursor: pointer;
+                position: relative;
+                >span{
+                  position: absolute;
+                  top: 50%;
+                  left: 50%;
+                  -webkit-transform: translate(-50%,-50%);
+                  transform: translate(-50%,-50%);
+                  width: 100%;
+                }
+            }
+          }
+        }
         .dtow-edit{
           bottom: 40px;
         }

+ 3 - 2
pc/src/page/manage/temp/information.vue

@@ -381,10 +381,11 @@ export default {
         city,
         shipMobile,
         shipName,
-        id
+        id: this.address.id
       }
+      let url = this.address.id ? 'updateAddress' : 'insertAddress'
       this.$http
-        .post('/user/updateAddress', params, {
+        .post(`/user/${url}`, params, {
           headers: {
             token: this.token
           }

+ 12 - 6
pc/src/page/manage/temp/order.vue

@@ -53,16 +53,20 @@
             <template v-else-if="getStatus(item) === 'received'">
               <span class="expreeNum">{{langOrders.received}}:{{item.orderItems[0].expressNum}}</span>
             </template>
-
+            <template v-else-if="getStatus(item) === 'expire'">
+              <span class="expreeNum">{{langOrders.expire}}</span>
+            </template>
             <template v-else>
               <span class="expreeNum">{{langOrders.hasCancal}}</span>
             </template>
           </div>
           <div class="to-pay">
-            <span class="cancel btns" @click="changeIvoiceStatus(i,item)">{{langOrders.invoice}}</span>
-            <template v-if="getStatus(item) === 'unpaid'">
-              <span class="cancel btns" @click="cancal(item)">{{langOrders.cancal}}</span>
-              <span class="pay btns" @click="toPay(item)">{{langOrders.pay}}</span>
+            <template v-if="getStatus(item) !== 'expire'">
+              <span class="cancel btns" @click="changeIvoiceStatus(i,item)">{{langOrders.invoice}}</span>
+              <template v-if="getStatus(item) === 'unpaid'">
+                <span class="cancel btns" @click="cancal(item)">{{langOrders.cancal}}</span>
+                <span class="pay btns" @click="toPay(item)">{{langOrders.pay}}</span>
+              </template>
             </template>
           </div>
         </div>
@@ -252,7 +256,9 @@ export default {
         case 'processed':
           sPay()
           break
-
+        case 'expire':
+          temp = 'expire'
+          break
         default:
           break
       }

+ 25 - 5
pc/src/page/manage/temp/scene.vue

@@ -1,11 +1,17 @@
 <template>
   <div class="scene-layout">
     <div class="d-header">
-        <ul class="tab-list">
+        <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}}
           </li>
         </ul>
+
+        <ul class="tab-list" v-else>
+          <li class="active" v-for="(item,i) in [langScenes.tabList[0]]" :key="i">
+            {{item.name}}
+          </li>
+        </ul>
       <div class="tab-search">
         <input
           v-model="searchKey"
@@ -22,7 +28,7 @@
         <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">
             <div class="share-btn" v-if="((item.status === 1||item.status===-2)&&item.payStatus !== -2)" @click.stop="handleShare(item)"></div>
-            <div class="cooperation" v-if="item.cooperationUserName"><i class="iconfont icon-case_teamwork"></i><span>{{langScenes.user}}: {{item.cooperationUserName}}</span></div>
+            <div class="cooperation" v-if="item.cooperationUserName&&!deviceLogin"><i class="iconfont icon-case_teamwork"></i><span>{{langScenes.user}}: {{item.cooperationUserName}}</span></div>
             <div class="card-img" :style="{backgroundImage: `url(${getSceneImg(item)})`}"></div>
             <div class="loading-hover" v-if="item.status === 0">
               <div class="loading-icon">
@@ -46,7 +52,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">{{item.cooperationUserId?langScenes.qxfp:langScenes.fenpei}}</li>
+                  <li @click="handleCooperation(item)" v-if="(item.status === 1||item.status===-2)&&!deviceLogin">{{item.cooperationUserId?langScenes.qxfp:langScenes.fenpei}}</li>
                   <li v-if="item.status !== 0" @click="del(item)">{{langScenes.delete}}</li>
                 </ul>
               </template>
@@ -89,7 +95,10 @@
         <div class="t-con">
           <p class="t-label">{{langScenes.share.website}}</p>
           <input type="text" v-model="url">
-          <div class="btn-copy" @click="copyTextToClipboard(url)" >{{langScenes.share.copy}}</div>
+          <div class="copy-con">
+            <div class="btn-copy" @click="copyTextToClipboard(url)" >{{langScenes.share.copy1}}</div>
+            <div class="btn-copy" @click="copyTextToClipboard(num)" >{{langScenes.share.copy2}}</div>
+          </div>
           <div class="t-label">{{langScenes.share.shareto}}</div>
           <div class="img-share" v-for="(item,i) in imgs" :key="i">
             <div v-if="item.id === 0" class="trangle"></div>
@@ -253,7 +262,10 @@ export default {
           return this.$toast.show('warn', this.langToast[data.code], () => {})
         }
       } else {
-        this.$toast.showCooperation(item.num, () => {
+        this.$toast.showCooperation({
+          num: item.num,
+          type: 'scene'
+        }, () => {
           this.getList()
         })
       }
@@ -836,6 +848,14 @@ $font-color: #2d2d2d;
             height: 32px;
           }
         }
+        .copy-con{
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          .btn-copy{
+            width: 49%;
+          }
+        }
         .btn-copy{
           text-align: center;
           background: #ddd;

+ 7 - 1
pc/src/store/language/cn/manage.js

@@ -137,6 +137,8 @@ export default{
       height: '高:',
       defaultSize: '(默认窗口尺寸:853 X 480px)',
       copy: '复制',
+      copy1: '复制场景链接',
+      copy2: '复制场景码',
       sub: '将嵌入代码粘贴至HTML编辑器中,就像嵌入网络视频一样简单。您也可以将以上代码发送给您的网络管理员,并要求他们将其放置在网页指定位置上。',
       sub2: '*该功能有效期与您的容量使用情况有关,有可能因未续费容量而导致失效。',
       copysuccess: '复制成功',
@@ -166,6 +168,7 @@ export default{
     partShipped: '部分发货',
     received: '已收货',
     hasCancal: '已取消',
+    expire: '已失效',
     edit: '修改(发货后7天内可修改)',
     dontneed: '发票类型:不需要发票',
     type1: '不需要发票',
@@ -194,16 +197,19 @@ export default{
       }
     ],
     placeholder: {
-      searchID: '搜索设备S/N'
+      searchID: '搜索设备S/N或协作者手机'
     },
     storage: '云容量:',
     renew: '续费',
     upgrade: '升级',
     capacity: '扩容',
     unbind: '解绑',
+    fenpei: '分配协作',
+    qxfp: '取消协作',
     recharge: '充值',
     expire: '到期:',
     expand: '套餐:',
+    xiezuo: '协作:',
     jijiang: '即将到期',
     rongliang: '容量已满',
     norecord: '暂无任何记录'

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

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

+ 7 - 1
pc/src/store/language/en/manage.js

@@ -138,6 +138,8 @@ export default{
       height: 'Height: ',
       defaultSize: '(Default window size: 853 X 480px)',
       copy: 'Copy',
+      copy1: 'Copy scene link',
+      copy2: 'Copy scene code',
       sub: 'Pasting the embed code into an HTML editor is as easy as embedding a web video. You can also send the above code to your network administrator and ask him to place it in the designated location on the web page.',
       sub2: '* The validity period of this function is related to your storage usage. It may be invalid because the capacity is not renewed.',
       copysuccess: 'Success',
@@ -167,6 +169,7 @@ export default{
     partShipped: 'Partly dispatched',
     received: 'Received',
     hasCancal: 'Cancelled',
+    expire: 'Expired',
     edit: 'Edit (Only within 7 days after delivery)',
     dontneed: 'Invoice type: No invoice required',
     type1: 'No invoice required',
@@ -195,16 +198,19 @@ export default{
       }
     ],
     placeholder: {
-      searchID: 'Search device S/N'
+      searchID: 'Search S/N or Tel No.'
     },
     storage: 'Storage: ',
     upgrade: 'Upgrade',
     renew: 'Renew',
     capacity: 'Expand',
     unbind: 'Unbind',
+    fenpei: 'Invite collaborator',
+    qxfp: 'Cancel collaborator',
     recharge: 'Top up',
     expire: 'Expiry on: ',
     expand: 'Package: ',
+    xiezuo: 'Collaborator:',
     jijiang: 'About to Expire',
     rongliang: 'Storage Full',
     norecord: 'No Records'

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

@@ -80,6 +80,15 @@ 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.',
+
+  '3023': 'The verification code has been obtained too many times, please try again tomorrow.',
+  '3024': 'Can’t assign scene to yourself.',
+  '6012': 'The camera has not bound to user.',
+  '6013': '必须输入需迁相机所绑定用户的验证码',
+  '6014': '必须输入目标相机所绑定用户的验证码',
+  '6015': 'Please cancel the collaborator first then to add another one.',
+  '3025': 'Can’t assign camera to yourself.',
+
   '8001': 'Order doesn\'t exist.',
   '8002': 'Payment failure',
   '5001': 'Empty modeldata.json',

+ 1 - 0
pc/src/util/http.js

@@ -46,6 +46,7 @@ axios.interceptors.request.use(function (config) {
     }
   }
   // vue.$toast.showLoading()
+  vue.$toast.showLoading()
   return config
 }, function (error) {
   // 对请求错误做些什么