From ecb6cadc3f016cf9968f48e0cc77479a1e56365b Mon Sep 17 00:00:00 2001
From: hanbaoshan <hanbaoshan@aiotlink.com>
Date: 星期日, 20 十二月 2020 17:32:06 +0800
Subject: [PATCH] 标定添加关联摄像机tab,绘制区域组件参数更新

---
 src/pages/labelMark-copy/index/App.vue                 |  118 ++
 src/components/canvas/Dialog.vue                       |   26 
 src/pages/desktop/index/components/ToolsEntry.vue      |   16 
 src/pages/labelMark/index/main.ts                      |    3 
 src/components/canvas/index.vue                        |   18 
 src/pages/labelMark-copy/index/main.ts                 |   17 
 src/pages/cameraAccess/components/scene/SlideScene.vue |   22 
 src/pages/labelMark-copy/components/RightSide.vue      |  986 +++++++++++++++++
 src/scripts/util.js                                    |   19 
 src/api/camera.ts                                      |   27 
 src/pages/labelMark/components/RightSide.vue           |  831 ++++++++++++--
 src/pages/labelMark/components/SlideCanvas.vue         |  222 +++
 src/api/polygon.ts                                     |   31 
 src/pages/labelMark/components/RightSide-COPY.vue      |  862 ++++++++++++++
 src/pages/labelMark/index/App.vue                      |   10 
 src/pages/labelMark-copy/index/mixins.ts               |   14 
 src/pages/labelMark-copy/components/SlideCanvas.vue    |  225 +++
 17 files changed, 3,275 insertions(+), 172 deletions(-)

diff --git a/src/api/camera.ts b/src/api/camera.ts
index 4705f56..e830ecf 100644
--- a/src/api/camera.ts
+++ b/src/api/camera.ts
@@ -189,4 +189,29 @@
     method: 'post',
     data
   })
-}
\ No newline at end of file
+}
+
+//淇濆瓨鎽勫儚鏈哄垎缁�
+export const saveCameraGroupInfo = (data:any) => {
+  return request({
+    url: '/data/api-v/camera/group/save',
+    method: 'post',
+    data
+  })
+}
+
+//鏌ヨ鎽勫儚鏈哄垎缁勪俊鎭�
+export const findCameraGroups = () => {
+  return request({
+    url: '/data/api-v/camera/group/findAll',
+    method: 'get'
+  })
+}
+
+export const delCameraGroup = (groupId:string)=>{
+  return request({
+    url:'/data/api-v/camera/group/del?groupId='+groupId,
+    method: 'post'
+  })
+}
+
diff --git a/src/api/polygon.ts b/src/api/polygon.ts
index cfa4bf9..c7d1202 100644
--- a/src/api/polygon.ts
+++ b/src/api/polygon.ts
@@ -23,3 +23,34 @@
     data: params
   });
 };
+
+export const findByCamGroup = (query: any) => {
+  return request({
+    url:'/data/api-v/polygon/findByCamGroup',
+    method: 'get',
+    params: query
+  });
+}
+
+export const saveRelationPolygon = (data: any) => {
+  return request({
+    url: "/data/api-v/polygon/relation/save",
+    method: "post",
+    data
+  });
+}
+
+export const findByGroup = (query:any) =>{
+  return request({
+    url:"/data/api-v/polygon/relation/findByGroup",
+    method: "get",
+    params: query
+  })
+}
+
+export const delRelation = (id:string) => {
+  return request({
+    url: "/data/api-v/polygon/relation/del?id="+id,
+    method: "post"
+  })
+}
\ No newline at end of file
diff --git a/src/components/canvas/Dialog.vue b/src/components/canvas/Dialog.vue
index e0f11e1..da99d2b 100644
--- a/src/components/canvas/Dialog.vue
+++ b/src/components/canvas/Dialog.vue
@@ -198,7 +198,8 @@
   methods: {
     // 鍒濆鍖栧嚱鏁�
     init() {
-      this.c = document.querySelector("#canvasDialog");
+      //this.c = document.querySelector("#canvasDialog");
+      this.c = this.$refs['canvasDialog'];
       this.ctx = this.c.getContext("2d");
       this.drawCanvasInit();
       this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
@@ -394,7 +395,6 @@
     },
     // 鍒犻櫎鍏冪礌
     del() {
-      debugger
       let delEle = {};
       switch (this.delCursor.type) {
         case "1":
@@ -411,7 +411,7 @@
           break;
         case "5":
           delEle = this.canvasData.polygon[this.delCursor.index];
-          this.canvasData.polygon.splice(this.delCursor.index+1, 1);
+          this.canvasData.polygon.splice(this.delCursor.index, 1);
           break;
       }
       this.clickSelect();
@@ -522,6 +522,7 @@
         }
       });
       _this.canvasData.rect.forEach(function (v, i) {
+        
         _this.ctx.strokeStyle = "yellow";
         _this.ctx.beginPath();
         _this.ctx.moveTo(v.location[0].x, v.location[0].y);
@@ -788,6 +789,7 @@
       // console.log("鎾ら攢锛�",this.canvasData);
     },
     disabledOthers(type) {
+      
       console.log("褰撳墠type:", type)
       switch (type) {
         case "1":
@@ -825,6 +827,7 @@
       console.log("绂佺敤澶氳竟褰細", this.disablePolygon)
     },
     undisabled() {
+      
       this.disableLine = false
       this.disableRect = false
       this.disableArrow = false
@@ -854,7 +857,7 @@
       width = typeof width !== "undefined" ? width : 1;
       // color = typeof color !== 'undefined' ? color : 'yellow'
       // 璁$畻鍚勮搴﹀拰瀵瑰簲鐨凱2,P3鍧愭爣
-      debugger
+      
       let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
       let angle1 = ((angle + theta) * Math.PI) / 180;
       let angle2 = ((angle - theta) * Math.PI) / 180;
@@ -884,6 +887,7 @@
     },
     // 鑾峰彇鐩稿鍧愭爣(鏆備笉鐢�)
     getLocation(x, y, c) {
+      
       let bbox = c.getBoundingClientRect();
       return {
         x: (x - bbox.left) * (c.width / bbox.width),
@@ -898,6 +902,7 @@
     },
     // 鐢熸垚鍥惧舰澶囨敞
     remarks(x, y, type) {
+      
       this.ctx.moveTo(x, y - 20);
       this.ctx.fillStyle = "green"; // 璁剧疆濉厖棰滆壊涓虹豢鑹�
       this.ctx.font = '20px "寰蒋闆呴粦"'; // 璁剧疆瀛椾綋
@@ -927,6 +932,7 @@
     },
     // 鍥炴樉鍥惧舰澶囨敞
     showRemarks(x, y, remarks, isHightlight) {
+      
       this.ctx.moveTo(x, y - 20);
       if (isHightlight) {
         this.ctx.fillStyle = "#8ae22e"; // 璁剧疆濉厖棰滆壊涓虹豢鑹�
@@ -940,6 +946,7 @@
     },
     // 閲嶇幇淇濆瓨鐢婚潰
     loadImage() {
+      
       if (this.step > -1) {
         let img = new Image();
         img.src = this.canvasHistory[this.step].src;
@@ -948,6 +955,7 @@
     },
     // 鍒囨崲鐢荤嚎绫诲瀷
     changeType(num) {
+      
       if (num === '0') {
         this.c.style.cursor = "pointer";
       } else {
@@ -957,6 +965,7 @@
     },
     // 缁樺埗澶氳竟褰㈡柟娉�
     drawPolygonUtil(points) {
+      
       this.ctx.strokeStyle = "yellow";
       this.ctx.lineWidth = 2;
       this.ctx.beginPath();
@@ -983,6 +992,7 @@
     },
     // 鐢荤煩褰㈢Щ鍔ㄥ嚱鏁�
     drawRect(e) {
+      
       if (this.flag) {
         this.ctx.clearRect(0, 0, this.c.width, this.c.height);
         this.loadImage();
@@ -1017,11 +1027,13 @@
       }
     },
     twoPointDistance(p1, p2) {
+      
       let dep = Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2));
       return dep;
     },
     // 鐢诲杈瑰舰绉诲姩鍑芥暟
     drawPolygon(e) {
+      
       if (this.flag) {
         this.ctx.clearRect(0, 0, this.c.width, this.c.height);
         this.loadImage();
@@ -1040,6 +1052,7 @@
     },
     // 鐢荤洿绾挎姮璧�
     lineMouseUp(e) {
+      
       if (
         Math.abs(this.originX - e.offsetX) < 5 &&
         Math.abs(this.originY - e.offsetY) < 5
@@ -1096,6 +1109,7 @@
     },
     // 鐢荤煩褰㈡姮璧�
     rectMouseUp(e) {
+      
       if (
         Math.abs(this.originX - e.offsetX) < 5 &&
         Math.abs(this.originY - e.offsetY) < 5
@@ -1218,6 +1232,7 @@
     },
     // 鐢诲杈瑰舰缁撴潫鏃跺弻鍑�
     polygonDblclick(e) {
+      
       this.flag = false;
       this.points.pop(); // 鍙屽嚮涔嬪悗澶氫竴涓偣鐨勯噸澶嶅潗鏍囷紝闇�瑕佸垹闄�
       let Id
@@ -1265,6 +1280,7 @@
     },
     // 閲婃斁缂栬緫鐘舵��
     freedEdit() {
+      
       this.editObj = {}
     },
     // 鍥炴樉鍘嗗彶鏁版嵁鏃惰绠椾竴涓嬪洖鏄剧殑姣忕鍏冪礌鐨勬暟閲忎互渚跨敓鎴愬浘褰㈡敞瑙f椂鑾峰緱姝g‘鐨勫紑澶�
@@ -1279,6 +1295,7 @@
     },
     // 鐢熸垚uuid
     getUuid() {
+      
       let originStr = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
       let originChar = "0123456789abcdef";
       let len = originChar.length;
@@ -1288,6 +1305,7 @@
     },
     // 鍒ゆ柇涓�涓偣鏄惁绂讳竴涓浘褰㈢殑鏈�灏忚窛绂讳负n鍍忕礌浠ュ唴
     minDistance(x, y, locations, n) {
+      
       let flag = false
       for (let i = 0; i < locations.length; i++) {
         if (i == locations.length - 1) {
diff --git a/src/components/canvas/index.vue b/src/components/canvas/index.vue
index c26ef7b..a7dae5a 100644
--- a/src/components/canvas/index.vue
+++ b/src/components/canvas/index.vue
@@ -1,10 +1,10 @@
 <template>
-  <div class="s-cavas">
+  <div class="s-cavas" :style="{width:canvasWidth+'px',height:canvasHeight+'px'}">
     <canvas
       ref="myCanvas"
       :width="canvasWidth"
       :height="canvasHeight"
-      :style="`background:url(${canvasBg}) center / 576px 324px no-repeat; background-size: contain;`"
+      :style="`background:url(${canvasBg}) center / ${canvasWidth}px ${canvasHeight}px no-repeat; background-size: contain;`"
     ></canvas>
 
     <el-tooltip content="鍒锋柊搴曞浘" placement="bottom" popper-class="atooltip" v-if="isShowRefresh">
@@ -93,6 +93,10 @@
     canvasHeight: {
       type: Number,
       default: 324
+    },
+    showProportion: {
+      type: Number,
+      default: 1.666
     }
   },
   computed: {
@@ -124,7 +128,7 @@
       ctx: null,
       visible: false,
       baseImg: undefined,
-      showProportion: 1.666
+      //showProportion: 1.666
     };
   },
   watch: {
@@ -193,10 +197,11 @@
       this.$nextTick(() => {
         // this.$refs.bigCanvas.delCursor = {}
       })
+      
     },
     cancelFunc() {
       this.visible = false;
-      this.$refs.bigCanvas.cancel()
+      this.$refs.bigCanvas.cancel();
       // console.log("鍏抽棴浜�");
     },
     handleOk() {
@@ -220,6 +225,7 @@
       // 椤轰究鐢╁埌鏇村灞傚幓
       this.$emit("fromCanvas", this.$refs.bigCanvas.canvasData);
       // console.log("浣犲ソ", this.canvasData);
+
       this.clickSelect(this.canvasData);
       this.visible = false;
     },
@@ -501,8 +507,8 @@
   left: 0;
 }
 .s-cavas {
-  width: 576px;
-  height: 324px;
+  // width: 576px;
+  // height: 324px;
   margin-top: 10px;
   position: relative;
   overflow: auto;
diff --git a/src/pages/cameraAccess/components/scene/SlideScene.vue b/src/pages/cameraAccess/components/scene/SlideScene.vue
index 4bf640f..ee755f0 100644
--- a/src/pages/cameraAccess/components/scene/SlideScene.vue
+++ b/src/pages/cameraAccess/components/scene/SlideScene.vue
@@ -79,6 +79,7 @@
 </template>
 
 <script>
+import {chunkArr} from '@/scripts/util';
 export default {
   props: [
     // 'swiperOption',
@@ -130,27 +131,10 @@
     // this.mySwiper = this.$refs.sceneSwiper.swiper;
 
   },
-  methods: {
-    //鎷嗗垎浜岀淮鏁扮粍
-    chunk(arr, size = 1) {
-      if (arr.length == 0) return;
-      const tempContainer = [];
-      let innerArr = [];
-      arr.forEach(item => {
-        if (innerArr.length == 0) {
-          tempContainer.push(innerArr);
-        }
-        innerArr.push(item);
-        if (innerArr.length == size) {
-          innerArr = [];
-        }
-      });
-      return tempContainer;
-    }
-  },
+
   computed: {
     slides() {
-      return this.chunk(this.mockSceneData, 5);
+      return chunkArr(this.mockSceneData, 5);
     }
   }
 };
diff --git a/src/pages/desktop/index/components/ToolsEntry.vue b/src/pages/desktop/index/components/ToolsEntry.vue
index cbc5e4f..6d329c8 100644
--- a/src/pages/desktop/index/components/ToolsEntry.vue
+++ b/src/pages/desktop/index/components/ToolsEntry.vue
@@ -64,6 +64,7 @@
 <script>
 import draggable from "vuedraggable"
 import { findAllSdk } from '@/api/taskMange';
+import {chunkArr} from '@/scripts/util';
 export default {
   name: 'toolsEntry',
   components: { draggable },
@@ -84,7 +85,7 @@
           title: '浜哄憳璺熻釜'
         }
       ],
-      rowSize: 3,
+      //rowSize: 3,
       badgeNum: 0,
     }
   },
@@ -100,14 +101,23 @@
       let arr = null;
       //鏍规嵁灞忓箷楂樺害鏉ュ垽鏂槸灞曠ず3鎺掕繕鏄�4鎺� 闃堝��:970
       if (window.innerHeight >= 930) {
-        this.rowSize = 4;
+        //this.rowSize = 4;
         arr = this.chunk(tempArr, 24);
+        //arr = chunkArr(tempArr,24);
       } else {
-        this.rowSize = 3;
+        //this.rowSize = 3;
         arr = this.chunk(tempArr, 18);
+        //arr = chunkArr(tempArr, 18);
       }
       console.log(arr)
       return arr
+    },
+    rowSize (){
+      if (window.innerHeight >= 930) {
+        return 4;
+      }else{
+        return 3;
+      }
     }
   },
   mounted () {
diff --git a/src/pages/labelMark-copy/components/RightSide.vue b/src/pages/labelMark-copy/components/RightSide.vue
new file mode 100644
index 0000000..a6a86c1
--- /dev/null
+++ b/src/pages/labelMark-copy/components/RightSide.vue
@@ -0,0 +1,986 @@
+<template>
+  <div class="right-side">
+    
+    <div class="figure s-system-manage">
+      <el-tabs
+        id="e-basic-setting"
+        @tab-click="changeTab"
+        v-model="actPage"
+        v-loading="loading"
+        element-loading-text="鍔犺浇涓�"
+        type="border-card"
+      >
+        <el-tab-pane label="浣嶇疆鏍囨敞" name="1">
+          <el-tabs type="border-card">
+            <el-tab-pane label="鎽勫儚鏈烘爣娉�" name="11">
+              <div class>
+                <div class="action-bar">
+                  <div class="tool-bar">
+                    <div>
+                      <!-- <input type="color" ref="colorPicker" v-model="color"> -->
+                      <label for>鎷捐壊鍣�:</label>
+                      <el-color-picker v-model="colorPick" show-alpha size="mini"></el-color-picker>
+                    </div>
+                    <div style="width:250px;">
+                      <label for>绗旇Е:</label>
+                      <el-slider v-model="dotSize" :min="1" :max="20"></el-slider>
+                    </div>
+                    <div>
+                      <el-button
+                        v-if="!isEdit"
+                        class="drawboard-trigger"
+                        size="small"
+                        @click="editCameraData"
+                        icon="el-icon-edit"
+                      >缂栬緫</el-button>
+
+                      <el-button
+                        v-if="isEdit"
+                        class="drawboard-trigger save"
+                        size="small"
+                        @click="submitInfo"
+                        icon="el-icon-lock"
+                      >淇濆瓨</el-button>
+                    </div>
+                  </div>
+                </div>
+                <div class="drawboard shadow-box">
+                  <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard">
+                    <div
+                      class="label"
+                      @click="editLabel(item)"
+                      v-for="(item,index) in curCameraData.coords"
+                      :key="index"
+                      :style="{left:`${item.x0}px`, top:`${item.y0}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"
+                    ></div>
+                  </div>
+                  <img v-show="snapshot_url" :src="`/httpImage/${snapshot_url}`" alt />
+                  <div
+                    class="popBox"
+                    v-show="isShowPop"
+                    :style="`top:${curLabel.y0 + 22}px;left:${curLabel.x0}px`"
+                  >
+                    <div class="title">鏍囨敞淇℃伅</div>
+                    <div class="details">
+                      <el-form :model="curLabel" :rules="rules" ref="labelForm">
+                        <div class="detail-item">
+                          <div class="left">
+                            <el-form-item prop="x0">
+                              <label for>骞抽潰鍧愭爣X:</label>
+                              <span class="fix-width">{{curLabel.x0}}</span>
+                              <i>px</i>
+                            </el-form-item>
+                          </div>
+                          <span class="devide"></span>
+                          <div class="right">
+                            <el-form-item prop="x1">
+                              <label for>瀹為檯鍧愭爣X:</label>
+                              <el-input
+                                type="text"
+                                size="mini"
+                                style="width:90px"
+                                v-model.number="curLabel.x1"
+                              ></el-input>
+                            </el-form-item>
+                          </div>
+                        </div>
+                        <div class="detail-item">
+                          <div class="left">
+                            <el-form-item prop="y0">
+                              <label for>骞抽潰鍧愭爣Y:</label>
+                              <span class="fix-width">{{curLabel.y0}}</span>
+                              <i>px</i>
+                            </el-form-item>
+                          </div>
+                          <span class="devide"></span>
+                          <div class="right">
+                            <el-form-item prop="y1">
+                              <label for>瀹為檯鍧愭爣Y:</label>
+                              <el-input
+                                type="text"
+                                size="mini"
+                                style="width:90px"
+                                v-model.number="curLabel.y1"
+                              ></el-input>
+                            </el-form-item>
+                          </div>
+                        </div>
+                        <div class="btns">
+                          <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
+                          <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
+                          <el-button size="mini" type="success" @click="sure">纭畾</el-button>
+                        </div>
+                      </el-form>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </el-tab-pane>
+            <el-tab-pane label="瀹炴櫙鍧愭爣" name="12">
+              <div class="user-upload">
+                <div class="img-card">
+                  <el-upload
+                    class="upload-demo"
+                    drag
+                    action="https://jsonplaceholder.typicode.com/posts/"
+                    :http-request="definedUpload"
+                    :on-change="onChange"
+                    :show-file-list="false"
+                  >
+                    <el-image
+                      class="preview"
+                      v-if="userImg"
+                      :src="userImg"
+                      fit="contain"
+                      @mousemove="showCurPos"
+                      @mouseout="isShowCurPos=false"
+                    ></el-image>
+                    <div class="el-upload__text">
+                      灏嗘枃浠舵嫋鍒版澶勶紝鎴�
+                      <em>鐐瑰嚮涓婁紶</em>
+                    </div>
+                  </el-upload>
+                </div>
+                <div class="info">
+                  <div class="input-area">
+                    <div>
+                      <label for>绌洪棿瀹�:</label>
+                      <el-input v-model="spaceWidth" placeholder="璇疯緭鍏ュ疄闄呯┖闂村" size="small"></el-input>
+                    </div>
+                    <div>
+                      <label for>绌洪棿楂�:</label>
+                      <el-input v-model="spaceHeight" placeholder="璇疯緭鍏ュ疄闄呯┖闂撮珮" size="small"></el-input>
+                    </div>
+                  </div>
+                  <div class="pos" v-show="isShowCurPos">
+                    褰撳墠浣嶇疆:
+                    <b>{{traceX}}</b>,
+                    <b>{{traceY}}</b>
+                  </div>
+                </div>
+              </div>
+            </el-tab-pane>
+          </el-tabs>
+        </el-tab-pane>
+        <el-tab-pane label="杞ㄨ抗鍥�" name="2"></el-tab-pane>
+        <!-- <el-tab-pane label="杩借釜瀹炴櫙鍧愭爣" name="2">
+          <div class="user-upload">
+            <div class="img-card">
+              <el-upload
+                class="upload-demo"
+                drag
+                action="https://jsonplaceholder.typicode.com/posts/"
+                :http-request="definedUpload"
+                :on-change="onChange"
+                :show-file-list="false"
+              >
+                <el-image
+                  class="preview"
+                  v-if="userImg"
+                  :src="userImg"
+                  fit="contain"
+                  @mousemove="showCurPos"
+                  @mouseout="isShowCurPos=false"
+                ></el-image>
+                <div class="el-upload__text">
+                  灏嗘枃浠舵嫋鍒版澶勶紝鎴�
+                  <em>鐐瑰嚮涓婁紶</em>
+                </div>
+              </el-upload>
+            </div>
+            <div class="info">
+              <div class="input-area">
+                <div>
+                  <label for>绌洪棿瀹�:</label>
+                  <el-input v-model="spaceWidth" placeholder="璇疯緭鍏ュ疄闄呯┖闂村" size="small"></el-input>
+                </div>
+                <div>
+                  <label for>绌洪棿楂�:</label>
+                  <el-input v-model="spaceHeight" placeholder="璇疯緭鍏ュ疄闄呯┖闂撮珮" size="small"></el-input>
+                </div>
+              </div>
+              <div class="pos" v-show="isShowCurPos">
+                褰撳墠浣嶇疆:
+                <b>{{traceX}}</b>,
+                <b>{{traceY}}</b>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>-->
+        <el-tab-pane label="鍏宠仈鎽勫儚鏈�" name="3">
+          <div class="tab-relation">
+            <div class="part">
+              <div class="title">
+                <span>鍏宠仈璁惧鍒嗙粍</span>
+                <el-button @click="newGroup" icon="el-icon-plus" size="mini" type="primary">鏂板缓鍒嗙粍</el-button>
+              </div>
+              <el-alert
+                type="info"
+                title="鎻愮ず:璇风偣鍑讳笂鏂�'鏂板缓鍒嗙粍'鎸夐挳寤虹珛鍒嗙粍"
+                show-icon
+                v-if="groupList.length==0"
+              ></el-alert>
+              <div class="flex-box">
+                <div
+                  class="group-card"
+                  v-for="(group,index) in groupList"
+                  :key="index"
+                  @click="checkCurrentGroup(group)"
+                >
+                  <div class="top">
+                    <div class="left">
+                      <span class="icon el-icon-video-camera"></span>
+                    </div>
+                    <div class="right">
+                      <div class="name">{{group.name}}</div>
+                      <div class="details">
+                        鎽勫儚鏈�:
+                        <span
+                          class="sub"
+                          v-for="camera in group"
+                          :key="camera.id"
+                        >{{camera.name}}</span>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="bottom">
+                    <span @click.stop="editGroup(group)">缂栬緫鍒嗙粍</span>
+                    <span @click.stop="removeGroup(group)">鍒犻櫎鍒嗙粍</span>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <!-- <div class="part" v-if="groupList.length"> -->
+            <div class="part" v-if="Object.keys(curGroup)">
+              <div class="title">缁樺埗鍖哄煙(鐢ㄤ簬绠楁硶鍒嗘瀽)</div>
+              <div class="relative-partment" v-if="curGroup.cameras&&curGroup.cameras.length">
+                <div class="area-wrap" v-for="i in 2" :key="'sc'+i">
+                  <slide-canvas :cameras="curGroup.cameras"></slide-canvas>
+                </div>
+              </div>
+            </div>
+            <div class="part relative-config" v-if="Object.keys(curGroup)">
+              <div class="title">
+                <div class="left">
+                  <span>鍏宠仈鍖哄煙閰嶇疆</span>
+                </div>
+                <div class="right">
+                  <el-button
+                    icon="el-icon-plus"
+                    size="mini"
+                    type="primary"
+                    @click="addRelation"
+                  >娣诲姞鍏宠仈</el-button>
+                </div>
+              </div>
+              <div class="relative-list">
+                <div class="relative-item" v-for="(item,index) in relativeList" :key="index">
+                  <div class="left">
+                    <el-select v-model="item.cameraArea1" size="small">
+                      <el-option></el-option>
+                    </el-select>
+                    <i class="el-icon-connection"></i>
+                    <el-select v-model="item.cameraArea2" size="small">
+                      <el-option></el-option>
+                    </el-select>
+                  </div>
+                  <div class="right">
+                    <div class="btn-del" @click="delRelation(item)">
+                      <i class="el-icon-delete"></i>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+      <el-dialog class="dialog-group" title="鏂板缓鍒嗙粍" :visible.sync="groupModelVisible">
+        <el-form :model="groupForm" ref="groupForm">
+          <el-form-item>
+            <label>鍒嗙粍鍚嶇О</label>
+            <div>
+              <el-input v-model="groupForm.name"></el-input>
+            </div>
+          </el-form-item>
+          <el-form-item>
+            <label>閫夋嫨鎽勫儚鏈�</label>
+            <div>
+              <el-select v-model="groupForm.cameras" value-key="id" multiple>
+                <el-option
+                  :label="camera.name"
+                  :value="camera"
+                  v-for="camera in cameraData"
+                  :key="camera.id"
+                ></el-option>
+              </el-select>
+            </div>
+          </el-form-item>
+          <div class="btns">
+            <el-button @click="groupModelVisible=false;">鍙栨秷</el-button>
+            <el-button type="primary" @click="confirmGroupDialog">纭畾</el-button>
+          </div>
+        </el-form>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getCamerasByServer } from '@/api/pollConfig';
+import { getCameraMarks, updateCameraMarks } from '@/api/camera';
+import { getSearchList } from '@/api/search';
+import TreeDataPool from "@/Pool/TreeData";
+import { isNonnegativeInteger } from '@/scripts/validate';
+import { getAllPolygon } from '@/api/polygon';
+import SlideCanvas from './SlideCanvas';
+
+export default {
+  components: { SlideCanvas },
+  data () {
+    return {
+      labels: [],
+      colorPick: '#79f2fb',
+      dotSize: 3,
+      isEdit: false,
+      isShowPop: false,
+      isNewLabel: false,
+      // curLabel: {
+      //   id: '',
+      //   posX: '',
+      //   posY: '',
+      //   x: '',
+      //   y: ''
+      // },
+      curLabel: {
+        id: '',
+        x1: '',
+        y1: '',
+        x0: '',
+        y0: ''
+      },
+      rules: {
+        x1: [
+          { validator: isNonnegativeInteger, trigger: 'change' }
+        ],
+        y1: [
+          { validator: isNonnegativeInteger, trigger: 'change' }
+        ]
+      },
+      baseUrl: '',
+      snapshot_url: '',
+      userImg: '',
+      cameraData: [],
+      traceX: 0,
+      traceY: 0,
+      isShowCurPos: false,
+      actPage: '1',
+      loading: false,
+      spaceWidth: '',
+      spaceHeight: '',
+      curCameraData: {
+        cameraId: '',
+        coords: []
+      },
+      relativeCameras: [],
+      relativeList: [],
+      groupModelVisible: false,
+      groupList: [],
+      curGroup: {},
+      groupForm: {
+        name: '',
+        cameras: []
+      },
+      groupCameras: [],
+      groupCamera: {
+
+      },
+
+    }
+  },
+  computed: {
+
+  },
+  mounted () {
+    this.getAllCameraData();
+    //mock鍥炴樉鏍囨敞
+    setTimeout(() => {
+      let mockData = [{ id: 'a1', x0: 15, y0: 33, x1: 150, y1: 330 }, { id: 'b2', x0: 56, y0: 87, x1: 560, y1: 870 }];
+      //this.curCameraData.coords = mockData;
+    }, 1000);
+  },
+  watch: {
+    'TreeDataPool.selectedNode': {
+      handler (n, o) {
+        let curCamera = this.cameraData.find(item => item.id == n.id);
+        //璁剧疆鎽勫儚鏈哄簳鍥�
+        this.snapshot_url = curCamera.snapshot_url;
+        this.findCameraMarks(n.id);
+      },
+      deep: true
+    },
+    'TreeDataPool.selectedNodes': {
+      handler (n, o) {
+        debugger
+        if (n.length >= 2) {
+
+
+        }
+      },
+      deep: true
+    },
+    isEdit (n, o) {
+      if (n) {
+        this.$refs['editBoard'].addEventListener('click', this.bindListen);
+      } else {
+        this.$refs['editBoard'].removeEventListener('click', this.bindListen);
+      }
+    }
+  },
+  methods: {
+    addRelation () {
+      let obj = { cameraArea1: '', cameraArea2: '' };
+      this.relativeList.push(obj)
+    },
+    swiperOption () {
+      return {
+        slidesPerView: 1,
+        spaceBetween: 0,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        navigation: {
+          nextEl: ".swiper-next-border",
+          prevEl: ".swiper-pre-border"
+        },
+        observer: true,//淇敼swiper鑷繁鎴栧瓙鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+        observeParents: true,//淇敼swiper鐨勭埗鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+      }
+    },
+    editGroup (gruop) {
+      this.groupModelVisible = true;
+      debugger
+      this.$refs['groupForm'].resetFields();
+    },
+    removeGroup (group) {
+
+    },
+    checkCurrentGroup (group) {
+      debugger
+      this.curGroup = group;
+    },
+    confirmGroupDialog () {
+      //璇锋眰淇濆瓨鏂板缓鎴栫紪杈戝垎缁�
+      let _this = this;
+      this.groupForm.cameras.forEach(camera => {
+        getAllPolygon({ cameraId: camera.id }).then(res => {
+          _this.groupCameras.push(res.data);
+        }).catch(e => {
+          console.log(e)
+        });
+      })
+      this.groupList.push(this.groupForm);
+
+      this.groupModelVisible = false;
+      //鏍规嵁鍒嗙粍鍐呮憚鍍忔満id鏌ュ悇鑷尯鍩�
+    },
+    newGroup () {
+      this.groupModelVisible = true;
+      this.$nextTick(() => {
+        this.$refs['groupForm'].resetFields();
+      })
+    },
+    changeTab () {
+      if (this.actPage == '1') {
+        this.$parent.$children[0].$el.parentNode.parentElement.style.display = 'block';
+      } else {
+        this.$parent.$children[0].$el.parentNode.parentElement.style.display = 'none';
+      }
+    },
+    sure () {
+      let _this = this;
+      this.$refs['labelForm'].validate(valid => {
+        console.log(valid)
+        if (valid) {
+          _this.isShowPop = false;
+          debugger
+          //缂栬緫纭畾
+          if (_this.curLabel.id) {
+            let editedIndex = _this.curCameraData.coords.findIndex(one => one.id == _this.curLabel.id);
+            _this.curCameraData.coords[editedIndex] = JSON.parse(JSON.stringify(_this.curLabel));
+
+          }
+          console.log(_this.curCameraData.coords)
+          this.$refs['labelForm'].clearValidate();
+        }
+      });
+    },
+    //鑾峰彇鎽勫儚鏈烘爣娉�
+    findCameraMarks (id) {
+      getCameraMarks({ cameraId: id }).then(res => {
+        if (res.success) {
+          this.curCameraData.cameraId = id;
+          this.curCameraData.coords = res.data.map((item, index) => ({ id: 'm' + index, x0: item.x0, y0: item.y0, x1: item.x1, y1: item.y1 }));
+        }
+      }).catch(e => {
+        console.log(e)
+      });
+    },
+    editCameraData () {
+      if (!this.TreeDataPool.selectedNode.id) {
+        this.$notify({
+          message: '璇峰厛閫夋嫨鎽勫儚鏈�',
+          type: 'warning'
+        });
+        return;
+      }
+      this.isEdit = !this.isEdit;
+    },
+    async submitInfo () {
+      this.isEdit = false;
+      let res = await updateCameraMarks(this.curCameraData);
+      if (res.success) {
+        this.findCameraMarks(this.curCameraData.cameraId);
+      }
+    },
+    chnageActPage () {
+
+    },
+    showCurPos (e) {
+      console.log(e);
+      this.isShowCurPos = true;
+      this.traceX = e.offsetX;
+      this.traceY = e.offsetY;
+    },
+    onChange (file, fileList) {
+      fileList = [file]
+      this.isShowCurPos = false;
+      // this.traceX = e.offsetX;
+      // this.traceY = e.offsetY;
+      //fileList.push(file)
+    },
+    definedUpload (params) {
+      let _file = params.file
+      let fileReader = new FileReader()
+      fileReader.onload = () => {
+        this.userImg = fileReader.result
+      }
+      if (_file) {
+        fileReader.readAsDataURL(_file)
+      }
+    },
+    getAllCameraData () {
+      getCamerasByServer().then(res => {
+        if (res.success) {
+          this.cameraData = res.data;
+          debugger
+        }
+      }).catch(e => {
+        console.log(e)
+      })
+    },
+    bindListen (e) {
+      this.newLabel(e);
+    },
+    newLabel (e) {
+      console.log('鐐瑰嚮浜嗙敾鏉�')
+      if (this.isShowPop) return;
+      //鑾峰彇榧犳爣鐩稿浜庣敾鏉跨殑瀹氫綅
+      console.log('鑾峰彇褰撳墠瀹氫綅淇℃伅');
+      this.$refs['labelForm'].resetFields();
+      let target = {
+        id: '',
+        x0: e.offsetX,
+        y0: e.offsetY,
+        x1: '',
+        y1: ''
+      };
+      target.id = 'n' + (this.curCameraData.coords.length - 1);
+      //this.labels.push(target);
+      this.curCameraData.coords.push(target);
+      this.curLabel = target;
+      this.isShowPop = true;
+      this.isNewLabel = true;
+    },
+    editLabel (label) {
+      debugger
+      if (!this.isEdit) return;
+      this.isShowPop = true;
+      this.$refs['labelForm'].clearValidate();
+      this.curLabel = JSON.parse(JSON.stringify(label));
+      console.log(this.curLabel)
+      //this.curLabel = label;
+    },
+    cancle () {
+      this.isShowPop = false;
+      //濡傛灉鏄湭淇濆瓨杩囩殑label鐩存帴鍒犻櫎(鏈繚瀛樼殑灏辨槸labels鏁扮粍涓渶鍚庝竴涓�)
+      if (!this.curLabel.id) {
+        //this.labels.pop();
+        this.curCameraData.coords.pop();
+      }
+    },
+    deleteLabel () {
+      if (this.curLabel.id) {
+        let index = this.curCameraData.coords.findIndex(item => item.id == this.curLabel.id);
+        this.curCameraData.coords.splice(index, 1);
+
+      } else {
+        //this.labels.pop();
+        this.curCameraData.coords.pop();
+      }
+      this.isShowPop = false;
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.right-side {
+  background: #d2dcea;
+  
+  .figure {
+    .el-tabs__content {
+      background: #d2dcea;
+      height: calc(100vh - 85px);
+    }
+  }
+  .tool-bar {
+    //width: 40px;
+    height: 100%;
+    padding: 10px 0 10px 20px;
+    box-sizing: border-box;
+    //background: rgb(250, 250, 250);
+    background: rgba(26, 45, 74, 0.6);
+    //margin-bottom: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    > div {
+      cursor: pointer;
+      //background: rgba(245, 245, 245, 0.3);
+      padding: 0 5px;
+      height: 40px;
+      margin: 7px;
+      display: flex;
+      align-items: center;
+      label {
+        margin-right: 10px;
+        color: rgb(161, 161, 161);
+        color: #fff;
+      }
+      .el-slider {
+        width: 110px;
+      }
+    }
+  }
+  .shadow-box {
+    box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
+  }
+  .action-bar {
+    width: 960px;
+    margin: auto;
+    margin-top: 30px;
+    //margin-bottom: 20px;
+    text-align: right;
+    .drawboard-trigger {
+      background: transparent;
+      color: #fff;
+      border-color: rgba(255, 255, 255, 0.3);
+    }
+  }
+  .drawboard {
+    margin: auto;
+    width: 960px;
+    height: 540px;
+    margin-bottom: 130px;
+    position: relative;
+    //background: #fff;
+    background: #f0ffca;
+    //box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
+    .mask {
+      position: absolute;
+      background: transparent;
+      width: 100%;
+      height: 100%;
+      overflow: hidden;
+      &.edit-status-mask {
+        background: rgba(20, 181, 255, 0.1);
+      }
+      .label {
+        position: absolute;
+        z-index: 2;
+        border-radius: 50%;
+      }
+    }
+    img {
+      width: 960px;
+      height: 540px;
+      background: #f0ffca;
+    }
+    .right-panel {
+      width: 150px;
+      height: 100%;
+      background: rgba(26, 45, 74, 0.7);
+    }
+    .popBox {
+      position: absolute;
+      z-index: 99;
+      padding: 14px;
+      border-radius: 3px;
+      color: #fff;
+      background: rgba(26, 45, 74, 0.7);
+      .title {
+        font-weight: bold;
+        text-align: left;
+        font-size: 15px;
+        margin-bottom: 14px;
+        letter-spacing: 2px;
+      }
+      .details {
+        .detail-item {
+          display: flex;
+          margin: 5px 0;
+          label {
+            color: #a9a9a9;
+            width: 65px;
+            display: inline-block;
+          }
+          .left {
+            width: 110px;
+            text-align: left;
+            line-height: 28px;
+            .fix-width {
+              display: inline-block;
+              width: 23px;
+            }
+          }
+          .right {
+            width: 160px;
+          }
+          .devide {
+            width: 10px;
+            height: 1px;
+            background: #a9a9a9;
+            margin: 14px 3px;
+          }
+        }
+        .btns {
+          margin-top: 10px;
+        }
+        .el-form-item {
+          margin-bottom: 12px;
+        }
+        .el-form-item__content {
+          font-size: 12px;
+          line-height: 30px;
+        }
+        .el-form-item__error {
+          left: 70px;
+          top: 94%;
+        }
+      }
+    }
+  }
+  .user-upload {
+    margin: auto;
+    padding: 50px;
+    display: flex;
+    .info {
+      margin-left: 20px;
+      margin-top: 20px;
+      text-align: left;
+      font-size: 15px;
+      .input-area {
+        width: 300px;
+        label {
+          width: 80px;
+          color: rgba(39, 68, 111, 0.67);
+        }
+        > div {
+          display: flex;
+          align-items: center;
+          height: 40px;
+        }
+      }
+      .pos {
+        margin-top: 10px;
+        text-align: left;
+        color: rgba(39, 68, 111, 0.67);
+        b {
+          font-style: italic;
+        }
+        //color: #4966b7
+      }
+    }
+    .img-card {
+    }
+    .upload-demo,
+    .el-upload {
+      height: 100%;
+      width: 100%;
+      margin: 0 auto;
+    }
+    .upload-demo .el-upload__input {
+      visibility: hidden;
+    }
+    .upload-demo .el-upload-dragger {
+      width: 100%;
+      height: 90%;
+      width: 962px;
+      height: 542px;
+      margin: 20px 0 0;
+      background: transparent;
+      /* border: none; */
+      //position: relative;
+      overflow: visible;
+    }
+    .upload-demo .el-upload__text {
+      position: absolute;
+      top: -24px;
+      left: 50%;
+      margin-left: -91px;
+    }
+    .upload-demo .preview {
+      object-fit: contain;
+      //position: relative;
+      // width: 100%;
+      // height: 100%;
+    }
+    .upload-demo .preview img {
+      // position: absolute;
+      // top: 50%;
+      // left: 50%;
+      // transform: translate(-50%, -50%);
+      // width: 100%;
+      // height: 100%;
+    }
+  }
+  .tab-relation {
+    .el-alert--info {
+      background: rgba(230, 247, 255, 1);
+      border-color: rgba(145, 213, 255, 1);
+      color: #666;
+      .el-alert__icon.el-icon-info {
+        color: #1890ff;
+      }
+    }
+    .title {
+      text-align: left;
+      font-size: 15px;
+      line-height: 40px;
+      .el-button {
+        margin-left: 14px;
+      }
+    }
+    .group-card {
+      background: #fff;
+      width: 293px;
+      height: 152px;
+      box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
+      .top {
+        height: 104px;
+        display: flex;
+        padding-left: 20px;
+        align-items: center;
+        .icon {
+          font-size: 40px;
+        }
+        .name {
+          font-size: 16px;
+          padding-left: 14px;
+          font-weight: bold;
+        }
+      }
+      .bottom {
+        border-top: 1px solid #e9e9e9;
+        height: 48px;
+        line-height: 48px;
+        background: #f7f9fa;
+        position: relative;
+        display: flex;
+        &:after {
+          content: '';
+          position: absolute;
+          font-size: 0;
+          width: 1px;
+          height: 14px;
+          background: #0000006d;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+        }
+        span {
+          cursor: pointer;
+          width: 50%;
+          font-size: 14px;
+          color: #0000006d;
+        }
+      }
+    }
+    .part {
+      margin-bottom: 20px;
+      .relative-partment {
+        width: 1200px;
+        margin: 0 auto;
+        display: flex;
+        justify-content: space-between;
+        .area-wrap {
+          width: 576px;
+        }
+      }
+    }
+    .relative-config {
+      width: 700px;
+      .title {
+        display: flex;
+        justify-content: space-between;
+      }
+      .relative-list {
+        .relative-item {
+          width: 680px;
+          height: 48px;
+          padding-left: 20px;
+          background: #ecf2f5;
+          margin-bottom: 6px;
+          display: flex;
+          align-items: center;
+          .left {
+            width: 650px;
+            text-align: left;
+          }
+          i {
+            font-size: 20px;
+            padding: 0 10px;
+            cursor: pointer;
+          }
+        }
+      }
+    }
+  }
+  .dialog-group {
+    .el-form {
+      .el-form-item__content {
+        display: flex;
+        label {
+          width: 80px;
+          text-align: left;
+        }
+        & > div {
+          flex: 1;
+          .el-select {
+            width: 100%;
+          }
+        }
+      }
+    }
+  }
+}
+.el-input__inner:focus {
+  outline: none;
+  border-color: rgba(42, 56, 93, 71%) !important;
+}
+.el-upload-dragger:hover {
+  border-color: rgba(42, 56, 93, 71%) !important;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/labelMark-copy/components/SlideCanvas.vue b/src/pages/labelMark-copy/components/SlideCanvas.vue
new file mode 100644
index 0000000..71821f4
--- /dev/null
+++ b/src/pages/labelMark-copy/components/SlideCanvas.vue
@@ -0,0 +1,225 @@
+<template>
+  <div class="swiper-box">
+    <p class="task-tip" v-if="cameras.length == 0 "></p>
+    <swiper
+      ref="cameraSwiper"
+      v-if="cameras.length>=1"
+      :options="swiperOption"
+      class="swiper-box-container"
+    >
+      <swiper-slide v-for="camera in cameras" :key="camera.id+'s'">
+        <div class="swiper-draw-box-title">
+          <b>{{camera.name}}</b>
+          <b style="margin-left:14px;">缁樺埗鍖哄煙</b>
+          <span
+            class="el-dropdown-link"
+            @click="drawBaseImg(camera.id)"
+            style="position: relative;top: 5px; cursor:pointer"
+          >
+            <i class="iconfont iconbianji1" style="font-size: 28px; "></i>
+          </span>
+        </div>
+        <polygon-canvas
+          class="polygon-canvas"
+          :ref="`polygonCanvas_${camera.id}`"
+          :snapshot_url="camera.snapshot_url"
+          :canvasDataShow="camera.canvasData"
+          :canvasWidth="576"
+          :canvasHeight="324"
+        ></polygon-canvas>
+      </swiper-slide>
+    </swiper>
+    <div class="swiper-pre-border" slot="button-prev" @click="pre" >
+      <div class="icon-btn" >
+        <i class="iconfont iconzuo"></i>
+      </div>
+    </div>
+    <div class="swiper-next-border" slot="button-next" @click="next">
+      <div class="icon-btn" >
+        <i class="iconfont iconyou1"></i>
+      </div>
+    </div>
+    <!-- <div class="swiper-pre-border" slot="button-prev" @click="pre" >
+      <div class="icon-btn" >
+        <i class="iconfont iconzuo"></i>
+      </div>
+    </div>
+    <div class="swiper-next-border" slot="button-next" @click="next">
+      <div class="icon-btn" >
+        <i class="iconfont iconyou1"></i>
+      </div>
+    </div> -->
+  </div>
+</template>
+
+<script>
+import { chunkArr } from '@/scripts/util';
+import PolygonCanvas from '@/components/canvas';
+
+export default {
+  //cameras: [{ id: '',snapshot_url:'', canvasData: {} }]
+  props: [
+    'cameras',
+    //'swiperOption'
+  ],
+  watch: {
+    cameras: {
+      handler (n, o) {
+        debugger
+      },
+      deep: true
+    }
+  },
+  components: { PolygonCanvas },
+  data () {
+    return {
+      swiperOption: this.newOption(),
+      //mySwiper: {}
+    }
+  },
+  computed: {
+    swiper () {
+      return this.$refs['cameraSwiper'].swiper
+    }
+  },
+  mounted () {
+    debugger
+    //this.mySwiper = this.$refs.sceneSwiper.swiper;
+    console.log(this.swiper)
+  },
+  methods: {
+    newOption () {
+      return {
+        slidesPerView: 1,
+        spaceBetween: 0,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        observer: true,//淇敼swiper鑷繁鎴栧瓙鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+        observeParents: true,//淇敼swiper鐨勭埗鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+      }
+    },
+
+    pre () {
+      this.swiper.activeIndex--
+      this.swiper.slideTo(this.swiper.activeIndex)
+    },
+    next () {
+      this.swiper.activeIndex++
+      this.swiper.slideTo(this.swiper.activeIndex)
+    },
+    drawBaseImg (id) {
+      this.$refs[`polygonCanvas_${id}`][0].showModal();
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+.task-tip {
+  font-family: PingFangSC-Regular;
+  font-size: 12px;
+  color: #cccccc;
+  margin-top: 10%;
+}
+.swiper-box {
+  position: relative;
+}
+.swiper-pre-border,
+.swiper-next-border {
+  width: 40px;
+  height: 40px;
+  position: absolute;
+  background: #8888;
+  top: 50%;
+  margin-top: -20px;
+  z-index: 99;
+  border-radius: 4em;
+  outline: none;
+  .icon-btn {
+    color: rgb(255, 255, 255);
+    text-align: center;
+    line-height: 38px;
+    cursor: pointer;
+  }
+}
+.swiper-pre-border {
+  left: 10px;
+}
+.swiper-pre-border:hover {
+  background: #666;
+}
+.swiper-next-border {
+  right: 10px;
+}
+.swiper-next-border:hover {
+  background: #666;
+}
+.swiper-draw-box-title {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 24px;
+  b {
+    font-size: 14px;
+  }
+}
+.wrap-box {
+  width: 100%;
+  display: inline-block;
+  .inner {
+    width: 90%;
+    box-sizing: border-box;
+    position: relative;
+    font-size: 14px;
+    padding: 7px 0 48px;
+    transition: all 1s;
+    background: #ffffff;
+    border: 1px solid #e2e2e2;
+    box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+    border-radius: 4px;
+    margin: auto;
+    &:hover {
+      .mask {
+        display: block;
+      }
+    }
+    .mask {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background: rgba(0, 0, 0, 0.65);
+      backdrop-filter: blur(1px) brightness(100%);
+      text-align: center;
+      z-index: 1;
+      border-radius: 3px;
+      display: none;
+      .tool {
+        position: absolute;
+        top: 49%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        i {
+          font-size: 50px;
+        }
+        i:nth-of-type(1) {
+          margin-right: 30px;
+        }
+        i:nth-of-type(2) {
+          color: red;
+        }
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/labelMark-copy/index/App.vue b/src/pages/labelMark-copy/index/App.vue
new file mode 100644
index 0000000..afbfc81
--- /dev/null
+++ b/src/pages/labelMark-copy/index/App.vue
@@ -0,0 +1,118 @@
+<template>
+  <div class="column">
+    <!-- <div class="column-left" ref="leftTree">
+      <div class="resize-bar"></div>
+      <div class="resize-line"></div>
+      <div class="resize-save">
+        <left-nav :appName="'Camera'" :height="screenHeight - 40"></left-nav>
+      </div>
+    </div> -->
+    <div class="column-right">
+      <right-side />
+    </div>
+  </div>
+</template>
+<script>
+
+import RightSide from "../components/RightSide";
+import TreeDataPool from "@/Pool/TreeData";
+export default {
+  components: { RightSide },
+  data () {
+    return {
+      screenHeight: 0,
+    }
+  },
+  created(){
+    this.TreeDataPool.multiple = true;
+  },
+  mounted() {
+    this.screenHeight = document.documentElement.clientHeight - 20;
+    window.onresize = () => {
+      return (() => {
+        this.screenHeight = document.documentElement.clientHeight - 20;
+      })();
+    };
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+
+.column {
+  overflow: hidden;
+  min-width: 1399px;
+  height: 100%;
+}
+.column-left {
+  background-color: #fff;
+  position: relative;
+  float: left;
+  height: 100vh;
+  //height: inherit;
+}
+.column-right {
+  height: 100vh;
+  background-color: #f5f5f5;
+  box-sizing: border-box;
+  //overflow: hidden;
+  overflow-x: auto;
+  overflow-y: auto;
+}
+.resize-save {
+  position: absolute;
+  top: 0;
+  right: 5px;
+  bottom: 0;
+  left: 0;
+  padding: 14px;
+  overflow-x: hidden;
+}
+.resize-bar {
+  width: 310px;
+  height: inherit;
+  resize: horizontal;
+  cursor: ew-resize;
+  opacity: 0;
+  overflow: scroll;
+  max-width: 500px; //璁惧畾鏈�澶ф媺浼搁暱搴�
+  min-width: 33px; //璁惧畾鏈�灏忓搴�
+}
+/* 鎷栨嫿绾� */
+.resize-line {
+  position: absolute;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  border-right: 2px solid #efefef;
+  border-left: 1px solid #e0e0e0;
+  pointer-events: none;
+}
+.resize-bar:hover ~ .resize-line,
+.resize-bar:active ~ .resize-line {
+  border-left: 1px dashed skyblue;
+}
+.resize-bar::-webkit-scrollbar {
+  width: 200px;
+  height: inherit;
+}
+
+/* Firefox鍙湁涓嬮潰涓�灏忓潡鍖哄煙鍙互鎷変几 */
+@supports (-moz-user-select: none) {
+  .resize-bar:hover ~ .resize-line,
+  .resize-bar:active ~ .resize-line {
+    border-left: 1px solid #bbb;
+  }
+  .resize-bar:hover ~ .resize-line::after,
+  .resize-bar:active ~ .resize-line::after {
+    content: "";
+    position: absolute;
+    width: 16px;
+    height: 16px;
+    bottom: 0;
+    right: -8px;
+    // background: url(./resize.svg);
+    background-size: 100% 100%;
+  }
+}
+</style>
diff --git a/src/pages/labelMark-copy/index/main.ts b/src/pages/labelMark-copy/index/main.ts
new file mode 100644
index 0000000..b9b1993
--- /dev/null
+++ b/src/pages/labelMark-copy/index/main.ts
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import App from './App.vue';
+
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import "@/assets/css/element-variables.scss";
+import VueAwesomeSwiper from "vue-awesome-swiper";
+import "swiper/dist/css/swiper.css";
+import Mixin from "./mixins";
+
+Vue.use(ElementUI);
+Vue.use(VueAwesomeSwiper as any);
+Vue.mixin(Mixin);
+new Vue({
+  el: '#app',
+  render: h => h(App)
+});
\ No newline at end of file
diff --git a/src/pages/labelMark-copy/index/mixins.ts b/src/pages/labelMark-copy/index/mixins.ts
new file mode 100644
index 0000000..feda309
--- /dev/null
+++ b/src/pages/labelMark-copy/index/mixins.ts
@@ -0,0 +1,14 @@
+import TreeDataPool from "@/Pool/TreeData";
+
+/* eslint-disable */
+const onlyTreeDataPool = new TreeDataPool
+
+const mixin = {
+  data() {
+    return {
+      TreeDataPool: onlyTreeDataPool
+
+    };
+  },
+};
+export default mixin;
\ No newline at end of file
diff --git a/src/pages/labelMark/components/RightSide-COPY.vue b/src/pages/labelMark/components/RightSide-COPY.vue
new file mode 100644
index 0000000..a846575
--- /dev/null
+++ b/src/pages/labelMark/components/RightSide-COPY.vue
@@ -0,0 +1,862 @@
+<template>
+  <div class="right-side">
+    <div class="figure s-system-manage">
+      <el-tabs
+        id="e-basic-setting"
+        v-model="actPage"
+        v-loading="loading"
+        element-loading-text="鍔犺浇涓�"
+        type="border-card"
+      >
+        <el-tab-pane label="鎽勫儚鏈烘爣娉�" name="1">
+          <div class v-for="camera in relativeCameras" :key="camera.id">
+            <div class="action-bar">
+              <div class="tool-bar">
+                <div>
+                  <!-- <input type="color" ref="colorPicker" v-model="color"> -->
+                  <label for>鎷捐壊鍣�:</label>
+                  <el-color-picker v-model="camera.colorPick" show-alpha size="mini"></el-color-picker>
+                </div>
+                <div style="width:250px;">
+                  <label for>绗旇Е:</label>
+                  <el-slider v-model="camera.dotSize" :min="1" :max="20"></el-slider>
+                </div>
+                <div>
+                  <el-button type="text" @click="editPolygon(camera.id)">缂栬緫鍖哄煙</el-button>
+                  <el-button @click="editCoor(camera.id)">缂栬緫鏍囨敞淇℃伅</el-button>
+                </div>
+                <div>
+                  <el-button
+                    v-if="!camera.isEdit"
+                    class="drawboard-trigger"
+                    size="small"
+                    @click="editCameraData(camera)"
+                    icon="el-icon-edit"
+                  >缂栬緫</el-button>
+
+                  <el-button
+                    v-if="camera.isEdit"
+                    class="drawboard-trigger save"
+                    size="small"
+                    @click="submitInfo"
+                    icon="el-icon-lock"
+                  >淇濆瓨</el-button>
+                </div>
+              </div>
+            </div>
+            <el-dialog :visible.sync="coordsDialogVisible" width="1150px">
+              <div class="drawboard shadow-box">
+                <div
+                  class="mask"
+                  :class="{'edit-status-mask':camera.isEdit}"
+                  :ref="`editBoard_${camera.id}`"
+                >
+                  <polygon-canvas
+                    class="polygon-canvas"
+                    :ref="`polygonCanvas_${camera.id}`"
+                    :snapshot_url="camera.snapshot_url"
+                    :canvasWidth="960"
+                    :canvasHeight="540"
+                  ></polygon-canvas>
+                  <!-- <div
+                  class="label"
+                  @click="editLabel(item)"
+                  v-for="(item,index) in curCameraData.coords"
+                  :key="index"
+                  :style="{left:`${item.x0}px`, top:`${item.y0}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"
+                  ></div>-->
+                  <div
+                    class="label"
+                    @click="editLabel(item)"
+                    v-for="(item,index) in camera.coords"
+                    :key="index"
+                    :style="{left:`${item.x0}px`, top:`${item.y0}px`, backgroundColor: camera.colorPick, width: `${camera.dotSize}px`, height: `${camera.dotSize}px` }"
+                  ></div>
+                </div>
+                <img v-show="camera.snapshot_url" :src="`/httpImage/${camera.snapshot_url}`" alt />
+                <div
+                  class="popBox"
+                  v-show="camera.isShowPop"
+                  :style="`top:${curLabel.y0 + 22}px;left:${curLabel.x0}px`"
+                >
+                  <div class="title">鏍囨敞淇℃伅</div>
+                  <div class="details">
+                    <el-form :model="curLabel" :rules="rules" :ref="`labelForm_${camera.id}`">
+                      <div class="detail-item">
+                        <div class="left">
+                          <el-form-item prop="x0">
+                            <label for>骞抽潰鍧愭爣X:</label>
+                            <span class="fix-width">{{curLabel.x0}}</span>
+                            <i>px</i>
+                          </el-form-item>
+                        </div>
+                        <span class="devide"></span>
+                        <div class="right">
+                          <el-form-item prop="x1">
+                            <label for>瀹為檯鍧愭爣X:</label>
+                            <el-input
+                              type="text"
+                              size="mini"
+                              style="width:90px"
+                              v-model.number="curLabel.x1"
+                            ></el-input>
+                          </el-form-item>
+                        </div>
+                      </div>
+                      <div class="detail-item">
+                        <div class="left">
+                          <el-form-item prop="y0">
+                            <label for>骞抽潰鍧愭爣Y:</label>
+                            <span class="fix-width">{{curLabel.y0}}</span>
+                            <i>px</i>
+                          </el-form-item>
+                        </div>
+                        <span class="devide"></span>
+                        <div class="right">
+                          <el-form-item prop="y1">
+                            <label for>瀹為檯鍧愭爣Y:</label>
+                            <el-input
+                              type="text"
+                              size="mini"
+                              style="width:90px"
+                              v-model.number="curLabel.y1"
+                            ></el-input>
+                          </el-form-item>
+                        </div>
+                      </div>
+                      <div class="btns">
+                        <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
+                        <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
+                        <el-button size="mini" type="success" @click="sure">纭畾</el-button>
+                      </div>
+                    </el-form>
+                  </div>
+                </div>
+              </div>
+            </el-dialog>
+            <!-- <div class="drawboard shadow-box">
+              <div class="mask" :class="{'edit-status-mask':camera.isEdit}" :ref="`editBoard_${camera.id}`">
+                <polygon-canvas
+                  class="polygon-canvas"
+                  :ref="`polygonCanvas_${camera.id}`"
+                  :snapshot_url="camera.snapshot_url"
+                  :canvasWidth="960"
+                  :canvasHeight="540"
+                ></polygon-canvas>
+                <div
+                  class="label"
+                  @click="editLabel(item)"
+                  v-for="(item,index) in camera.coords"
+                  :key="index"
+                  :style="{left:`${item.x0}px`, top:`${item.y0}px`, backgroundColor: camera.colorPick, width: `${camera.dotSize}px`, height: `${camera.dotSize}px` }"
+                ></div>
+              </div>
+              <img v-show="camera.snapshot_url" :src="`/httpImage/${camera.snapshot_url}`" alt />
+              <div
+                class="popBox"
+                v-show="camera.isShowPop"
+                :style="`top:${curLabel.y0 + 22}px;left:${curLabel.x0}px`"
+              >
+                <div class="title">鏍囨敞淇℃伅</div>
+                <div class="details">
+                  <el-form :model="curLabel" :rules="rules" :ref="`labelForm_${camera.id}`">
+                    <div class="detail-item">
+                      <div class="left">
+                        <el-form-item prop="x0">
+                          <label for>骞抽潰鍧愭爣X:</label>
+                          <span class="fix-width">{{curLabel.x0}}</span>
+                          <i>px</i>
+                        </el-form-item>
+                      </div>
+                      <span class="devide"></span>
+                      <div class="right">
+                        <el-form-item prop="x1">
+                          <label for>瀹為檯鍧愭爣X:</label>
+                          <el-input
+                            type="text"
+                            size="mini"
+                            style="width:90px"
+                            v-model.number="curLabel.x1"
+                          ></el-input>
+                        </el-form-item>
+                      </div>
+                    </div>
+                    <div class="detail-item">
+                      <div class="left">
+                        <el-form-item prop="y0">
+                          <label for>骞抽潰鍧愭爣Y:</label>
+                          <span class="fix-width">{{curLabel.y0}}</span>
+                          <i>px</i>
+                        </el-form-item>
+                      </div>
+                      <span class="devide"></span>
+                      <div class="right">
+                        <el-form-item prop="y1">
+                          <label for>瀹為檯鍧愭爣Y:</label>
+                          <el-input
+                            type="text"
+                            size="mini"
+                            style="width:90px"
+                            v-model.number="curLabel.y1"
+                          ></el-input>
+                        </el-form-item>
+                      </div>
+                    </div>
+                    <div class="btns">
+                      <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
+                      <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
+                      <el-button size="mini" type="success" @click="sure">纭畾</el-button>
+                    </div>
+                  </el-form>
+                </div>
+              </div>
+            </div>-->
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="杩借釜瀹炴櫙鍧愭爣" name="2">
+          <div class="user-upload">
+            <canvas id="trackArea" width="960" height="540"></canvas>
+            <div class="img-card">
+              <el-upload
+                class="upload-demo"
+                drag
+                action="https://jsonplaceholder.typicode.com/posts/"
+                :http-request="definedUpload"
+                :on-change="onChange"
+                :show-file-list="false"
+              >
+                <el-image
+                  class="preview"
+                  v-if="userImg"
+                  :src="userImg"
+                  fit="contain"
+                  @mousemove="showCurPos"
+                  @mouseout="isShowCurPos=false"
+                ></el-image>
+                <div class="el-upload__text">
+                  灏嗘枃浠舵嫋鍒版澶勶紝鎴�
+                  <em>鐐瑰嚮涓婁紶</em>
+                </div>
+              </el-upload>
+            </div>
+            <div class="info">
+              <div class="input-area">
+                <div>
+                  <label for>绌洪棿瀹�:</label>
+                  <el-input v-model="spaceWidth" placeholder="璇疯緭鍏ュ疄闄呯┖闂村" size="small"></el-input>
+                </div>
+                <div>
+                  <label for>绌洪棿楂�:</label>
+                  <el-input v-model="spaceHeight" placeholder="璇疯緭鍏ュ疄闄呯┖闂撮珮" size="small"></el-input>
+                </div>
+              </div>
+              <div class="pos" v-show="isShowCurPos">
+                褰撳墠浣嶇疆:
+                <b>{{traceX}}</b>,
+                <b>{{traceY}}</b>
+              </div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+      <!-- <el-collapse v-model="actPage">
+        <el-collapse-item title="鎽勫儚鏈烘爣娉�" name="1">
+          
+        </el-collapse-item>
+        <el-collapse-item title="杩借釜瀹炴櫙鍧愭爣" name="2">
+          <div class="user-upload">
+            <div class="img-card">
+              <el-upload
+                class="upload-demo"
+                drag
+                action="https://jsonplaceholder.typicode.com/posts/"
+                :http-request="definedUpload"
+                :on-change="onChange"
+                :show-file-list="false"
+              >
+                <el-image
+                  class="preview"
+                  v-if="userImg"
+                  :src="userImg"
+                  fit="contain"
+                  @mousemove="showCurPos"
+                  @mouseout="isShowCurPos=false"
+                ></el-image>
+                <div class="el-upload__text">
+                  灏嗘枃浠舵嫋鍒版澶勶紝鎴�
+                  <em>鐐瑰嚮涓婁紶</em>
+                </div>
+              </el-upload>
+            </div>
+            <div class="info" v-show="isShowCurPos">褰撳墠浣嶇疆:{{traceX}},{{traceY}}</div>
+          </div>
+        </el-collapse-item>
+      </el-collapse>-->
+    </div>
+  </div>
+</template>
+
+<script>
+import { getCamerasByServer } from '@/api/pollConfig';
+import { getCameraMarks, updateCameraMarks } from '@/api/camera';
+import TreeDataPool from "@/Pool/TreeData";
+import { isNonnegativeInteger } from '@/scripts/validate';
+import polygonCanvas from "@/components/canvas";
+export default {
+  components: { polygonCanvas },
+  data () {
+    return {
+      labels: [],
+      // colorPick: '#79f2fb',
+      // dotSize: 3,
+      // isEdit: false,
+      // isShowPop: false,
+      // isNewLabel: false,
+      curLabel: {
+        id: '',
+        x1: '',
+        y1: '',
+        x0: '',
+        y0: ''
+      },
+      rules: {
+        x1: [
+          { validator: isNonnegativeInteger, trigger: 'change' }
+        ],
+        y1: [
+          { validator: isNonnegativeInteger, trigger: 'change' }
+        ]
+      },
+      baseUrl: '',
+      //snapshot_url: '',
+      userImg: '',
+      cameraData: [],
+      traceX: 0,
+      traceY: 0,
+      isShowCurPos: false,
+      actPage: '1',
+      loading: false,
+      spaceWidth: '',
+      spaceHeight: '',
+      curCameraData: {
+        cameraId: '',
+        coords: []
+      },
+      relativeCameras: [],
+      relativeCamera: {
+        colorPick: '#79f2fb',
+        cameraId: '',
+        snapshot_url: '',
+        dotSize: 3,
+        isEdit: false,
+        isShowPop: false,
+        isNewLabel: false,
+        coords: [],
+        polygons: {}
+      },
+      trackData: []
+    }
+  },
+  computed: {
+
+  },
+  mounted () {
+    this.getAllCameraData();
+    //mock鍥炴樉鏍囨敞
+    setTimeout(() => {
+      let mockData = [{ id: 'a1', x0: 15, y0: 33, x1: 150, y1: 330 }, { id: 'b2', x0: 56, y0: 87, x1: 560, y1: 870 }];
+      //this.curCameraData.coords = mockData;
+      //this.trackData = [[950,370],[945,368],[940,360],[936,350],[930,340],[930,340]];
+      let tempArr = [];
+      for (var i = 0; i < 1000; i++) {
+        //let x = 960-i*9, y = 370 - i*3;
+        let x = Math.floor(Math.random() * 960);
+        let y = Math.floor(Math.random() * 540)
+        tempArr.push([x, y])
+      }
+      this.trackData = tempArr;
+      let canvas = document.querySelector('#trackArea');
+      let ctx = canvas.getContext('2d');
+      ctx.strokeStyle = 'yellow';
+      ctx.fillStyle = 'aqua';
+      // ctx.globalAlpha=0.5;
+      ctx.lineWidth = 1;
+      //ctx.lineJoin='round';
+      ctx.lineCap = 'round';
+      for (var i = 0; i < this.trackData.length; i++) {
+        ctx.fillRect(this.trackData[i][0], this.trackData[i][1], 5, 5);
+        ctx.lineTo(this.trackData[i][0], this.trackData[i][1]);
+      }
+      ctx.stroke();
+    }, 1000);
+    debugger
+  },
+  watch: {
+    // 'TreeDataPool.selectedNode': {
+    //   handler (n, o) {
+    //     let curCamera = this.cameraData.find(item => item.id == n.id);
+    //     //璁剧疆鎽勫儚鏈哄簳鍥�
+    //     this.snapshot_url = curCamera.snapshot_url;
+    //     this.findCameraMarks(n.id);
+    //   },
+    //   deep: true
+    // },
+    'TreeDataPool.selectedNodes': {
+      handler (n, o) {
+        debugger
+        // if (n.length > 2) {
+        //   this.$notify({
+        //     type: 'warning',
+        //     message: '鏈�澶氫粎鑳藉叧鑱斾袱涓憚鍍忔満'
+        //   });
+        //   this.TreeDataPool.selectedNodes.length = 2;
+        //   //鐩綍鏍戣鍥炬湭鏇存柊  
+        // }
+        var tempArr = [];
+        //鏍规嵁id鍙栨憚鍍忔満鏍囨敞淇℃伅鍙婂尯鍩�
+        let _this = this;
+        n.forEach(cameraId => {
+          //this.findCameraMarks(cameraId);
+          getCameraMarks({ cameraId }).then(res => {
+            let obj = _this.newCameraData();
+            //Object.assign(obj,)
+            //寰呰仈璋�
+            tempArr.push(res.data)
+          })
+        })
+        //mock
+        tempArr = [
+          { id: '81b4c468-9828-41ad-a681-e90feb59490e', isEdit: false, isShowPop: false, colorPick: '#79f2fb', isNewLabel: false, dotSize: 3 },
+          { id: '28477df1-78ec-49bc-8734-e977992667cc', isEdit: false, isShowPop: false, colorPick: '#79f2fb', isNewLabel: false, dotSize: 3 }
+        ];
+        tempArr.forEach(item => {
+          this.cameraData.find(camera => {
+            if (camera.id == item.id) {
+              item.snapshot_url = camera.snapshot_url;
+            }
+          })
+        })
+
+        this.relativeCameras = tempArr
+      },
+      deep: true
+    },
+    relativeCameras: {
+      handler (n, o) {
+        var _this = this;
+        n.forEach(camera => {
+          debugger
+          // if(camera.isEdit){
+          //   _this.$refs[`editBoard_${camera.id}`][0].addEventListener('click', this.bindListen);
+          // }else{
+          //   _this.$refs[`editBoard_${camera.id}`][0].removeEventListener('click', this.bindListen);
+          // }
+        })
+      },
+      deep: true
+    },
+    // isEdit (n, o) {
+    //   if (n) {
+    //     this.$refs['editBoard'].addEventListener('click', this.bindListen);
+    //   } else {
+    //     this.$refs['editBoard'].removeEventListener('click', this.bindListen);
+    //   }
+    // }
+  },
+  methods: {
+    newCameraData () {
+      return {
+        colorPick: '#79f2fb',
+        id: '',
+        snapshot_url: '',
+        dotSize: 3,
+        isEdit: false,
+        isShowPop: false,
+        isNewLabel: false,
+        coords: [],
+        polygons: {}
+      }
+    },
+    editPolygon (cameraId) {
+      debugger
+      this.$refs[`polygonCanvas_${cameraId}`][0].showModal();
+    },
+    sure () {
+      let _this = this;
+      // this.$refs[`labelForm_${}`].validate(valid => {
+      //   console.log(valid)
+      //   if (valid) {
+      //     _this.isShowPop = false;
+      //     debugger
+      //     //缂栬緫纭畾
+      //     if (_this.curLabel.id) {
+      //       // let editedIndex = _this.curCameraData.coords.findIndex(one => one.id == _this.curLabel.id);
+      //       // _this.curCameraData.coords[editedIndex] = JSON.parse(JSON.stringify(_this.curLabel));
+      //       let editedIndex = _this.relativeCamera.coords.findIndex(one => one.id == _this.curLabel.id);
+      //       _this.relativeCamera.coords[editedIndex] = JSON.parse(JSON.stringify(_this.curLabel));
+      //     }
+      //     console.log(_this.curCameraData.coords)
+      //     this.$refs['labelForm'].clearValidate();
+      //   }
+      // });
+    },
+    //鑾峰彇鎽勫儚鏈烘爣娉�
+    findCameraMarks (id) {
+      getCameraMarks({ cameraId: id }).then(res => {
+        if (res.success) {
+          this.curCameraData.cameraId = id;
+          this.curCameraData.coords = res.data.map((item, index) => ({ id: 'm' + index, x0: item.x0, y0: item.y0, x1: item.x1, y1: item.y1 }));
+
+        }
+      }).catch(e => {
+        console.log(e)
+      });
+    },
+    editCameraData (camera) {
+      if (!this.TreeDataPool.selectedNode.id) {
+        this.$notify({
+          message: '璇峰厛閫夋嫨鎽勫儚鏈�',
+          type: 'warning'
+        });
+        return;
+      }
+      camera.isEdit = !camera.isEdit;
+      this.$refs[`editBoard_${camera.id}`][0].addEventListener('click', this.bindListen);
+    },
+    async submitInfo () {
+      this.isEdit = false;
+      let res = await updateCameraMarks(this.curCameraData);
+      if (res.success) {
+        this.findCameraMarks(this.curCameraData.cameraId);
+      }
+    },
+    showCurPos (e) {
+      console.log(e);
+      this.isShowCurPos = true;
+      this.traceX = e.offsetX;
+      this.traceY = e.offsetY;
+    },
+    onChange (file, fileList) {
+      fileList = [file]
+      this.isShowCurPos = false;
+      // this.traceX = e.offsetX;
+      // this.traceY = e.offsetY;
+      //fileList.push(file)
+    },
+    definedUpload (params) {
+      let _file = params.file
+      let fileReader = new FileReader()
+      fileReader.onload = () => {
+        this.userImg = fileReader.result
+      }
+      if (_file) {
+        fileReader.readAsDataURL(_file)
+      }
+    },
+    getAllCameraData () {
+      getCamerasByServer().then(res => {
+        if (res.success) {
+          this.cameraData = res.data;
+        }
+      }).catch(e => {
+        console.log(e)
+      })
+    },
+    bindListen (e) {
+      this.newLabel(e);
+    },
+    newLabel (e) {
+      debugger
+      console.log('鐐瑰嚮浜嗙敾鏉�')
+      if (this.isShowPop) return;
+      //鑾峰彇榧犳爣鐩稿浜庣敾鏉跨殑瀹氫綅
+      console.log('鑾峰彇褰撳墠瀹氫綅淇℃伅');
+      this.$refs['labelForm'].resetFields();
+      let target = {
+        id: '',
+        x0: e.offsetX,
+        y0: e.offsetY,
+        x1: '',
+        y1: ''
+      };
+      target.id = 'n' + (this.curCameraData.coords.length - 1);
+      //this.labels.push(target);
+      this.curCameraData.coords.push(target);
+      this.curLabel = target;
+      this.isShowPop = true;
+      this.isNewLabel = true;
+    },
+    editLabel (label) {
+      debugger
+      if (!this.isEdit) return;
+      this.isShowPop = true;
+      this.$refs['labelForm'].clearValidate();
+      this.curLabel = JSON.parse(JSON.stringify(label));
+      console.log(this.curLabel)
+      //this.curLabel = label;
+    },
+    cancle () {
+      this.isShowPop = false;
+      //濡傛灉鏄湭淇濆瓨杩囩殑label鐩存帴鍒犻櫎(鏈繚瀛樼殑灏辨槸labels鏁扮粍涓渶鍚庝竴涓�)
+      if (!this.curLabel.id) {
+        //this.labels.pop();
+        this.curCameraData.coords.pop();
+      }
+    },
+    deleteLabel () {
+      if (this.curLabel.id) {
+        let index = this.curCameraData.coords.findIndex(item => item.id == this.curLabel.id);
+        this.curCameraData.coords.splice(index, 1);
+
+      } else {
+        //this.labels.pop();
+        this.curCameraData.coords.pop();
+      }
+      this.isShowPop = false;
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.right-side {
+  background: #d2dcea;
+  .figure {
+    .el-tabs__content {
+      background: #d2dcea;
+      height: calc(100vh - 85px);
+    }
+  }
+  .tool-bar {
+    //width: 40px;
+    height: 100%;
+    padding: 10px 0 10px 20px;
+    box-sizing: border-box;
+    //background: rgb(250, 250, 250);
+    background: rgba(26, 45, 74, 0.6);
+    //margin-bottom: 40px;
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    > div {
+      cursor: pointer;
+      //background: rgba(245, 245, 245, 0.3);
+      padding: 0 5px;
+      height: 40px;
+      margin: 7px;
+      display: flex;
+      align-items: center;
+      label {
+        margin-right: 10px;
+        color: rgb(161, 161, 161);
+        color: #fff;
+      }
+      .el-slider {
+        width: 110px;
+      }
+    }
+  }
+  .shadow-box {
+    box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
+  }
+  .action-bar {
+    width: 960px;
+    margin: auto;
+    margin-top: 30px;
+    //margin-bottom: 20px;
+    text-align: right;
+    .drawboard-trigger {
+      background: transparent;
+      color: #fff;
+      border-color: rgba(255, 255, 255, 0.3);
+    }
+  }
+  .drawboard {
+    margin: auto;
+    width: 960px;
+    height: 540px;
+    margin-bottom: 130px;
+    position: relative;
+    //background: #fff;
+    background: #f0ffca;
+    //box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
+    .mask {
+      position: absolute;
+      background: transparent;
+      width: 100%;
+      height: 100%;
+      overflow: hidden;
+      &.edit-status-mask {
+        background: rgba(20, 181, 255, 0.1);
+      }
+      .label {
+        position: absolute;
+        z-index: 2;
+        border-radius: 50%;
+      }
+    }
+    .polygon-canvas {
+      position: absolute;
+      top: 0;
+      left: 0;
+    }
+    img {
+      width: 960px;
+      height: 540px;
+      background: #f0ffca;
+    }
+    .polygon-canvas {
+      position: absolute;
+    }
+    .right-panel {
+      width: 150px;
+      height: 100%;
+      background: rgba(26, 45, 74, 0.7);
+    }
+    .popBox {
+      position: absolute;
+      z-index: 99;
+      padding: 14px;
+      border-radius: 3px;
+      color: #fff;
+      background: rgba(26, 45, 74, 0.7);
+      .title {
+        font-weight: bold;
+        text-align: left;
+        font-size: 15px;
+        margin-bottom: 14px;
+        letter-spacing: 2px;
+      }
+      .details {
+        .detail-item {
+          display: flex;
+          margin: 5px 0;
+          label {
+            color: #a9a9a9;
+            width: 65px;
+            display: inline-block;
+          }
+          .left {
+            width: 110px;
+            text-align: left;
+            line-height: 28px;
+            .fix-width {
+              display: inline-block;
+              width: 23px;
+            }
+          }
+          .right {
+            width: 160px;
+          }
+          .devide {
+            width: 10px;
+            height: 1px;
+            background: #a9a9a9;
+            margin: 14px 3px;
+          }
+        }
+        .btns {
+          margin-top: 10px;
+        }
+        .el-form-item {
+          margin-bottom: 12px;
+        }
+        .el-form-item__content {
+          font-size: 12px;
+          line-height: 30px;
+        }
+        .el-form-item__error {
+          left: 70px;
+          top: 94%;
+        }
+      }
+    }
+  }
+  .user-upload {
+    margin: auto;
+    padding: 50px;
+    display: flex;
+    position: relative;
+    #trackArea {
+      position: absolute;
+      background: rgba(136, 214, 228, 0.1);
+    }
+    .info {
+      margin-left: 20px;
+      margin-top: 20px;
+      text-align: left;
+      font-size: 15px;
+      .input-area {
+        width: 300px;
+        label {
+          width: 80px;
+          color: rgba(39, 68, 111, 0.67);
+        }
+        > div {
+          display: flex;
+          align-items: center;
+          height: 40px;
+        }
+      }
+      .pos {
+        margin-top: 10px;
+        text-align: left;
+        color: rgba(39, 68, 111, 0.67);
+        b {
+          font-style: italic;
+        }
+        //color: #4966b7
+      }
+    }
+    .img-card {
+    }
+    .upload-demo,
+    .el-upload {
+      height: 100%;
+      width: 100%;
+      margin: 0 auto;
+    }
+    .upload-demo .el-upload__input {
+      visibility: hidden;
+    }
+    .upload-demo .el-upload-dragger {
+      width: 100%;
+      height: 90%;
+      width: 962px;
+      height: 542px;
+      margin: 20px 0 0;
+      background: transparent;
+      /* border: none; */
+      //position: relative;
+      overflow: visible;
+    }
+    .upload-demo .el-upload__text {
+      position: absolute;
+      top: -24px;
+      left: 50%;
+      margin-left: -91px;
+    }
+    .upload-demo .preview {
+      object-fit: contain;
+      //position: relative;
+      // width: 100%;
+      // height: 100%;
+    }
+    .upload-demo .preview img {
+      // position: absolute;
+      // top: 50%;
+      // left: 50%;
+      // transform: translate(-50%, -50%);
+      // width: 100%;
+      // height: 100%;
+    }
+  }
+}
+.el-input__inner:focus {
+  outline: none;
+  border-color: rgba(42, 56, 93, 71%) !important;
+}
+.el-upload-dragger:hover {
+  border-color: rgba(42, 56, 93, 71%) !important;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/labelMark/components/RightSide.vue b/src/pages/labelMark/components/RightSide.vue
index e1f2177..e243da4 100644
--- a/src/pages/labelMark/components/RightSide.vue
+++ b/src/pages/labelMark/components/RightSide.vue
@@ -3,116 +3,166 @@
     <div class="figure s-system-manage">
       <el-tabs
         id="e-basic-setting"
+        @tab-click="changeTab"
         v-model="actPage"
         v-loading="loading"
         element-loading-text="鍔犺浇涓�"
         type="border-card"
       >
-        <el-tab-pane label="鎽勫儚鏈烘爣娉�" name="1">
-          <div class>
-            <div class="action-bar">
-              <div class="tool-bar">
-                <div>
-                  <!-- <input type="color" ref="colorPicker" v-model="color"> -->
-                  <label for>鎷捐壊鍣�:</label>
-                  <el-color-picker v-model="colorPick" show-alpha size="mini"></el-color-picker>
-                </div>
-                <div style="width:250px;">
-                  <label for>绗旇Е:</label>
-                  <el-slider v-model="dotSize" :min="1" :max="20"></el-slider>
-                </div>
-                <div>
-                  <el-button
-                    v-if="!isEdit"
-                    class="drawboard-trigger"
-                    size="small"
-                    @click="editCameraData"
-                    icon="el-icon-edit"
-                  >缂栬緫</el-button>
+        <el-tab-pane label="浣嶇疆鏍囨敞" name="1">
+          <el-tabs type="border-card">
+            <el-tab-pane label="鎽勫儚鏈烘爣娉�" name="11">
+              <div class>
+                <div class="action-bar">
+                  <div class="tool-bar">
+                    <div>
+                      <!-- <input type="color" ref="colorPicker" v-model="color"> -->
+                      <label for>鎷捐壊鍣�:</label>
+                      <el-color-picker v-model="colorPick" show-alpha size="mini"></el-color-picker>
+                    </div>
+                    <div style="width:250px;">
+                      <label for>绗旇Е:</label>
+                      <el-slider v-model="dotSize" :min="1" :max="20"></el-slider>
+                    </div>
+                    <div>
+                      <el-button
+                        v-if="!isEdit"
+                        class="drawboard-trigger"
+                        size="small"
+                        @click="editCameraData"
+                        icon="el-icon-edit"
+                      >缂栬緫</el-button>
 
-                  <el-button
-                    v-if="isEdit"
-                    class="drawboard-trigger save"
-                    size="small"
-                    @click="submitInfo"
-                    icon="el-icon-lock"
-                  >淇濆瓨</el-button>
+                      <el-button
+                        v-if="isEdit"
+                        class="drawboard-trigger save"
+                        size="small"
+                        @click="submitInfo"
+                        icon="el-icon-lock"
+                      >淇濆瓨</el-button>
+                    </div>
+                  </div>
+                </div>
+                <div class="drawboard shadow-box">
+                  <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard">
+                    <div
+                      class="label"
+                      @click="editLabel(item)"
+                      v-for="(item,index) in curCameraData.coords"
+                      :key="index"
+                      :style="{left:`${item.x0}px`, top:`${item.y0}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"
+                    ></div>
+                  </div>
+                  <img v-show="snapshot_url" :src="`/httpImage/${snapshot_url}`" alt />
+                  <div
+                    class="popBox"
+                    v-show="isShowPop"
+                    :style="`top:${curLabel.y0 + 22}px;left:${curLabel.x0}px`"
+                  >
+                    <div class="title">鏍囨敞淇℃伅</div>
+                    <div class="details">
+                      <el-form :model="curLabel" :rules="rules" ref="labelForm">
+                        <div class="detail-item">
+                          <div class="left">
+                            <el-form-item prop="x0">
+                              <label for>骞抽潰鍧愭爣X:</label>
+                              <span class="fix-width">{{curLabel.x0}}</span>
+                              <i>px</i>
+                            </el-form-item>
+                          </div>
+                          <span class="devide"></span>
+                          <div class="right">
+                            <el-form-item prop="x1">
+                              <label for>瀹為檯鍧愭爣X:</label>
+                              <el-input
+                                type="text"
+                                size="mini"
+                                style="width:90px"
+                                v-model.number="curLabel.x1"
+                              ></el-input>
+                            </el-form-item>
+                          </div>
+                        </div>
+                        <div class="detail-item">
+                          <div class="left">
+                            <el-form-item prop="y0">
+                              <label for>骞抽潰鍧愭爣Y:</label>
+                              <span class="fix-width">{{curLabel.y0}}</span>
+                              <i>px</i>
+                            </el-form-item>
+                          </div>
+                          <span class="devide"></span>
+                          <div class="right">
+                            <el-form-item prop="y1">
+                              <label for>瀹為檯鍧愭爣Y:</label>
+                              <el-input
+                                type="text"
+                                size="mini"
+                                style="width:90px"
+                                v-model.number="curLabel.y1"
+                              ></el-input>
+                            </el-form-item>
+                          </div>
+                        </div>
+                        <div class="btns">
+                          <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
+                          <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
+                          <el-button size="mini" type="success" @click="sure">纭畾</el-button>
+                        </div>
+                      </el-form>
+                    </div>
+                  </div>
                 </div>
               </div>
-            </div>
-            <div class="drawboard shadow-box">
-              <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard">
-                <div
-                  class="label"
-                  @click="editLabel(item)"
-                  v-for="(item,index) in curCameraData.coords"
-                  :key="index"
-                  :style="{left:`${item.x0}px`, top:`${item.y0}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"
-                ></div>
-              </div>
-              <img v-show="snapshot_url" :src="`/httpImage/${snapshot_url}`" alt />
-              <div
-                class="popBox"
-                v-show="isShowPop"
-                :style="`top:${curLabel.y0 + 22}px;left:${curLabel.x0}px`"
-              >
-                <div class="title">鏍囨敞淇℃伅</div>
-                <div class="details">
-                  <el-form :model="curLabel" :rules="rules" ref="labelForm">
-                    <div class="detail-item">
-                      <div class="left">
-                        <el-form-item prop="x0">
-                          <label for>骞抽潰鍧愭爣X:</label>
-                          <span class="fix-width">{{curLabel.x0}}</span>
-                          <i>px</i>
-                        </el-form-item>
-                      </div>
-                      <span class="devide"></span>
-                      <div class="right">
-                        <el-form-item prop="x1">
-                          <label for>瀹為檯鍧愭爣X:</label>
-                          <el-input
-                            type="text"
-                            size="mini"
-                            style="width:90px"
-                            v-model.number="curLabel.x1"
-                          ></el-input>
-                        </el-form-item>
-                      </div>
+            </el-tab-pane>
+            <el-tab-pane label="瀹炴櫙鍧愭爣" name="12">
+              <div class="user-upload">
+                <div class="img-card">
+                  <el-upload
+                    class="upload-demo"
+                    drag
+                    action="https://jsonplaceholder.typicode.com/posts/"
+                    :http-request="definedUpload"
+                    :on-change="onChange"
+                    :show-file-list="false"
+                  >
+                    <el-image
+                      class="preview"
+                      v-if="userImg"
+                      :src="userImg"
+                      fit="contain"
+                      @mousemove="showCurPos"
+                      @mouseout="isShowCurPos=false"
+                    ></el-image>
+                    <div class="el-upload__text">
+                      灏嗘枃浠舵嫋鍒版澶勶紝鎴�
+                      <em>鐐瑰嚮涓婁紶</em>
                     </div>
-                    <div class="detail-item">
-                      <div class="left">
-                        <el-form-item prop="y0">
-                          <label for>骞抽潰鍧愭爣Y:</label>
-                          <span class="fix-width">{{curLabel.y0}}</span>
-                          <i>px</i>
-                        </el-form-item>
-                      </div>
-                      <span class="devide"></span>
-                      <div class="right">
-                        <el-form-item prop="y1">
-                          <label for>瀹為檯鍧愭爣Y:</label>
-                          <el-input
-                            type="text"
-                            size="mini"
-                            style="width:90px"
-                            v-model.number="curLabel.y1"
-                          ></el-input>
-                        </el-form-item>
-                      </div>
+                  </el-upload>
+                </div>
+                <div class="info">
+                  <div class="input-area">
+                    <div>
+                      <label for>绌洪棿瀹�:</label>
+                      <el-input v-model="spaceWidth" placeholder="璇疯緭鍏ュ疄闄呯┖闂村" size="small"></el-input>
                     </div>
-                    <div class="btns">
-                      <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
-                      <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
-                      <el-button size="mini" type="success" @click="sure">纭畾</el-button>
+                    <div>
+                      <label for>绌洪棿楂�:</label>
+                      <el-input v-model="spaceHeight" placeholder="璇疯緭鍏ュ疄闄呯┖闂撮珮" size="small"></el-input>
                     </div>
-                  </el-form>
+                  </div>
+                  <div class="pos" v-show="isShowCurPos">
+                    褰撳墠浣嶇疆:
+                    <b>{{traceX}}</b>,
+                    <b>{{traceY}}</b>
+                  </div>
                 </div>
               </div>
-            </div>
-          </div>
+            </el-tab-pane>
+          </el-tabs>
         </el-tab-pane>
-        <el-tab-pane label="杩借釜瀹炴櫙鍧愭爣" name="2">
+        <el-tab-pane label="杞ㄨ抗鍥�" name="2"></el-tab-pane>
+        <!-- <el-tab-pane label="杩借釜瀹炴櫙鍧愭爣" name="2">
           <div class="user-upload">
             <div class="img-card">
               <el-upload
@@ -155,51 +205,155 @@
               </div>
             </div>
           </div>
+        </el-tab-pane>-->
+        <el-tab-pane label="鍏宠仈鎽勫儚鏈�" name="3">
+          <div class="tab-relation">
+            <div class="part">
+              <div class="title">
+                <span>鍏宠仈璁惧鍒嗙粍</span>
+                <el-button @click="newGroup" icon="el-icon-plus" size="mini" type="primary">鏂板缓鍒嗙粍</el-button>
+              </div>
+              <el-alert
+                type="info"
+                title="鎻愮ず:璇风偣鍑讳笂鏂�'鏂板缓鍒嗙粍'鎸夐挳寤虹珛鍒嗙粍"
+                show-icon
+                v-if="groupList.length==0"
+              ></el-alert>
+              <div class="flex-box">
+                <div
+                  class="group-card"
+                  :class="{'checked':group.checked}"
+                  v-for="(group,index) in groupList"
+                  :key="index"
+                  @click="checkCurrentGroup(group)"
+                >
+                  <div class="top">
+                    <div class="left">
+                      <span class="icon el-icon-video-camera"></span>
+                    </div>
+                    <div class="right">
+                      <div class="name">{{group.groupName}}</div>
+                      <div class="details">
+                        <label>鎽勫儚鏈�:</label>
+                        <span
+                          class="sub"
+                          v-for="(camera,index) in group.cameras"
+                          :key="camera.id"
+                        >{{camera.name}} {{index!==group.cameras.length-1?'/':''}}</span>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="bottom">
+                    <span @click.stop="editGroup(group)">缂栬緫鍒嗙粍</span>
+                    <el-popconfirm title="纭畾鍒犻櫎鏀瑰垎缁勫悧?" @onConfirm="removeGroup(group)">
+                      <el-button slot="reference" type="text">鍒犻櫎鍒嗙粍</el-button>
+                    </el-popconfirm>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <!-- <div class="part" v-if="groupList.length"> -->
+            <div class="part" v-if="Object.keys(curGroup)">
+              <div class="title">缁樺埗鍖哄煙(鐢ㄤ簬绠楁硶鍒嗘瀽)</div>
+              <div class="relative-partment" v-if="curGroup.cameras&&curGroup.cameras.length">
+                <div class="area-wrap" v-for="i in 2" :key="'sc'+i">
+                  <slide-canvas :cameras="curGroup.cameras" @polygonDataUpdate="polygonUpdate"></slide-canvas>
+                </div>
+              </div>
+            </div>
+            <div class="part relative-config" v-if="Object.keys(curGroup)">
+              <div class="title">
+                <div class="left">
+                  <span>鍏宠仈鍖哄煙閰嶇疆</span>
+                </div>
+                <div class="right" v-if="curGroup.id">
+                  <el-button
+                    icon="el-icon-plus"
+                    size="mini"
+                    type="primary"
+                    @click="addRelation"
+                  >娣诲姞鍏宠仈</el-button>
+                </div>
+              </div>
+              <div class="relative-list">
+                <div class="relative-item" v-for="(item,index) in relativeList" :key="index">
+                  <div class="left">
+                    <el-select v-model="item.sourceObj" value-key="polygonId" size="small">
+                      <el-option
+                        v-for="area in cameraAreas"
+                        :key="area.polygonId"
+                        :label="area.name"
+                        :value="area"
+                      ></el-option>
+                    </el-select>
+                    <i class="el-icon-connection"></i>
+                    <el-select v-model="item.targetObj" value-key="polygonId" size="small">
+                      <el-option
+                        v-for="area in cameraAreas"
+                        :key="area.polygonId"
+                        :label="area.name"
+                        :value="area"
+                      ></el-option>
+                    </el-select>
+                  </div>
+                  <div class="right">
+                    <el-button type="text" @click="saveRelativePolygon(item)">淇濆瓨</el-button>
+                    <div class="btn-del" @click="delRelation(item)">
+                      <i class="el-icon-delete"></i>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <!-- <div class="btns">
+                <el-button size="small" >鍙栨秷</el-button>
+                <el-button size="small" type="primary" @click="saveRelativeList">淇濆瓨</el-button>
+              </div>-->
+            </div>
+          </div>
         </el-tab-pane>
       </el-tabs>
-      <!-- <el-collapse v-model="actPage" @change="chnageActPage">
-        <el-collapse-item title="鎽勫儚鏈烘爣娉�" name="1">
-          
-        </el-collapse-item>
-        <el-collapse-item title="杩借釜瀹炴櫙鍧愭爣" name="2">
-          <div class="user-upload">
-            <div class="img-card">
-              <el-upload
-                class="upload-demo"
-                drag
-                action="https://jsonplaceholder.typicode.com/posts/"
-                :http-request="definedUpload"
-                :on-change="onChange"
-                :show-file-list="false"
-              >
-                <el-image
-                  class="preview"
-                  v-if="userImg"
-                  :src="userImg"
-                  fit="contain"
-                  @mousemove="showCurPos"
-                  @mouseout="isShowCurPos=false"
-                ></el-image>
-                <div class="el-upload__text">
-                  灏嗘枃浠舵嫋鍒版澶勶紝鎴�
-                  <em>鐐瑰嚮涓婁紶</em>
-                </div>
-              </el-upload>
+      <el-dialog class="dialog-group" title="鏂板缓鍒嗙粍" :visible.sync="groupModelVisible">
+        <el-form :model="groupForm" ref="groupForm">
+          <el-form-item>
+            <label>鍒嗙粍鍚嶇О</label>
+            <div>
+              <el-input v-model="groupForm.groupName"></el-input>
             </div>
-            <div class="info" v-show="isShowCurPos">褰撳墠浣嶇疆:{{traceX}},{{traceY}}</div>
+          </el-form-item>
+          <el-form-item>
+            <label>閫夋嫨鎽勫儚鏈�</label>
+            <div>
+              <el-select v-model="groupForm.cameras" value-key="id" multiple>
+                <el-option
+                  :label="camera.name"
+                  :value="camera"
+                  v-for="camera in cameraData"
+                  :key="camera.id"
+                ></el-option>
+              </el-select>
+            </div>
+          </el-form-item>
+          <div class="btns">
+            <el-button @click="groupModelVisible=false;">鍙栨秷</el-button>
+            <el-button type="primary" @click="confirmGroupDialog">纭畾</el-button>
           </div>
-        </el-collapse-item>
-      </el-collapse>-->
+        </el-form>
+      </el-dialog>
     </div>
   </div>
 </template>
 
 <script>
 import { getCamerasByServer } from '@/api/pollConfig';
-import { getCameraMarks, updateCameraMarks } from '@/api/camera';
+import { getCameraMarks, updateCameraMarks, findCameraGroups, saveCameraGroupInfo, delCameraGroup } from '@/api/camera';
+import { getSearchList } from '@/api/search';
 import TreeDataPool from "@/Pool/TreeData";
 import { isNonnegativeInteger } from '@/scripts/validate';
+import { getAllPolygon, saveRelationPolygon, findByCamGroup, findByGroup, delRelation } from '@/api/polygon';
+import SlideCanvas from './SlideCanvas';
+
 export default {
+  components: { SlideCanvas },
   data () {
     return {
       labels: [],
@@ -244,7 +398,22 @@
       curCameraData: {
         cameraId: '',
         coords: []
-      }
+      },
+      relativeCameras: [],
+      relativeList: [],
+      cameraAreas: [],
+      groupModelVisible: false,
+      groupList: [],
+      curGroup: {},
+      groupForm: {
+        groupName: '',
+        cameras: []
+      },
+      groupCameras: [],
+      groupCamera: {
+
+      },
+      cameraAndPolygonData: []
     }
   },
   computed: {
@@ -268,6 +437,12 @@
       },
       deep: true
     },
+    'TreeDataPool.selectedNodes': {
+      handler (n, o) {
+
+      },
+      deep: true
+    },
     isEdit (n, o) {
       if (n) {
         this.$refs['editBoard'].addEventListener('click', this.bindListen);
@@ -277,18 +452,248 @@
     }
   },
   methods: {
+    polygonUpdate(){
+      debugger
+      this.getAllGroups();
+    },
+    delRelation (item) {
+      let _this = this;
+      delRelation(item.id).then(res => {
+        if (res.success) {
+          this.$notify({
+            type: 'success',
+            message: res.data
+          });
+          _this.findRelationByGroup();
+        }
+      })
+    },
+    findRelationByGroup () {
+      let _this = this;
+      findByGroup({ groupId: this.curGroup.id }).then(res => {
+
+        _this.relativeList = res.data.map(relation => {
+          let obj = { sourceObj: {}, targetObj: {} };
+          obj.sourceObj.cameraId = relation.source_camera_id;
+          obj.sourceObj.polygonId = relation.source_polygon_id;
+          obj.targetObj.cameraId = relation.target_camera_id;
+          obj.targetObj.polygonId = relation.target_polygon_id;
+          obj.sourceObj.name = relation.source_polygon.name;
+          obj.targetObj.name = relation.target_polygon.name;
+          obj.id = relation.id;
+          return obj;
+        })
+      })
+    },
+    saveRelativePolygon (item) {
+      let _this = this;
+      let params = {
+        groupId: this.curGroup.id,
+        source_camera_id: item.sourceObj.cameraId,
+        target_camera_id: item.targetObj.cameraId,
+        source_polygon_id: item.sourceObj.polygonId,
+        target_polygon_id: item.targetObj.polygonId,
+        id: item.id || ''
+      }
+
+      saveRelationPolygon(params).then(res => {
+        if (res.success) {
+          this.$notify({
+            type: 'success',
+            message: '淇濆瓨鎴愬姛',
+          });
+          _this.findRelationByGroup()
+        }
+      })
+    },
+    saveRelativeList () {
+      let params = {
+        groupId: this.curGroup.id,
+
+      }
+      //saveRelationPolygon().then()
+    },
+    async findPolygonByIds (cameras) {
+      for (var i = 0; i < cameras.length; i++) {
+        let res = await getAllPolygon({ cameraId: cameras[i].id });
+        cameras[i].canvasData = res.data;
+      }
+      return cameras
+    },
+
+    async getAllGroupInfo () {
+      let _this = this;
+      let res = await findCameraGroups();
+      let groupArr = res.data.map(item => {
+        let obj = {}; //group
+        obj.groupName = item.groupName;
+        obj.id = item.id;
+        let cameras = []; //cameras
+        item.cameraIds.forEach(id => {
+          let camera = {};
+          _this.cameraData.find(one => {
+            if (one.id == id) {
+              camera.name = one.name;
+              camera.id = id;
+            }
+          });
+          cameras.push(camera)
+        });
+        //cameras [{id,name}]
+        obj.cameras = cameras;
+        return obj;
+
+      });
+      return groupArr;
+    },
+    // async getAllGroups () {
+    //   let _this = this;
+    //   let groups = await this.getAllGroupInfo();
+    //   let promiseArr = [];
+    //   for (var i = 0; i < groups.length; i++) {
+    //     let pro = new Promise(resolve => {
+    //       resolve(_this.findPolygonByIds(groups[i].cameras))
+    //     });
+    //     promiseArr.push(pro)
+    //   }
+    //   Promise.allSettled(promiseArr).then(camerasArr => {
+
+    //     for (var i = 0; i < camerasArr.length; i++) {
+    //       groups[i].cameras = camerasArr[i].value
+    //     }
+    //     _this.groupList = groups;
+    //     //閫変腑绗竴涓�
+    //     _this.checkCurrentGroup(_this.groupList[0]);
+    //   })
+    // },
+    async getAllGroups(){
+      let _this = this;
+      let groups = await this.getAllGroupInfo();
+      for(var i = 0; i< groups.length; i++){
+        groups[i].cameras = await _this.findPolygonByIds(groups[i].cameras)
+      }
+      this.groupList = groups
+      //閫変腑绗竴涓�
+      this.checkCurrentGroup(_this.groupList[0]);
+    },
+
+    addRelation () {
+      let obj = { cameraArea1: '', cameraArea2: '' };
+      this.relativeList.push(obj)
+    },
+
+    editGroup (group) {
+      this.groupModelVisible = true;
+      //this.$refs['groupForm'].resetFields();
+      this.groupForm = group;
+    },
+    removeGroup (group) {
+      let _this = this;
+      delCameraGroup(group.id).then(res => {
+        _this.getAllGroups()
+      })
+    },
+    checkCurrentGroup (group) {
+      this.groupList.forEach(group => {
+        group.checked = false;
+      })
+      this.curGroup = group;
+      this.curGroup.checked = true;
+      this.findRelationByGroup();
+      //鏌ヨ绗竴涓垎缁勪笅鎽勫儚鏈哄尯鍩�
+      findByCamGroup({ groupId: group.id }).then(res => {
+        let tempArr = [];
+        res.data.forEach(camera => {
+          let cameraArea = [];
+          camera.polygon.forEach(item => {
+            let area = {};
+            area.name = camera.camera_name + '' + item.name;
+            area.cameraId = camera.camera_id;
+            area.polygonId = item.id;
+            cameraArea.push(area);
+          });
+          camera.rect.forEach(item => {
+            let area = {};
+            area.name = camera.camera_name + '' + item.name;
+            area.cameraId = camera.camera_id;
+            area.polygonId = item.id;
+            cameraArea.push(area);
+          });
+          tempArr = tempArr.concat(cameraArea)
+        });
+        this.cameraAreas = tempArr;
+        console.log(this.cameraAreas)
+      })
+    },
+    confirmGroupDialog () {
+      //璇锋眰淇濆瓨鏂板缓鎴栫紪杈戝垎缁�
+      let _this = this;
+      let params = {
+        cameraIds: [],
+        groupName: '',
+        id: ''
+      };
+      if (!this.groupForm.groupName.trim()) {
+        this.$notify({
+          type: 'warning',
+          message: '璇疯緭鍏ュ垎缁勫悕绉�'
+        });
+        return
+      }
+      if (this.groupForm.cameras.length < 2) {
+        this.$notify({
+          type: 'warning',
+          message: '璇烽�夋嫨鑷冲皯涓や釜鎽勫儚鏈�'
+        });
+        return
+      }
+      params.groupName = this.groupForm.groupName;
+      params.id = this.groupForm.id || '';
+      this.groupForm.cameras.forEach(camera => {
+        params.cameraIds.push(camera.id);
+        //鏍规嵁鍒嗙粍鍐呮憚鍍忔満id鏌ュ悇鑷尯鍩�
+        getAllPolygon({ cameraId: camera.id }).then(res => {
+          _this.groupCameras.push(res.data);
+        }).catch(e => {
+          console.log(e)
+        });
+      })
+      //this.groupList.push(this.groupForm);
+      saveCameraGroupInfo(params).then(res => {
+        _this.getAllGroups();
+      })
+      this.groupModelVisible = false;
+
+    },
+    newGroup () {
+      this.groupModelVisible = true;
+      this.$nextTick(() => {
+        this.$refs['groupForm'].resetFields();
+      })
+      this.groupForm = {
+        groupName: '',
+        cameras: []
+      }
+
+    },
+    changeTab () {
+      if (this.actPage == '1') {
+        this.$parent.$children[0].$el.parentNode.parentElement.style.display = 'block';
+      } else {
+        this.$parent.$children[0].$el.parentNode.parentElement.style.display = 'none';
+      }
+    },
     sure () {
       let _this = this;
       this.$refs['labelForm'].validate(valid => {
         console.log(valid)
         if (valid) {
           _this.isShowPop = false;
-          debugger
           //缂栬緫纭畾
           if (_this.curLabel.id) {
             let editedIndex = _this.curCameraData.coords.findIndex(one => one.id == _this.curLabel.id);
             _this.curCameraData.coords[editedIndex] = JSON.parse(JSON.stringify(_this.curLabel));
-            
+
           }
           console.log(_this.curCameraData.coords)
           this.$refs['labelForm'].clearValidate();
@@ -350,14 +755,28 @@
       }
     },
     getAllCameraData () {
+      let _this = this;
       getCamerasByServer().then(res => {
         if (res.success) {
-          this.cameraData = res.data;
+          _this.cameraData = res.data;
+          _this.getAllGroups();
         }
       }).catch(e => {
         console.log(e)
       })
     },
+    // async getAllCameraData () {
+    //   let res = await getCamerasByServer();
+    //   this.cameraData = res.data;
+    //   let tempArr = [];
+    //   this.cameraData.forEach(camera=>{
+    //     getAllPolygon({ cameraId: camera.id }).then(res=>{
+    //       tempArr.push(res.data);
+    //     })
+    //   });
+    //   this.cameraAndPolygonData = tempArr;
+    //   console.log(this.cameraAndPolygonData)
+    // },
     bindListen (e) {
       this.newLabel(e);
     },
@@ -374,7 +793,7 @@
         x1: '',
         y1: ''
       };
-      target.id = 'n'+(this.curCameraData.coords.length-1);
+      target.id = 'n' + (this.curCameraData.coords.length - 1);
       //this.labels.push(target);
       this.curCameraData.coords.push(target);
       this.curLabel = target;
@@ -393,7 +812,7 @@
     cancle () {
       this.isShowPop = false;
       //濡傛灉鏄湭淇濆瓨杩囩殑label鐩存帴鍒犻櫎(鏈繚瀛樼殑灏辨槸labels鏁扮粍涓渶鍚庝竴涓�)
-      if (!this.curLabel.id) {
+      if (this.curLabel.id.startsWith('n')) {
         //this.labels.pop();
         this.curCameraData.coords.pop();
       }
@@ -420,6 +839,7 @@
     .el-tabs__content {
       background: #d2dcea;
       height: calc(100vh - 85px);
+      overflow-y: auto;
     }
   }
   .tool-bar {
@@ -633,6 +1053,149 @@
       // height: 100%;
     }
   }
+  .tab-relation {
+    .el-alert--info {
+      background: rgba(230, 247, 255, 1);
+      border-color: rgba(145, 213, 255, 1);
+      color: #666;
+      .el-alert__icon.el-icon-info {
+        color: #1890ff;
+      }
+    }
+    .title {
+      text-align: left;
+      font-size: 15px;
+      line-height: 40px;
+      .el-button {
+        margin-left: 14px;
+      }
+    }
+    .group-card {
+      background: #fff;
+      width: 293px;
+      height: 153px;
+      margin-right: 10px;
+      box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
+      border: 1px solid transparent;
+      &.checked {
+        border-color: #1890ff;
+      }
+      .top {
+        height: 104px;
+        display: flex;
+        padding-left: 20px;
+        padding-top: 20px;
+        box-sizing: border-box;
+        //align-items: center;
+        .right {
+          text-align: left;
+          padding-left: 14px;
+        }
+        .icon {
+          font-size: 40px;
+        }
+        .name {
+          font-size: 16px;
+          margin-bottom: 10px;
+          font-weight: bold;
+        }
+        .details {
+          display: flex;
+          flex-wrap: wrap;
+          label {
+            width: 46px;
+          }
+          .sub {
+          }
+        }
+      }
+      .bottom {
+        border-top: 1px solid #e9e9e9;
+        height: 48px;
+        line-height: 48px;
+        background: #f7f9fa;
+        position: relative;
+        display: flex;
+        &:after {
+          content: '';
+          position: absolute;
+          font-size: 0;
+          width: 1px;
+          height: 14px;
+          background: #0000006d;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+        }
+        span {
+          cursor: pointer;
+          width: 50%;
+          font-size: 14px;
+          color: #0000006d;
+        }
+      }
+    }
+    .part {
+      margin-bottom: 20px;
+      .relative-partment {
+        width: 1200px;
+        margin: 0 auto;
+        display: flex;
+        justify-content: space-between;
+        .area-wrap {
+          width: 576px;
+        }
+      }
+    }
+    .relative-config {
+      width: 700px;
+      .title {
+        display: flex;
+        justify-content: space-between;
+      }
+      .relative-list {
+        .relative-item {
+          width: 680px;
+          height: 48px;
+          padding-left: 20px;
+          background: #ecf2f5;
+          margin-bottom: 6px;
+          display: flex;
+          align-items: center;
+          .left {
+            width: 650px;
+            text-align: left;
+          }
+          .right {
+            display: flex;
+            align-items: center;
+          }
+          i {
+            font-size: 20px;
+            padding: 0 10px;
+            cursor: pointer;
+          }
+        }
+      }
+    }
+  }
+  .dialog-group {
+    .el-form {
+      .el-form-item__content {
+        display: flex;
+        label {
+          width: 80px;
+          text-align: left;
+        }
+        & > div {
+          flex: 1;
+          .el-select {
+            width: 100%;
+          }
+        }
+      }
+    }
+  }
 }
 .el-input__inner:focus {
   outline: none;
diff --git a/src/pages/labelMark/components/SlideCanvas.vue b/src/pages/labelMark/components/SlideCanvas.vue
new file mode 100644
index 0000000..ba82824
--- /dev/null
+++ b/src/pages/labelMark/components/SlideCanvas.vue
@@ -0,0 +1,222 @@
+<template>
+  <div class="swiper-box">
+    <p class="task-tip" v-if="cameras.length == 0 "></p>
+    <swiper
+      ref="cameraSwiper"
+      v-if="cameras.length>=1"
+      :options="swiperOption"
+      class="swiper-box-container"
+    >
+      <swiper-slide v-for="camera in cameras" :key="camera.id+'c'">
+        <div class="swiper-draw-box-title">
+          <b>{{camera.name}}</b>
+          <b style="margin-left:14px;">缁樺埗鍖哄煙</b>
+          <span
+            class="el-dropdown-link"
+            @click="drawBaseImg(camera.id)"
+            style="position: relative;top: 5px; cursor:pointer"
+          >
+            <i class="iconfont iconbianji1" style="font-size: 28px; "></i>
+          </span>
+        </div>
+        <polygon-canvas
+          class="polygon-canvas"
+          :ref="`polygonCanvas_${camera.id}`"
+          :snapshot_url="camera.canvasData.snapshot_url"
+          :canvasDataShow="camera.canvasData"
+          :canvasWidth="576"
+          :canvasHeight="324"
+          @fromCanvas="getCanvasData"
+        ></polygon-canvas>
+      </swiper-slide>
+    </swiper>
+    <div class="swiper-pre-border" slot="button-prev" @click="pre" >
+      <div class="icon-btn" >
+        <i class="iconfont iconzuo"></i>
+      </div>
+    </div>
+    <div class="swiper-next-border" slot="button-next" @click="next">
+      <div class="icon-btn" >
+        <i class="iconfont iconyou1"></i>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import { chunkArr } from '@/scripts/util';
+import PolygonCanvas from '@/components/canvas';
+import { savePolygon } from "@/api/polygon";
+export default {
+  //cameras: [{ id: '',snapshot_url:'', canvasData: {} }]
+  props: [
+    'cameras',
+    //'swiperOption'
+  ],
+  watch:{
+    cameras:{
+      handler(n,o){
+        console.log('slidecanvas cameras',n)
+      },
+      deep: true
+    }
+  },
+  components: { PolygonCanvas },
+  data () {
+    return {
+      swiperOption: this.newOption(),
+      //mySwiper: {}
+    }
+  },
+  computed: {
+    swiper () {
+      return this.$refs['cameraSwiper'].swiper
+    }
+  },
+  mounted () {
+    //this.mySwiper = this.$refs.sceneSwiper.swiper;
+    console.log(this.swiper)
+  },
+  methods: {
+    getCanvasData(data) {
+      let _this = this;
+      savePolygon(data).then(rsp => {
+        _this.$emit('polygonDataUpdate')
+      });
+    },
+    newOption () {
+      return {
+        slidesPerView: 1,
+        spaceBetween: 0,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        observer: true,//淇敼swiper鑷繁鎴栧瓙鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+        observeParents: true,//淇敼swiper鐨勭埗鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+      }
+    },
+
+    pre () {
+      this.swiper.activeIndex--
+      this.swiper.slideTo(this.swiper.activeIndex);
+    },
+    next () {
+      this.swiper.activeIndex++
+      this.swiper.slideTo(this.swiper.activeIndex);
+    },
+    drawBaseImg (id) {
+      this.$refs[`polygonCanvas_${id}`][0].showModal();
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+.task-tip {
+  font-family: PingFangSC-Regular;
+  font-size: 12px;
+  color: #cccccc;
+  margin-top: 10%;
+}
+.swiper-box {
+  position: relative;
+}
+.swiper-pre-border,
+.swiper-next-border {
+  width: 40px;
+  height: 40px;
+  position: absolute;
+  background: #8888;
+  top: 50%;
+  margin-top: -20px;
+  z-index: 99;
+  border-radius: 4em;
+  outline: none;
+  .icon-btn {
+    color: rgb(255, 255, 255);
+    text-align: center;
+    line-height: 38px;
+    cursor: pointer;
+  }
+}
+.swiper-pre-border {
+  left: 10px;
+}
+.swiper-pre-border:hover {
+  background: #666;
+}
+.swiper-next-border {
+  right: 10px;
+}
+.swiper-next-border:hover {
+  background: #666;
+}
+.swiper-draw-box-title {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 24px;
+  b {
+    font-size: 14px;
+  }
+}
+.wrap-box {
+  width: 100%;
+  display: inline-block;
+  .inner {
+    width: 90%;
+    box-sizing: border-box;
+    position: relative;
+    font-size: 14px;
+    padding: 7px 0 48px;
+    transition: all 1s;
+    background: #ffffff;
+    border: 1px solid #e2e2e2;
+    box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+    border-radius: 4px;
+    margin: auto;
+    &:hover {
+      .mask {
+        display: block;
+      }
+    }
+    .mask {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background: rgba(0, 0, 0, 0.65);
+      backdrop-filter: blur(1px) brightness(100%);
+      text-align: center;
+      z-index: 1;
+      border-radius: 3px;
+      display: none;
+      .tool {
+        position: absolute;
+        top: 49%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        i {
+          font-size: 50px;
+        }
+        i:nth-of-type(1) {
+          margin-right: 30px;
+        }
+        i:nth-of-type(2) {
+          color: red;
+        }
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/labelMark/index/App.vue b/src/pages/labelMark/index/App.vue
index df72374..2624781 100644
--- a/src/pages/labelMark/index/App.vue
+++ b/src/pages/labelMark/index/App.vue
@@ -1,6 +1,6 @@
 <template>
   <div class="column">
-    <div class="column-left">
+    <div class="column-left" ref="leftTree">
       <div class="resize-bar"></div>
       <div class="resize-line"></div>
       <div class="resize-save">
@@ -8,22 +8,24 @@
       </div>
     </div>
     <div class="column-right">
-      <right-side />
+      <right-side ref="content"/>
     </div>
   </div>
 </template>
 <script>
 import LeftNav from "@/components/LeftNav";
 import RightSide from "../components/RightSide";
-
+import TreeDataPool from "@/Pool/TreeData";
 export default {
   components: { LeftNav, RightSide },
   data () {
     return {
       screenHeight: 0,
-
     }
   },
+  // created(){
+  //   this.TreeDataPool.multiple = true;
+  // },
   mounted() {
     this.screenHeight = document.documentElement.clientHeight - 20;
     window.onresize = () => {
diff --git a/src/pages/labelMark/index/main.ts b/src/pages/labelMark/index/main.ts
index a8cc111..b9b1993 100644
--- a/src/pages/labelMark/index/main.ts
+++ b/src/pages/labelMark/index/main.ts
@@ -4,9 +4,12 @@
 import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';
 import "@/assets/css/element-variables.scss";
+import VueAwesomeSwiper from "vue-awesome-swiper";
+import "swiper/dist/css/swiper.css";
 import Mixin from "./mixins";
 
 Vue.use(ElementUI);
+Vue.use(VueAwesomeSwiper as any);
 Vue.mixin(Mixin);
 new Vue({
   el: '#app',
diff --git a/src/scripts/util.js b/src/scripts/util.js
index 19cd19d..2f4261f 100644
--- a/src/scripts/util.js
+++ b/src/scripts/util.js
@@ -249,6 +249,22 @@
   }
 }
 
+//鎷嗗垎浜岀淮鏁扮粍
+const chunkArr = (arr, size = 1)=>{
+  if (arr.length == 0) return;
+  const tempContainer = [];
+  let innerArr = [];
+  arr.forEach(item => {
+    if (innerArr.length == 0) {
+      tempContainer.push(innerArr);
+    }
+    innerArr.push(item);
+    if (innerArr.length == size) {
+      innerArr = [];
+    }
+  });
+  return tempContainer;
+}
 export {
   thisRouterObjFn,
   json2url,
@@ -264,5 +280,6 @@
   guid,
   cloneDeep,
   getYearWeek,
-  getContainerRect
+  getContainerRect,
+  chunkArr
 }

--
Gitblit v1.8.0