From 673b81925c955494efa51c2052b00379702feca7 Mon Sep 17 00:00:00 2001
From: heyujie <516346543@qq.com>
Date: 星期一, 24 五月 2021 17:35:06 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.5.5:10010/r/vue-smart-ai

---
 public/images/systemMonitor/disk.png                |    0 
 src/pages/gb28181/index/App.vue                     |  472 ++++++-------
 src/pages/panoramicView/index/App.vue               |   19 
 src/pages/panoramicView/components/RelateCamera.vue |   58 
 public/images/systemMonitor/mem.png                 |    0 
 public/images/systemMonitor/net.png                 |    0 
 src/pages/panoramicView/components/SlideCanvas.vue  |   24 
 src/components/LeftNav.vue                          |    4 
 src/pages/gb28181/index/api.ts                      |   39 +
 src/pages/systemMonitor/api/api.ts                  |   16 
 public/apps.json                                    |   30 
 src/components/player/index.vue                     |   77 +
 src/pages/gb28181/index/main.ts                     |   14 
 src/components/giantTree/index.vue                  |   22 
 src/pages/panoramicView/components/LabelMark.vue    |   18 
 src/pages/systemMonitor/index/App.vue               |  715 +++++++++++++++++---
 src/components/giantTree/zTree/ztree.vue            |    7 
 src/Pool/TreeData.ts                                |  222 ++---
 public/images/systemMonitor/cpu.png                 |    0 
 public/images/systemMonitor/gpu.png                 |    0 
 src/pages/panoramicView/components/History.vue      |  241 +++++++
 src/pages/panoramicView/components/TracePlot.vue    |    9 
 22 files changed, 1,367 insertions(+), 620 deletions(-)

diff --git a/public/apps.json b/public/apps.json
index fd63aa6..29a9792 100644
--- a/public/apps.json
+++ b/public/apps.json
@@ -331,8 +331,8 @@
       "type": "2",
       "url": "/view/gb28181/",
       "title": "GB28181閰嶇疆",
-      "width": 600,
-      "height": 670,
+      "width": 1200,
+      "height": 970,
       "iconBlob": "",
       "icon": "../../images/app-mid/GB-config.png",
       "version": "1.0.2",
@@ -484,8 +484,8 @@
       "installed": true,
       "isUpgrade": false,
       "progressMsg": ""
-    },{
-      
+    },
+    {
       "id": "fa5674ee-70cf-4e22-8a06-c17429fb777",
       "name": "涔樺姟鍛樺畨鍏ㄨ涓哄垎鏋�",
       "package": "shuohuangMonitorAnalyze",
@@ -509,19 +509,19 @@
       "progressMsg": ""
     },
     {
-      "id": "af412cbe-472e-4dbc-b962-b290483c9ea1",
-      "name": "璁惧涓績",
-      "package": "deviceCenter",
+      "id": "fa5674ee-70cf-4e22-8a06-c171292b777",
+      "name": "绯荤粺鐩戞帶",
+      "package": "systemMonitor",
       "type": "2",
-      "url": "/view/deviceCenter/",
-      "title": "璁惧涓績",
-      "width": 1200,
-      "height": 670,
+      "url": "/view/systemMonitor/",
+      "title": "绯荤粺鐩戞帶",
+      "width": 1220,
+      "height": 800,
       "iconBlob": "",
-      "icon": "../../images/app-mid/datastack-config.png",
-      "version": "1.0.1",
-      "create_time": "2021-04-01 21:47:38",
-      "create_by": "basic",
+      "icon": "../../images/app-mid/visual.png",
+      "version": "1.0.0",
+      "create_time": "2020-10-09 14:00:08",
+      "create_by": "",
       "update_time": "",
       "update_by": "",
       "isDelete": 0,
diff --git a/public/images/systemMonitor/cpu.png b/public/images/systemMonitor/cpu.png
new file mode 100644
index 0000000..f7ce397
--- /dev/null
+++ b/public/images/systemMonitor/cpu.png
Binary files differ
diff --git a/public/images/systemMonitor/disk.png b/public/images/systemMonitor/disk.png
new file mode 100644
index 0000000..0af8eca
--- /dev/null
+++ b/public/images/systemMonitor/disk.png
Binary files differ
diff --git a/public/images/systemMonitor/gpu.png b/public/images/systemMonitor/gpu.png
new file mode 100644
index 0000000..73836b2
--- /dev/null
+++ b/public/images/systemMonitor/gpu.png
Binary files differ
diff --git a/public/images/systemMonitor/mem.png b/public/images/systemMonitor/mem.png
new file mode 100644
index 0000000..9de8c56
--- /dev/null
+++ b/public/images/systemMonitor/mem.png
Binary files differ
diff --git a/public/images/systemMonitor/net.png b/public/images/systemMonitor/net.png
new file mode 100644
index 0000000..fc8461b
--- /dev/null
+++ b/public/images/systemMonitor/net.png
Binary files differ
diff --git a/src/Pool/TreeData.ts b/src/Pool/TreeData.ts
index 0289f6c..4d5c6a5 100644
--- a/src/Pool/TreeData.ts
+++ b/src/Pool/TreeData.ts
@@ -8,10 +8,11 @@
   refreshGB28181Tree,
   updateCameraArea
 } from '@/api/area'
-import { findAllFile, show, changeEnable } from '@/api/localVedio'
 
 export default class TreeDataPool {
   public openeds: Array<boolean>
+  public activeTreeData: Array<object>
+
   public treeData: Array<object>
   public clusterData: Array<object>
   public gb28181Data: Array<object>
@@ -37,20 +38,6 @@
   public foldNodeList: object
   //璁板綍宸︿晶tab锛歛ctiveName
   public treeActiveName: string
-  //鏈湴瑙嗛锛氳棰戝垎鏋愬鐞�
-  public vedioAnaliyseSwitch: boolean
-  //鏈湴瑙嗛鍒楄〃
-  public localVedioList: Array<any>
-  //鏈湴瑙嗛褰撳墠椤�
-  public localCurrentPage: number
-  //鏈湴瑙嗛姣忛〉鏌ヨ20鏉�
-  public localPageSize: number
-  //鏈湴瑙嗛鎬绘潯鏁�
-  public localTotal: number
-  //鍕鹃�夌殑鏈湴瑙嗛
-  public checkedLocalVedio: Array<any>
-  //褰撳墠閫変腑鐨勬湰鍦拌棰�
-  public clickLocalVideo: object
   //鎺у埗寮�濮嬨�佹殏鍋滄寜閽樉绀虹姸鎬�
   public btnStaus: string
   //鏈湴瑙嗛绫诲瀷
@@ -60,10 +47,19 @@
   //璁板綍澶嶅埗鐨勬憚鍍忔満name
   public ctrlCameraName: string
 
+  // 鏄惁浣跨敤ztree
   public zTree: boolean
+
+  public checkedTreeNode: Array<object>
+
+  // 閫変腑鐨勬憚鍍忔満涓暟
+  public gb28181CheckedCount: number
+  // 鎬绘憚鍍忔満涓暟
+  public gb28181ChildNodeCount: number
 
   constructor() {
     this.openeds = [true, true, false]
+    this.activeTreeData = []
     this.treeData = []
     this.gb28181Data = []
     this.clusterData = []
@@ -84,20 +80,17 @@
     this.selectedNode = {}
     this.treeType = ''
     this.foldNodeList = {}
-    this.vedioAnaliyseSwitch = false
     this.treeActiveName = 'camera'
     this.searchLocalType = 0
-    this.localVedioList = []
-    this.checkedLocalVedio = []
-    this.clickLocalVideo = {}
+
     //1:鏆傚仠鐘舵�侊紱2锛氱瓑寰呯姸鎬�;3:缃伆
     this.btnStaus = '3'
-    this.localCurrentPage = 1
-    this.localPageSize = 20
-    this.localTotal = 0
     this.ctrlCameraId = ''
     this.ctrlCameraName = ''
     this.zTree = false
+    this.checkedTreeNode = []
+    this.gb28181CheckedCount = 0
+    this.gb28181ChildNodeCount = 0
   }
 
   setVideoArr(index: number, value: object, vue: any): void {
@@ -261,8 +254,6 @@
     this.isFold(this.gb28181Data)
     this.selectedNodes = []
     this.selectedNode = {}
-
-    this.cleanLocalVedio()
   }
 
   cleanTree(tree) {
@@ -397,8 +388,6 @@
     if (this.openeds[1]) {
       this.fetchGbTree()
     }
-
-    this.findAllFile({})
   }
 
   async add(name: string, parent: string) {
@@ -434,109 +423,84 @@
     // this.fetchGbTree()
   }
 
-  async findAllFile(params: any) {
-    ; (params.fileName = this.searchInput), (params.type = this.searchLocalType)
-    params.page = this.localCurrentPage
-    params.size = this.localPageSize
-    let res: any = await findAllFile(params)
-    if (res && res.success) {
-      let list = res.data.dataList.map(i => {
-        let obj: any = {}
-        Object.assign(obj, i)
-        if (i.ruleType == 0) {
-          obj.iconStatus2 = '0'
-        } else {
-          obj.iconStatus2 = '1'
-        }
-        if (!i.snapshot_url) {
-          // obj.snapshot_url = require('@/assets/nobody.png')
-          obj.snapshot_url = ''
-        } else {
-          obj.snapshot_url = '/httpImage/' + obj.snapshot_url
-        }
-        if (i.is_running) {
-          obj.iconStatus1 = '1'
-        } else if (i.progress == 100) {
-          obj.iconStatus1 = '2'
-        } else if (i.status == 1 && i.progress == 0 && i.hasRule) {
-          obj.iconStatus1 = '3'
-        } else if (!i.hasRule && i.progress == 0) {
-          obj.iconStatus1 = '4'
-        }
-        obj.checkStatus = false
-        obj.clickStatus = false
-        obj.showCheckBox = false
-        return obj
-      })
-      this.localVedioList = list
-      this.localTotal = res.data.total
-      // console.log(this.localVedioList,this.searchInput,'鏈湴瑙嗛鍒楄〃')
-    }
-  }
-
-  async show() {
-    let res: any = await show()
-    if (res && res.success) {
-      this.vedioAnaliyseSwitch = res.data.videoEnable
-    }
-  }
-
-  async changeEnable() {
-    let res: any = await changeEnable({
-      enable: this.vedioAnaliyseSwitch
-    })
-  }
-
-  getCheckedFiles() {
-    this.checkedLocalVedio = this.localVedioList.filter(i => {
-      return i.checkStatus
-    })
-    this.clickLocalVideo = this.localVedioList.filter(i => {
-      return i.clickStatus
-    })[0]
-
-    if (this.checkedLocalVedio.length === 0) {
-      this.btnStaus = '3'
-      return false
-    }
-    this.checkedLocalVedio.every((i, index) => {
-      let t = ''
-      if (i.status == 0 && i.hasRule) {
-        t = '1'
-      } else if (i.status == 1 && i.hasRule && !i.is_running) {
-        t = '2'
-      } else {
-        t = '3'
-      }
-      if (index == 0) {
-        this.btnStaus = t
-      } else {
-        if (this.btnStaus !== t) {
-          this.btnStaus = '3'
-          return false
-        }
-      }
-    })
-  }
-
-  filterLocalVideoWell() {
-    if (this.localVedioList.length !== 0) {
-      this.localVedioList = this.localVedioList.filter(i => {
-        return i.progress == 100
-      })
-    }
-  }
-
-  cleanLocalVedio() {
-    this.localVedioList.map(i => {
-      i.checkStatus = false
-      i.clickStatus = false
-    })
-    this.checkedLocalVedio = []
-    this.btnStaus = '3'
-  }
-
-  async dropNode(cameraId, areaId) {
+  async dropNode(cameraId: string, areaId: string) {
     await updateCameraArea({ cameraId: cameraId, areaId: areaId })
   }
+
+  getAllChildrenNodes(treeNode, arr) {
+    for (var i = 0; i < treeNode.length; i++) {
+      var sonList = treeNode[i].children;
+      if (!sonList) {
+        if (treeNode[i].type == "camera") {
+          arr.push(treeNode[i]);
+
+          if (treeNode[i].checked) {
+            this.gb28181CheckedCount += 1;
+          }
+        }
+      } else {
+        this.getAllChildrenNodes(sonList, arr);
+      }
+    }
+    return arr;
+  }
+  countChildrenNodes(treeNode) {
+    let arry = []
+
+    this.getAllChildrenNodes(treeNode, arry)
+
+    return arry.length
+  }
+
+  async fetchVideosvrCameras() {
+    const rsp: any = await refreshGB28181Tree()
+
+    if (rsp && rsp.success) {
+      this.selectedNode = {}
+      this.treeData = rsp.data ? rsp.data : []
+      if (this.treeData && this.treeData.length > 0) {
+        this.sortTreeData(this.treeData)
+      }
+
+      // 璁剧疆绂佹鎷栨嫿鎽勫儚鏈哄埌鎽勫儚鏈鸿妭鐐�
+      this.setDropDisable(this.treeData)
+      this.isFold(this.treeData)
+
+      this.activeTreeData = this.treeData
+
+      this.gb28181CheckedCount = 0;
+      this.gb28181ChildNodeCount = this.countChildrenNodes(this.treeData)
+    }
+  }
+
+  removeNoCheckedNode(nodes: Array<any>) {
+    for (let i = 0; i < nodes.length;) {
+      if (!nodes[i].checked) {
+        nodes.splice(i, 1)
+        continue
+      }
+
+      if (nodes[i].children && nodes[i].children.length) {
+        this.removeNoCheckedNode(nodes[i].children)
+      }
+      i++
+    }
+  }
+
+  countCheckedNodes(nodes: Array<any>) {
+    let count = 0
+    nodes.forEach(n => {
+      if (n.type == "camera") {
+        count++
+      }
+    })
+    this.gb28181CheckedCount = count
+  }
+
+  newTreeByChecked(nodes: Array<object>) {
+    let newTree = JSON.parse(JSON.stringify(nodes))
+    this.removeNoCheckedNode(newTree)
+
+    return newTree
+  }
 }
diff --git a/src/components/LeftNav.vue b/src/components/LeftNav.vue
index 0c1137f..e63e984 100644
--- a/src/components/LeftNav.vue
+++ b/src/components/LeftNav.vue
@@ -123,14 +123,14 @@
               </template>
 
               <!-- 鍥芥爣鍒锋柊鍥炬爣 -->
-              <div class="tree-edit gb-refresh" v-show="!TreeDataPool.gbReadonly">
+              <!-- <div class="tree-edit gb-refresh" v-show="!TreeDataPool.gbReadonly">
                 <el-tooltip content="鍒锋柊" placement="top" popper-class="atooltip">
                   <button @click="refreshGB">
                     <i v-if="loadingGBTree" class="el-icon-loading" style="font-size:16px"></i>
                     <i v-else class="el-icon-refresh" style="font-size:16px"></i>
                   </button>
                 </el-tooltip>
-              </div>
+              </div>-->
               <div class="tree-edit gb-lock" v-show="showLock">
                 <button @click="gbLockSwitch">
                   <i v-if="TreeDataPool.gbReadonly" class="el-icon-lock" style="font-size:16px"></i>
diff --git a/src/components/giantTree/index.vue b/src/components/giantTree/index.vue
index aabca2d..8ba269b 100644
--- a/src/components/giantTree/index.vue
+++ b/src/components/giantTree/index.vue
@@ -5,6 +5,7 @@
       :show-checkbox="TreeDataPool.multiple"
       :readonly="TreeDataPool.readonly"
       :gb28181="gb28181"
+      :setting="setting"
       @onCreated="handleCreated"
       @onClick="itemClick"
       @onCheck="itemCheck"
@@ -66,7 +67,14 @@
     height: {
       type: Number,
       default: 0
-    }
+    },
+    setting: {
+      type: Object,
+      require: false,
+      default: function () {
+        return {};
+      },
+    },
   },
   data() {
     return {
@@ -117,13 +125,10 @@
         //鎽勫儚鏈轰俊鎭洿鏂颁俊鎭悗锛屽鏋滆妭鐐逛綅缃湁鍙榯Id灏变笉鍑嗕簡,this.TreeDataPool.selectedNode姝ゆ椂杩樻槸鏃х殑淇℃伅
         let ztreeNodes = ztreeObj.getNodes();
         //var curNodeTid = '';
-        console.log(ztreeNodes)
         _this.findTidByIdFromArr(ztreeNodes);
-        console.log('curNodeTid', _this.curNodeTid)
         this.TreeDataPool.selectedNode.tId = _this.curNodeTid;
         let node = this.ztreeObj.getNodeByTId(this.TreeDataPool.selectedNode.tId)
-        console.log('selecBode', this.TreeDataPool.selectedNode)
-        console.log('selectedNode.tId', this.TreeDataPool.selectedNode.tId)
+
         // 澶氶�夋椂, 閫変腑鍗曢�夊崟鍑荤殑鑺傜偣
         if (this.TreeDataPool.multiple) {
           this.ztreeObj.checkAllNodes(false);
@@ -266,7 +271,6 @@
       this.showDialog = true;
     },
     itemClick(evt, treeId, treeNode) {
-      console.log(evt, treeId)
 
       this.TreeDataPool.selectedNode = treeNode;
       this.TreeDataPool.treeType = this.treeName;
@@ -301,6 +305,12 @@
       // this.ztreeObj.checkNode(treeNode, true, false, false);
       let checkedNodes = this.ztreeObj.getCheckedNodes(true);
       this.TreeDataPool.updateZTreeCheckNodes(checkedNodes);
+
+      // 瀹炴椂缁熻閫変腑涓暟
+      this.TreeDataPool.countCheckedNodes(checkedNodes);
+
+      // 淇濆瓨涓�浠芥暟鎹�
+      this.TreeDataPool.activeTreeData = this.ztreeObj.getNodes()
     },
     //灞曞紑
     itemExpand(e, id, node) {
diff --git a/src/components/giantTree/zTree/ztree.vue b/src/components/giantTree/zTree/ztree.vue
index 15a905b..b8e5024 100644
--- a/src/components/giantTree/zTree/ztree.vue
+++ b/src/components/giantTree/zTree/ztree.vue
@@ -112,7 +112,6 @@
             Object.assign({}, this.ztreeSetting, this.setting),
             this.list
           );
-          console.log('onCreated,ztr')
           this.$emit("onCreated", this.ztreeObj);
         });
       },
@@ -275,8 +274,8 @@
   padding: 5px;
   color: #333;
 }
-.ztree .iconfenxishexiangji{
-  color: #3d68e1!important;
+.ztree .iconfenxishexiangji {
+  color: #3d68e1 !important;
 }
 .ztree li {
   padding: 0;
@@ -386,7 +385,7 @@
   background-attachment: scroll;
   /* background-image: url("./img/zTreeStandard.png"); */
   /* *background-image: url("./img/zTreeStandard.gif"); */
-  
+
   background-image: url(data:image/png;base64,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);
   *background-image: url(data:image/gif;base64,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);
 }
diff --git a/src/components/player/index.vue b/src/components/player/index.vue
index c64cf57..a1757a3 100644
--- a/src/components/player/index.vue
+++ b/src/components/player/index.vue
@@ -47,9 +47,8 @@
       default: false
     }
   },
- 
-  computed: {
 
+  computed: {
     poster() {
       return "/images/player/player_poster.gif?t=" + Math.random()
     }
@@ -76,6 +75,7 @@
       ctx: null,
       canvasWidth: 0,
       canvasHeight: 0,
+      algoDataSocket: null
     };
   },
   watch: {
@@ -83,6 +83,7 @@
       if (newVal !== oldVal) {
         if (this.wfs.config) {
           this.wfs.destroy();
+          !!this.algoDataSocket && this.algoDataSocket.close()
         }
         this.$nextTick(() => {
           this.clickStart();
@@ -90,13 +91,29 @@
       }
     }
   },
+  mounted() {
+    this.clickStart();
+    this.$nextTick(() => {
+      this.canvas = this.$refs.areaCanvas;
+      this.ctx = this.canvas.getContext("2d");
+      this.ctx.lineWidth = 1;
+      this.initArea();
+
+    })
+  },
+  beforeDestroy() {
+    this.wfs.destroy();
+    this.wfsId = "";
+
+    !!this.algoDataSocket && this.algoDataSocket.close()
+  },
   methods: {
     checkConnect(id) {
       // console.log(this.wfs)
       if (id !== this.wfsId) {
         return
       }
-      
+
       if (this.wfs.websocketLoader && this.wfs.websocketLoader.client) {
         if (this.wfs.websocketLoader.client.disconnected) {
           this.clickStart();
@@ -176,7 +193,7 @@
         _this.ctx.lineTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
         _this.ctx.stroke();
         _this.canvas.style.cursor = "default";
-        
+
       });
       _this.canvasData.arrow.forEach(function (v, i) {
         _this.ctx.strokeStyle = "yellow";
@@ -189,9 +206,9 @@
           20,
           30,
           "yellow"
-        ); 
+        );
         _this.canvas.style.cursor = "default";
-        
+
       });
       _this.canvasData.polygon.forEach(function (v, i) {
         if (v.location.length === 0) {
@@ -206,12 +223,12 @@
         _this.ctx.closePath();
         _this.ctx.stroke();
         _this.canvas.style.cursor = "default";
-        
+
       });
     },
-    
+
     // 绠ご缁樺埗鍑芥暟
-    drawArrow(ctx, fromX, fromY, toX, toY, theta=30, headlen=10, width=1, color="yellow") {
+    drawArrow(ctx, fromX, fromY, toX, toY, theta = 30, headlen = 10, width = 1, color = "yellow") {
       // ctx锛欳anvas缁樺浘鐜
       // fromX, fromY锛氳捣鐐瑰潗鏍囷紙涔熷彲浠ユ崲鎴恜1锛屽彧涓嶈繃瀹冩槸涓�涓暟缁勶級
       // toX, toY锛氱粓鐐瑰潗鏍� (涔熷彲浠ユ崲鎴恜2锛屽彧涓嶈繃瀹冩槸涓�涓暟缁�)
@@ -251,7 +268,7 @@
       ctx.stroke();
       ctx.restore();
     },
-    
+
     // 鍥炴樉鍥惧舰澶囨敞
     showRemarks(x, y, remarks) {
       this.ctx.moveTo(x, y - 10); // 鍥犱负鏀惧ぇ涔嬪悗鏄痽-20锛屾墍浠ョ缉灏忕増鐨勪负y-10
@@ -269,41 +286,43 @@
         this.Camera.getCameraTask();
       });
     },
-    setWidthHeight(){
+    setWidthHeight() {
       this.canvasWidth = this.$refs.videoPlayer.offsetWidth;
       this.canvasHeight = this.$refs.videoPlayer.offsetHeight;
-      console.log(this.canvasWidth,this.canvasHeight)
+      console.log(this.canvasWidth, this.canvasHeight)
     },
-    async initArea(){
+    async initArea() {
       console.log('init')
-      const res = await getAllPolygon({cameraId: this.TreeDataPool.selectedNode.id});
+      const res = await getAllPolygon({ cameraId: this.TreeDataPool.selectedNode.id });
       this.canvasData.line = res.data.line;
       this.canvasData.rect = res.data.rect;
       this.canvasData.arrow = res.data.arrow;
       this.canvasData.polygon = res.data.polygon;
       console.log(this.canvasData)
       this.clickSelect(this.canvasData);
+    },
+    initAlgoDataWebScoket() {
+      if (typeof (WebSocket) === "undefined") {
+        console.log("error,鎮ㄧ殑娴忚鍣ㄤ笉鏀寔socket")
+      } else {
+        this.algoDataSocket = new WebSocket()
+        this.algoDataSocket.onopen = () => {
+          console.log("socket杩炴帴鎴愬姛")
+        }
+        this.algoDataSocket.onerror = () => {
+          console.log("杩炴帴閿欒")
+        }
+        this.algoDataSocket.onmessage = msg => {
+          console.log(msg)
+        }
+      }
     }
-  },
-  mounted() {
-    this.clickStart();
-    this.$nextTick(()=>{
-      this.canvas = this.$refs.areaCanvas;
-      this.ctx = this.canvas.getContext("2d");
-      this.ctx.lineWidth = 1;
-      this.initArea();
-
-    })
-  },
-  beforeDestroy() {
-    this.wfs.destroy();
-    this.wfsId = "";
   }
 };
 </script>
 
 <style lang="scss">
-#area-canvas{
+#area-canvas {
   background: transparent;
   position: absolute;
   top: 0;
diff --git a/src/pages/gb28181/index/App.vue b/src/pages/gb28181/index/App.vue
index 45f138f..4ec547c 100644
--- a/src/pages/gb28181/index/App.vue
+++ b/src/pages/gb28181/index/App.vue
@@ -1,20 +1,15 @@
 <template>
-  <div class="s-basic-setting" @contextmenu.prevent="toOpenMenuList">
-    <el-menu
-      :default-openeds="openeds"
-      background-color="#fff"
-      text-color="#303133"
-      active-text-color="#409EFF"
-      style="height: 100%;"
-      class="menu-css"
-      @open="menuOpen"
-      @close="menuClose"
-    >
-      <el-submenu index="0">
-        <template slot="title">
-          <b class="tree-font">鍥介檯ID</b>
-        </template>
-        <el-menu-item-group class="item-group">
+  <div class="s-system-manage">
+    <div class="s-basic-setting">
+      <el-tabs
+        id="e-basic-setting"
+        v-model="activeName"
+        v-loading="loading"
+        :element-loading-text="loadingText"
+        type="border-card"
+        @tab-click="hanleTabClick"
+      >
+        <el-tab-pane label="鍥芥爣ID" name="gb28181">
           <!-- GB28181璁剧疆 -->
           <el-form
             :model="gb28181"
@@ -115,45 +110,60 @@
               <el-button type="primary" @click="submitGB28281" size="small">淇濆瓨</el-button>
             </el-form-item>
           </el-form>
-        </el-menu-item-group>
-      </el-submenu>
-      <el-submenu index="1">
-        <template slot="title">
-          <b class="tree-font">鎺ュ叆骞冲彴鍒楄〃</b>
-        </template>
-        <el-menu-item-group class="item-group">
-          <div>
-            <el-table
-              :data="tableList"
-              border
-              fit
-              highlight-current-row
-              style="width: 100%; color:#000"
-              :header-cell-style="{ background: '#f8f8f8', color: '#222222', height:'30px'  }"
-            >
-              <el-table-column type="index" label="搴忓彿" align="center" width="50"></el-table-column>
-              <el-table-column prop="name" label="鍚嶇О" align="center"></el-table-column>
-              <el-table-column prop="id" label="ID" align="center"></el-table-column>
-              <el-table-column prop="ip" label="IP" align="center"></el-table-column>
-              <el-table-column prop="status" label="鐘舵��" align="center"></el-table-column>
-              <el-table-column prop="mark" label="澶囨敞" align="center"></el-table-column>
-            </el-table>
+        </el-tab-pane>
+
+        <el-tab-pane label="鎺ュ叆骞冲彴鍒楄〃" name="subordinates">
+          <el-table
+            :data="subDevTable"
+            border
+            fit
+            highlight-current-row
+            style="width: 100%; color:#000"
+            :header-cell-style="{ background: '#f8f8f8', color: '#222222', height:'30px'  }"
+          >
+            <el-table-column type="index" label="搴忓彿" align="center" width="50"></el-table-column>
+            <el-table-column prop="name" label="鍚嶇О" align="center"></el-table-column>
+            <el-table-column prop="publicid" label="ID" align="center"></el-table-column>
+            <el-table-column prop="ip" label="IP" align="center"></el-table-column>
+            <el-table-column prop="status" label="鐘舵��" align="center">
+              <template slot-scope="scope">
+                <span
+                  :style="scope.row.active ? `color:#047d19` : 'color:#f11a1a;' "
+                >{{scope.row.active ? "鍦ㄧ嚎": "绂荤嚎"}}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="mark" label="澶囨敞" align="center"></el-table-column>
+          </el-table>
+        </el-tab-pane>
+        <el-tab-pane label="鍥芥爣鎽勫儚鏈�" name="cameras">
+          <div style="text-align:left">
+            <el-button type="primary" size="small" @click="getCamerasFromVideosvr">鍒锋柊</el-button>
           </div>
-        </el-menu-item-group>
-      </el-submenu>
-      <el-submenu index="2">
-        <template slot="title">
-          <b class="tree-font">鍥介檯鎽勫儚鏈�</b>
-        </template>
-        <el-menu-item-group class="item-group">
-          <div>
-            <div>
-              <el-button type="primary" size="small">鍒锋柊</el-button>
-            </div>
+          <div class="camera-title">
+            <b>鍥芥爣鎽勫儚鏈洪厤缃�</b>
+            <span>(鏈�澶氬嬀閫�500璺憚鍍忔満)</span>
           </div>
-        </el-menu-item-group>
-      </el-submenu>
-    </el-menu>
+          <tree-menu
+            ref="tree"
+            app="gb28181"
+            treeName="localTree"
+            :node="TreeDataPool.treeData"
+            :height="treeHeight"
+            :setting="treeSettings"
+          />
+
+          <el-divider></el-divider>
+
+          <span class="camera-seleted-text">
+            宸查�夋嫨 (
+            <b>{{TreeDataPool.gb28181CheckedCount}}</b>
+            / {{TreeDataPool.gb28181ChildNodeCount}} ) 璺�
+          </span>
+
+          <el-button type="primary" size="small" @click="saveChecked">淇濆瓨</el-button>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
   </div>
 </template>
 
@@ -162,13 +172,20 @@
   getGB28181Config,
   saveGB28181Config,
   getGb28181AreaList,
-  newGb28181ID
+  newGb28181ID,
+  getLocalCameraTree,
+  getAllSubServer,
+  saveGb28181CamTree
 } from './api'
 
+import TreeMenu from "@/components/giantTree/index";
 import { isPort, isIPv4 } from '@/scripts/validate'
 import bus from '@/plugin/bus'
 export default {
   name: 'Gb28181Setting',
+  components: {
+    TreeMenu
+  },
   directives: {
     focus: {
       inserted: function (el) {
@@ -179,10 +196,19 @@
 
   data() {
     return {
+      activeName: "gb28181",
+      treeHeight: 750,
+      loading: false,
+      loadingText: "",
       openeds: ['0'],
       gb28181: {},
-      tableList: [],
+      subDevTable: [],
       idType: 1,
+      treeSettings: {
+        check: {
+          enable: true
+        }
+      },
       rules: {
         ip: [
           {
@@ -228,12 +254,59 @@
     }
   },
   mounted() {
+    this.TreeDataPool.multiple = true;
 
-    //this.$nextTick(()=>{
-    this.initGB28181Conf()
-    //})
+    this.initGB28181Conf();
   },
   methods: {
+    hanleTabClick(tab, event) {
+      if (this.activeName == "subordinates") {
+        getAllSubServer().then(rsp => {
+          if (rsp && rsp.success) {
+            this.subDevTable = rsp.data;
+          }
+        })
+      } else if (this.activeName == "cameras") {
+        this.getCamerasFromVideosvr();
+      }
+
+
+    },
+    async getCamerasFromVideosvr() {
+      this.loading = true;
+      await this.TreeDataPool.fetchVideosvrCameras();
+      this.loading = false;
+    },
+    saveChecked() {
+      if (this.TreeDataPool.gb28181CheckedCount > 500) {
+        this.$message({
+          type: "warning",
+          message: "鏈�澶氫粎鏀寔閫夋嫨500璺憚鍍忔満. 璇烽噸鏂伴�夋嫨"
+        })
+
+        return;
+      }
+
+      this.loading = true;
+
+      let treeData = this.TreeDataPool.newTreeByChecked(this.TreeDataPool.activeTreeData)
+
+      saveGb28181CamTree({ checkedMenus: treeData }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$message({
+            type: "success",
+            message: "淇濆瓨鎴愬姛"
+          })
+        }
+        this.loading = false;
+      }).catch(err => {
+        this.$message({
+          type: "error",
+          message: "淇濆瓨澶辫触"
+        })
+        this.loading = false;
+      })
+    },
     initGB28181Conf() {
       getGB28181Config().then(rsp => {
         if (rsp && rsp.success) {
@@ -311,236 +384,119 @@
 }
 </script>
 <style lang="scss">
-.s-basic-setting {
+.s-system-manage {
+  width: 100% !important;
+  min-width: 1067px;
   height: 100%;
-  padding: 20px;
   box-sizing: border-box;
-  .item-group {
-    padding: 0 15px;
-    margin-bottom: 15px;
-  }
-  .el-form {
-    .el-form-item {
-      text-align: left;
-      margin-bottom: 16px;
-      &:last-of-type {
-        width: 490px;
-      }
-      .el-button {
-        float: right;
-      }
-      .el-select {
-        margin-right: 10px;
-      }
-      .el-form-item__content {
-        text-align: left;
-        input {
-          max-width: 360px;
-        }
-        .el-date-editor.el-input,
-        .el-date-editor.el-input__inner {
-          width: 216px;
-        }
-        .el-checkbox__label {
-          padding-left: 5px;
-        }
-      }
-
-      .el-form-item__label {
-        text-align: left;
-      }
-      &.el-form-item.is-required:not(.is-no-asterisk)
-        > .el-form-item__label:before {
-        margin-left: -9px;
-      }
-    }
-  }
-  .alarmSetting {
-    .el-input {
-      width: 100%;
-      // padding-right: 10px;
-    }
-    .el-select {
-      max-width: 113px;
-    }
-    .el-slider {
-      width: calc(100% - 120px);
-      display: inline-block;
-      padding-right: 30px;
-      box-sizing: border-box;
-      vertical-align: middle;
-    }
-    .el-input-number {
-      width: 100px;
-      display: inline-block;
-      .el-input {
-        width: 100%;
-      }
-    }
+  padding: 10px;
+  background-color: #f8f9fb;
+  .s-system-manage-breadcrumb {
+    height: 5%;
+    box-sizing: border-box;
+    border: 1px solid #e4e7ed;
+    box-shadow: #e4e7ed 0px 0px 9px inset;
+    box-shadow: #e4e7ed 0px 0px 9px inset;
+    border-radius: 5px;
   }
 
-  .time-type {
-    height: 25px;
-    width: 413px;
-    line-height: 28px;
-    padding: 3px 23px;
-    font-size: 14px;
-    font-weight: 600;
-    background-color: #e4e6ed;
-  }
-  #e-basic-setting {
+  .el-tabs--border-card {
+    border: 0px solid #dcdfe6;
+    -webkit-box-shadow: none;
+    box-shadow: none;
     .el-tabs__header {
       border: 0px solid #dcdfe6;
       .el-tabs__item {
         padding: 5px 50px;
         height: 50px;
         font-family: PingFangSC-Regular;
-        font-size: 14px;
+        font-size: 15px;
         color: #222222;
         text-align: center;
         border: 0px solid transparent;
       }
       .el-tabs__item:nth-child(2) {
-        padding-left: 50px;
+        padding-left: 50px !important;
       }
       .el-tabs__item:last-child {
-        padding-right: 50px;
+        padding-right: 50px !important;
       }
       .el-tabs__item.is-active {
-        color: #ff7733;
-        font-weight: bold;
+        color: #3d68e1;
+
         // border-right-color: #fff;
         // border-left-color: #fff;
       }
       .el-tabs__item:not(.is-disabled):hover {
-        color: #ff7733;
-      }
-    }
-    .el-tabs__active-bar {
-      background-color: #ff7733;
-    }
-    .xiangqin-label {
-      text-align: left;
-      width: 85px;
-      font-size: 14px;
-      line-height: 30px;
-    }
-    .xiangqing-info {
-      text-align: left;
-      font-size: 14px;
-      line-height: 30px;
-    }
-  }
-
-  #cut_min_duration {
-    .el-slider__bar {
-      background-color: #3d68e1;
-    }
-    .el-slider__button {
-      width: 10px;
-      height: 10px;
-      border: 4px solid #3d68e1;
-    }
-  }
-
-  #cut_max_duration {
-    .el-slider__bar {
-      background-color: #ff9e6e;
-    }
-    .el-slider__button {
-      width: 10px;
-      height: 10px;
-      border: 4px solid #ff9e6e;
-    }
-  }
-  .menu-css,
-  .el-menu {
-    border-right: none;
-    list-style: none;
-    position: relative;
-    margin: 0;
-    padding-left: 0;
-    background-color: #ffffff;
-    .el-submenu__title {
-      height: 35px;
-      line-height: 35px;
-      font-size: 14px;
-      color: #303133;
-      padding: 0 20px;
-      list-style: none;
-      cursor: pointer;
-      position: relative;
-      -webkit-transition: border-color 0.3s, background-color 0.3s, color 0.3s;
-      transition: border-color 0.3s, background-color 0.3s, color 0.3s;
-      -webkit-box-sizing: border-box;
-      box-sizing: border-box;
-      white-space: nowrap;
-    }
-    .tree-font {
-      font-family: PingFangSC-Medium;
-      font-size: 14px;
-      color: #222222;
-      text-align: left;
-    }
-    li {
-      text-align: left;
-      .el-submenu__title {
-        // border-bottom: solid 1px #e6e6e6;
-        padding-left: 10px !important;
-        background-color: #e4e6ed !important;
-        border-radius: 2px;
-        .el-submenu__icon-arrow {
-          position: absolute;
-          top: 50%;
-          right: auto;
-          left: 135px;
-          margin-top: -7px;
-          -webkit-transition: -webkit-transform 0.3s;
-          transition: -webkit-transform 0.3s;
-          transition: transform 0.3s;
-          transition: transform 0.3s, -webkit-transform 0.3s;
-          font-size: 12px;
-        }
+        color: #3d68e1;
       }
     }
   }
-  .save-btn {
-    text-align: right;
-    position: relative;
-    right: 40px;
+  .el-tabs__header {
+    margin-bottom: 0;
   }
-}
-</style>
-<style lang="scss" scoped>
-.menu-css,
-.el-menu {
-  border-right: none;
-  list-style: none;
-  position: relative;
-  margin: 0;
-  padding-left: 0;
-  background-color: #ffffff;
+  .el-tabs__content {
+    height: calc(100% - 64px);
+    box-sizing: border-box;
+    overflow-y: auto;
+    padding: 20px 40px !important;
+    background: #fff;
+    .el-tab-pane {
+      width: 100%;
+      .s-title {
+        text-align: left;
+        padding: 15px 0px;
+        font-size: 16px;
+      }
+    }
+  }
 
-  .tree-font {
-    font-family: PingFangSC-Medium;
+  .s-table {
+    border: 1px solid #e8e8e9;
+    margin-top: 40px;
+  }
+
+  .ui-top-title {
+    padding-bottom: 10px;
+    /* border-bottom: 1px solid #ebebeb; */
+    position: relative;
+    text-align: left;
+    padding-left: 15px;
+    font-size: 16px;
+    font-weight: bold;
+  }
+
+  .ui-top-title:before {
+    content: " ";
+    border-left: 4px solid #f53d3d;
+    display: inline-block;
+    height: 16px;
+    position: absolute;
+    top: 50%;
+    left: 0;
+    margin-top: -13px;
+  }
+
+  .el-button--text {
+    color: #3d68e1;
+    text-decoration: underline;
+  }
+
+  .camera-title {
+    text-align: left;
+    padding: 0px 10px;
+    margin: 5px 0px;
+    height: 33px;
+    background-color: #e4e2e2;
+    line-height: 33px;
     font-size: 14px;
-    color: #222222;
-    text-align: left;
   }
-  li {
-    text-align: left;
-    .el-submenu__title {
-      .el-submenu__icon-arrow {
-        position: absolute;
-        top: 50%;
-        right: 0;
-        margin-top: -7px;
-        -webkit-transition: -webkit-transform 0.3s;
-        transition: -webkit-transform 0.3s;
-        transition: transform 0.3s;
-        transition: transform 0.3s, -webkit-transform 0.3s;
-        font-size: 12px;
-      }
+
+  .camera-seleted-text {
+    margin-right: 20px;
+
+    .b {
+      color: #3d68e1;
     }
   }
 }
diff --git a/src/pages/gb28181/index/api.ts b/src/pages/gb28181/index/api.ts
index e81ffe2..37da6af 100644
--- a/src/pages/gb28181/index/api.ts
+++ b/src/pages/gb28181/index/api.ts
@@ -24,10 +24,49 @@
   });
 };
 
+export const getAllSubServer = (query: any) => {
+  return request({
+    url: "/data/api-v/gb28181/getAllSubServer",
+    method: "get",
+    params: query
+  });
+};
+
 export const newGb28181ID = (query: any) => {
   return request({
     url: "/data/api-v/gb28181/newGbId",
     method: "get",
     params: query
   });
+};
+
+export const getLocalCameraTree = (query: any) => {
+  return request({
+    url: "/data/api-v/area/localmenu",
+    method: "get",
+    params: query
+  });
+};
+
+export const getGB28181CameraTree = (query: any) => {
+  return request({
+    url: "/data/api-v/area/gb28181Tree",
+    method: "get",
+    params: query
+  });
+};
+
+export const refreshGB28181Tree = () => {
+  return request({
+    url: "/data/api-v/area/gb28181RefreshTree",
+    method: "post",
+  });
+};
+
+export const saveGb28181CamTree = (query: any) => {
+  return request({
+    url: "/data/api-v/gb28181/saveGb28181CamTree",
+    method: "post",
+    data: query
+  });
 };
\ No newline at end of file
diff --git a/src/pages/gb28181/index/main.ts b/src/pages/gb28181/index/main.ts
index 491ea9a..d48da00 100644
--- a/src/pages/gb28181/index/main.ts
+++ b/src/pages/gb28181/index/main.ts
@@ -1,11 +1,25 @@
 import Vue from 'vue';
 import App from './App.vue';
 
+import TreeDataPool from "@/Pool/TreeData";
+
 import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';
 import "@/assets/css/element-variables.scss";
 Vue.use(ElementUI)
 
+const onlyTreeDataPool = new TreeDataPool
+
+const mixin = {
+  data() {
+    return {
+      TreeDataPool: onlyTreeDataPool
+    };
+  },
+};
+
+Vue.mixin(mixin);
+
 new Vue({
   el: '#app',
   render: h => h(App)
diff --git a/src/pages/panoramicView/components/History.vue b/src/pages/panoramicView/components/History.vue
new file mode 100644
index 0000000..00d4f02
--- /dev/null
+++ b/src/pages/panoramicView/components/History.vue
@@ -0,0 +1,241 @@
+<template>
+  <div class="p-histroy">
+    <div class="filter-bar">
+      <el-date-picker
+        size="small"
+        v-model="searchTime"
+        @change="checkTime"
+        type="datetimerange"
+        :picker-options="pickerOptions"
+        start-placeholder="寮�濮嬫棩鏈�"
+        end-placeholder="缁撴潫鏃ユ湡"
+        value-format="yyyy-MM-dd HH:mm:ss"
+        :default-time="['00:00:00','23:59:59']"
+      ></el-date-picker>
+      <el-button @click="checkTime" size="small" type="primary" class="btn-search">鏌� 璇�</el-button>
+    </div>
+
+    <div class="persons">
+      <div class="board">
+        <b>鍘嗗彶杩借釜浜哄憳</b>
+        <span>鍏� 10 鏉℃暟鎹�</span>
+      </div>
+      <div class="target-list">
+        <div
+          class="list-item"
+          v-for="item in personList"
+          :key="item.id"
+          :style="selectedID == item.id ? 'border-color:#3D68E1': ''"
+          @click="checkTarget(item)"
+        >
+          <!-- <img src alt :style="{backgroundColor:item.color}"/> -->
+          <img :src="'/httpImage/' + item.picSmUrl" />
+        </div>
+      </div>
+    </div>
+    <div class="videos">
+      <div class="video-item" v-for="v in videoList" :key="v.name">
+        <video :src="'/httpImage/' + v.videoUrl" controls="controls" width="480px" height="270px"></video>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "histroy",
+  data() {
+    return {
+      searchTime: [
+        this.$moment().format("YYYY-MM-DD 00:00:00"),
+        this.$moment().format("YYYY-MM-DD 23:59:59")
+        //this.$moment().format("YYYY-MM-DD HH:mm:ss")
+      ],
+      pickerOptions: {
+        shortcuts: [{
+          text: '杩戜竴灏忔椂',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 60 * 60 * 1000);
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '杩戜笁灏忔椂',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 60 * 60 * 1000 * 3);
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '杩戝叚灏忔椂',
+          onClick(picker) {
+            const end = new Date();
+            const start = new Date();
+            start.setTime(start.getTime() - 60 * 60 * 1000 * 6);
+            picker.$emit('pick', [start, end])
+          }
+        }]
+      },
+      selectedID: "",
+      personList: [
+        {
+          id: "0",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          id: "1",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          id: "2",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          id: "3",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          id: "4",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          id: "5",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          id: "6",
+          picSmUrl: "192.168.20.10:6700/52361,cdd84d471eaa7d?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+      ],
+      videoList: [
+        {
+          name: "1",
+          videoUrl: "192.168.20.10:6700/52369,cddbfed6886fc0?collection=2021-05-18-DSVAD010120190622-video",
+          pathImg: "192.168.20.10:6700/52360,cddbfc05f6d697?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          name: "2",
+          videoUrl: "192.168.20.10:6700/52369,cddbfed6886fc0?collection=2021-05-18-DSVAD010120190622-video",
+          pathImg: "192.168.20.10:6700/52360,cddbfc05f6d697?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          name: "3",
+          videoUrl: "192.168.20.10:6700/52369,cddbfed6886fc0?collection=2021-05-18-DSVAD010120190622-video",
+          pathImg: "192.168.20.10:6700/52360,cddbfc05f6d697?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+        {
+          name: "4",
+          videoUrl: "192.168.20.10:6700/52369,cddbfed6886fc0?collection=2021-05-18-DSVAD010120190622-video",
+          pathImg: "192.168.20.10:6700/52360,cddbfc05f6d697?collection=2021-05-18-DSVAD010120190622-picture"
+        },
+      ]
+    }
+  },
+  methods: {
+    checkTime() {
+      if (!this.searchTime) {
+        this.$notify({
+          type: 'warning',
+          message: '璇烽�夋嫨鏃堕棿!'
+        });
+        return;
+      }
+      clearInterval(this.timer);
+      //鍒ゆ柇鏄惁鏄煡鍘嗗彶鏁版嵁
+      if (Date.parse(this.searchTime[1]) < Date.now()) {
+        this.filterData()
+      } else {
+        this.activeObjHashMap = {};
+        //瀹炴椂鏌�
+        this.searchData();
+      }
+
+    },
+    checkTarget(item) {
+      this.selectedID = item.id;
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.p-histroy {
+  height: 800px;
+  background: inherit;
+  background-color: rgba(240, 242, 245, 1);
+
+  .filter-bar {
+    text-align: left;
+    padding: 15px 10px;
+    height: 35px;
+    background-color: #fff;
+  }
+
+  .persons {
+    width: 18%;
+    height: 670px;
+    background-color: #fff;
+    margin: 10px 10px;
+    float: left;
+    .board {
+      height: 70px;
+      line-height: 50px;
+      text-align: left;
+      padding: 0px 10px;
+      b {
+        font-size: 14px;
+      }
+      span {
+        margin-left: 160px;
+      }
+    }
+    .target-list {
+      display: flex;
+      flex-wrap: wrap;
+      // justify-content: space-between;
+      width: 375px;
+      overflow: auto;
+      height: auto;
+      .list-item {
+        width: 70px;
+        height: 70px;
+        /* margin-bottom: 10px; */
+        margin: 5px 4px;
+        border: 2px solid #dedede;
+        border-radius: 50%;
+        cursor: pointer;
+        img {
+          width: 100%;
+          height: 100%;
+          display: block;
+          border-radius: 50%;
+        }
+        &.deact {
+          opacity: 0.5;
+          background: rgba(0, 0, 0, 0.3);
+        }
+      }
+    }
+  }
+
+  .videos {
+    width: 80%;
+    margin: 10px 10px;
+    height: 88%;
+    display: flex;
+    flex-wrap: wrap;
+    .video-item {
+      width: 500px;
+      height: 320px;
+      margin-left: 10px;
+      background-color: #fff;
+
+      video {
+        margin: 10px;
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/panoramicView/components/LabelMark.vue b/src/pages/panoramicView/components/LabelMark.vue
index 0ef6c44..6686a05 100644
--- a/src/pages/panoramicView/components/LabelMark.vue
+++ b/src/pages/panoramicView/components/LabelMark.vue
@@ -319,7 +319,6 @@
     sure() {
       let _this = this;
       this.$refs['labelForm'].validate(valid => {
-        console.log(valid)
         if (valid) {
           _this.isShowPop = false;
           //缂栬緫纭畾
@@ -328,7 +327,6 @@
             _this.curCameraData.coords[editedIndex] = JSON.parse(JSON.stringify(_this.curLabel));
 
           }
-          console.log(_this.curCameraData.coords)
           this.$refs['labelForm'].clearValidate();
         }
       });
@@ -360,8 +358,21 @@
     },
     async submitInfo() {
       this.isEdit = false;
+
+      if (this.curCameraData.coords.length > 0 && this.curCameraData.coords.length < 4) {
+        this.$message({
+          type: "warning",
+          message: "淇濆瓨澶辫触! 鑷冲皯闇�瑕佹爣璁�4澶�!"
+        })
+        return
+      }
+
       let res = await updateCameraMarks(this.curCameraData);
       if (res.success) {
+        this.$message({
+          type: "success",
+          message: "淇濆瓨鎴愬姛"
+        })
         this.findCameraMarks(this.curCameraData.cameraId);
       }
     },
@@ -381,7 +392,6 @@
       })
     },
     showCurPos(e) {
-      console.log(e);
       this.isShowCurPos = true;
       this.traceX = e.offsetX;
       this.traceY = e.offsetY;
@@ -411,10 +421,8 @@
       this.newLabel(e);
     },
     newLabel(e) {
-      console.log('鐐瑰嚮浜嗙敾鏉�')
       if (this.isShowPop) return;
       //鑾峰彇榧犳爣鐩稿浜庣敾鏉跨殑瀹氫綅
-      console.log('鑾峰彇褰撳墠瀹氫綅淇℃伅');
       this.$refs['labelForm'].resetFields();
       let target = {
         id: '',
diff --git a/src/pages/panoramicView/components/RelateCamera.vue b/src/pages/panoramicView/components/RelateCamera.vue
index 8b846d3..8933b5a 100644
--- a/src/pages/panoramicView/components/RelateCamera.vue
+++ b/src/pages/panoramicView/components/RelateCamera.vue
@@ -40,6 +40,7 @@
       </div>
     </div>
     <!-- <div class="part" v-if="groupList.length"> -->
+    <el-divider></el-divider>
     <div class="part" v-if="groupList.length!==0 && Object.keys(curGroup)">
       <div class="title">缁樺埗鍖哄煙(鐢ㄤ簬绠楁硶鍒嗘瀽)</div>
       <div class="relative-partment" v-if="curGroup.cameras&&curGroup.cameras.length">
@@ -48,6 +49,7 @@
         </div>
       </div>
     </div>
+    <el-divider></el-divider>
     <div class="part relative-config" v-if="Object.keys(curGroup)">
       <div class="title">
         <div class="left">
@@ -142,7 +144,7 @@
 
 export default {
   components: { SlideCanvas },
-  data () {
+  data() {
     return {
       cameraData: [],
       relativeList: [],
@@ -161,11 +163,11 @@
       cameraAndPolygonData: []
     }
   },
-  mounted () {
+  mounted() {
     this.getAllCameraData();
   },
   methods: {
-    getAllCameraData () {
+    getAllCameraData() {
       let _this = this;
       getCamerasByServer().then(res => {
         if (res.success) {
@@ -176,10 +178,10 @@
         console.log(e)
       })
     },
-    polygonUpdate () {
+    polygonUpdate() {
       this.getAllGroups();
     },
-    delRelation (item, index) {
+    delRelation(item, index) {
       let _this = this;
       if (item.id) {
         delRelation(item.id).then(res => {
@@ -191,12 +193,12 @@
             _this.findRelationByGroup();
           }
         })
-      }else{
-        this.relativeList.splice(index,1);
+      } else {
+        this.relativeList.splice(index, 1);
       }
 
     },
-    findRelationByGroup () {
+    findRelationByGroup() {
       let _this = this;
       findByGroup({ groupId: this.curGroup.id }).then(res => {
 
@@ -213,7 +215,7 @@
         })
       })
     },
-    saveRelativePolygon (item) {
+    saveRelativePolygon(item) {
       // debugger
       if (!item.sourceObj || !item.targetObj) {
         this.$notify({
@@ -250,17 +252,21 @@
       })
     },
 
-    async findPolygonByIds (cameras) {
+    async findPolygonByIds(cameras) {
       for (var i = 0; i < cameras.length; i++) {
+        if (Object.keys(cameras[i]).length == 0)
+          continue
         let res = await getAllPolygon({ cameraId: cameras[i].id });
         cameras[i].canvasData = res.data;
       }
       return cameras
     },
 
-    async getAllGroupInfo () {
+    async getAllGroupInfo() {
       let _this = this;
+      console.log("_this.cameraData", _this.cameraData)
       let res = await findCameraGroups();
+      console.log("res", res);
       let groupArr = res.data.map(item => {
         let obj = {}; //group
         obj.groupName = item.groupName;
@@ -303,9 +309,10 @@
     //     _this.checkCurrentGroup(_this.groupList[0]);
     //   })
     // },
-    async getAllGroups () {
+    async getAllGroups() {
       let _this = this;
       let groups = await this.getAllGroupInfo();
+      console.log("groups", groups)
       for (var i = 0; i < groups.length; i++) {
         groups[i].cameras = await _this.findPolygonByIds(groups[i].cameras)
       }
@@ -316,36 +323,36 @@
         this.groupList.length && this.checkCurrentGroup(_this.groupList[0]);
       } else {
         let group = this.groupList.find(one => one.id == this.groupForm.id);
-        if(group){
+        if (group) {
           this.groupList.length && this.checkCurrentGroup(group);
-        }else{
+        } else {
           this.groupList.length && this.checkCurrentGroup(_this.groupList[0]);
         }
-        
+
       }
 
 
     },
 
-    addRelation () {
+    addRelation() {
       let obj = { cameraArea1: '', cameraArea2: '' };
       this.relativeList.push(obj)
     },
 
-    editGroup (group) {
+    editGroup(group) {
       // debugger
       this.groupModelVisible = true;
       //this.$refs['groupForm'].resetFields();
       //this.groupForm = group;
       this.groupForm = JSON.parse(JSON.stringify(group));
     },
-    removeGroup (group) {
+    removeGroup(group) {
       let _this = this;
       delCameraGroup(group.id).then(res => {
         _this.getAllGroups()
       })
     },
-    checkCurrentGroup (group) {
+    checkCurrentGroup(group) {
       this.groupList.forEach(group => {
         group.checked = false;
       });
@@ -375,10 +382,9 @@
           tempArr = tempArr.concat(cameraArea)
         });
         this.cameraAreas = tempArr;
-        console.log(this.cameraAreas)
       })
     },
-    confirmGroupDialog () {
+    confirmGroupDialog() {
       //璇锋眰淇濆瓨鏂板缓鎴栫紪杈戝垎缁�
       let _this = this;
       let params = {
@@ -413,7 +419,7 @@
       })
       //this.groupList.push(this.groupForm);
       saveCameraGroupInfo(params).then(res => {
-        if(res.success){
+        if (res.success) {
           this.$notify({
             type: 'success',
             message: '淇濆瓨鎴愬姛!'
@@ -424,7 +430,7 @@
       this.groupModelVisible = false;
 
     },
-    newGroup () {
+    newGroup() {
       this.groupModelVisible = true;
       this.$nextTick(() => {
         this.$refs['groupForm'].resetFields();
@@ -509,7 +515,7 @@
       position: relative;
       display: flex;
       &:after {
-        content: '';
+        content: "";
         position: absolute;
         font-size: 0;
         width: 1px;
@@ -531,7 +537,7 @@
     margin-bottom: 20px;
     .relative-partment {
       width: 1200px;
-      margin: 0 auto;
+      // margin: 0 auto;
       display: flex;
       justify-content: space-between;
       .area-wrap {
@@ -561,7 +567,7 @@
         .right {
           display: flex;
           align-items: center;
-          .el-button + .el-button{
+          .el-button + .el-button {
             margin-left: 0;
           }
         }
diff --git a/src/pages/panoramicView/components/SlideCanvas.vue b/src/pages/panoramicView/components/SlideCanvas.vue
index f8367e9..02bfbcb 100644
--- a/src/pages/panoramicView/components/SlideCanvas.vue
+++ b/src/pages/panoramicView/components/SlideCanvas.vue
@@ -59,39 +59,39 @@
   ],
   watch: {
     cameras: {
-      handler (n, o) {
+      handler(n, o) {
         console.log('slidecanvas cameras', n)
       },
       deep: true
     }
   },
   components: { PolygonCanvas },
-  data () {
+  data() {
     return {
       swiperOption: this.newOption(),
       //mySwiper: {}
     }
   },
   computed: {
-    swiper () {
+    swiper() {
       return this.$refs['cameraSwiper'].swiper
     }
   },
-  mounted () {
+  mounted() {
     //this.mySwiper = this.$refs.sceneSwiper.swiper;
-    console.log(this.swiper)
+    // console.log(this.swiper)
   },
   methods: {
-    refresh (url, cameraId) {
+    refresh(url, cameraId) {
       this.$emit('polygonDataUpdate')
     },
-    getCanvasData (data) {
+    getCanvasData(data) {
       let _this = this;
       savePolygon(data).then(rsp => {
         _this.$emit('polygonDataUpdate')
       });
     },
-    newOption () {
+    newOption() {
       return {
         slidesPerView: 1,
         spaceBetween: 0,
@@ -104,21 +104,21 @@
       }
     },
 
-    pre () {
+    pre() {
       this.swiper.activeIndex--;
       if (this.swiper.activeIndex == -1) {
         this.swiper.activeIndex = this.cameras.length - 1;
       }
       this.swiper.slideTo(this.swiper.activeIndex);
     },
-    next () {
+    next() {
       this.swiper.activeIndex++;
       if (this.swiper.activeIndex == this.cameras.length) {
         this.swiper.activeIndex = 0;
       }
       this.swiper.slideTo(this.swiper.activeIndex);
     },
-    drawBaseImg (id) {
+    drawBaseImg(id) {
       this.$refs[`polygonCanvas_${id}`][0].showModal();
     }
   }
@@ -181,7 +181,7 @@
   b {
     font-size: 14px;
   }
-  .left-fixed{
+  .left-fixed {
     position: absolute;
     left: 0;
     top: -6px;
diff --git a/src/pages/panoramicView/components/TracePlot.vue b/src/pages/panoramicView/components/TracePlot.vue
index 1c91063..b17498b 100644
--- a/src/pages/panoramicView/components/TracePlot.vue
+++ b/src/pages/panoramicView/components/TracePlot.vue
@@ -29,6 +29,7 @@
           @click="checkTarget(item)"
         >
           <!-- <img src alt :style="{backgroundColor:item.color}"/> -->
+          <img :src="'/httpImage/'+item.picSmUrl" />
         </div>
       </div>
     </div>
@@ -113,7 +114,6 @@
 
   },
   beforeDestroy() {
-    console.log('beforeDestroy')
     clearInterval(this.timer);
   },
   methods: {
@@ -224,7 +224,6 @@
       })
     },
     drawTracePath() {
-      console.log(this.actObjs)
       let canvas = this.$refs['trackArea'];
       let ctx = canvas.getContext('2d');
       ctx.clearRect(0, 0, canvas.width, canvas.height);
@@ -341,13 +340,15 @@
           _this.actObjs[i].color = _this.colorArr[i % 10];
           this.$set(_this.actObjs[i], 'isHide', _this.actObjs[i].isHide);
         }
-        console.log(new Date(), _this.actObjs);
 
+        console.log(_this.actObjs)
         _this.drawTracePath();
         _this.timeMark = new Date();
         _this.timer = setTimeout(() => {
           _this.searchData()
         }, _this.intervalTime)
+
+
       })
     }
   }
@@ -358,7 +359,7 @@
 .trace-plot {
   .filter-bar {
     width: 960px;
-    margin: 20px auto;
+    margin: 20px 10px;
     display: flex;
     align-items: center;
     flex-direction: end;
diff --git a/src/pages/panoramicView/index/App.vue b/src/pages/panoramicView/index/App.vue
index d641446..8291124 100644
--- a/src/pages/panoramicView/index/App.vue
+++ b/src/pages/panoramicView/index/App.vue
@@ -11,12 +11,16 @@
         mode="horizontal"
         @select="checkMenu"
       >
+        <el-menu-item index="0">鍘嗗彶璁板綍鏌ヨ</el-menu-item>
         <el-menu-item index="1">浣嶇疆鏍囧畾</el-menu-item>
         <el-menu-item index="2">杞ㄨ抗鍥�</el-menu-item>
         <el-menu-item index="3">鍏宠仈鎽勫儚鏈�</el-menu-item>
       </el-menu>
     </div>
     <div class="act-view">
+      <template v-if="actMenuIndex=='0'">
+        <History />
+      </template>
       <template v-if="actMenuIndex=='1'">
         <label-mark></label-mark>
       </template>
@@ -34,15 +38,16 @@
 import LabelMark from '../components/LabelMark';
 import TracePlot from '../components/TracePlot';
 import RelateCamera from '../components/RelateCamera';
+import History from '../components/History';
 export default {
-  components: { LabelMark, TracePlot, RelateCamera },
-  data () {
+  components: { LabelMark, TracePlot, RelateCamera, History },
+  data() {
     return {
-      actMenuIndex: '1',
+      actMenuIndex: '0',
     }
   },
   methods: {
-    checkMenu (key, keyPath) {
+    checkMenu(key, keyPath) {
       this.actMenuIndex = key;
     }
   }
@@ -61,10 +66,10 @@
       width: 310px;
       display: flex;
       align-items: center;
-      .icon{
+      .icon {
         width: 50px;
       }
-      .title{
+      .title {
         text-decoration: none;
         margin-left: 10px;
         font-size: 17px;
@@ -79,7 +84,7 @@
     .el-menu--horizontal > .el-menu-item {
       border-bottom: 0;
       color: #fff;
-      &:hover{
+      &:hover {
         color: #fff;
         background: rgb(24, 35, 182);
       }
diff --git a/src/pages/systemMonitor/api/api.ts b/src/pages/systemMonitor/api/api.ts
index 9ddfa95..abba575 100644
--- a/src/pages/systemMonitor/api/api.ts
+++ b/src/pages/systemMonitor/api/api.ts
@@ -2,7 +2,21 @@
 
 export const showSystemStates = () => {
   return request({
-    url: "/data/api-z/system/ShowSystemStates",
+    url: "/data/api-z/system/showSystemStates",
+    method: "get"
+  });
+};
+
+export const showService = () => {
+  return request({
+    url: "/data/api-z/system/showService",
+    method: "get"
+  });
+};
+
+export const showProcesses = () => {
+  return request({
+    url: "/data/api-z/system/showProcesses",
     method: "get"
   });
 };
diff --git a/src/pages/systemMonitor/index/App.vue b/src/pages/systemMonitor/index/App.vue
index 73ad2c8..88437be 100644
--- a/src/pages/systemMonitor/index/App.vue
+++ b/src/pages/systemMonitor/index/App.vue
@@ -3,66 +3,193 @@
     <el-tabs id="systemMonitor" v-model="activeName">
       <el-tab-pane label="鍗曞厓" name="proc">
         <div class="form-title">
-          <b>绠楁硶鍗曞厓</b>(姝e湪杩涜5涓畻娉曞崟鍏�)
+          <b>绠楁硶鍗曞厓</b>
+          (姝e湪杩涜{{algoProcessData.length}}涓畻娉曞崟鍏�)
+          <el-table :data="algoProcessData" style="width: 100%">
+            <el-table-column prop="desc" label="鍚嶇О" width="180"></el-table-column>
+            <el-table-column label="CPU" width="180">
+              <template slot-scope="scope">
+                <span>{{ scope.row.cpu.toFixed(2)}} %</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鍐呭瓨">
+              <template slot-scope="scope">
+                <span>{{ scope.row.mem.toFixed(2)}} %</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="disk" label="纭洏"></el-table-column>
+            <el-table-column label="绠楀姏">
+              <template slot-scope="scope">
+                <span>{{ scope.row.gpu}} M</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="net" label="缃戠粶"></el-table-column>
+          </el-table>
         </div>
-        <el-divider></el-divider>
 
-        <div class="form-title">
-          <b>搴旂敤鍗曞厓</b>(姝e湪杩涜5涓簲鐢ㄥ崟鍏�)
+        <div class="form-title" style="margin-top:20px">
+          <b>搴旂敤鍗曞厓</b>
+          (姝e湪杩涜{{appProcessData.length}}涓簲鐢ㄥ崟鍏�)
+          <el-table :data="appProcessData" style="width: 100%">
+            <el-table-column prop="desc" label="鍚嶇О" width="180"></el-table-column>
+            <el-table-column prop="cpu" label="CPU" width="180"></el-table-column>
+            <el-table-column prop="mem" label="鍐呭瓨"></el-table-column>
+            <el-table-column prop="disk" label="纭洏"></el-table-column>
+            <el-table-column prop="gpu" label="绠楀姏"></el-table-column>
+            <el-table-column prop="net" label="缃戠粶"></el-table-column>
+          </el-table>
         </div>
-        <el-divider></el-divider>
       </el-tab-pane>
 
       <el-tab-pane label="鎬ц兘" name="top">
         <div class="column-left" ref="left">
           <div class="resize-bar">
-            <div class="ax_default">
-              <div class="ax_default_pic"></div>
-              <div>CPU</div>
-              <div>100%</div>
+            <div
+              :class="['ax_default', activeChartItem == 'cpu' ?'selected': '']"
+              @click="setActiveChartItem('cpu')"
+            >
+              <div class="ax_default_pic color-cpu"></div>
+              <div class="ax_default_text">CPU</div>
+              <div class="ax_default_subtext">{{cpuUsedPercent}}%</div>
             </div>
 
-            <div class="ax_default">
-              <div class="ax_default_pic"></div>
-              <div>鍐呭瓨</div>
-              <div>100%</div>
+            <div
+              :class="['ax_default', activeChartItem == 'mem' ?'selected': '']"
+              @click="setActiveChartItem('mem')"
+            >
+              <div class="ax_default_pic color-mem"></div>
+              <div class="ax_default_text">鍐呭瓨</div>
+              <div class="ax_default_subtext">{{memUsedPercent}}%</div>
             </div>
 
-            <div class="ax_default">
-              <div class="ax_default_pic"></div>
-              <div>纾佺洏</div>
-              <div>100%</div>
+            <div
+              :class="['ax_default', activeChartItem == 'gpu' ?'selected': '']"
+              @click="setActiveChartItem('gpu')"
+            >
+              <div class="ax_default_pic color-gpu"></div>
+              <div class="ax_default_text">绠楀姏</div>
+              <div class="ax_default_subtext">{{gpuUsedPercent}}%</div>
             </div>
 
-            <div class="ax_default">
-              <div class="ax_default_pic"></div>
-              <div>绠楀姏</div>
-              <div>100%</div>
+            <div
+              :class="['ax_default', activeChartItem == 'net' ?'selected': '']"
+              @click="setActiveChartItem('net')"
+            >
+              <div class="ax_default_pic color-net"></div>
+              <div class="ax_default_text">缃戠粶</div>
+              <div class="ax_default_subtext">{{netSend | byteConver}} / {{netRecive | byteConver}}</div>
             </div>
 
-            <div class="ax_default">
-              <div class="ax_default_pic"></div>
-              <div>缃戠粶</div>
-              <div>100%</div>
+            <div
+              v-for="(v, k) in disks"
+              :key="k"
+              :class="['ax_default', activeChartItem == ('disk|' + k) ?'selected': '']"
+              @click="setActiveChartItem('disk|'+k)"
+            >
+              <div class="ax_default_pic color-disk"></div>
+              <div class="ax_default_text">纾佺洏 {{k}}</div>
+              <div class="ax_default_subtext">{{v.info.total | byteConver}}</div>
             </div>
           </div>
 
           <div class="resize-line"></div>
         </div>
+
         <div class="column-right">
+          <div class="max-val">{{yAxisMaxVal}}</div>
           <div ref="graphs" class="graphs-chart"></div>
+
+          <div v-show="activeChartItem == 'cpu'">
+            <div class="ax_default_label">
+              <b>鍗犵敤鐜�</b>
+              <p>{{cpuUsedPercent}}%</p>
+            </div>
+            <div class="ax_default_label">
+              <b>涓婚</b>
+              <p>{{cpuMaxRate}}Ghz</p>
+            </div>
+            <div class="ax_default_label">
+              <b>鎻掓Ы</b>
+              <p>{{cpuCount}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>鍐呮牳</b>
+              <p>{{cpuCore}}</p>
+            </div>
+          </div>
+
+          <div v-show="activeChartItem == 'mem'">
+            <div class="ax_default_label">
+              <b>浣跨敤涓�</b>
+              <p>{{memUsed}}G</p>
+            </div>
+            <div class="ax_default_label">
+              <b>宸茬紦瀛�</b>
+              <p>{{memCache}}G</p>
+            </div>
+            <div class="ax_default_label">
+              <b>鍙敤</b>
+              <p>{{memFree}}G</p>
+            </div>
+          </div>
+
+          <div v-show="activeChartItem == 'net'">
+            <div class="ax_default_label">
+              <b>鎺ユ敹</b>
+              <p>{{netRecive |byteConver}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>鍙戦��</b>
+              <p>{{netSend |byteConver}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>IP鍦板潃</b>
+              <p>{{ipAddr}}</p>
+            </div>
+            <div class="ax_default_label" style="margin-left: 19px;">
+              <b>MAC鍦板潃</b>
+              <p>{{macAddr}}</p>
+            </div>
+          </div>
+
+          <div v-show="isDisk">
+            <div class="ax_default_label">
+              <b>瀹归噺</b>
+              <p>{{activeDisk.total |byteConver}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>宸茬敤</b>
+              <p>{{activeDisk.used |byteConver}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>鍙敤</b>
+              <p>{{activeDisk.free |byteConver}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>璇诲彇閫熷害</b>
+              <p>{{ioRead | byteConver}}</p>
+            </div>
+            <div class="ax_default_label">
+              <b>鍐欏叆閫熷害</b>
+              <p>{{ioWrite | byteConver}}</p>
+            </div>
+          </div>
         </div>
       </el-tab-pane>
 
       <el-tab-pane label="鏈嶅姟" name="service">
-        <el-table height="93%" :data="services" border :cell-style="cellStyle">
-          <el-table-column label="鍚嶇О" align="center" show-overflow-tooltip>
+        <el-table :data="vasystemServicesData">
+          <el-table-column label="鍚嶇О" show-overflow-tooltip>
             <template slot-scope="scope">
               <span>{{ scope.row.name}}</span>
             </template>
           </el-table-column>
-          <el-table-column label="鐘舵��" prop="status" align="center" width="130px"></el-table-column>
-          <el-table-column label="鎻忚堪" prop="text" align="center"></el-table-column>
+          <el-table-column label="鐘舵��" prop="status">
+            <template slot-scope="scope">
+              <span>{{ scope.row.pid == 0 ? "鏈惎鍔�" : "宸插惎鍔�" }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎻忚堪" prop="desc"></el-table-column>
         </el-table>
       </el-tab-pane>
     </el-tabs>
@@ -71,66 +198,15 @@
 
 <script>
 import echarts from "echarts";
-import { showSystemStates } from "../api/api"
+import { showSystemStates, showService, showProcesses } from "../api/api"
 
 export default {
   components: {
-    
-
-  },
-  data() {
-    return {
-      activeName: "proc",
-      eChartsObj: {},
-      eChartsBaseOpt: {
-        animation: false,
-        xAxis: {
-          type: "category",
-          boundaryGap: false,
-          data: Array.from({ length: 100 }, () => 0),
-          axisLabel: {
-            show: false
-          },
-          axisTick: {
-            show: false
-          }
-        },
-        yAxis: {
-          type: 'value',
-          axisLabel: {
-            show: false
-          },
-          axisTick: {
-            show: false
-          }
-        },
-        series: [
-          {
-            type: 'line',
-            symbol: 'none',
-            data: Array.from({ length: 100 }, () => 0),
-            // smooth: true,
-            areaStyle: {}
-          }
-        ]
-      },
-      services: [
-        {
-          name: "绯荤粺閰嶇疆鏈嶅姟",
-          status: "宸插惎鍔�",
-          text: "瀹炵幇绯荤粺鐨勯�氱敤鍔熻兘閰嶇疆"
-
-        }
-      ]
-    };
-  },
-  mounted() {
-    this.initChart();
-    if (!this.isShow('vindicate:device')) {
-      this.activeName = "dbvdc"
-    }
   },
   computed: {
+    isDisk() {
+      return this.activeChartItem.indexOf("disk") == 0
+    },
     isAdmin() {
       if (
         sessionStorage.getItem('userInfo') &&
@@ -144,7 +220,248 @@
       return false;
     }
   },
+  filters: {
+    byteConver(limit) {
+      var size = "";
+      if (limit < 1024) { //濡傛灉灏忎簬0.1KB杞寲鎴怋  
+        size = limit + "B";
+      } else if (limit < 1024 * 1024) {//濡傛灉灏忎簬0.1MB杞寲鎴怟B  
+        size = (limit / 1024).toFixed(2) + "KB";
+      } else if (limit < 1024 * 1024 * 1024) { //濡傛灉灏忎簬0.1GB杞寲鎴怣B  
+        size = (limit / (1024 * 1024)).toFixed(2) + "MB";
+      } else if (limit < 1024 * 1024 * 1024 * 1024) { //鍏朵粬杞寲鎴怗B  
+        size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
+      } else {
+        size = (limit / (1024 * 1024 * 1024 * 1024)).toFixed(2) + "TB";
+      }
+
+      var sizestr = size + "";
+      var len = sizestr.indexOf("\.");
+      var dec = sizestr.substr(len + 1, 2);
+      if (dec == "00") {//褰撳皬鏁扮偣鍚庝负00鏃� 鍘绘帀灏忔暟閮ㄥ垎  
+        return sizestr.substring(0, len) + sizestr.substr(len + 3, 2);
+      }
+
+      return sizestr;
+    }
+  },
+  data() {
+    return {
+      activeName: "proc",
+      activeChartItem: "cpu",
+      yAxisMaxVal: "100%",
+      algoProcessData: [],
+      appProcessData: [],
+      vasystemServicesData: [],
+      eChartsObj: {},
+      eChartsBaseOpt: {
+        title: {
+          top: 10,
+        },
+        animation: false,
+        grid: {
+          show: true,
+          left: '1%',
+          right: '4%',
+          bottom: '3%',
+          containLabel: true,
+          borderWidth: 2,
+          borderColor: '#000'
+        },
+        xAxis: {
+          type: "category",
+          boundaryGap: false,
+          data: Array.from({ length: 60 }, () => 0),
+          // show: false,
+          axisLabel: {
+            show: false
+          },
+          axisTick: {
+            show: false
+          },
+          splitLine: {
+            show: true,
+            interval: 5,
+            lineStyle: {
+              width: 1,
+              type: 'solid'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          // show: false,
+          axisLine: {
+            show: false
+          },
+          axisLabel: {
+            show: false
+          },
+          axisTick: {
+            show: false
+          }
+        },
+        series: [
+          {
+            type: 'line',
+            symbol: 'none',
+            data: Array.from({ length: 60 }, () => 0),
+            // smooth: true,
+            itemStyle: {},
+            areaStyle: {}
+          }
+        ]
+      },
+      cpuUtilizations: Array.from({ length: 60 }, () => 0),
+      memUtilizations: Array.from({ length: 60 }, () => 0),
+      gpuUtilizations: Array.from({ length: 60 }, () => 0),
+      diskIOWriteCount: Array.from({ length: 60 }, () => 0),
+      diskIOReadCount: Array.from({ length: 60 }, () => 0),
+      netReciveCount: Array.from({ length: 60 }, () => 0),
+      netSendCount: Array.from({ length: 60 }, () => 0),
+      cpuModel: "",
+      cpuUsedPercent: 0,
+      cpuMaxRate: 0,
+      cpuCount: 0,
+      cpuCore: 0,
+      memTotal: 0,
+      memUsed: 0,
+      memFree: 0,
+      memCache: 0,
+      memUsedPercent: 0,
+      netSend: 0,
+      netRecive: 0,
+      ipAddr: "",
+      macAddr: "",
+      gpuUsedPercent: 0,
+      disks: {},
+      activeDisk: {},
+      ioRead: 0,
+      ioWrite: 0
+    };
+  },
+  mounted() {
+    this.dataCollection();
+    this.initChart();
+  },
   methods: {
+    // 寰幆閲囬泦鎵�鏈夋暟鎹�
+    dataCollection() {
+      this.serviceCollect();
+      this.procCollect();
+      setTimeout(() => {
+        this.dataCollection();
+      }, 5000)
+    },
+    serviceCollect() {
+      showService().then(rsp => {
+        if (rsp && rsp.success) {
+          rsp.data.sort(function (obj1, obj2) {
+            var val1 = obj1.name
+            var val2 = obj2.name
+            if (val1 < val2) {
+              return -1
+            } else if (val1 > val2) {
+              return 1
+            } else {
+              return 0
+            }
+          })
+          this.vasystemServicesData = rsp.data;
+        }
+      }).catch(() => { })
+
+    },
+    procCollect() {
+      showProcesses().then(rsp => {
+        if (rsp && rsp.success) {
+          if (rsp.data.algos)
+            this.algoProcessData = rsp.data.algos;
+
+          if (rsp.data.apps)
+            this.appProcessData = rsp.data.apps;
+        }
+
+      }).catch(() => { })
+    },
+    getSystemState() {
+      showSystemStates().then(rsp => {
+        if (rsp && rsp.success) {
+          // 澶勭悊cpu
+          this.cpuUtilizations = this.cpuUtilizations.slice(1);
+          this.cpuUtilizations.push(rsp.data.cpu.toFixed(2));
+          this.cpuUsedPercent = this.cpuUtilizations[59];
+          if (rsp.data.cpu_info) {
+            this.cpuMaxRate = (rsp.data.cpu_info[0].mhz / 1024).toFixed(2);
+            this.cpuModel = rsp.data.cpu_info[0].modelName;
+            this.cpuCore = Number(rsp.data.cpu_info[rsp.data.cpu_info.length - 1].coreId) + 1;
+            this.cpuCount = (rsp.data.cpu_info.length / this.cpuCore).toFixed(0);
+          }
+
+          // 鍐呭瓨
+          this.memUtilizations = this.memUtilizations.slice(1);
+          this.memUtilizations.push(rsp.data.mem.usedPercent.toFixed(2));
+          this.memTotal = (rsp.data.mem.total / 1024 / 1024 / 1000).toFixed(0);
+          this.memUsed = (rsp.data.mem.used / 1024 / 1024 / 1000).toFixed(2);
+          this.memFree = (rsp.data.mem.free / 1024 / 1024 / 1000).toFixed(2);
+          this.memCache = ((rsp.data.mem.cached + rsp.data.mem.buffers) / 1024 / 1024 / 1000).toFixed(2);
+          this.memUsedPercent = rsp.data.mem.usedPercent.toFixed(2);
+
+          // 绠楀姏
+          this.gpuUtilizations = this.gpuUtilizations.slice(1);
+          this.gpuUtilizations.push(rsp.data.gpu.toFixed(2));
+          this.gpuUsedPercent = this.gpuUtilizations[59];
+
+          // 缃戠粶
+          this.netReciveCount = this.netReciveCount.slice(1);
+          this.netReciveCount.push(rsp.data.net.bytesRecv);
+          this.netSendCount = this.netSendCount.slice(1);
+          this.netSendCount.push(rsp.data.net.bytesSent);
+
+          this.netRecive = this.netReciveCount[59];
+          this.netSend = this.netSendCount[59];
+          this.macAddr = rsp.data.net.mac;
+          if (rsp.data.net.addr.length) {
+            this.ipAddr = rsp.data.net.addr[0].addr;
+          }
+
+          // 纾佺洏
+          rsp.data.disk.sort(function (obj1, obj2) {
+            var val1 = obj1.name;
+            var val2 = obj2.name;
+            if (val1 < val2) {
+              return -1;
+            } else if (val1 > val2) {
+              return 1;
+            } else {
+              return 0;
+            }
+          })
+
+          rsp.data.disk.forEach(d => {
+            if (d.name in this.disks) {
+              this.disks[d.name].readBytes = this.disks[d.name].readBytes.slice(1);
+              this.disks[d.name].readBytes.push(d.readBytes);
+              this.disks[d.name].writeBytes = this.disks[d.name].writeBytes.slice(1);
+              this.disks[d.name].writeBytes.push(d.writeBytes);
+            } else {
+              this.disks[d.name] = {};
+              this.disks[d.name]["info"] = d.info;
+              this.disks[d.name]["readBytes"] = Array.from({ length: 60 }, () => 0);
+              this.disks[d.name]["writeBytes"] = Array.from({ length: 60 }, () => 0);
+            }
+          });
+
+          // this.disks = rsp.data.disk;
+        }
+
+
+        this.setChartData();
+        setTimeout(() => {
+          this.getSystemState();
+        }, 1000)
+      })
+    },
     isShow(authority) {
       if (this.isAdmin) {
         return true
@@ -162,20 +479,105 @@
         this.$moment(array[1]).format("YYYY-MM-DD")
       ];
     },
+    setActiveChartItem(item) {
+      this.activeChartItem = item;
+      this.eChartsObj.clear();
+      this.setChartData();
+    },
     initChart() {
       this.eChartsObj = echarts.init(this.$refs.graphs);
-      this.eChartsObj.setOption(this.eChartsBaseOpt);
-      this.cpuMonitor()
+      this.getSystemState();
     },
-    cpuMonitor() {
-      let rate = Math.floor(Math.random() * 100);
-      let data = this.eChartsBaseOpt.series[0].data.slice(1);
-      data.push(rate)
-      this.eChartsBaseOpt.series[0].data = data;
-      this.eChartsObj.setOption(this.eChartsBaseOpt);
-      setTimeout(() => {
-        this.cpuMonitor()
-      }, 1000)
+    setChartData() {
+      let option = JSON.parse(JSON.stringify(this.eChartsBaseOpt));
+      switch (this.activeChartItem) {
+        case 'cpu':
+          this.yAxisMaxVal = this.cpuModel;
+          option.title.text = "CPU";
+          option.title.subtext = "%鍗犵敤鐜�";
+          option.yAxis.max = 100;
+          option.yAxis.min = 0;
+          option.grid.borderColor = "#8aadd0";
+          option.series[0].itemStyle.color = "#8aadd0";
+          option.series[0].areaStyle.color = "#a8d4ff";
+          option.series[0].data = this.cpuUtilizations;
+
+          break;
+        case 'mem':
+          this.yAxisMaxVal = this.memTotal + "G";
+          option.title.text = "鍐呭瓨";
+          option.title.subtext = "鍐呭瓨浣跨敤閲�";
+          option.yAxis.max = 100;
+          option.yAxis.min = 0;
+          option.grid.borderColor = "#ff9900";
+          option.series[0].itemStyle.color = "#ff9900";
+          option.series[0].areaStyle.color = "#f7bb88";
+          option.series[0].data = this.memUtilizations;
+          break;
+        case 'gpu':
+          this.yAxisMaxVal = "100%";
+          option.title.text = "绠楀姏";
+          option.title.subtext = "%浣跨敤鐜�";
+          option.yAxis.max = 100;
+          option.yAxis.min = 0;
+          option.grid.borderColor = "#bc84d8";
+          option.series[0].itemStyle.color = "#bc84d8";
+          option.series[0].areaStyle.color = "#de9dff";
+          option.series[0].data = this.gpuUtilizations;
+          break;
+        case 'net':
+          this.yAxisMaxVal = "";
+          option.title.text = "缃戠粶";
+          option.title.subtext = "缃戠粶璐熻浇";
+          option.grid.borderColor = "#4696da";
+          option.series[0].itemStyle.color = "#ffa16a";
+          option.series[0].areaStyle.color = "#d68658";
+          option.series[0].data = this.netReciveCount;
+          option.series.push({
+            type: 'line',
+            symbol: 'none',
+            data: this.netSendCount,
+            // smooth: true,
+            itemStyle: {
+              color: "#4696da"
+            },
+            areaStyle: {
+              color: "#4eacfd"
+            }
+          })
+          break;
+        default:
+          if (this.activeChartItem.indexOf("disk|") == 0) {
+            let dev = this.activeChartItem.split("|")[1];
+
+            this.yAxisMaxVal = "";
+            option.title.text = "纾佺洏";
+            option.title.subtext = "纾佺洏浼犺緭閫熺巼";
+            option.grid.borderColor = "#33cc66";
+            option.series[0].itemStyle.color = "#4696da";
+            option.series[0].areaStyle.color = "#4eacfd";
+            option.series[0].data = this.disks[dev].readBytes;
+            option.series.push({
+              type: 'line',
+              symbol: 'none',
+              data: this.disks[dev].writeBytes,
+              // smooth: true,
+              itemStyle: {
+                color: "#33ff66"
+              },
+              areaStyle: {
+                color: "#33cc66"
+              }
+            })
+
+            this.activeDisk = this.disks[dev].info;
+            this.ioRead = this.disks[dev].readBytes[59];
+            this.ioWrite = this.disks[dev].writeBytes[59];
+          }
+          break;
+      }
+
+      this.eChartsObj.setOption(option);
     }
 
   }
@@ -195,24 +597,35 @@
   }
 
   .graphs-chart {
-    height: 380px;
-    width: 450px;
+    height: 500px;
+    width: 900px;
+    margin-left: 15px;
     // border: 1px solid rgb(69, 69, 172);
   }
+
   .column-left {
     background-color: #fff;
     position: relative;
     float: left;
   }
+
   .column-right {
     //overflow: hidden;
     overflow-y: hidden;
     overflow-x: auto;
   }
-  .resize-bar {
-    width: 200px;
-    height: 400px;
+
+  .max-val {
+    position: absolute;
+    right: 4%;
+    top: 8%;
   }
+
+  .resize-bar {
+    width: 238px;
+    height: 610px;
+  }
+
   /* 鎷栨嫿绾� */
   .resize-line {
     position: absolute;
@@ -225,41 +638,98 @@
   }
 
   .ax_default {
-    font-family: "Arial Normal", "Arial";
-    font-weight: 400;
-    font-style: normal;
-    font-size: 13px;
-    text-align: center;
-    line-height: normal;
-    width: 200px;
-    height: 50px;
-    font-size: 16px;
+    width: 207px;
+    height: 45px;
+    padding: 10px;
+    font-size: 15px;
+    margin: 5px;
     cursor: pointer;
-    margin-bottom: 15px;
+  }
+
+  .selected {
+    background: inherit;
+    background-color: #cde8ff;
+    border: none;
+    border-radius: 8px;
   }
 
   .ax_default_pic {
     position: absolute;
     border-width: 0px;
-    width: 65px;
+    width: 66px;
     height: 45px;
-    background: inherit;
-    background-color: rgba(255, 255, 255, 0);
     box-sizing: border-box;
-    border-width: 1px;
-    border-style: solid;
-    border-color: rgba(255, 153, 0, 1);
-    border-radius: 0px;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
+    border: 1px solid rgba(255, 153, 0, 1);
+    background-repeat: no-repeat;
+    background-position: bottom;
   }
 
+  .color-cpu {
+    border-color: #8aadd0;
+    background-image: url("/images/systemMonitor/cpu.png");
+  }
+
+  .color-mem {
+    border-color: #ff9900;
+    background-image: url("/images/systemMonitor/mem.png");
+  }
+
+  .color-gpu {
+    border-color: #bc84d8;
+    background-image: url("/images/systemMonitor/gpu.png");
+  }
+
+  .color-net {
+    border-color: #4696da;
+    background-image: url("/images/systemMonitor/net.png");
+  }
+
+  .color-disk {
+    border-color: #33cc66;
+    background-image: url("/images/systemMonitor/disk.png");
+  }
+
+  .ax_default_text {
+    position: relative;
+    text-align: left;
+    margin-left: 72px;
+  }
+
+  .ax_default_subtext {
+    font-size: 13px;
+    margin-left: 72px;
+    line-height: 35px;
+    color: #4e4d4d;
+    text-align: left;
+  }
+
+  .ax_default_label {
+    width: 120px;
+    font-size: 15px;
+    display: inline-block;
+    float: left;
+
+    b {
+      font-family: "鎬濇簮榛戜綋";
+      font-weight: 400;
+      font-style: normal;
+      color: #a1a1a1;
+    }
+
+    p {
+      margin-top: 5px;
+    }
+  }
+  .ax_label_flex {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+  }
   .s-system-monitor-breadcrumb {
     height: 5%;
     box-sizing: border-box;
     border: 1px solid #e4e7ed;
-    box-shadow: #e4e7ed 0px 0px 9px inset;
     box-shadow: #e4e7ed 0px 0px 9px inset;
     border-radius: 5px;
   }
@@ -296,12 +766,13 @@
       }
     }
   }
+
   .el-tabs__content {
     height: calc(100% - 64px);
     width: calc(100% - 20px);
     box-sizing: border-box;
     overflow-y: auto;
-    padding: 10px 40px !important;
+    padding: 10px 10px !important;
     .el-tab-pane {
       width: 100%;
       .s-title {

--
Gitblit v1.8.0