From c99cad106ef5be9f818e45d385dfdcec29ce19e5 Mon Sep 17 00:00:00 2001
From: hanbaoshan <hanbaoshan@aiotlink.com>
Date: 星期四, 03 十二月 2020 16:52:24 +0800
Subject: [PATCH] 修复绘制多边形撤销错误的bug

---
 src/pages/labelMark/components/RightSide.vue |  628 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 504 insertions(+), 124 deletions(-)

diff --git a/src/pages/labelMark/components/RightSide.vue b/src/pages/labelMark/components/RightSide.vue
index 9bf6d66..e1f2177 100644
--- a/src/pages/labelMark/components/RightSide.vue
+++ b/src/pages/labelMark/components/RightSide.vue
@@ -1,65 +1,204 @@
 <template>
   <div class="right-side">
-    <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>
-    <div class="action-bar">
-      <el-button class="drawboard-trigger" size="small" @click="isEdit=!isEdit" :icon="isEdit?'el-icon-lock':'el-icon-edit'">{{isEdit?'閿佸畾':'缂栬緫'}}</el-button>
-    </div>
-    <div class="drawboard">
-      <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard" >
-        <div class="label" @click="editLabel(item)" v-for="(item,index) in labels" :key="index" :style="{left:`${item.x}px`, top:`${item.y}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"></div>
-      </div>
-      <img :src="baseUrl" alt />
-      <div class="popBox" v-show="isShowPop" :style="`top:${curLabel.y + 22}px;left:${curLabel.x}px`">
-        <div class="title">鏍囨敞淇℃伅</div>
-        <div class="details">
-          <div class="detail-item">
-            <div class="left">
-              <label for="">骞抽潰鍧愭爣X:</label>
-              <span class="fix-width">{{curLabel.x}}</span>
-              <i>px</i>
+    <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>
+            <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>
-            <span class="devide"></span>
-            <div class="right">
-              <label for="">瀹為檯鍧愭爣X:</label>
-              <el-input type="text" size="mini" style="width:90px" v-model="curLabel.posX"></el-input>
+            <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 class="detail-item">
-            <div class="left">
-              <label for="">骞抽潰鍧愭爣Y:</label>
-              <span class="fix-width">{{curLabel.y}}</span>
-              <i>px</i>
+        </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>
-            <span class="devide"></span>
-            <div class="right">
-              <label for="">瀹為檯鍧愭爣Y:</label>
-              <el-input type="text" size="mini" style="width:90px" v-model="curLabel.posY"></el-input>
+            <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>
-          <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="submitInfo">纭畾</el-button>
+        </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>
+            </div>
+            <div class="info" v-show="isShowCurPos">褰撳墠浣嶇疆:{{traceX}},{{traceY}}</div>
           </div>
-        </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';
 export default {
   data () {
     return {
@@ -69,99 +208,234 @@
       isEdit: false,
       isShowPop: false,
       isNewLabel: false,
+      // curLabel: {
+      //   id: '',
+      //   posX: '',
+      //   posY: '',
+      //   x: '',
+      //   y: ''
+      // },
       curLabel: {
-        id:'',
-        posX:'',
-        posY:'',
-        x:'',
-        y:''
+        id: '',
+        x1: '',
+        y1: '',
+        x0: '',
+        y0: ''
       },
-      baseUrl: ''
+      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: []
+      }
     }
   },
   computed: {
-    
+
   },
-  mounted(){
-    setTimeout(()=>{
-      let mockData = [{id:'a1',x:15, y:33, posX:150, posY:330},{id:'b2',x:56, y:87, posX:560, posY:870}];
-      this.labels = mockData;
-    },1000);
+  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:{
-    isEdit(n,o){
-      if(n){
-        this.$refs['editBoard'].addEventListener('click',this.bindListen);
-      }else{
-        this.$refs['editBoard'].removeEventListener('click',this.bindListen);
+  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
+    },
+    isEdit (n, o) {
+      if (n) {
+        this.$refs['editBoard'].addEventListener('click', this.bindListen);
+      } else {
+        this.$refs['editBoard'].removeEventListener('click', this.bindListen);
       }
     }
   },
   methods: {
-    bindListen(e){
+    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;
+        }
+      }).catch(e => {
+        console.log(e)
+      })
+    },
+    bindListen (e) {
       this.newLabel(e);
     },
-    newLabel(e){
+    newLabel (e) {
       console.log('鐐瑰嚮浜嗙敾鏉�')
-      if(this.isShowPop) return;
+      if (this.isShowPop) return;
       //鑾峰彇榧犳爣鐩稿浜庣敾鏉跨殑瀹氫綅
       console.log('鑾峰彇褰撳墠瀹氫綅淇℃伅');
+      this.$refs['labelForm'].resetFields();
       let target = {
-        id:'',
-        x:e.offsetX,
-        y:e.offsetY,
-        posX:'',
-        posY:''
+        id: '',
+        x0: e.offsetX,
+        y0: e.offsetY,
+        x1: '',
+        y1: ''
       };
-      this.labels.push(target);
+      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){
+    editLabel (label) {
       debugger
-      if(!this.isEdit) return;
+      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(){
+    cancle () {
       this.isShowPop = false;
       //濡傛灉鏄湭淇濆瓨杩囩殑label鐩存帴鍒犻櫎(鏈繚瀛樼殑灏辨槸labels鏁扮粍涓渶鍚庝竴涓�)
-      if(!this.curLabel.id){
-        this.labels.pop();
+      if (!this.curLabel.id) {
+        //this.labels.pop();
+        this.curCameraData.coords.pop();
       }
     },
-    deleteLabel(){
-      if(this.curLabel.id){
-        //璇锋眰鍚庡彴鍒犻櫎
-      }else{
-        this.labels.pop();
-        this.isShowPop = false;
-      }
-    },
-    submitInfo(){
+    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 {
-  height: 100%;
   background: #d2dcea;
+  .figure {
+    .el-tabs__content {
+      background: #d2dcea;
+      height: calc(100vh - 85px);
+    }
+  }
   .tool-bar {
-    width: 100%;
-    height: 60px;
-    padding: 10px 20px;
+    //width: 40px;
+    height: 100%;
+    padding: 10px 0 10px 20px;
     box-sizing: border-box;
-    background: rgb(250, 250, 250);
-    margin-bottom: 40px;
+    //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: rgb(245, 245, 245);
+      //background: rgba(245, 245, 245, 0.3);
       padding: 0 5px;
       height: 40px;
       margin: 7px;
@@ -170,95 +444,201 @@
       label {
         margin-right: 10px;
         color: rgb(161, 161, 161);
+        color: #fff;
       }
       .el-slider {
         width: 110px;
       }
     }
   }
-  .action-bar{
+  .shadow-box {
+    box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
+  }
+  .action-bar {
     width: 960px;
     margin: auto;
-    margin-bottom: 20px;
+    margin-top: 30px;
+    //margin-bottom: 20px;
     text-align: right;
-    .drawboard-trigger{
+    .drawboard-trigger {
       background: transparent;
       color: #fff;
-      border-color: rgba(255,255,255,.3);
+      border-color: rgba(255, 255, 255, 0.3);
     }
   }
   .drawboard {
     margin: auto;
     width: 960px;
     height: 540px;
+    margin-bottom: 130px;
     position: relative;
-    background: #fff;
-    box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
-    .mask{
+    //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{
+      &.edit-status-mask {
         background: rgba(20, 181, 255, 0.1);
       }
-      .label{
+      .label {
         position: absolute;
         z-index: 2;
         border-radius: 50%;
       }
     }
-    img{
+    img {
       width: 960px;
       height: 540px;
-      background:#f0ffca;
+      background: #f0ffca;
     }
-    .popBox{
+    .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(0,0,0,.7);
-      .title{
+      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{
+      .details {
+        .detail-item {
           display: flex;
-          align-items: center;
           margin: 5px 0;
-          label{
-            color: #ccc;
-            width:65px;
+          label {
+            color: #a9a9a9;
+            width: 65px;
             display: inline-block;
           }
-          .left{
+          .left {
             width: 110px;
             text-align: left;
             line-height: 28px;
-            .fix-width{
+            .fix-width {
               display: inline-block;
               width: 23px;
             }
           }
-          .right{
+          .right {
             width: 160px;
           }
-          .devide{
+          .devide {
             width: 10px;
             height: 1px;
-            background: #ccc;
-            margin: 0 3px;
+            background: #a9a9a9;
+            margin: 14px 3px;
           }
         }
-        .btns{
-          margin-top: 10px;          
+        .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%;
+    }
+  }
+}
+.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

--
Gitblit v1.8.0