From c5fdff95386976da7942021a8711dbc80abac9df Mon Sep 17 00:00:00 2001
From: hanbaoshan <hanbaoshan@aiotlink.com>
Date: 星期四, 30 七月 2020 15:47:37 +0800
Subject: [PATCH] 摄像机接入

---
 src/components/camera/SceneRule.vue        |  520 +++
 src/components/canvas/Dialog.vue           | 1362 ++++++++
 src/components/scene/Editor.vue            | 1675 +++++++++
 src/components/camera/SeparateRules.vue    |  873 +++++
 src/components/canvas/index.vue            |  510 +++
 src/components/camera/PollSetting.vue      |  614 +++
 src/components/camera/localSeparate.vue    |  729 ++++
 src/components/camera/CameraInfoEditor.vue |  270 +
 src/pages/desktop/index/mock/userData.json |   11 
 src/pages/cameraAccess/index/main.ts       |   11 
 src/components/camera/infoCard.vue         |   75 
 src/components/camera/slider-vedio.vue     |  268 +
 src/pages/cameraAccess/index/App.vue       |  307 +
 src/pages/cameraAccess/index/mixins.ts     |    0 
 src/components/camera/TimeSlider.vue       |  226 +
 src/components/scene/SlideScene.vue        |  285 +
 package.json                               |    2 
 src/components/camera/LinkageRule.vue      |  674 +++
 src/components/camera/CameraInfo.vue       |  650 +++
 src/components/camera/DataStackInfo.vue    |  819 ++++
 src/components/camera/SystemInfo.vue       |  212 +
 21 files changed, 10,084 insertions(+), 9 deletions(-)

diff --git a/package.json b/package.json
index 7266107..e1b2d58 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
     "axios": "^0.19.2",
     "d3-force": "^2.0.1",
     "echarts": "^4.8.0",
+    "echarts-liquidfill": "^2.0.6",
     "element-ui": "^2.13.2",
     "less-loader": "^6.2.0",
     "moment": "^2.27.0",
@@ -26,6 +27,7 @@
     "vue-awesome-swiper": "^3.1.3",
     "vue-js-toggle-button": "^1.3.3",
     "vue-qrcode-component": "^2.1.1",
+    "vue-slider-component": "^3.2.2",
     "vuex": "^3.5.1"
   },
   "devDependencies": {
diff --git a/src/components/camera/CameraInfo.vue b/src/components/camera/CameraInfo.vue
new file mode 100644
index 0000000..38aa371
--- /dev/null
+++ b/src/components/camera/CameraInfo.vue
@@ -0,0 +1,650 @@
+<template>
+  <div class="camera-info">
+    <el-form ref="addForm" :model="form" :rules="rules" label-width="88px">
+      <el-row>
+        <el-col :span="9">
+          <el-form-item label="RTSP鍦板潃" :span="11" prop="rtsp">
+            <el-input v-model="form.rtsp" placeholder="rtsp://" :disabled="isDisabled" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="9" :offset="1">
+          <el-form-item label="鍧愭爣" style="width:100%;">
+            <label slot="label">&nbsp;&nbsp;&nbsp;鍧愭爣</label>
+            <el-col :span="11">
+              <el-input
+                v-model="form.latitude"
+                placeholder="缁忓害"
+                :disabled="isDisabled"
+                size="small"
+              ></el-input>
+            </el-col>
+            <el-col :span="11" :offset="2">
+              <el-input
+                v-model="form.longitude"
+                placeholder="绾害"
+                :disabled="isDisabled"
+                size="small"
+              ></el-input>
+            </el-col>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="9">
+          <el-form-item label="璁惧鍚嶇О" style="width:100%" prop="name">
+            <el-input v-model="form.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�" :disabled="isDisabled" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="9" :offset="1">
+          <el-form-item label="璁惧鍦板潃" style="width:100%" prop="addr">
+            <el-input v-model="form.addr" placeholder="璇疯緭鍏ュ湴鍧�鎻忚堪" :disabled="!form.rtsp" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="9">
+          <el-form-item label="澶勭悊鍒嗚鲸鐜�" style="width:100%">
+            <el-select
+              v-model="form.resolution"
+              placeholder="鏈満鍒嗚鲸鐜�"
+              style="position: absolute;left: 0;"
+              size="small"
+            >
+              <el-option
+                v-for="item in resolutionList"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="9" :offset="1" style="padding-left: 11px;">
+          <el-form-item label="浜嬩欢澹伴煶">
+            <div class="flex-wrap" style="margin-left:-10px">
+              <el-switch v-model="form.voiceEnable" active-color="#409eff" :width="50"></el-switch>
+              <el-select
+                v-model="form.voiceId"
+                placeholder="閫夋嫨澹伴煶"
+                size="small"
+                value-key="id"
+                @change="selSound"
+              >
+                <el-option
+                  v-for="item in soundList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item"
+                ></el-option>
+              </el-select>
+              <span class="player-btn" @click="togglePlayer">
+                <i
+                  class="el-icon-video-play"
+                  style="font-size:26px; vertical-align:middle; color:#409eff"
+                ></i>
+              </span>
+            </div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row v-show="isGb28182">
+        <el-col :span="9">
+          <el-form-item label="璁惧鍒悕" style="width:100%" prop="alias">
+            <el-input v-model="form.alias" placeholder="璇疯緭鍏ヨ澶囧埆鍚�" size="small"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <!-- 娣诲姞浼犳劅鍣� -->
+        <CameraInfoEditor ref="cameraEditor" :Carmeras="form" :sensors="sensors"></CameraInfoEditor>
+      </el-row>
+
+      <el-row style="padding-top: 15px">
+        <el-col :span="19" style="text-align: right;">
+          <el-button
+            size="small"
+            type="primary"
+            @click="onSubmit('addForm')"
+            :disabled="conDisabled"
+          >淇濆瓨</el-button>
+          <el-button
+            type="danger"
+            size="small"
+            @click="deleteCamera"
+            v-if="!isAdd"
+            :disabled="isDisabled"
+          >鍒犻櫎鎽勫儚鏈�</el-button>
+        </el-col>
+      </el-row>
+      <el-divider></el-divider>
+      <input v-model="form.id" type="hidden" />
+      <input v-model="form.areaid" type="hidden" />
+      <el-row>
+        <el-col :span="12" style="text-align: right;">
+          <el-button size="small" type="primary" @click="cameraConnet" :disabled="conDisabled">杩炴帴娴嬭瘯</el-button>
+        </el-col>
+      </el-row>
+      <el-row style="padding-top: 15px">
+        <el-col :span="12">
+          <camera-player
+            :cameraName="videoItem.name"
+            :cameraID="videoItem.id"
+            :isGb="videoItem.cameraType === 1"
+            :rtspUrl="videoItem.rtsp"
+            :isRunning="false"
+            v-if="videoItem !== '' && videoItem !== undefined && videoItem !== null && visibilityState"
+          ></camera-player>
+          <video v-else poster="../../assets/baseimg_cameara.png" preload="none"></video>
+        </el-col>
+
+        <!-- 绯荤粺杩愯淇℃伅 -->
+        <el-col :span="11" :offset="1">
+          <div class="sysinfo-box">
+            <div style="width: 70%">
+              <ul>
+                <li style="width:100%">
+                  <info-card
+                    style="width:100%;min-width: 440px"
+                    :realtime="PollData.RealTimeSum"
+                    :polling="PollData.PollValidCount"
+                    :dataStack="PollData.stackChannelCount"
+                  ></info-card>
+                </li>
+              </ul>
+            </div>
+            <div
+              :style="`width:80%;height:174px;position: relative;left: -12px;`"
+              v-if="PollData.barCharts && PollData.barCharts.length !== 0"
+            >
+              <eChartsBar ref="cpuMeneryCharts" :xAxisData="PollData.barCharts"></eChartsBar>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+<script>
+import {
+  checkCameraConnet,
+  createCamera,
+  updateCameraInfo,
+  getCameraInfo,
+  delCamera
+} from "@/api/camera";
+import { getSoundList } from "@/api/event";
+import { changeRunType } from "@/api/pollConfig";
+
+import CameraPlayer from "@/components/player";
+import InfoCard from "@/components/camera/infoCard"
+import eChartsBar from '@/components/subComponents/eChartsBar'
+import CameraInfoEditor from '@/components/camera/CameraInfoEditor'
+
+export default {
+  name: "CameraInfo",
+  components: {
+    CameraPlayer,
+    InfoCard,
+    eChartsBar,
+    CameraInfoEditor
+  },
+  props: {
+    cameraList: {
+      default: () => {
+        return [];
+      },
+      type: Array
+    }
+  },
+  data() {
+    return {
+      videoItem: null,
+      visibilityState: true,
+      soundList: [],
+      togglePlay: true,
+      eventAudio: new Audio(),
+      soundPath: '',
+      form: {
+        latitude: 0,
+        rtsp: "",
+        longitude: 0,
+        name: "",
+        addr: "",
+        alias: "",
+        areaid: "",
+        brand: "",
+        id: "",
+        ip: "",
+        reserved: "",
+        run_type: 0,
+        isAI: false,
+        username: "",
+        password: "",
+        cameraType: 0,
+        resolution: "",
+        voiceId: "",
+        voiceEnable: true
+      },
+      // 璁板綍娣诲姞鐘舵��
+      isAdd: false,
+      addParentId: "",
+      rules: {
+        name: [
+          { required: true, message: "璁惧鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+        rtsp: [
+          { required: true, message: "RTSP鍦板潃涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+        addr: [
+          { required: true, message: "璁惧鍦板潃涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      resolutionList: [],
+      //浼犳劅鍣ㄥ垪琛�
+      sensors: []
+    };
+  },
+  computed: {
+    isSelected() {
+      return this.TreeDataPool.selectedNode.type !== "4"
+    },
+    isGb28182() {
+      return this.TreeDataPool.selectedNode.cameraType === 1;
+    },
+    isDisabled() {
+      if (this.isGb28182) {
+        return true;
+      }
+
+      return this.isAdd ? false : this.TreeDataPool.selectedNode.type !== "4";
+    },
+    conDisabled() {
+      return this.isAdd ? false : this.TreeDataPool.selectedNode.type !== "4";
+    }
+  },
+  mounted() {
+    this.initFormData();
+    document.addEventListener("visibilitychange", () => {
+      this.visibilitychange();
+    });
+    this.getSounds();
+  },
+  methods: {
+    getSounds() {
+      getSoundList().then(res => {
+        if (res.success) {
+          this.soundList = res.data.list
+        }
+      }).catch(
+        e => console.log(e)
+      )
+    },
+    selSound(sound) {
+      this.soundPath = sound.path;
+      this.form.voiceId = sound.id
+    },
+    togglePlayer() {
+      if (!this.soundPath) {
+        this.$notify({
+          type: 'info',
+          message: '璇峰厛閫夋嫨涓�涓0闊�!'
+        })
+        return false;
+      }
+      this.eventAudio.src = this.soundPath;
+
+      if (this.togglePlay) {
+        this.eventAudio.play();
+      } else {
+        this.eventAudio.pause()
+      }
+      this.togglePlay = !this.togglePlay
+    },
+    visibilitychange() {
+      switch (document.visibilityState) {
+        case "hidden":
+          this.visibilityState = false;
+          break;
+        case "visible":
+          this.visibilityState = true;
+          break;
+      }
+    },
+    selectCamera(node) {
+      this.isAdd = false;
+      this.videoItem = null;
+      this.$refs.addForm.resetFields();
+      // this.initFormData();
+      // this.$refs.addForm.clearValidate();
+      if (node.type === "4") {
+        getCameraInfo(node.id).then(res => {
+          if (res.success) {
+            console.log(res, '鑾峰彇鎽勫儚鏈轰俊鎭�')
+            if (res.data.resolutions) {
+              let list = res.data.resolutions.map(i => {
+                let obj = {}
+                if (i.width == 0 && i.height == 0) {
+                  obj.label = "鏈満鍒嗚鲸鐜�"
+                  obj.value = "0*0"
+                } else {
+                  obj.label = i.width + "*" + i.height
+                  obj.value = i.width + "*" + i.height
+                }
+                return obj
+              })
+              this.resolutionList = list
+              this.sensors = res.data.sensors
+            }
+            this.$nextTick(() => {
+              Object.assign(this.form, res.data)
+              if (this.form.run_type !== -1) {
+                this.form.isAI = true
+              } else {
+                this.form.isAI = false
+              }
+              this.form.resolution = this.form.resolution_width + "*" + this.form.resolution_height
+            })
+          }
+        });
+      }
+    },
+    // 淇濆瓨
+    onSubmit(formName) {
+      let list = this.$refs.cameraEditor.getResult()
+      console.log(list, "sensor")
+      // id涓虹┖锛屾柊澧炴憚鍍忔満
+      this.$refs[formName].validate(async valid => {
+        if (valid) {
+          const isRequire = this.verifyRequrie();
+          if (!isRequire) return false;
+          // 鏇存柊
+          if (this.form.id !== "") {
+            this.form.areaid = this.TreeDataPool.getParent(this.form.id, this.isGb28182);
+            this.form.latitude = Number.isNaN(parseFloat(this.form.latitude)) ? 0 : parseFloat(this.form.latitude);
+            this.form.longitude = Number.isNaN(parseFloat(this.form.longitude)) ? 0 : parseFloat(this.form.longitude);
+            this.form.sensors = list
+            this.form.resolution_width = Number(this.form.resolution.split("*")[0])
+            this.form.resolution_height = Number(this.form.resolution.split("*")[1])
+            updateCameraInfo(this.form).then(rsp => {
+              if (rsp.success) {
+                this.$notify({
+                  type: "success",
+                  message: "鎽勫儚鏈轰俊鎭慨鏀规垚鍔燂紒"
+                });
+                this.TreeDataPool.fetchTreeData();
+              } else {
+                this.selectCamera(this.TreeDataPool.selectedNode);
+                this.$notify({
+                  type: "error",
+                  message: "鎽勫儚鏈轰俊鎭慨鏀瑰け璐ワ紒"
+                });
+              }
+            });
+          } else {
+            this.form.areaid = this.addParentId;
+            this.form.sensors = list
+            const { ...json } = this.form;
+            createCamera({
+              latitude: parseFloat(json.latitude),
+              rtsp: this.form.rtsp,
+              longitude: parseFloat(json.longitude),
+              name: this.form.name,
+              addr: this.form.addr,
+              areaid: this.form.areaid,
+              brand: this.form.brand,
+              id: this.form.id,
+              ip: this.form.ip,
+              port: parseFloat(json.port),
+              reserved: this.form.reserved,
+              run_type: this.form.isAI ? this.form.run_type : -1,
+              username: this.form.username,
+              password: this.form.password,
+              areaId: this.form.areaId,
+              sensors: this.form.sensors
+            }).then(rsp => {
+              if (rsp.success) {
+                this.$notify({
+                  type: "success",
+                  message: "鎽勫儚鏈烘坊鍔犳垚鍔燂紒"
+                });
+                this.TreeDataPool.selectedNode = rsp.data;
+                this.TreeDataPool.fetchTreeData();
+                // 鍚庣杩斿洖缁撴灉涓�0锛屾煡璇㈠悗涓�4
+                this.TreeDataPool.selectedNode.type = "4";
+                this.selectCamera(this.TreeDataPool.selectedNode);
+              } else {
+                this.$notify({
+                  type: "error",
+                  message: "鎽勫儚鏈烘坊鍔犲け璐ワ紒"
+                });
+              }
+            });
+          }
+        }
+      });
+    },
+    // 杩炴帴娴嬭瘯
+    cameraConnet() {
+      this.videoItem = null;
+      this.$nextTick(() => {
+        this.videoItem = {
+          name: this.form.name,
+          rtsp: this.form.rtsp,
+          id: this.form.id,
+          isRunning: this.form.run_enable,
+          cameraType: this.form.type
+        };
+      })
+    },
+    // * 楠岃瘉蹇呴�夐」
+    verifyRequrie() {
+      if (this.isGb28182) {
+        return true;
+      }
+      // const rtspReg = /^(rtsp:\/\/)([a-zA-Z0-9_]+):([a-zA-Z0-9_]+)@(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{4}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])(\/)([a-zA-Z0-9_/]+)$/;
+      // !rtspReg.test(this.form.rtsp
+
+      if (this.form.rtsp === "") {
+        this.$notify({
+          type: "warning",
+          message: "璇疯緭鍏ユ纭殑rtsp鍦板潃"
+        });
+        return false;
+      }
+      return true;
+    },
+    // 鍒犻櫎鎽勫儚鏈�
+    deleteCamera() {
+      this.$confirm("鏄惁鍒犻櫎姝ゆ憚鍍忔満锛�", {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      }).then(() => {
+        delCamera(this.form.id).then(res => {
+          if (res.success) {
+            this.initFormData();
+            this.$notify({
+              type: "success",
+              message: "鍒犻櫎鎴愬姛锛�"
+            });
+            this.TreeDataPool.fetchTreeData();
+            this.TreeDataPool.selectedNode = {};
+          } else {
+            this.$notify({
+              type: "error",
+              message: "鍒犻櫎澶辫触锛�"
+            });
+          }
+        });
+      });
+    },
+    // 娓呯┖杈撳叆妗�
+    initFormData() {
+      this.form = {
+        latitude: 0,
+        rtsp: "",
+        longitude: 0,
+        name: "",
+        addr: "",
+        alias: "",
+        areaid: "",
+        brand: "",
+        id: "",
+        ip: "",
+        reserved: "",
+        run_type: 0,
+        isAI: false,
+        username: "",
+        password: "",
+        resolution: "",
+        voiceId: "",
+        voiceEnable: true
+      };
+    },
+    // 娣诲姞璁惧
+    addDevice(node) {
+      this.isAdd = true;
+      this.addParentId = node;
+      this.initFormData();
+    },
+    //瀹炴椂銆佽疆璇㈠垏鎹�
+    changePoll(row) {
+      // console.log(row,'瀹炴椂銆佽疆璇㈠垏鎹�',this.form,this.PollData.RealTimeSum)
+      //鍒ゆ柇鏄柊澧炶繕鏄洿鏂�
+      if (this.form.id && this.form.id !== undefined) {
+        if (this.PollData.RealTimeSum < 16) {
+          if (row.value) {
+            this.form.run_type = 1
+          } else {
+            this.form.run_type = 0
+          }
+          changeRunType({ camera_ids: [this.form.id], run_type: this.form.run_type }).then(
+            rsp => {
+              if (rsp && rsp.success) {
+                this.$notify({
+                  type: "success",
+                  message: "閰嶇疆鎴愬姛"
+                });
+              } else {
+                this.$notify({
+                  type: "error",
+                  message: "閰嶇疆澶辫触"
+                });
+              }
+            }
+          );
+        } else {
+          if (this.form.run_type === 1) {
+            this.form.run_type = 0
+            changeRunType({ camera_ids: [this.form.id], run_type: this.form.run_type }).then(
+              rsp => {
+                if (rsp && rsp.success) {
+                  this.$notify({
+                    type: "success",
+                    message: "閰嶇疆鎴愬姛"
+                  });
+                } else {
+                  this.$notify({
+                    type: "error",
+                    message: "閰嶇疆澶辫触"
+                  });
+                }
+              }
+            );
+          }
+          this.$nextTick(() => {
+            this.$set(this.form, 'run_type', 0)
+          })
+          // this.$notify({
+          //   type: 'warning',
+          //   message: '瀹炴椂澶勭悊璺暟宸茶揪鏈�澶у鐞嗚矾鏁帮紒'
+          // })
+        }
+        this.TreeDataPool.fetchTreeData();
+        this.PollData.statisticTaskInfo();
+      }
+    },
+    //鏄惁杩涜瑙嗛鍒嗘瀽澶勭悊
+    pollEnable(row) {
+      // console.log(row,'瀹炴椂銆佽疆璇㈠垏鎹�')
+      if (row) {
+        if (this.PollData.RealTimeSum < 16) {
+          this.form.run_type = 1
+        } else {
+          this.form.run_type = 0
+        }
+      } else {
+        this.form.run_type = -1
+      }
+      if (this.form.id && this.form.id !== undefined) {
+        changeRunType({ camera_ids: [this.form.id], run_type: this.form.run_type }).then(
+          rsp => {
+            if (rsp && rsp.success) {
+              this.$notify({
+                type: "success",
+                message: "閰嶇疆鎴愬姛"
+              });
+            } else {
+              this.$notify({
+                type: "error",
+                message: "閰嶇疆澶辫触"
+              });
+            }
+            this.selectCamera(this.TreeDataPool.selectedNode)
+          }
+        );
+      }
+      this.TreeDataPool.fetchTreeData();
+      this.PollData.statisticTaskInfo();
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.camera-info {
+  width: 100%;
+  height: 100%;
+  margin-left: 20px;
+  overflow: auto;
+  .ai-select {
+    text-align: left;
+  }
+  .el-form-item__label {
+    text-align: left;
+  }
+  .label {
+    color: #606266;
+    font-size: 14px;
+  }
+  .flex-wrap {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .el-select {
+      width: 70%;
+    }
+  }
+  .sysinfo-box {
+    .card-box {
+      float: left;
+    }
+    .chart-box {
+      float: left;
+      width: 50%;
+      margin-top: 20px;
+      margin-left: 20px;
+    }
+    ul {
+      list-style: none;
+      display: table;
+      width: 100%;
+      li {
+        display: table-cell;
+        text-align: center;
+      }
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/camera/CameraInfoEditor.vue b/src/components/camera/CameraInfoEditor.vue
new file mode 100644
index 0000000..2c74fc5
--- /dev/null
+++ b/src/components/camera/CameraInfoEditor.vue
@@ -0,0 +1,270 @@
+<template>
+  <div>
+    <div class="task-camera-box">
+      <p style="padding: 0">
+        <b style="font-size: 14px; line-height: 28px;">浼犳劅鍣�</b>
+        <span
+          class="add-btn"
+          @click="createSensor"
+        >
+          <i class="iconfont iconhebingxingzhuang "
+           style="color:#3D68E1;margin-left:10px;font-size:16px;cursor: pointer;"></i>
+        </span>
+      </p>
+
+      <div class="sub-task-rules-box">
+        <span class="task-blank" v-show="groupRules.length == 0 ">鏆傛棤浼犳劅鍣紝璇烽�夋嫨鏂板</span>
+        <div style=" text-align: left;" v-for="(rule, index) in groupRules" :key="index">
+
+          <div style="margin-left:10px;">
+            <!-- 閫夋嫨鍖哄煙 -->
+            <el-checkbox v-model="rule.enable">
+                <span>
+                    {{'寮�鍚�'}}
+                </span>
+            </el-checkbox>
+
+            <!-- 閫夋嫨绫诲瀷 -->
+            <el-select v-model="rule.type" placeholder="閫夋嫨绫诲瀷" size="small">
+                <el-option
+                    v-for="item in selectTypeOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                </el-option>
+            </el-select>
+
+            <!-- ip鍦板潃 -->
+            <div style="max-width:220px;display: inline-block;">
+                <ip-input
+                    :ip="rule.ip"
+                    @on-blur="rule.ip = arguments[0]"
+                ></ip-input>
+            </div>
+
+            <div style="max-width:120px;display: inline-block;margin-left:10px;">
+              <el-input v-model="rule.port" placeholder="璇疯緭鍏ョ鍙�"
+                size="small"></el-input>
+            </div>
+            
+            <div style="max-width:120px;display: inline-block;margin-left:10px;">
+              <el-input v-model="rule.username" placeholder="璇疯緭鍏ョ敤鎴峰悕"
+               size="small"></el-input>
+            </div>
+
+            <div style="max-width:120px;display: inline-block;margin-left:10px;">
+              <el-input v-model="rule.password" placeholder="璇疯緭鍏ュ瘑鐮�"
+               size="small"></el-input>
+            </div>
+
+            <div style="max-width:120px;display: inline-block;margin-left:10px;">
+              <el-input v-model="rule.threshold" placeholder="璇疯緭鍏ラ槇鍊�"
+               size="small"></el-input>
+            </div>
+
+            <!-- 鏂板銆佸垹闄� 鎸夐挳 -->
+            <el-button
+              type="text"
+              style="color: #F53D3D;margin-left:10px;"
+              class="iconfont iconshanchu11"
+              @click="groupRules.splice(index, 1)"
+            ></el-button>
+
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import {
+  deleteCameraRules,
+  updateRuleDefence,
+  updateAlarmLevel
+} from "@/api/camera";
+import {
+  findByType
+} from '@/api/taskMange'
+import ipInput from "@/components/subComponents/IPInput"
+
+
+export default {
+  name: "TaskRuleEditor",
+  components:{
+      ipInput
+  },
+  props: {
+    Carmeras: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+    sensors: {
+      type: Array,
+      default: () =>{
+        return []
+      }
+    }
+  },
+  filters: {
+  },
+  computed: {
+  },
+  watch: {
+    sensors: function(newVal, oldVal) {
+      if(newVal !== oldVal){
+        this.groupRules = newVal
+      }
+    }
+  },
+  data() {
+    return {
+      baseSensor: {
+        enable:false,
+        type: "",
+        ip: "",
+        id: "",
+        port: "",
+        username: "",
+        password: "",
+        threshold:""
+      },
+      groupRules: [
+          {
+            enable:false,
+            type: "",
+            ip: "",
+            id: "",
+            port: "",
+            username: "",
+            password: "",
+            threshold:""
+          }
+      ],
+      selectTypeOptions:[
+          {
+              value:"1",
+              label:"娓╁害"
+          },
+          {
+              value:"2",
+              label:"婀垮害"
+          },
+          {
+              value:"3",
+              label:"婀垮害"
+          }
+      ]
+    };
+  },
+  methods: {
+    createSensor(){
+      this.groupRules.push(this.baseSensor)
+    },
+    getResult(){
+      if(this.groupRules.length !== 0){
+        let list = this.groupRules.filter(item=>{
+          return item.selectType != "" || item.cameraIp != ""
+                 || item.cameraPort != "" || item.cameraUserName != ""
+                 || item.cameraPaw != "" || item.cameraThro != ""
+        })
+        this.groupRules = list
+        return list.map(i=>{
+          i.port = Number(i.port)
+          i.threshold = Number(i.threshold)
+          return i
+        })
+      }
+    },
+     // 鏌ヨ瀛楀吀
+    async findByType() {
+      let res = await findByType();
+      if (res && res.success) {
+        let list = res.data.sensorType.map(i => {
+          let obj = {};
+          obj.label = i.name;
+          obj.value = i.value;
+          return obj;
+        });
+        this.selectTypeOptions = [...list];
+      }
+    },
+  },
+  mounted() {
+    this.findByType();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.task-camera-box {
+  width: 100%;
+  border-top: 1px solid #ccc;
+  padding-top: 5px;
+  box-sizing: border-box;
+  .sub-task-rules-box {
+    width: 100%;
+    min-height: 50px;
+    padding-top: 7px;
+    box-sizing: border-box;
+    padding-bottom: 38px;
+    .task-rules-button {
+      text-align: right;
+      margin: 15px;
+    }
+
+    .el-select {
+      margin: 3px 8px;
+      min-width: 130px;
+      width: 12%;
+    }
+  }
+
+  .el-button--text {
+    text-decoration: unset;
+  }
+
+  p {
+    text-align: left;
+    // padding: 10px;
+    box-sizing: border-box;
+  }
+
+  .task-blank {
+    float: left;
+    font-family: PingFangSC-Regular;
+    font-size: 12px;
+    color: #cccccc;
+    margin-top: 5px;
+  }
+  .nocamera-css {
+    cursor: not-allowed;
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+  }
+}
+
+.task-rules-box2 {
+  .task-rules-table-box {
+    width: 98%;
+    padding: 0px;
+    box-sizing: border-box;
+  }
+
+  .el-input__inner {
+    border: 0px !important;
+    border-radius: 2px;
+    padding: 0 22px;
+    background-color: transparent;
+  }
+
+  .el-input__suffix {
+    right: 8px;
+  }
+  span {
+    cursor: pointer;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/camera/DataStackInfo.vue b/src/components/camera/DataStackInfo.vue
new file mode 100644
index 0000000..0ffd272
--- /dev/null
+++ b/src/components/camera/DataStackInfo.vue
@@ -0,0 +1,819 @@
+<template>
+  <div class="data-stack-info">
+    <el-row>
+      <el-col :span="12">
+        <el-form ref="addForm" :model="form" :rules="rules" label-width="88px">
+          <el-form-item label="鍚嶇О" prop="name" style="width:440px">
+            <el-input v-model="form.name" size="small" :disabled="isDisabled"></el-input>
+          </el-form-item>
+
+          <el-form-item label="绫诲瀷" prop="type" style="width:440px">
+            <el-radio v-model="form.type" :label="1" :disabled="!isAdd">瑙嗛</el-radio>
+            <el-radio v-model="form.type" :label="2" :disabled="!isAdd">鍥剧墖</el-radio>
+            <el-radio v-model="form.type" :label="3" :disabled="!isAdd">闊抽</el-radio>
+            <el-radio v-model="form.type" :label="4" :disabled="!isAdd">鍏朵粬鏁版嵁</el-radio>
+          </el-form-item>
+
+          <el-form-item
+            label="澶勭悊瀹屾垚鍚庤嚜鍔ㄥ垹闄ゆ枃浠�"
+            prop="isAutoDelFile"
+            label-width="200px"
+            style="width:440px"
+          >
+            <el-radio v-model="form.isAutoDelFile" :label="true" :disabled="isDisabled">鏄�</el-radio>
+            <el-radio v-model="form.isAutoDelFile" :label="false" :disabled="isDisabled">鍚�</el-radio>
+          </el-form-item>
+
+          <el-form-item label-width="0px" style="text-align: left">
+            <el-button
+              size="small"
+              type="primary"
+              @click="onSubmit('addForm')"
+              :disabled="isDisabled"
+            >淇濆瓨</el-button>
+            <el-button
+              type="danger"
+              size="small"
+              @click="deleteDir"
+              v-if="!isAdd"
+              :disabled="isDisabled"
+            >鍒犻櫎鏁版嵁鏍�</el-button>
+          </el-form-item>
+        </el-form>
+      </el-col>
+
+      <!-- 绯荤粺杩愯淇℃伅 -->
+      <el-col :span="11" :offset="1">
+        <div class="sysinfo-box">
+          <div style="width: 70%">
+            <ul>
+              <li>
+                   <info-card 
+                   style="width: 100%;min-width: 440px"
+                   :realtime="PollData.RealTimeSum"
+                   :polling="PollData.PollValidCount"
+                   :dataStack="PollData.stackChannelCount"
+                   >
+                   </info-card>
+              </li>
+            </ul>
+          </div>
+          <div
+            :style="`width:80%;height:174px;position: relative;left: -12px;`"
+            v-if="PollData.barCharts && PollData.barCharts.length !== 0"
+          >
+            <eChartsBar ref="cpuMeneryCharts" :xAxisData="PollData.barCharts"></eChartsBar>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+
+    <!-- 涓婁紶绠$悊 -->
+    <el-divider></el-divider>
+    <div class="upload-menu">
+      <span
+        @click="activeName = 'uploaded'"
+        :class="activeName === 'uploaded' ? 'active tab' : 'tab'"
+      >宸蹭笂浼�</span>
+      <span
+        @click="activeName = 'uploading'"
+        :class="activeName === 'uploading' ? 'active tab' : 'tab'"
+      >姝e湪涓婁紶</span>
+
+      <div class="btn-right">
+        <el-input
+          v-model="searchInput"
+          placeholder="鎼滅储"
+          clearable
+          style="width: 203px;"
+          size="small"
+          @change="handelSearchInputChange"
+        >
+          <i class="el-icon-search el-input__icon" style="color:#DCDFE6;padding:0px" slot="prefix"></i>
+        </el-input>
+
+        <!-- 鎵归噺鏆傚仠 -->
+        <el-tooltip content="鎵归噺鏆傚仠" placement="bottom" popper-class="atooltip">
+          <el-button
+            type="text"
+            class="iconfont iconzanting btn"
+            @click="handleFileStatus({}, 0, true)"
+          ></el-button>
+        </el-tooltip>
+        <!-- 鎵归噺鍒犻櫎 -->
+        <el-tooltip content="鎵归噺鍒犻櫎" placement="bottom" popper-class="atooltip">
+          <el-button type="text" class="el-icon-delete btn" @click="handleFileDelete({}, true)"></el-button>
+        </el-tooltip>
+
+        <!-- 鏂囦欢涓婁紶 -->
+        <el-button type="primary" size="small" @click="handleUpload">
+          涓婁紶
+          <i class="el-icon-upload el-icon--right"></i>
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 宸蹭笂浼犳枃浠跺垪琛� -->
+    <el-table
+      ref="multipleTable"
+      v-show="activeName === 'uploaded' "
+      :data="fileList"
+      tooltip-effect="dark"
+      style="width: 99%"
+      border
+      :header-cell-style="{background:'#f8f8f8', color:'#222222', textAlign:'center'}"
+      @select="handleSelect"
+      @select-all="handleSelect"
+    >
+      <el-table-column type="selection" width="50" align="center" :selectable="isSelectable"></el-table-column>
+      <el-table-column prop="name" label="鏂囦欢鍚�">
+        <template slot-scope="{row}">
+          <div :class="snapshotClass">
+            <el-image
+              v-show="row.snapshot_url !== ''"
+              style="width: 30x; height: 30px"
+              :src="'/httpImage/' + row.snapshot_url"
+              fit="fill"
+            >
+              <div slot="error" :class="snapshotClass"></div>
+            </el-image>
+          </div>
+
+          <el-input
+            v-if="editRowId === row.id"
+            :autofocus="editRowId === row.id"
+            v-model="row.name"
+            size="small"
+            @blur="cellRenameFile(row)"
+            style="display: inline-block;width: calc(100% - 50px);margin-left: 10px;"
+          />
+          <a
+            v-else
+            style="line-height: 30px;margin-left: 10px; cursor:pointer"
+            @click="preview(row)"
+          >{{row.name}}</a>
+        </template>
+      </el-table-column>
+      <el-table-column prop="fileSize" label="澶у皬" width="120">
+        <template slot-scope="scope">{{scope.row.size | readFileSizeUnit}}</template>
+      </el-table-column>
+      <el-table-column prop="duration" label="鏃堕暱" show-overflow-tooltip align="center"></el-table-column>
+      <el-table-column prop="uploadTime" label="涓婁紶鏃堕棿" show-overflow-tooltip align="center">
+        <template slot-scope="scope">{{scope.row.createTime | moment}}</template>
+      </el-table-column>
+      <el-table-column prop="status" label="澶勭悊鐘舵��" show-overflow-tooltip align="center">
+        <template slot-scope="scope">{{scope.row.status | statusFormat}}</template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" show-overflow-tooltip align="center">
+        <template slot-scope="scope">
+          <div class="btn-operation">
+            <!-- 鎺掑簭 -->
+            <el-button
+              type="text"
+              :disabled="scope.row.status == 2"
+              class="el-icon-top btn"
+              @click="handleSortFile(1, scope.row.id)"
+              :style="scope.row.id === fileList[0].id ? 'visibility:hidden' : 'visibility:initial'"
+            ></el-button>
+            <!-- 鏆傚仠 -->
+            <el-tooltip content="鏆傚仠澶勭悊" placement="bottom" popper-class="atooltip">
+              <el-button
+                type="text"
+                :disabled="scope.row.status == 2"
+                class="iconfont iconzanting btn"
+                @click="handleFileStatus(scope.row, 0)"
+                v-show="scope.row.status === 1"
+              ></el-button>
+            </el-tooltip>
+
+            <!-- 寮�濮� -->
+            <el-tooltip content="閲嶆柊寮�濮�" placement="bottom" popper-class="atooltip">
+              <el-button
+                type="text"
+                :disabled="scope.row.status == 2"
+                class="iconfont iconkaishi btn"
+                @click="handleFileStatus(scope.row, 1)"
+                v-show="scope.row.status === 0"
+              ></el-button>
+            </el-tooltip>
+
+            <!-- 閲嶆柊澶勭悊 -->
+            <el-tooltip content="閲嶆柊澶勭悊" placement="bottom" popper-class="atooltip">
+              <el-button
+                type="text"
+                :disabled="scope.row.status == 2"
+                class="iconfont iconzhongxinkaishi btn"
+                @click="handleFileStatus(scope.row, 1)"
+                v-show="scope.row.status === 9"
+              ></el-button>
+            </el-tooltip>
+
+            <!-- 鍏朵粬鎿嶄綔 -->
+            <el-dropdown @command="dropdownClick">
+              <!-- <span class="iconfont icongengduo1 btn"></span> -->
+              <el-button
+                type="text"
+                :disabled="scope.row.status == 2"
+                class="iconfont icongengduo1 btn"
+              ></el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item
+                  icon="el-icon-edit"
+                  :command="{cb: handleFileRename, data: scope.row}"
+                >閲嶅懡鍚�</el-dropdown-item>
+                <el-dropdown-item
+                  icon="el-icon-copy-document"
+                  :command="{cb: handleFileMove, data: scope.row}"
+                >绉诲姩/澶嶅埗</el-dropdown-item>
+                <el-dropdown-item
+                  icon="el-icon-delete"
+                  :command="{cb: handleFileDelete, data: scope.row}"
+                >鍒犻櫎</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 鍒嗛〉 -->
+    <div class="pagination">
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleRefrashFileList"
+        :current-page="page"
+        :page-sizes="[5, 10, 15, 20]"
+        :page-size="size"
+        style="position:absolute;right:10px;bottom:5px"
+        :total="total"
+        layout="total, sizes, prev, pager, next"
+      ></el-pagination>
+    </div>
+
+    <!-- 鏂囦欢涓婁紶缁勪欢 -->
+    <file-uploader ref="uploader" v-show="activeName === 'uploading'" />
+
+    <!-- 鏂囦欢棰勮 -->
+    <el-dialog title="鏌ョ湅鏂囦欢" :visible.sync="previewDialog" width="500px">
+      <video :src="videoUrl" controls style="margin-top: 12px;">鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 video 鏍囩銆�</video>
+    </el-dialog>
+
+    <el-dialog title="绉诲姩/澶嶅埗" :visible.sync="fileDialog" width="500px">
+      <p style="margin:0px 0px 20px 0px">璇烽�夋嫨鎮ㄦ兂澶嶅埗/绮樿创鍒扮殑 鏁版嵁鏍堬細</p>
+      <span class="iconfont iconwenjian" style="color:#3d68e1; margin-right:5px"></span>
+      <el-select v-model="targetDir" placeholder="璇烽�夋嫨鐩爣鏂囦欢澶�" size="mini">
+        <el-option v-for="item in dirOptions" :key="item.id" :label="item.name" :value="item.id">
+          <span class="iconfont iconwenjian"></span>
+          <span style="margin-left: 10px">{{ item.name }}</span>
+        </el-option>
+      </el-select>
+
+      <div style="margin-top:20px">
+        <el-button type="primary" size="mini" @click="cellFileCopy">澶嶅埗</el-button>
+        <el-button type="primary" size="mini" @click="cellFileMove">绉诲姩</el-button>
+        <el-button type="info" size="mini" @click="fileDialog = false">鍙栨秷</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  getDirDetails,
+  saveDir,
+  sortFile,
+  updateStatus,
+  delDir,
+  deleteLocalFile,
+  findAllFileByStackId,
+  renameFile,
+  moveFile,
+  copyFile
+} from "@/api/localVedio";
+
+import { changeRunType } from "@/api/pollConfig";
+
+import InfoCard from "@/components/camera/infoCard"
+import eChartsBar from '@/components/subComponents/eChartsBar'
+import FileUploader from '@/components/subComponents/FileUpload'
+
+export default {
+  name: "DataStackInfo",
+  components: {
+    InfoCard,
+    eChartsBar,
+    FileUploader
+  },
+  props: {
+    cameraList: {
+      default: () => {
+        return [];
+      },
+      type: Array
+    }
+  },
+  filters: {
+    statusFormat(value) {
+      let statusCode = {
+        "-1": "宸插垹闄�",
+        "0": "鏆傚仠澶勭悊",
+        "1": "绛夊緟澶勭悊",
+        "2": "澶勭悊涓�",
+        "9": "澶勭悊瀹屾垚"
+      }
+      return statusCode[value];
+    },
+    readFileSizeUnit(value) {
+      let UNITS = [' B', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
+      let format = function (value, power) {
+        return (value / Math.pow(1024, power)).toFixed(2) + UNITS[power];
+      };
+
+      value = parseFloat(value, 10);
+      for (var i = 0; i < UNITS.length; i++) {
+        if (value < Math.pow(1024, i)) {
+          if (UNITS[i - 1]) {
+            return format(value, i - 1);
+          }
+          return value + UNITS[i];
+        }
+      }
+      return format(value, i - 1);
+    }
+  },
+  computed: {
+    snapshotClass() {
+      let classs = ["snapshot"];
+      if (this.form.type === 1) {
+        classs.push("snapshot-video")
+      } else if (this.form.type === 2) {
+        classs.push("snapshot-image")
+      } else if (this.form.type === 3) {
+        classs.push("snapshot-audio")
+      } else {
+        classs.push("snapshot-files")
+      }
+
+      return classs;
+    },
+    dirOptions() {
+      return this.DataStackPool.dirs.filter(dir => {
+        return dir.id !== this.DataStackPool.selectedDir.id
+      })
+    }
+  },
+  data() {
+    return {
+      videoUrl: "",
+      previewDialog: false,
+      fileDialog: false,
+      isDisabled: true,
+      videoItem: null,
+      visibilityState: true,
+      multipleSelection: [],
+      searchInput: "",
+      form: {
+        id: ""
+      },
+      fileList: [],
+      // 璁板綍娣诲姞鐘舵��
+      isAdd: false,
+      addParentId: "",
+      rules: {
+        dirName: [
+          { required: true, message: "璁惧鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      },
+      activeName: "uploaded",
+      page: 1,
+      size: 10,
+      total: 0,
+      taskUid: 0,
+      editRowId: "",
+      timer: 0,
+      targetDir: "",
+      targetFile: ""
+    };
+  },
+  mounted() {
+    this.initFormData();
+  },
+  beforeDestroy() {
+    this.taskUid = 0;
+  },
+  methods: {
+    preview(row) {
+      if (this.form.type === 1) {
+        this.previewDialog = true;
+        this.videoUrl = "/files/" + row.identifier + ".mp4"
+      }
+    },
+    // 娓呯┖杈撳叆妗�
+    initFormData() {
+      this.form = {
+        enable: false,
+        id: "",
+        isAutoDelFile: false,
+        name: "",
+        sort: 0,
+        status: 0,
+        type: 1
+      };
+    },
+    // 娣诲姞璁惧
+    addDir(node) {
+      this.isAdd = true;
+      this.isDisabled = false;
+      this.initFormData();
+    },
+    selectDir(node) {
+      if (node.id === "") {
+        return
+      }
+
+      this.isDisabled = false;
+      this.isAdd = false;
+      this.videoItem = null;
+      this.$refs.addForm.resetFields();
+      // this.initFormData();
+      // this.$refs.addForm.clearValidate();
+      this.form = { ...node };
+      delete this.form.createTime;
+      delete this.form.updateTime;
+      delete this.form.status;
+
+      this.fileList = [];
+      this.searchInput = "";
+      this.page = 1;
+      this.size = 10;
+      this.total = 0;
+      this.multipleSelection = []; // 娓呯┖閫変腑鐘舵��
+      this.initFetchListTask();
+    },
+    initFetchListTask() {
+      const uid = Math.round(Math.random() * 1000);
+      this.taskUid = uid;
+      this.timingtask(uid);
+    },
+    timingtask(uid) {
+      if (uid !== this.taskUid || this.form.id === "") {
+        return;
+      }
+
+      this.fetchFileList();
+
+      let _this = this;
+      this.timer = setTimeout(() => {
+        _this.timingtask(uid);
+      }, 2 * 1000);
+    },
+    fetchFileList() {
+      findAllFileByStackId({ name: this.searchInput, stackId: this.form.id, page: this.page, size: this.size, type: 0 }).then(rsp => {
+        if (rsp && rsp.success && rsp.data.total > 0) {
+          this.fileList = rsp.data.dataList;
+          this.total = rsp.data.total;
+
+          // 瀹氭椂鍒锋柊浼氭竻绌洪�変腑鐘舵�侊紝鍦ㄨ繖閲屾仮澶�
+          this.fileList.forEach(row => {
+            if (this.multipleSelection.indexOf(row.id) !== -1) {
+              this.$nextTick(() => {
+                this.$refs.multipleTable.toggleRowSelection(row);
+              })
+            }
+          });
+        }
+      }).catch(err => {
+        console.log(err)
+      })
+
+    },
+
+    // 淇濆瓨
+    onSubmit(formName) {
+      this.$refs[formName].validate(async valid => {
+        if (valid) {
+          saveDir(this.form).then(rsp => {
+            if (rsp.success) {
+              this.$notify({
+                type: "success",
+                message: "鏁版嵁鏍堜俊鎭繚瀛樻垚鍔燂紒"
+              });
+              this.DataStackPool.fetchFiles();
+            } else {
+              this.$notify({
+                type: "error",
+                message: "鏁版嵁鏍堜俊鎭繚瀛樺け璐ワ紒"
+              });
+            }
+          })
+        }
+      });
+    },
+    // 鍒犻櫎鎽勫儚鏈�
+    deleteDir() {
+      this.$confirm("鏄惁鍒犻櫎姝ゆ枃浠跺す锛�", {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      }).then(() => {
+        delDir(this.form.id).then(res => {
+          if (res.success) {
+            this.initFormData();
+            this.$notify({
+              type: "success",
+              message: "鍒犻櫎鎴愬姛锛�"
+            });
+            this.DataStackPool.fetchFiles();
+            this.DataStackPool.selectedDir = {};
+          } else {
+            this.$notify({
+              type: "error",
+              message: "鍒犻櫎澶辫触锛�"
+            });
+          }
+        }).catch(err => {
+          this.$notify({
+            type: "error",
+            message: "鍒犻櫎澶辫触锛�"
+          });
+        });
+      });
+    },
+    handleTabClick(tab, event) {
+      console.log(tab, event);
+    },
+    handleSelect(val) {
+      this.multipleSelection = val.map(row => {
+        return row.id;
+      });
+    },
+    handelSearchInputChange(val) {
+      this.multipleSelection = [];
+    },
+    handleUpload() {
+      console.log(this.$refs.uploader.$refs.button.$refs.btn.click())
+    },
+    handleRefrashFileList(val) {
+      this.page = val;
+      this.multipleSelection = [];
+      this.fetchFileList();
+    },
+    handleSizeChange(val) {
+      this.size = val;
+      this.multipleSelection = [];
+      this.fetchFileList();
+    },
+    async handleSortFile(direct, id) {
+      let res = await sortFile({
+        id: id,
+        direct: direct
+      })
+      if (res && res.success) {
+        this.fetchFileList();
+        this.$notify({
+          type: "success",
+          message: "鏂囦欢鎺掑簭鎴愬姛锛�"
+        })
+      }
+    },
+    async handleFileStatus(row, status, multi = false) {
+      let ids = this.multipleSelection;
+      if (!multi) {
+        ids = [row.id];
+      }
+      if (!ids.length) {
+        this.$notify({
+          type: "error",
+          message: "鏈�変腑鏂囦欢"
+        })
+        return
+      }
+      try {
+        let res = await updateStatus({
+          ids: ids,
+          status: status
+        })
+        if (res && res.success) {
+          this.fetchFileList();
+          this.$notify({
+            type: "success",
+            message: "鍒囨崲鏂囦欢澶勭悊鐘舵�佹垚鍔�"
+          })
+        }
+      } catch {
+        console.log("err")
+      }
+    },
+    dropdownClick(cmd) {
+      cmd.cb(cmd.data);
+    },
+    handleFileDelete(rows, multi = false) {
+      let ids = this.multipleSelection;
+      if (!multi) {
+        ids = [rows.id];
+      }
+      if (!ids.length) {
+        this.$notify({
+          type: "error",
+          message: "鏈�変腑鏂囦欢"
+        })
+        return
+      }
+      this.$confirm('鎻愮ず锛氱‘瀹氬垹闄よ鏂囦欢鍚楋紵', {
+        center: true,
+        cancelButtonClass: 'comfirm-class-cancle',
+        confirmButtonClass: 'comfirm-class-sure'
+      }).then(() => {
+        deleteLocalFile({ ids: ids }).then(rsp => {
+          this.$notify({
+            type: "error",
+            message: "鏂囦欢宸插垹闄�"
+          })
+        })
+      }).catch(() => { })
+    },
+    handleFileMove(row) {
+      this.targetDir = "";
+      this.targetFile = row.id;
+      this.fileDialog = true;
+    },
+    handleFileRename(row) {
+      this.editRowId = row.id;
+      clearTimeout(this.timer);
+      this.timer = null;
+    },
+    cellRenameFile(row) {
+      this.editRowId = "";
+      renameFile({ id: row.id, name: row.name }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "鏂囦欢閲嶅懡鍚嶆垚鍔�"
+          })
+        } else {
+          this.$notify({
+            type: "error",
+            message: "鏂囦欢閲嶅懡鍚嶅け璐�"
+          })
+        }
+        if (!this.timer) {
+          this.initFetchListTask();
+        }
+      }).catch(() => {
+        if (!this.timer) {
+          this.initFetchListTask();
+        }
+      })
+    },
+    isSelectable(row, rowIndex) {
+      return row.status !== 2
+    },
+    cellFileCopy() {
+      copyFile({ id: this.targetFile, stackIds: [this.targetDir] }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "澶嶅埗鎴愬姛"
+          })
+          this.fileDialog = false;
+        } else {
+          this.$notify({
+            type: "error",
+            message: "澶嶅埗澶辫触"
+          })
+        }
+      })
+    },
+    cellFileMove() {
+      moveFile({ id: this.targetFile, stackId: this.targetDir }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: "success",
+            message: "绉诲姩鎴愬姛"
+          })
+          this.fileDialog = false;
+        } else {
+          this.$notify({
+            type: "error",
+            message: "绉诲姩澶辫触"
+          })
+        }
+      })
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.data-stack-info {
+  width: 100%;
+  height: 100%;
+  margin-left: 20px;
+  overflow: auto;
+  .ai-select {
+    text-align: left;
+  }
+  .el-form-item__label {
+    text-align: left;
+  }
+  .label {
+    color: #606266;
+    font-size: 14px;
+  }
+  .sysinfo-box {
+    .card-box {
+      float: left;
+    }
+    .chart-box {
+      float: left;
+      width: 50%;
+      margin-top: 20px;
+      margin-left: 20px;
+    }
+    ul {
+      list-style: none;
+      display: table;
+      width: 100%;
+      li {
+        display: table-cell;
+        text-align: center;
+      }
+    }
+  }
+  .el-tabs__content {
+    padding: unset !important;
+  }
+
+  .upload-menu {
+    height: 40px;
+    width: 100%;
+    text-align: left;
+
+    .tab {
+      padding: 10px;
+      font-size: 14px;
+      cursor: pointer;
+      margin-right: 40px;
+    }
+
+    .active {
+      border-bottom: solid 2px #3d68e1;
+    }
+
+    .icon {
+      font-size: 20px;
+      margin: 0px 10px;
+    }
+
+    .btn-right {
+      float: right;
+      margin-top: -5px;
+      margin-right: 10px;
+      .btn {
+        cursor: pointer;
+        font-size: 20px;
+        margin: 0px 5px;
+      }
+      .btn:hover {
+        color: #3d68e1;
+      }
+    }
+  }
+  .btn-operation {
+    .btn {
+      cursor: pointer;
+      font-size: 20px;
+      margin: 0px 5px;
+    }
+    .btn:hover {
+      color: #3d68e1;
+    }
+  }
+  .pagination {
+    height: 40px;
+    position: relative;
+  }
+  .snapshot {
+    display: inline-block;
+    width: 30px;
+    height: 30px;
+    vertical-align: middle;
+  }
+  .snapshot-video {
+    background: url("../../assets/img/video.png");
+    background-repeat: round;
+  }
+  .snapshot-image {
+    background: url("../../assets/img/image.png");
+    background-repeat: round;
+  }
+  .snapshot-audio {
+    background: url("../../assets/img/audio.png");
+    background-repeat: round;
+  }
+  .snapshot-files {
+    background: url("../../assets/img/files.png");
+    background-repeat: round;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/camera/LinkageRule.vue b/src/components/camera/LinkageRule.vue
new file mode 100644
index 0000000..50a4b50
--- /dev/null
+++ b/src/components/camera/LinkageRule.vue
@@ -0,0 +1,674 @@
+<template>
+  <div class="s-linkage-rules">
+    <div class="top">
+      <p style="text-align:left;margin-bottom: 14px;">
+        <b style="font-size: 14px;line-height: 18px;">宸查�夌畻娉�</b>
+      </p>
+      <!-- <swiper :options="swiperTaskOption" class="swiper-box-container swiper-no-swiping">
+        <span class="task-tip" v-show="tableRuleList.length == 0 ">鏆傛棤绠楁硶锛岃鍦ㄧ嫭绔嬭鍒欎腑閫夋嫨绠楁硶</span>
+        <swiper-slide v-for="(item, index) in tableRuleList" :key="index">
+          <div class="item-card">
+            <p style="text-align: right; width:100%; height:25px"></p>
+            <p style="color: #0066EB;padding-top: 20px;'">
+              <b>{{ item.scene_name }}</b>
+            </p>
+          </div>
+        </swiper-slide>
+      </swiper>
+
+      <div class="pre-border" v-show="tableRuleList.length > 4 ">
+        <div class="icon-btn" slot="button-prev">
+          <i class="iconfont iconzuo"></i>
+        </div>
+      </div>
+      <div class="next-border" v-show="tableRuleList.length > 4 ">
+        <div class="icon-btn" slot="button-next">
+          <i class="iconfont iconyou1"></i>
+        </div>
+      </div> -->
+      <div>
+        <div class="slide-scene">
+          <span class="task-tip" v-if="tableRuleList.length == 0 ">鏆傛棤绠楁硶锛岃鍦ㄧ嫭绔嬭鍒欎腑閫夋嫨绠楁硶</span>
+          <slide-scene :sceneData="tableRuleList"></slide-scene>
+        </div>
+        <!-- <slide-scene :sceneData="Camera.rules"></slide-scene> -->
+        <!-- 绯荤粺淇℃伅 -->
+        <div class="top-right">
+          <sysinfo
+            v-if="showSysInfo"
+            style="margin-left: 25px;margin-top: -10px;"
+            :ShowLocalVedio="this.TreeDataPool.treeActiveName !== 'camera'"
+            :showRealPoll="this.TreeDataPool.treeActiveName == 'camera'"
+          />
+        </div>
+      </div>
+    </div>
+
+    <div class="bottom">
+      <div
+        style="width: calc(100% + 80px);height: 10px;background-color: #E9EBF2;p;position:relative;left:-50px"
+      ></div>
+      <div class="bottom-right">
+        <div class="draw-and-time-box">
+          <div class="draw-box">
+            <p style="text-align:left;padding: 10px 0px 0px 0px;box-sizing: border-box;">
+              <b style="font-size: 14px">鏌ョ湅鍖哄煙</b>
+            </p>
+            <div class="img-box">
+              <span class="camera-tip" v-show="swipercanvasData.length == 0 ">鏆傛棤鍖哄煙锛岃鑷冲皯閫夋嫨2涓憚鍍忔満</span>
+              <!-- swiper 灞曠ず -->
+              <swiper
+                ref="swiper"
+                :options="swiperOption"
+                @slideChange="swiperSlideChange"
+                class="swiper-box-container2"
+              >
+                <swiper-slide v-for="(data, index) in swipercanvasData" :key="index">
+                  <b class="video-title" style="font-size:14px;margin-top:-10px">{{ data.name }}</b>
+                  <polygon-canvas
+                    ref="canvas"
+                    v-loading="loading"
+                    element-loading-text="鍒锋柊涓紝璇风◢绛�..."
+                    element-loading-background="rgba(0, 0, 0, 0.8)"
+                    :divId="data.cameraId"
+                    :isShowDrawArrow="true"
+                    :isLink="true"
+                    :disabled="false"
+                    :loading="data.loading"
+                    :snapshot_url="data.baseImg"
+                    :canvasDataShow="data.canvasData"
+                    :currentCameraId="data.cameraId"
+                    @changeLoading="changeLoading"
+                    @fromCanvas="getCanvasData"
+                  ></polygon-canvas>
+                </swiper-slide>
+              </swiper>
+              <div class="swiper-local-prev" v-show="swipercanvasData.length>1">
+                <div class="icon-btn" slot="button-prev">
+                  <i class="iconfont iconzuo"></i>
+                </div>
+              </div>
+              <div class="swiper-local-next" v-show="swipercanvasData.length>1">
+                <div class="icon-btn" slot="button-next">
+                  <i class="iconfont iconyou1"></i>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div style="float:left;width:calc(10% - 90px);height:100%;"></div>
+          <div
+            class="time-box"
+            style="width:calc(90% + 90px - 576px);overflow-x:auto;overflow-y:hidden"
+          >
+            <p style="text-align:left;padding: 10px;box-sizing: border-box">
+              <b style="font-size: 14px">鏃堕棿瑙勫垯</b>
+            </p>
+            <time-slider ref="timeSlider" :type="'link'" />
+          </div>
+        </div>
+
+        <!-- 鍦烘櫙瑙勫垯 -->
+        <scene-rule
+          linkRule
+          :seletedCameras="Carmeras"
+          :tableRuleList="tableRuleList"
+          :onSaveScene="saveSceneRule"
+          @delete-rule="showRules"
+        ></scene-rule>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  saveLinkScene,
+  getLinkSceneRule,
+} from '@/api/scene'
+
+import VideoRuleData from "@/Pool/VideoRuleData";
+import polygonCanvas from "@/components/canvas";
+import TimeSlider from "./TimeSlider";
+import Sysinfo from "./SystemInfo"
+import SceneRule from "./SceneRule";
+import SlideScene from "../scene/SlideScene";
+
+export default {
+  components: {
+    TimeSlider,
+    polygonCanvas,
+    SceneRule,
+    Sysinfo,
+    SlideScene
+  },
+  computed: {
+    selectedCameraIds() {
+      let ids = [];
+      if (this.TreeDataPool.treeActiveName == 'dataStack') {
+        if (this.TreeDataPool.checkedLocalVedio.length > 0) {
+          ids = this.TreeDataPool.checkedLocalVedio.map(i => {
+            return i.id;
+          })
+
+        }
+      } else {
+        if (this.TreeDataPool.selectedNodes.length > 0) {
+          ids = this.TreeDataPool.selectedNodes;
+        }
+      }
+
+      return ids;
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      Carmeras: [],
+      Camera: new VideoRuleData(),
+      tasksTable: {},
+      swipercanvasData: [],
+      seqNumber: 0,
+      tableRuleList: [],
+      swiperIndex: 0,
+      swiperOption: {
+        grabCursor: true,
+        pagination: {
+          el: ".swiper-pagination",
+          type: "fraction"
+        },
+        navigation: {
+          nextEl: ".swiper-local-next",
+          prevEl: ".swiper-local-prev"
+        }
+      },
+      swiperTaskOption: {
+        slidesPerView: 4,
+        // spaceBetween: 10,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        navigation: {
+          nextEl: ".next-border",
+          prevEl: ".pre-border"
+        }
+      },
+      showSysInfo: false
+    };
+  },
+  watch: {
+    Carmeras: {
+      handler(newVal, oldVal) {
+        this.setSwiperData();
+      },
+      deep: true
+    }
+  },
+
+  methods: {
+    swiperSlideChange() {
+      this.swiperIndex = this.$refs.swiper.swiper.activeIndex;
+    },
+    initCameraData() {
+      this.$nextTick(() => {
+        this.Carmeras = [];
+        this.loading = false;
+        this.showSysInfo = true
+        if (this.TreeDataPool.treeActiveName == 'dataStack') {
+          this.TreeDataPool.checkedLocalVedio.forEach(camera => {
+            this.Carmeras.push(new VideoRuleData(camera.id));
+          });
+        } else {
+          this.TreeDataPool.selectedNodes.forEach(camera => {
+            this.Carmeras.push(new VideoRuleData(camera));
+          });
+        }
+        this.$refs.timeSlider.activeTab = this.VideoManageData.TimeRules[0].id;
+        this.showRules();
+      })
+    },
+    setSwiperData() {
+      let swipers = [];
+      let carmeras = this.Carmeras;
+      for (let i = 0; i < carmeras.length; i++) {
+        swipers = swipers.concat({
+          cameraId: carmeras[i].cameraId,
+          name: carmeras[i].camearInfo.name,
+          baseImg: carmeras[i].baseImg ? carmeras[i].baseImg : undefined,
+          canvasData: carmeras[i].canvasData,
+          loading: carmeras[i].loading,
+        });
+      }
+      this.swipercanvasData = swipers;
+    },
+    getCanvasData() { },
+    showRules() {
+      this.tableRuleList = [];
+
+      if (this.selectedCameraIds.length > 0) {
+        getLinkSceneRule({ cameraIds: this.selectedCameraIds }).then(
+          rsp => {
+            if (rsp && rsp.success) {
+              debugger
+              this.tableRuleList = rsp.data;
+
+              // 缁熶竴瑙勫垯缂栬緫鐨勬暟鎹粨鏋�
+              for (let i = 0; i < this.tableRuleList.length; i++) {
+                this.tableRuleList[i].group_rules = this.tableRuleList[i].rules;
+              }
+            }
+            // this.TreeDataPool.fetchTreeData();
+          }
+        );
+      }
+
+    },
+
+    saveSceneRule(groupRule) {
+      const payload = { ...groupRule }
+      payload.cameraIds = this.selectedCameraIds;
+
+      saveLinkScene(payload).then(rsp => {
+        if (rsp && rsp.success) {
+          //this.Camera.update();
+          this.initCameraData();
+          this.$notify({
+            type: "success",
+            message: "浠诲姟淇濆瓨鎴愬姛锛�"
+          });
+        } else {
+          this.$notify({
+            type: "error",
+            message: rsp.data
+          });
+        }
+      }).catch(err => {
+        this.$message({
+          type: "error",
+          message: "淇濆瓨澶辫触锛�" + err.data
+        });
+      });
+    },
+    changeLoading(params) {
+      this.loading = params
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-linkage-rules {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .top {
+    width: 100%;
+    height: 174px;
+    position: relative;
+    top: 0;
+    .swiper-box {
+      height: 100%;
+      float: left;
+      width: 48%;
+      margin-top: -10px;
+      position: relative;
+    }
+    .swiper-container {
+      position: initial;
+      min-width: 472px;
+      width: 80%;
+      
+      // height: 124px;
+    }
+    .swiper-slide {
+      position: relative;
+      width: 100%;
+      .item-card {
+        height: 110px !important;
+        max-width: 126px;
+        width: 100%;
+        position: absolute;
+        left: 0px;
+        right: 0px;
+        bottom: 0px;
+        top: 0px;
+        margin: auto;
+        background: #ffffff;
+        border: 1px solid #e2e2e2;
+        box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+        border-radius: 4px;
+        cursor: pointer;
+        .icon-xingzhuangcopy {
+          position: relative;
+          left: 0px;
+          right: 0px;
+          bottom: 0px;
+          top: 5px;
+          margin: auto;
+          color: #959699;
+        }
+
+        .mask {
+          position: absolute;
+          width: 100%;
+          height: 100%;
+          background: rgba(0, 0, 0, 0.65);
+          /* filter: blur(20px); */
+          backdrop-filter: blur(1px) brightness(100%);
+          display: none;
+        }
+
+        // @media screen and(max-width: 1280px) {
+        //   max-width: 110px;
+        // }
+        @media screen and(max-width: 1440px) {
+          max-width: 110px;
+        }
+      }
+      .item-card:hover {
+        .mask {
+          display: block;
+        }
+      }
+    }
+    .swiper-pre-border,
+    .swiper-next-border {
+      width: 40px;
+      height: 40px;
+      position: absolute;
+      background: #8888;
+      top: 35%;
+      z-index: 99;
+      border-radius: 4em;
+      outline: none;
+      .icon-btn {
+        color: rgb(255, 255, 255);
+        text-align: center;
+        line-height: 38px;
+        cursor: pointer;
+      }
+    }
+    .swiper-pre-border {
+      left: 10px;
+    }
+    .swiper-pre-border:hover {
+      background: #666;
+    }
+    .swiper-next-border {
+      right: 10px;
+    }
+    .swiper-next-border:hover {
+      background: #666;
+    }
+    .top-right {
+      float: right;
+      width: 52%;
+      height: 144px;
+    }
+    .task-css {
+      text-align: left;
+      margin-bottom: 14px;
+    }
+  }
+  // .top {
+  //   width: 100%;
+  //   height: 174px;
+  //   border-bottom: 1px solid #ccc;
+  //   position: relative;
+  //   .slide-scene {
+  //     position: initial;
+  //     min-width: 472px;
+  //     width: 47%;
+  //     float: left;
+  //     height: 124px;
+  //   }
+  //   .swiper-slide {
+  //     position: relative;
+  //     width: 100%;
+  //     .item-card {
+  //       height: 110px !important;
+  //       max-width: 126px;
+  //       width: 100%;
+  //       position: absolute;
+  //       left: 0px;
+  //       right: 0px;
+  //       bottom: 0px;
+  //       top: 0px;
+  //       margin: auto;
+  //       background: #ffffff;
+  //       border: 1px solid #e2e2e2;
+  //       box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+  //       border-radius: 4px;
+  //       cursor: pointer;
+  //       .icon-xingzhuangcopy {
+  //         position: relative;
+  //         left: 0px;
+  //         right: 0px;
+  //         bottom: 0px;
+  //         top: 5px;
+  //         margin: auto;
+  //         color: #959699;
+  //       }
+
+  //       .mask {
+  //         position: absolute;
+  //         width: 100%;
+  //         height: 100%;
+  //         background: rgba(0, 0, 0, 0.65);
+  //         /* filter: blur(20px); */
+  //         backdrop-filter: blur(1px) brightness(100%);
+  //         display: none;
+  //       }
+
+  //       // @media screen and(max-width: 1280px) {
+  //       //   max-width: 110px;
+  //       // }
+  //       @media screen and(max-width: 1440px) {
+  //         max-width: 110px;
+  //       }
+  //     }
+  //   }
+  //   .top-right {
+  //     float: right;
+  //     width: 52%;
+  //     height: 144px;
+  //   }
+
+  //   .pre-border {
+  //     left: 0px;
+  //     top: 40%;
+  //   }
+  //   .next-border {
+  //     left: 40%;
+  //     top: 40%;
+  //   }
+  // }
+  .bottom {
+    width: 100%;
+    height: calc(100% - 190px);
+    position: absolute;
+    top: 190px;
+    .bottom-side {
+      height: 100%;
+      width: 250px;
+      float: left;
+      overflow: auto;
+      border-right: 1px solid #ccc;
+      border-bottom: 1px solid #ccc;
+      padding: 10px;
+      box-sizing: border-box;
+      .selectTask {
+        margin: 10px auto;
+        width: 140px;
+        padding: 10px;
+        box-sizing: border-box;
+        border: 1px solid #ccc;
+        position: relative;
+        .selectTaskDelete {
+          position: absolute;
+          right: 10px;
+          font-size: 18px;
+          cursor: pointer;
+        }
+      }
+    }
+    .bottom-right {
+      width: calc(100% + 30px);
+      height: 100%;
+      float: left;
+      overflow: auto;
+      padding: 10px 0px;
+      box-sizing: border-box;
+      .draw-and-time-box {
+        height: 430px;
+        width: 100%;
+        .draw-box,
+        .time-box {
+          float: left;
+          width: 50%;
+          height: 100%;
+          .img-box {
+            height: calc(100% - 32px);
+            width: 100%;
+            // padding: 5px;
+            box-sizing: border-box;
+            display: flex;
+            // justify-content: center;
+            // align-items: center;
+            position: relative;
+            overflow: hidden;
+            .refresh-btn {
+              position: absolute;
+              right: 10px;
+              top: 10px;
+            }
+            img {
+              width: 90%;
+              padding: 5px;
+              box-sizing: border-box;
+            }
+            .swiper-box-container2 {
+              width: 100%;
+              //padding: 8px 8px 0px 8px;
+              .el-card__body {
+                height: 100%;
+                padding: 0px;
+              }
+              height: calc(100% - 10px);
+              .info {
+                width: 100%;
+                height: 100%;
+                .info-left {
+                  width: 50%;
+                  height: 100%;
+                  float: left;
+                  img {
+                    width: 100%;
+                  }
+                }
+                .info-right {
+                  width: 50%;
+                  height: 100%;
+                  float: left;
+                  box-sizing: border-box;
+                  padding: 10px;
+                  p {
+                    padding: 4px 0px;
+                  }
+                  .infoIcon {
+                    height: 24px;
+                    cursor: pointer;
+                    i {
+                      margin: 5px;
+                      font-size: 22px;
+                    }
+                  }
+                }
+              }
+            }
+            .swiper-local-prev,
+            .swiper-local-next {
+              width: 40px;
+              height: 40px;
+              position: absolute;
+              background: #8888;
+              top: 40%;
+              z-index: 99;
+              border-radius: 4em;
+              outline: none;
+              .icon-btn {
+                color: rgb(255, 255, 255);
+                text-align: center;
+                line-height: 38px;
+                cursor: pointer;
+              }
+            }
+            .swiper-local-prev {
+              left: 10px;
+            }
+            .swiper-local-prev:hover {
+              background: #666;
+            }
+            .swiper-local-next {
+              left: 90%;
+            }
+            .swiper-local-next:hover {
+              background: #666;
+            }
+            .camera-tip {
+              position: relative;
+              width: 300px;
+              top: 40%;
+              left: 40%;
+              font-size: 12px;
+              color: #cccccc;
+              font-family: PingFangSC-Regular;
+            }
+          }
+        }
+        .draw-box {
+          width: 576px;
+        }
+      }
+    }
+    .bottom-right::-webkit-scrollbar {
+      width: 0 !important;
+    }
+  }
+
+  .add-btn {
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+    cursor: pointer;
+  }
+  .add-btn:hover {
+    color: #2249b4;
+  }
+  .task-tip {
+    font-family: PingFangSC-Regular;
+    font-size: 12px;
+    color: #cccccc;
+    margin-top: 10%;
+    margin-left: 38%;
+  }
+}
+</style>
+<style lang="scss" scoped>
+.el-loading-spinner {
+  background: url("../../assets/gif/loading.gif") no-repeat;
+  top: 50%;
+  margin-top: -21px;
+  width: calc(100% - 260px) !important;
+  text-align: center;
+  position: absolute;
+  margin-left: 260px;
+  .el-loading-text {
+    color: #3d68e1;
+    margin: 3px 0;
+    font-size: 14px;
+    text-align: left;
+    margin-top: 22px !important;
+    padding-left: 30px;
+  }
+}
+</style>
diff --git a/src/components/camera/PollSetting.vue b/src/components/camera/PollSetting.vue
new file mode 100644
index 0000000..7b34e04
--- /dev/null
+++ b/src/components/camera/PollSetting.vue
@@ -0,0 +1,614 @@
+<template>
+  <div class="s-poll-setting">
+    <div class="top" v-show="!strethTable">
+      <div class="percentBall">
+        <sysinfo
+          ref="sysInfo"
+          v-if="showSysInfo"
+          :ShowLocalVedio="true"
+          showTask
+          showClass="sysinfo-box flex-row-left"
+        />
+        <slider-vedio
+          v-show="false"
+          :channelTotal="PollData.channelTotal"
+          :list="PollData.sliderList"
+          @changeSlider="changeSlider"
+        ></slider-vedio>
+      </div>
+
+      <div class="barGraph">
+        <div id="barSimple"></div>
+      </div>
+    </div>
+
+    <div class="bottom">
+      <div style="width: 100%;height: 10px;background-color: #E9EBF2;"></div>
+      <div class="content">
+        <div class="toolBar">
+          <el-input
+            size="small"
+            style="width: 180px;"
+            placeholder="璇疯緭鍏ユ悳绱㈠唴瀹�"
+            prefix-icon="el-icon-search"
+            clearable
+            v-model="PollData.SearchName"
+          ></el-input>
+          <el-button
+            size="small"
+            type="primary"
+            style="margin-left: 20px; margin-right: 50px;"
+            @click="pollSeach"
+          >鎼滅储</el-button>
+          <div class="tip">
+            <span>
+              杞鏃堕棿 :
+              <b>{{PollData.Config.poll_period}}</b>鍒嗛挓
+            </span>
+            <span>
+              杞鍛ㄦ湡 :
+              <b>{{pollCycle}}</b>鍒嗛挓
+            </span>
+            <span>
+              杞寮�鍏� :
+              <b>{{PollData.Enabled | switchText}}</b>
+            </span>
+          </div>
+          <span :class="stretchStyle" @click="strethTable = !strethTable"></span>
+
+          <el-button size="small" type="primary" style="float:right" @click="openDrawer">璁剧疆</el-button>
+        </div>
+
+        <el-table
+          :header-cell-style="{background:'#F8F8F8', color: '#222222'}"
+          :data="PollData.CameraList"
+          height="93%"
+          border
+        >
+          <el-table-column label="搴忓彿" type="index" align="center" width="100px"></el-table-column>
+          <el-table-column label="鎽勫儚鏈哄悕绉�" align="center" show-overflow-tooltip sortable>
+            <template slot-scope="scope">
+              <span
+                :style="scope.row.is_running ? `color:#3d68e1` : '' "
+              >{{scope.row.alias !== '' ? scope.row.alias: scope.row.name}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎽勫儚鏈哄湴鍧�" prop="addr" align="center" show-overflow-tooltip sortable></el-table-column>
+          <el-table-column label="鎽勫儚鏈篒P" prop="ip" align="center" width="130px" sortable></el-table-column>
+          <el-table-column label="鎽勫儚鏈虹被鍨�" align="center" width="110px" sortable>
+            <template slot-scope="scope">
+              <span>{{scope.row.run_type | cameraType}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎵ц绠楁硶" align="center" show-overflow-tooltip sortable>
+            <template slot-scope="scope">
+              <span v-if="scope.row.run_type === -1 ">-</span>
+              <span v-else>{{scope.row.tasks | taskList}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="杩愯璁惧" align="center" width="160px">
+            <template slot-scope="scope">
+              <span v-if="scope.row.run_type === -1 ">-</span>
+              <span v-else>{{scope.row.runServerName}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鐘舵��" align="center" show-overflow-tooltip sortable width="100px">
+            <template slot-scope="scope">
+              <span v-if="scope.row.status === -1 ">-</span>
+              <span v-else-if="scope.row.status === 2">{{"澶勭悊涓�"}}</span>
+              <span v-else-if="scope.row.status === 1">{{"绛夊緟澶勭悊"}}</span>
+              <span v-else-if="scope.row.status === 0">{{"瑙勫垯涓嶅叏"}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="瀹炴椂/杞" align="center" width="100px">
+            <template slot-scope="scope">
+              <span v-if="scope.row.run_type === -1 ">-</span>
+              <toggle-button
+                v-else
+                :value="scope.row.run_type === 1"
+                :width="60"
+                :labels="{checked: '瀹炴椂', unchecked: '杞'}"
+                :color="{checked: '#4D88FF', unchecked: '#FF7733', disabled: '#CCCCCC'}"
+                :sync="true"
+                @change="pollSwitch(scope.row)"
+              />
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+
+    <!-- 璁剧疆寮圭獥 -->
+    <el-drawer
+      title="绠楀姏璁剧疆"
+      :visible.sync="drawer"
+      direction="rtl"
+      size="350px"
+      custom-class="e-drawer"
+      :before-close="closeDrawer"
+    >
+      <div class="dawer_details">
+        <span>鎬荤畻鍔� {{formData.totalChanle}} 閫氶亾</span>
+        <span style="margin-left:20px">瀹炴椂绠楀姏 {{formData.realTime}} 閫氶亾</span>
+      </div>
+      <div class="e-drawer_rate">
+        <div class="rate">
+          <label>杞鏃堕棿</label>
+          <el-input-number
+            size="small"
+            style="width: 60px;margin-left:25px"
+            v-model.number="formData.pollPeriod"
+            :controls="false"
+            :min="0"
+            :max="60 * 24 * 1"
+          ></el-input-number>
+          <span>鍒嗛挓</span>
+
+          <label>杞寮�鍏�</label>
+          <el-switch style="margin-left: 10px;" v-model="formData.pollEnable"></el-switch>
+        </div>
+        <div class="rate">
+          <label>杞绠楀姏</label>
+          <el-input-number
+            style="margin-left:25px;width:90px"
+            size="small"
+            v-model="formData.polling"
+            @change="changePoll"
+            controls-position="right"
+            :min="0"
+            :max="maxPoll"
+          ></el-input-number>
+        </div>
+        <div class="rate">
+          <label>鏁版嵁鏍堢畻鍔�</label>
+          <el-input-number
+            style="margin-left:11px;width:90px"
+            size="small"
+            v-model="formData.dataStack"
+            @change="changeStack"
+            controls-position="right"
+            :min="0"
+            :max="maxDataStack"
+          ></el-input-number>
+        </div>
+
+        <el-button
+          size="small"
+          type="primary"
+          style="margin:10px 10px 0px 200px"
+          @click="saveSetting"
+        >淇濆瓨</el-button>
+        <el-button size="small" type="info" style="color:black" @click="closeDrawer">鍙栨秷</el-button>
+      </div>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import echarts from "echarts";
+import { changeRunType, updatePollEnable, updatePollPeriod, updateChannelCount } from "@/api/pollConfig";
+
+import Sysinfo from "./SystemInfo"
+import SliderVedio from '@/components/camera/slider-vedio'
+// import eChartsBar from '@/components/subComponents/eChartsBar'
+
+export default {
+  name: "PollSeting",
+  components: {
+    Sysinfo,
+    SliderVedio,
+    // eChartsBar
+  },
+  filters: {
+    cameraType(type) {
+      return type === -1 ? "鐩戞帶鎽勫儚鏈�" : "AI鎽勫儚鏈�";
+    },
+    taskList(tasks) {
+      return tasks.filter(task => {
+        return task.hasRule;
+      }).map(task => {
+        return task.taskname
+      }).join(',')
+    },
+    switchText(type) {
+      return type ? "宸插紑鍚�" : "鏈紑鍚�";
+    }
+  },
+  computed: {
+    maxPoll() {
+      return this.formData.totalChanle - this.formData.realTime;
+    },
+    maxDataStack() {
+      return this.formData.totalChanle - this.formData.realTime;
+    },
+    stretchStyle() {
+      let arry = ["iconfont", "stretch-btn"];
+      arry.push(this.strethTable ? "iconzhankai" : "iconshouqi")
+      return arry;
+    },
+    pollCycle() {
+      let sumPollingCamera = 0;
+      this.PollData.CameraList.forEach(cam => {
+        if (cam.run_type === 0) {
+          sumPollingCamera++
+        }
+      })
+
+      return sumPollingCamera * this.PollData.Config.poll_period
+    }
+  },
+  data() {
+    return {
+      switchValue: true,
+      search: "",
+      timeout: null,
+      taskName: [],
+      dataList: [],
+      barChart: {},
+      localDataChannel: 2,
+      showSysInfo: false,
+      drawer: false,
+      formData: {},
+      strethTable: false
+    };
+  },
+  mounted() {
+    this.PollData.init();
+    this.statistic()
+    this.barChart = echarts.init(document.getElementById("barSimple"));
+  },
+  beforeDestroy() {
+    clearTimeout(this.timeout);
+  },
+  methods: {
+    openDrawer() {
+      this.initFormData();
+      this.drawer = true;
+    },
+    closeDrawer() {
+      this.drawer = false;
+      this.initFormData();
+    },
+    initFormData() {
+      this.formData = {
+        totalChanle: this.PollData.channelTotal,
+        realTime: this.PollData.RealTimeSum,
+        pollEnable: this.PollData.Enabled,
+        pollPeriod: this.PollData.Config.poll_period,
+        polling: this.PollData.PollChannelTotal,
+        dataStack: this.PollData.localVideo,
+      }
+    },
+    pollSeach() {
+      this.PollData.fetchPollList();
+    },
+    pollEnable() {
+      updatePollEnable({ enable: this.PollData.Enabled }).then(rsp => {
+        this.$notify({
+          type: "success",
+          message: "淇敼鎴愬姛"
+        });
+        // this.PollData.fetchPollConfig()
+      })
+    },
+    updateDelayTime() {
+      updatePollPeriod({ period: this.PollData.Config.poll_period }).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$notify({
+            type: 'success',
+            message: '杞鏃堕棿淇敼鎴愬姛锛�'
+          })
+        } else {
+          this.$notify({
+            type: 'error',
+            message: '杞鏃堕棿淇敼澶辫触锛�'
+          })
+        }
+      })
+    },
+    statistic() {
+      this.PollData.statistics();
+      let _this = this;
+      _this.timeout = setTimeout(() => {
+        _this.statistic();
+      }, 10 * 1000);
+    },
+    pollSwitch(row) {
+      changeRunType({ camera_ids: [row.id], run_type: row.run_type ^ 1 }).then(
+        rsp => {
+          if (rsp && rsp.success) {
+            this.$notify({
+              type: "success",
+              message: "閰嶇疆鎴愬姛"
+            });
+
+            row.run_type = row.run_type ^ 1
+
+          } else {
+            this.$notify({
+              type: "error",
+              message: "閰嶇疆澶辫触"
+            });
+          }
+
+          // this.PollData.fetchPollList();
+        }
+      );
+    },
+    initLineChart() {
+      // console.log(this.barChart,'initLineChart')
+      // this.$refs.sysInfo.initCpuCharts();
+      let optionBar = {
+        color: ["#3D68E1"],
+        tooltip: {
+          trigger: "axis",
+          axisPointer: {
+            // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥
+            type: "shadow" // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow'
+          }
+        },
+        grid: {
+          top: 40,
+          // bottom: '45%',
+          left: 0,
+          containLabel: true
+        },
+
+        xAxis: [
+          {
+            type: "category",
+            data: this.taskName,
+            axisTick: {
+              // alignWithLabel: true
+            },
+            axisLine: {
+              show: false
+            },
+            nameLocation: 'start',
+            axisTick: {
+              show: false
+            },
+            axisLabel: {
+              rotate: 45,
+              formatter: function (value, index) {
+                let name = ""
+                if (value.length > 2) {
+                  name = value.substring(0, 2) + '...'
+                } else {
+                  name = value
+                }
+                let text = [`{a|${name}}`]
+                return text
+              },
+              rich: {
+                a: {
+                  fontSize: 10,
+                  with: 30
+                }
+              }
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: "value",
+            show: true,
+            axisLine: {
+              show: false
+            },
+            splitLine: {
+              lineStyle: {
+                type: "dotted",
+                color: ['#f1f1f1']
+              }
+            },
+            axisTick: {
+              show: false
+            }
+          }
+        ],
+        series: [
+          {
+            name: "鏁伴噺",
+            type: "bar",
+            barWidth: "30%",
+            data: this.dataList
+          }
+        ]
+      };
+      this.showSysInfo = true
+      this.barChart.setOption(optionBar);
+      this.barChart.resize()
+      this.$nextTick(() => {
+        this.barChart.resize()
+      })
+    },
+
+    //婊戝潡鏁版嵁鏇存柊鍥炶皟
+    changeSlider(val) {
+      // console.log(val, '婊戝潡鍊煎彉鍔�')
+      let fileChannelCount = val[val.length - 1] - val[val.length - 2]
+      let pollChannelCount = val[val.length - 2] - val[val.length - 3]
+      this.PollData.updateChannelCount(fileChannelCount, pollChannelCount)
+    },
+
+    async saveSetting() {
+      let rsp = await updatePollEnable({ enable: this.formData.pollEnable })
+      if (!rsp || !rsp.success) {
+        this.formData.pollEnable = !this.formData.pollEnable
+        this.$notify({
+          type: "error",
+          message: "杞寮�鍏冲垏鎹㈠け璐ワ紒"
+        });
+        return
+      }
+
+      rsp = await updatePollPeriod({ period: this.formData.pollPeriod })
+      if (!rsp || !rsp.success) {
+        this.$notify({
+          type: "error",
+          message: "杞鏃堕棿淇敼澶辫触锛�"
+        });
+        return
+      }
+      rsp = await updateChannelCount({ videoChannelCount: this.formData.dataStack, pollChannelCount: this.formData.polling })
+      if (!rsp || !rsp.success) {
+        this.$notify({
+          type: "error",
+          message: "绠楀姏閰嶇疆澶辫触锛�"
+        });
+        return
+      } else {
+        this.$notify({
+          type: "success",
+          message: "閰嶇疆淇濆瓨鎴愬姛"
+        });
+      }
+      this.PollData.statisticTaskInfo()
+      this.PollData.fetchPollConfig()
+    },
+
+    //鐩戝惉杞绠楀姏
+    changePoll(newVal, oldVal) {
+      if (newVal > oldVal) {
+        this.formData.dataStack--
+      }
+      if (newVal < oldVal) {
+        this.formData.dataStack++
+      }
+      // console.log("this.formData.dataStack:"+this.formData.dataStack)
+    },
+    //鐩戝惉鏁版嵁鏍堢畻鍔�
+    changeStack(newVal, oldVal) {
+      if (newVal > oldVal) {
+        this.formData.polling--
+      }
+      if (newVal < oldVal) {
+        this.formData.polling++
+      }
+      // console.log("this.formData.polling:"+this.formData.polling)
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-poll-setting {
+  width: 100%;
+  height: 100%;
+  font-size: 14px;
+  position: relative;
+  .top {
+    width: 100%;
+    height: 190px;
+    // border-bottom: 1px solid #ccc;
+    .progressBar {
+      width: 26%;
+    }
+    .percentBall {
+      width: 80%;
+      height: 82%;
+      float: left;
+      // @media screen and (min-width: 1280px) and (max-width: 1440px) {
+      //   width: 75%;
+      // }
+      // @media screen and (max-width: 1280px) {
+      //   width: 80%;
+      // }
+    }
+    .barGraph {
+      width: 20%;
+      height: 100%;
+      float: right;
+      // @media screen and (min-width: 1280px) and (max-width: 1440px) {
+      //   width: 25%;
+      // }
+      // @media screen and (max-width: 1280px) {
+      //   width: 20%;
+      // }
+      #barSimple {
+        width: 100%;
+        height: 250px;
+        margin-top: -30px;
+      }
+    }
+    .point {
+      text-align: right;
+      margin-left: 64px;
+      b {
+        display: inline-block;
+        width: 9px;
+        height: 9px;
+        border-radius: 50%;
+        background-color: #f53d3d;
+      }
+    }
+  }
+  .bottom {
+    width: calc(100% + 76px);
+    height: 100%;
+    // height: calc(100% - 220px);
+    position: absolute;
+    // top: 220px;
+    left: -38px;
+    .tip {
+      display: inline-block;
+      font-family: PingFangSC-Medium;
+      font-size: 14px;
+      span {
+        margin: 0px 10px;
+      }
+    }
+    .content {
+      padding: 20px 38px 38px 38px;
+      box-sizing: border-box;
+      width: 100%;
+      height: 100%;
+      .toolBar {
+        width: 100%;
+        height: 42px;
+        text-align: left;
+        margin-bottom: 15px;
+      }
+      .el-table {
+        border: 1px solid #e0e0e0;
+      }
+    }
+
+    .stretch-btn {
+      float: right;
+      margin-left: 10px;
+      line-height: 35px;
+      cursor: pointer;
+    }
+  }
+}
+
+.e-drawer {
+  // margin-top: 150px;
+
+  font-family: PingFangSC-Medium;
+  font-size: 14px;
+  .dawer_details {
+    text-align: left;
+    margin-left: 70px;
+    margin-top: 30px;
+  }
+  .e-drawer_rate {
+    width: 100%;
+    margin-top: 15px;
+    .rate {
+      width: 100%;
+      text-align: left;
+      margin-top: 15px;
+      margin-left: 50px;
+    }
+    label {
+      margin-left: 20px;
+    }
+  }
+
+  .el-drawer__header {
+    margin-bottom: 0px;
+  }
+}
+</style>
diff --git a/src/components/camera/SceneRule.vue b/src/components/camera/SceneRule.vue
new file mode 100644
index 0000000..5628197
--- /dev/null
+++ b/src/components/camera/SceneRule.vue
@@ -0,0 +1,520 @@
+<template>
+  <div class="scene-edit-container">
+    <div class="scene-title">
+      <b style="font-size: 14px; line-height: 18px;">鍦烘櫙</b>
+      <el-button type="primary" size="mini" @click="handleCreate" style="margin-left:87%" v-show='!editScene'>+ 娣诲姞鍦烘櫙</el-button>
+    </div>
+
+    <el-form ref="form" label-width="80px"  v-show="editScene">
+      <div class="flex-form">
+        <div class="left">
+          <el-form-item label="鍦烘櫙鍚嶇О">
+            <el-input v-model="sceneForm.scene_name" size="mini" maxlength="15"></el-input>
+          </el-form-item>
+          <el-form-item label="浜嬩欢绛夌骇" >
+            <el-select
+              v-model="sceneForm.alarm_level"
+              placeholder="璇烽�夋嫨"
+              size="mini"
+              style="width:250px"
+            >
+              <el-option label="涓�绾�" :value="1"></el-option>
+              <el-option label="浜岀骇" :value="2"></el-option>
+              <el-option label="涓夌骇" :value="3"></el-option>
+              <el-option label="鍥涚骇" :value="4"></el-option>
+              <el-option label="浜旂骇" :value="5"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鏃堕棿娈�">
+            <el-select
+              v-model="sceneForm.time_rule_id"
+              placeholder="璇烽�夋嫨"
+              size="mini"
+              
+            >
+              <el-option
+                v-for="item in VideoManageData.TimeRules"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </div>
+        <div class="right">
+          <el-form-item label="鍦烘櫙鎻忚堪">
+            <el-input v-model="sceneForm.desc" type="textarea" size="mini"></el-input>
+          </el-form-item>
+        </div>
+      </div>
+      <!-- <el-row>
+        <el-col :span="8"> -->
+          <!-- <el-form-item label="鍦烘櫙妯℃澘">
+            <el-select
+              v-model="sceneForm.template_id"
+              placeholder="璇烽�夋嫨"
+              @change="selectTemplate"
+              size="mini"
+              style="width:200px"
+            >
+              <el-option
+                v-for="item in sceneTemplates"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item> -->
+        <!-- </el-col>
+        <el-col :span="8">
+          <el-form-item label="鏃堕棿娈�">
+            <el-select
+              v-model="sceneForm.time_rule_id"
+              placeholder="璇烽�夋嫨"
+              size="mini"
+              style="width:200px"
+            >
+              <el-option
+                v-for="item in VideoManageData.TimeRules"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row> -->
+      <!-- <el-row>
+        <el-col :span="8">
+          <el-form-item label="鍦烘櫙鍚嶇О">
+            <el-input v-model="sceneForm.scene_name" size="mini" style="width:200px"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="鍦烘櫙鎻忚堪">
+            <el-input v-model="sceneForm.desc" type="textarea" size="mini" style="width:200px;height:180px;"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row> -->
+      <!-- <el-row>
+        <el-col :span="8">
+          <el-form-item label="浜嬩欢绛夌骇">
+            <el-select
+              v-model="sceneForm.alarm_level"
+              placeholder="璇烽�夋嫨"
+              size="mini"
+              style="width:200px"
+            >
+              <el-option label="涓�绾�" :value="1"></el-option>
+              <el-option label="浜岀骇" :value="2"></el-option>
+              <el-option label="涓夌骇" :value="3"></el-option>
+              <el-option label="鍥涚骇" :value="4"></el-option>
+              <el-option label="浜旂骇" :value="5"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row> -->
+
+      <scene-editor
+        ref="sceneEditor"
+        :isLinkRule="linkRule"
+        :Cameras="seletedCameras"
+        :ruleList="templateRules"
+        @sdkNameChange="getSceneName"
+      ></scene-editor>
+
+      <el-form-item style="width: 60%;min-width: 1048px;">
+        <el-button size="mini" @click="editScene = false">鍙栨秷</el-button>
+        <el-button type="primary" size="mini" @click="saveSceneRule">淇濆瓨</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 瑙勫垯鍒楄〃 -->
+    <div class="edit-rule-table" v-show="!editScene">
+      <div class="task-rules-table-box">
+        <el-table
+          :data="tableRuleList"
+          border
+          style="width: 100%"
+          :cell-style="cellStyle"
+          :header-cell-style="{background:'#f8f8f8',color:'#222222'}"
+        >
+          <el-table-column label="搴忓彿" type="index" align="center" width="50"></el-table-column>
+          <el-table-column
+            label="鍦烘櫙鍚嶇О"
+            prop="scene_name"
+            width="120"
+            align="center"
+            show-overflow-tooltip
+          ></el-table-column>
+          <el-table-column label="绛栫暐" prop="group_text" align="center" min-width="350px" >
+            <template slot-scope="scope">
+              <span v-html="scope.row.group_text"></span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏃堕棿娈�" prop="time_name" align="center" width="100">
+
+          </el-table-column>
+          <el-table-column label="鎻忚堪" prop="desc" align="center" min-width="150"></el-table-column>
+          <!-- <el-table-column label="鐘舵��" align="center" width="90">
+            <template slot-scope="scope">
+              <el-switch v-model="scope.row.defence_state" @change="updateDefence(scope.row)"></el-switch>
+            </template>
+          </el-table-column>-->
+          <el-table-column label="浜嬩欢绛夌骇" align="center" width="120">
+            <template slot-scope="scope">
+              <span>{{scope.row.alarm_level | alarmLevel }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="鎿嶄綔" fixed="right" align="center" width="100">
+            <template slot-scope="scope">
+              <el-tooltip content="缂栬緫" placement="top" popper-class="atooltip">
+                <i
+                  class="iconfont iconbianji1 btn-icon"
+                  style="font-size: 28px;"
+                  @click="handleEdit(scope.row)"
+                ></i>
+              </el-tooltip>
+              <el-tooltip content="鍒犻櫎" placement="top" popper-class="atooltipgroup_">
+                <i
+                  class="iconfont iconshanchu4 btn-icon"
+                  style="font-size: 28px; color:red;"
+                  @click="handleDelScene(scope.row)"
+                ></i>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  getAllTemplate,
+  saveCameraScene,
+  getCameraSceneRule,
+  deleteCameraScene
+} from '@/api/scene'
+import RuleEditor from "@/components/subComponents/RuleEditor";
+import SceneEditor from "@/components/scene/Editor";
+
+export default {
+  name: "SceneRuleEditor",
+  components: {
+    SceneEditor
+  },
+  props: {
+    seletedCameras: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    tableRuleList: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    onSaveScene: {
+      type: Function,
+      default: () => false
+    },
+    linkRule: {
+      type: Boolean,
+      default: false
+    }
+  },
+  filters: {
+    alarmLevel(level) {
+      switch (level) {
+        case 1:
+          return "涓�绾�";
+        case 2:
+          return "浜岀骇";
+        case 3:
+          return "涓夌骇";
+        case 4:
+          return "鍥涚骇";
+        case 5:
+          return "浜旂骇";
+      }
+    }
+  },
+  watch: {
+    tableRuleList(n, o) {
+      this.editScene = false;
+    }
+  },
+  mounted() {
+    // window.addEventListener('resize', this.windowSizeChange)
+    this.updateTemplates();
+  },
+  data() {
+    return {
+      editScene: false,
+      sceneTemplates: [],
+      sceneForm: {
+        alarm_level: 1,
+        enable: true,
+        scene_name: "",
+        desc: "",
+        template_id: "",
+        time_rule_id: "",
+      },
+      templateSdks: [],
+      templateRules: "",
+      ruleList: [],
+      sceneNameStore: []
+    }
+  },
+  methods: {
+    bubbleSort(arr){
+      for(var i = arr.length-1;i > 0 ; i--){
+          for(var j = 0; j < i; j++){
+              if(arr[j]>arr[j+1]){
+                  let temp = arr[j];
+                  arr[j]= arr[j+1];
+                  arr[j+1] = temp
+              }
+          }
+      }
+      return arr;
+    },
+    getSceneName(sdk_name){
+      this.sceneNameStore.push(sdk_name)
+
+      if(!this.sceneForm.scene_name.trim()){
+        this.sceneForm.scene_name = sdk_name
+      }
+      // }else if(this.sceneForm.scene_name == store[store.length-2]){
+      //   //鍦烘櫙鍚嶇О鍙栫殑鏄笂涓�娆′紶杩囨潵鐨勭畻娉曞悕绉帮紝鍒欓』鏇存柊涓烘渶鏂颁紶鏉ョ殑绠楁硶鍚�
+      //   this.sceneForm.scene_name = sdk_name
+      // }
+    },
+    cleanForm() {
+      this.sceneForm = {
+        alarm_level: 1,
+        enable: true,
+        scene_name: "",
+        desc: "",
+        template_id: "",
+        time_rule_id: "",
+      };
+      this.$refs.sceneEditor.cleanRule();
+    },
+    handleCreate() {
+      debugger
+      console.log(this.DataStackPool.selectedDir.id,this.TreeDataPool.treeActiveName=='dataStack')
+      if (this.linkRule && this.TreeDataPool.selectedNodes.length < 2) {
+        this.$notify({
+          type: "warning",
+          message: "璇烽�夋嫨鑷冲皯2涓憚鍍忔満!"
+        });
+        return false;
+      }else if(!this.linkRule && this.TreeDataPool.treeActiveName != 'dataStack' && this.TreeDataPool.selectedNodes.length < 1){
+        this.$notify({
+          type: "warning",
+          message: `璇烽�夋嫨1涓憚鍍忔満!`
+        });
+        return false;
+      }else if(this.TreeDataPool.treeActiveName=='dataStack' && !this.DataStackPool.selectedDir.id){
+        this.$notify({
+          type: "warning",
+          message: `璇峰厛閫夋嫨鏁版嵁鏍堟枃浠跺す!`
+        });
+        return false;
+      }
+      this.editScene = true;
+      this.cleanForm();
+      console.log(this.tableRuleList)
+   
+      //鍒濆鍖栧満鏅悕绉�
+      var pattern = /^鍦烘櫙\s*\d+\s*$/;
+      var tempArr = [];
+      this.tableRuleList.forEach(scene=>{
+        debugger
+        if(pattern.test(scene.scene_name)){
+          tempArr.push(Number(scene.scene_name.substring(2).trim()));
+        }
+      });
+      let latest = tempArr.length>0? this.bubbleSort(tempArr)[tempArr.length-1]+1 : 1;
+  
+      this.sceneForm.scene_name = '鍦烘櫙'+latest;
+      //鍒濆鍖栨椂闂存
+      this.sceneForm.time_rule_id = this.VideoManageData.TimeRules[0].id;
+      
+    },
+    handleEdit(scene) {
+      debugger
+      this.sceneForm = scene;
+      this.editScene = true;
+      let selectedTpl = {};
+      this.sceneTemplates.forEach((t) => {
+        if (t.id == this.sceneForm.template_id) {
+          selectedTpl = t
+        }
+      })
+      this.templateSdks = selectedTpl.sdks;
+      debugger
+      this.templateRules = JSON.stringify(scene.rules);
+      this.$refs.sceneEditor.editHandle(this.templateRules);
+      
+    },
+    updateTemplates() {
+      getAllTemplate().then(rsp => {
+        if (rsp && rsp.success) {
+          this.sceneTemplates = rsp.data;
+        }
+      })
+    },
+    selectTemplate() {
+      let selectedTpl = {};
+      this.sceneTemplates.forEach((t) => {
+        if (t.id == this.sceneForm.template_id) {
+          selectedTpl = t;
+        }
+      })
+
+      // 璁剧疆榛樿鍙傛暟, 鏃堕棿瑙勫垯鍙栫涓�涓�
+      this.sceneForm.time_rule_id = this.VideoManageData.TimeRules[0].id;
+      this.sceneForm.scene_name = selectedTpl.name;
+      this.sceneForm.desc = selectedTpl.desc;
+
+      this.templateSdks = selectedTpl.sdks;
+      this.templateRules = selectedTpl.rules;
+    },
+    validateForm(){
+      debugger
+      if(!this.sceneForm.scene_name.trim()){
+        this.$notify({
+          type: 'warning',
+          message: '鍦烘櫙鍚嶄笉鑳戒负绌�'
+        });
+        return false
+      }else if(!this.sceneForm.alarm_level){
+        this.$notify({
+          type: 'warning',
+          message: '浜嬩欢绛夌骇涓嶈兘涓虹┖'
+        });
+        return false
+      }else if(!this.sceneForm.time_rule_id){
+        this.$notify({
+          type: 'warning',
+          message: '鏃堕棿娈典笉鑳戒负绌�'
+        });
+        return false
+      }
+      return true
+    },
+    saveSceneRule() {
+      debugger
+      if(!this.validateForm()){
+        return
+      }
+      let editorResp = this.$refs.sceneEditor.submitRule();
+      this.sceneForm.rules = editorResp.rules;
+      this.sceneForm.id = editorResp.id;
+      this.sceneForm.group_text = editorResp.text;
+      this.onSaveScene(this.sceneForm);
+    },
+    handleDelScene(groupRule) {
+      this.$confirm("鎻愮ず锛氬垹闄ゅ悗锛岃鏉¤鍒欏皢澶辨晥锛屾槸鍚﹀垹闄わ紵", {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      })
+        .then(() => {
+          deleteCameraScene(groupRule.id).then(res => {
+            this.$emit("delete-rule");
+            if (res && res.success) {
+              this.$notify({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛"
+              });
+
+            } else {
+              this.$notify({
+                type: "error",
+                message: "鍒犻櫎澶辫触锛�"
+              });
+            }
+          });
+        })
+        .catch(() => { });
+    },
+    cellStyle(obj){
+      if(obj.column.label=='绛栫暐'){
+        return 'text-align:left;padding-left:8px;'
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.scene-edit-container {
+  .scene-title {
+    height: 30px;
+    text-align: left;
+    margin: 10px 0px;
+    
+  }
+  .flex-form{
+    display: flex;
+    width: 80%;
+    padding-left: 25px;
+    .left,.right{
+      width: 43.3%;
+      min-width: 550px;
+      .el-form-item{
+        margin-bottom: 16px;
+      }
+      .el-form-item__label{
+        text-align: left;
+      }
+      .el-form-item__content{
+        text-align: left;
+        .el-input,.el-select{
+          width: 400px !important;
+        }
+      }
+      textarea{
+        height: 143px;
+      }
+    }
+    .right{
+      padding-top: 6px;
+    }
+  }
+  .edit-rule-table {
+    .task-rules-table-box {
+      width: 98%;
+      padding: 0px;
+      box-sizing: border-box;
+    }
+    .el-form-item{
+      width: calc(100% - 30px);
+      
+    }
+    .el-input__inner {
+      border: 0px !important;
+      border-radius: 2px;
+      padding: 0 22px;
+      background-color: transparent;
+    }
+
+    .el-input__suffix {
+      right: 8px;
+    }
+    span {
+      cursor: pointer;
+    }
+    .cell{
+      padding-left: 0!important;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/camera/SeparateRules.vue b/src/components/camera/SeparateRules.vue
new file mode 100644
index 0000000..1099aaf
--- /dev/null
+++ b/src/components/camera/SeparateRules.vue
@@ -0,0 +1,873 @@
+<template>
+  <div class="s-separate-rules">
+    <div class="ai">
+      <div class="check-area">
+        <el-row class="mt5">
+          <el-col :span="24">
+            <div class="ai-select">
+              <div style="float:left;" v-show="cameraType === 'camera'">
+                <span>
+                  <span class="label">瑙嗛鍒嗘瀽澶勭悊</span>
+                  <el-switch
+                    style="margin-left: 10px;"
+                    v-model="Camera.analytics"
+                    @change="pollEnable"
+                    :disabled="!Camera.cameraId"
+                  ></el-switch>
+                </span>
+              </div>
+
+              <div
+                v-if="Camera.analytics"
+                style="float:left;margin-left: 5%;"
+                class="flex-box"
+                v-show="cameraType === 'camera'"
+              >
+                <span class="label" style="margin-right:10px;line-height: 22px;">澶勭悊鏂瑰紡</span>
+                <toggle-button
+                  :value="Camera.dealWay"
+                  :width="60"
+                  :labels="{checked: '瀹炴椂', unchecked: '杞'}"
+                  :color="{checked: '#3D68E1', unchecked: '#FF7733', disabled: '#CCCCCC'}"
+                  :sync="true"
+                  @change="changePoll"
+                />
+              </div>
+
+              <div
+                v-if="Camera.analytics"
+                style="float:left;margin-left:5%;"
+                class="flex-box"
+                v-show="cameraType === 'camera'"
+              >
+                <span class="label" style="line-height:25px">鍒嗚鲸鐜�</span>
+                <el-select
+                  v-model="Camera.selectResolution"
+                  placeholder="璇烽�夋嫨"
+                  size="mini"
+                  style="width: 134px;height: 30px;
+                    margin-left:10px;position: relative;bottom: 3px;"
+                >
+                  <el-option
+                    v-for="item in Camera.resolutionOption"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                  ></el-option>
+                </el-select>
+              </div>
+
+              <div v-if="Camera.analytics" style="float:left;margin-left:5%;" class="flex-box">
+                <span class="label" style="line-height:22px">鏅鸿兘璁$畻鑺傜偣: {{ Camera.runServerName}}</span>
+              </div>
+
+              <div
+                v-if="Camera.analytics"
+                style="float:left;margin-left: 5%;line-height: 22px;"
+                class="flex-box"
+              >
+                <span style="float:left;">绠楁硶蹇�熼�氶亾</span>
+                <div class="flex-box" style="float: left;
+                  margin-left: 5px;">
+                  <el-tooltip
+                    effect="dark"
+                    content="澶嶅埗姝ゆ憚鍍忔満绠楁硶瑙勫垯"
+                    placement="bottom"
+                    popper-class="atooltip"
+                  >
+                    <span
+                      style="color:#3D68E1;cursor: pointer;font-size:23px;"
+                      @click="ctrlC"
+                      class="iconfont iconfuzhiguize"
+                    ></span>
+                  </el-tooltip>
+                  <el-tooltip
+                    effect="dark"
+                    :content="!TreeDataPool.ctrlCameraId?'绮樿创绠楁硶瑙勫垯':`绮樿创绠楁硶瑙勫垯锛屾潵婧愶細${TreeDataPool.ctrlCameraName}`"
+                    placement="bottom"
+                    popper-class="atooltip"
+                  >
+                    <span
+                      :style="!TreeDataPool.ctrlCameraId?'cursor: not-allowed;font-size:23px;':'color:#3D68E1;font-size:23px;cursor: pointer;'"
+                      @click="ctrlV"
+                      class="iconfont iconniantie ml5"
+                    ></span>
+                  </el-tooltip>
+                </div>
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+
+    <div
+      style="width: calc(100% + 76px);position: absolute;left: -38px;top:38px;height: 10px;background-color: #E9EBF2;"
+    ></div>
+
+    <div class="top" style="top:60px;">
+      <p class="task-css">
+        <b style="font-size: 14px; line-height: 18px;">鍦烘櫙</b>
+      </p>
+      <div>
+        <slide-scene :sceneData="Camera.rules"></slide-scene>
+        <div class="top-right">
+          <sysinfo
+            :showRealPoll="cameraType === 'camera'"
+            :ShowLocalVedio="cameraType === 'dataStack'"
+            v-if="showSysInfo"
+            style="margin-left: 25px;margin-top:-10px"
+          />
+        </div>
+      </div>
+      
+      <!-- <swiper :options="swiperOption" class="swiper-box-container">
+       
+        <swiper-slide v-for="(item, index) in 10" :key="index">
+          <div class="item-card">
+            <p style="color: #0066EB;padding-top: 20px;">
+              <b>{{ item }}</b>
+            </p>
+          </div>
+        </swiper-slide>
+      </swiper>
+      <div class="swiper-pre-border" >
+        <div class="icon-btn" slot="button-prev">
+          <i class="iconfont iconzuo"></i>
+        </div>
+      </div>
+      <div class="swiper-next-border" >
+        <div class="icon-btn" slot="button-next">
+          <i class="iconfont iconyou1"></i>
+        </div>
+      </div> -->
+      <!-- <swiper :options="swiperOption" class="swiper-box-container">
+        <span class="task-tip" v-show="Camera.rules.length == 0 ">鏆傛棤鍦烘櫙,璇峰紑濮嬪垱寤�</span>
+        <swiper-slide v-for="(item, index) in Camera.rules" :key="index">
+          <div class="item-card">
+            <p style="color: #0066EB;padding-top: 20px;">
+              <b>{{ item.scene_name }}</b>
+            </p>
+          </div>
+        </swiper-slide>
+      </swiper>
+      <div class="swiper-pre-border" v-show="Camera.rules.length > 4 ">
+        <div class="icon-btn" slot="button-prev">
+          <i class="iconfont iconzuo"></i>
+        </div>
+      </div>
+      <div class="swiper-next-border" v-show="Camera.rules.length > 4 ">
+        <div class="icon-btn" slot="button-next">
+          <i class="iconfont iconyou1"></i>
+        </div>
+      </div> -->
+
+      <!-- 绯荤粺淇℃伅 -->
+      
+    </div>
+
+    <div class="bottom" style="top:254px;">
+      <div
+        style="width: calc(100% + 100px);height: 10px;background-color: #E9EBF2;position:relative;left:-40px"
+      ></div>
+      <div class="bottom-right">
+        <div class="draw-and-time-box">
+          <div class="draw-box">
+            <div class="draw-box-title">
+              <b style="font-size: 14px">缁樺埗鍖哄煙</b>
+              <span
+                class="el-dropdown-link"
+                @click="drawBaseImg"
+                style="position: relative;top: 5px; cursor:pointer"
+              >
+                <i class="iconfont iconbianji1" style="font-size: 28px; "></i>
+              </span>
+            </div>
+            <div style="width:590px;height:16px;">
+              <b
+                style="font-size:14px"
+              >{{ Camera.camearInfo.alias ? Camera.camearInfo.alias: Camera.camearInfo.name }}</b>
+            </div>
+            <div class="img-box">
+              <polygon-canvas
+                class="cavas"
+                ref="canvas"
+                v-if="showCanvas"
+                v-loading="loading"
+                element-loading-text="鍒锋柊涓紝璇风◢绛�..."
+                element-loading-background="rgba(0, 0, 0, 0.8)"
+                :isShowDrawArrow="false"
+                :disabled="false"
+                :snapshot_url="Camera.baseImg"
+                :canvasDataShow="Camera.canvasData"
+                :currentCameraId="Camera.cameraId"
+                :loading="Camera.loading"
+                :canvasWidth="canvasWidth"
+                :canvasHeight="canvasHeight"
+                @fromCanvas="getCanvasData"
+                @changeLoading="changeLoading"
+                @refresh="refresh"
+              ></polygon-canvas>
+            </div>
+          </div>
+          <div style="float:left;width:calc(10% - 90px);height:100%;"></div>
+          <div
+            class="time-box"
+            style="width:calc(90% + 90px - 576px);overflow-x:auto;overflow-y:hidden"
+          >
+            <p style="text-align:left;padding: 10px;box-sizing: border-box">
+              <b style="font-size: 14px">鏃堕棿娈�</b>
+              
+            </p>
+            <time-slider ref="timeSlider" :type="'sep'" />
+          </div>
+        </div>
+
+        <!-- 鍦烘櫙瑙勫垯 -->
+        <scene-rule
+          :seletedCameras="[Camera]"
+          :tableRuleList="Camera.rules"
+          :onSaveScene="saveSceneRule"
+          @delete-rule="delScenRule"
+        ></scene-rule>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+//import { timeSilderData } from "@/mockData/timeSilder";
+import { savePolygon } from "@/api/polygon";
+
+import {
+  pasteRules
+} from '@/api/task';
+
+import {
+  getAllTemplate,
+  saveCameraScene,
+  getCameraSceneRule,
+} from '@/api/scene'
+
+import { changeRunType } from "@/api/pollConfig";
+
+import VideoRuleData from "@/Pool/VideoRuleData";
+
+import TimeSlider from "./TimeSlider";
+import polygonCanvas from "@/components/canvas";
+import Sysinfo from "./SystemInfo";
+import SceneRule from "./SceneRule";
+import SlideScene from "../scene/SlideScene";
+export default {
+  components: {
+    TimeSlider,
+    polygonCanvas,
+    Sysinfo,
+    SceneRule,
+    SlideScene
+  },
+  directives: {
+    focus: {
+      inserted: function (el) {
+        el.querySelector('input').focus()
+      }
+    }
+  },
+  computed: {
+    cameraType() {
+      return this.TreeDataPool.treeActiveName === 'camera' ? "camera" : "dataStack"
+    }
+  },
+  data() {
+    return {
+      mockSceneData: [],
+      loading: false,
+      Camera: new VideoRuleData(),
+      runType: -1,
+      swiperOption: {
+        slidesPerView: 5,
+        spaceBetween: 8,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        navigation: {
+          nextEl: ".swiper-next-border",
+          prevEl: ".swiper-pre-border"
+        }
+      },
+      tableRuleList: [],
+
+      cameraId: "",
+      activeTaskIndex: 0,
+      activeTaskId: "",
+      booleanValue: false,
+      showSysInfo: false,
+      showCanvas: true,
+      canvasWidth: 576,
+      canvasHeight: 324
+    };
+  },
+  mounted(){
+    this.mockAsync()
+  },
+
+  methods: {
+    mockAsync(){
+      setTimeout(()=>{
+        this.mockSceneData = [
+        { scenename: "name1", id:1, icon: ["iconrenlianjiance", "icongetijingzhi"] },
+        { scenename: "name2", id:2, icon: ["iconchouyan-copy"] },
+        {
+          scenename: "name3",
+          id:3,
+          icon: [
+            "iconrenshukouzhao",
+            "iconchouyan-copy",
+            "iconrenlianjiance",
+            "icongetijingzhi"
+          ]
+        },
+        {
+          scenename: "name4",
+          id:4,
+          icon: ["iconchouyan-copy", "iconrenlianjiance", "icongetijingzhi"]
+        },
+        { scenename: "name5", id:5, icon: ["icongetijingzhi"] },
+        { scenename: "name6", id:6, icon: ["iconrenshukouzhao", "icongetijingzhi"] },
+        { scenename: "name7", id:7, icon: ["iconrenlianjiance"] }
+      ];
+      },3000)
+    },
+    drawBaseImg() {
+      this.$refs.canvas.showModal();
+    },
+    getCanvasData(data) {
+      let polyon = { ...data };
+      polyon.camera_id = this.Camera.cameraId;
+      savePolygon(polyon).then(rsp => {
+        this.Camera.getPolygon();
+        this.Camera.getCameraTask();
+      });
+    },
+    refresh(url) {
+      this.Camera.baseImg = url
+    },
+    // 鍒濆鍖栨憚鍍忔満淇℃伅锛岀埗缁勪欢璋冪敤
+    async initCameraData(id) {
+      this.Camera = new VideoRuleData();
+
+      if (id && id !== "") {
+        this.loading = false;
+        this.Camera.cameraId = id;
+        await this.Camera.update();
+      }
+
+      this.$refs.timeSlider.activeTab = this.VideoManageData.TimeRules[0].id;
+      this.showSysInfo = true
+      // 鍒ゆ柇姝e湪鎵ц瀹炴椂鎴栬�呰疆璇换鍔�
+      this.PollData.CameraList.forEach(element => {
+        if (element.id === this.Camera.cameraId) {
+          this.runType = element.run_type;
+        }
+      })
+
+    },
+    saveSceneRule(groupRule) {
+      const payload = { ...groupRule }
+      payload.cameraIds = [this.Camera.cameraId];
+      saveCameraScene(payload).then(rsp => {
+        if (rsp && rsp.success) {
+          this.Camera.update();
+          this.$notify({
+            type: "success",
+            message: "绛栫暐淇濆瓨鎴愬姛锛�"
+          });
+        }
+      });
+    },
+    delScenRule() {
+      this.Camera.update();
+    },
+    changeLoading(params) {
+      this.loading = params
+      // console.log(this.loading,'changeLoading',params)
+    },
+    //鏄惁杩涜瑙嗛鍒嗘瀽澶勭悊
+    pollEnable(row) {
+      let val = 0
+      if (row) {
+        if (this.PollData.RealTimeSum < this.PollData.channelTotal) {
+          this.Camera.dealWay = true
+          val = 1
+        } else {
+          this.Camera.dealWay = false
+          val = 0
+        }
+      } else {
+        this.Camera.dealWay = false
+        val = -1
+      }
+      if (this.Camera.cameraId && this.Camera.cameraId !== undefined) {
+        changeRunType({ camera_ids: [this.Camera.cameraId], run_type: val }).then(
+          rsp => {
+            if (rsp && rsp.success) {
+              this.$notify({
+                type: "success",
+                message: "閰嶇疆鎴愬姛"
+              });
+            } else {
+              this.$notify({
+                type: "error",
+                message: "閰嶇疆澶辫触"
+              });
+            }
+            // this.selectCamera(this.TreeDataPool.selectedNode)
+          }
+        );
+      }
+      this.TreeDataPool.fetchTreeData();
+      this.PollData.statisticTaskInfo();
+    },
+    //瀹炴椂銆佽疆璇㈠垏鎹�
+    changePoll(row) {
+      //鍒ゆ柇鏄柊澧炶繕鏄洿鏂�
+      if (this.Camera.cameraId && this.Camera.cameraId !== undefined) {
+        if (this.PollData.RealTimeSum < this.PollData.channelTotal) {
+          if (row.value) {
+            this.Camera.dealWay = true
+          } else {
+            this.Camera.dealWay = false
+          }
+          changeRunType({ camera_ids: [this.Camera.cameraId], run_type: this.Camera.dealWay ? 1 : 0 }).then(
+            rsp => {
+              if (rsp && rsp.success) {
+                this.$notify({
+                  type: "success",
+                  message: "閰嶇疆鎴愬姛"
+                });
+              } else {
+                this.$notify({
+                  type: "error",
+                  message: "閰嶇疆澶辫触"
+                });
+              }
+            }
+          );
+        } else {
+          if (this.Camera.dealWay) {
+            this.Camera.dealWay = false
+            changeRunType({ camera_ids: [this.Camera.cameraId], run_type: this.Camera.dealWay ? 1 : 0 }).then(
+              rsp => {
+                if (rsp && rsp.success) {
+                  this.$notify({
+                    type: "success",
+                    message: "閰嶇疆鎴愬姛"
+                  });
+                } else {
+                  this.$notify({
+                    type: "error",
+                    message: "閰嶇疆澶辫触"
+                  });
+                }
+              }
+            );
+          }
+        }
+        this.TreeDataPool.fetchTreeData();
+        this.PollData.statisticTaskInfo();
+      }
+    },
+    //澶嶅埗
+    ctrlC() {
+      this.TreeDataPool.ctrlCameraId = this.Camera.cameraId;
+      this.TreeDataPool.ctrlCameraName = this.Camera.cameraName;
+      this.$notify({
+        type: "success",
+        message: "澶嶅埗绠楁硶鎴愬姛锛�"
+      })
+    },
+    ctrlV() {
+      if (this.Camera.cameraId === this.TreeDataPool.ctrlCameraId) {
+        this.$notify({
+          type: "warning",
+          message: "涓嶈兘绮樿创鏈憚鍍忔満鐨勭畻娉曞埌鏈憚鍍忔満锛�"
+        })
+        return false;
+      }
+      pasteRules({
+        sourceId: this.TreeDataPool.ctrlCameraId,
+        targetIds: [this.Camera.cameraId]
+      }).then((res) => {
+        // console.log(res,'澶嶅埗绠楁硶')
+        if (res && res.success) {
+          this.$notify({
+            type: "success",
+            message: "绮樿创绠楁硶鎴愬姛锛�"
+          })
+          this.initCameraData(this.Camera.cameraId)
+        } else {
+          this.$notify({
+            type: "error",
+            message: "绮樿创绠楁硶澶辫触锛�"
+          })
+        }
+      }).catch(err => {
+        // console.log(err,'澶嶅埗绠楁硶鎶ラ敊锛�')
+        this.$notify({
+          type: "error",
+          message: "绮樿创绠楁硶澶辫触锛�"
+        })
+      })
+    },
+  }
+};
+</script>
+<style lang="scss">
+.s-separate-rules {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .ai {
+    width: calc(100% + 76px);
+    height: 38px;
+    position: absolute;
+    left: -38px;
+    .check-area {
+      width: 100%;
+      height: 100%;
+      float: left;
+      overflow: auto;
+      padding: 0 38px;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+    }
+  }
+  .top {
+    width: 100%;
+    height: 174px;
+    position: relative;
+    top: 60px;
+    .swiper-box {
+      height: 100%;
+      float: left;
+      width: 48%;
+      margin-top: -10px;
+      position: relative;
+    }
+    .swiper-container {
+      position: initial;
+      min-width: 472px;
+      width: 80%;
+      
+      // height: 124px;
+    }
+    .swiper-slide {
+      position: relative;
+      width: 100%;
+      .item-card {
+        height: 110px !important;
+        max-width: 126px;
+        width: 100%;
+        position: absolute;
+        left: 0px;
+        right: 0px;
+        bottom: 0px;
+        top: 0px;
+        margin: auto;
+        background: #ffffff;
+        border: 1px solid #e2e2e2;
+        box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+        border-radius: 4px;
+        cursor: pointer;
+        .icon-xingzhuangcopy {
+          position: relative;
+          left: 0px;
+          right: 0px;
+          bottom: 0px;
+          top: 5px;
+          margin: auto;
+          color: #959699;
+        }
+
+        .mask {
+          position: absolute;
+          width: 100%;
+          height: 100%;
+          background: rgba(0, 0, 0, 0.65);
+          /* filter: blur(20px); */
+          backdrop-filter: blur(1px) brightness(100%);
+          display: none;
+        }
+
+        // @media screen and(max-width: 1280px) {
+        //   max-width: 110px;
+        // }
+        @media screen and(max-width: 1440px) {
+          max-width: 110px;
+        }
+      }
+      .item-card:hover {
+        .mask {
+          display: block;
+        }
+      }
+    }
+    .swiper-pre-border,
+    .swiper-next-border {
+      width: 40px;
+      height: 40px;
+      position: absolute;
+      background: #8888;
+      top: 35%;
+      z-index: 99;
+      border-radius: 4em;
+      outline: none;
+      .icon-btn {
+        color: rgb(255, 255, 255);
+        text-align: center;
+        line-height: 38px;
+        cursor: pointer;
+      }
+    }
+    .swiper-pre-border {
+      left: 10px;
+    }
+    .swiper-pre-border:hover {
+      background: #666;
+    }
+    .swiper-next-border {
+      right: 10px;
+    }
+    .swiper-next-border:hover {
+      background: #666;
+    }
+    .top-right {
+      float: right;
+      width: 52%;
+      height: 144px;
+    }
+    .task-css {
+      text-align: left;
+      margin-bottom: 14px;
+    }
+  }
+  .bottom {
+    width: 100%;
+    height: calc(100% - 234px);
+    position: absolute;
+    top: 234px;
+    .bottom-side {
+      height: 100%;
+      width: 250px;
+      float: left;
+      overflow: auto;
+      border-right: 1px solid #ccc;
+      border-bottom: 1px solid #ccc;
+      padding: 10px;
+      box-sizing: border-box;
+      .selectTask {
+        margin: 10px auto;
+        width: 140px;
+        padding: 10px;
+        box-sizing: border-box;
+        border: 1px solid #ccc;
+        position: relative;
+        .selectTaskDelete {
+          position: absolute;
+          right: 10px;
+          font-size: 18px;
+          cursor: pointer;
+        }
+      }
+    }
+    .bottom-right {
+      width: calc(100% + 30px);
+      height: 100%;
+      float: left;
+      overflow: auto;
+      padding: 10px 0px;
+      box-sizing: border-box;
+      .draw-and-time-box {
+        height: 400px;
+        width: 100%;
+        //min-width: 1150px;
+        .draw-box,
+        .time-box {
+          float: left;
+          height: 100%;
+          .img-box {
+            height: calc(100% - 32px);
+            //width: 90%;
+            // padding: 5px;
+            box-sizing: border-box;
+            display: flex;
+            // justify-content: center;
+            // align-items: center;
+            position: relative;
+            overflow: hidden;
+            .refresh-btn {
+              position: absolute;
+              right: 10px;
+              top: 10px;
+            }
+            img {
+              width: 90%;
+              padding: 5px;
+              box-sizing: border-box;
+            }
+            .swiper-box-container {
+              margin-top: -10px;
+              text-align: left;
+              padding: 0px 8px 0px 8px;
+              .el-card__body {
+                height: 100%;
+                padding: 0px;
+              }
+              height: calc(100% - 10px);
+              .info {
+                width: 100%;
+                height: 100%;
+                .info-left {
+                  width: 50%;
+                  height: 100%;
+                  float: left;
+                  img {
+                    width: 100%;
+                  }
+                }
+                .info-right {
+                  width: 50%;
+                  height: 100%;
+                  float: left;
+                  box-sizing: border-box;
+                  padding: 10px;
+                  p {
+                    padding: 4px 0px;
+                  }
+                  .infoIcon {
+                    height: 24px;
+                    cursor: pointer;
+                    i {
+                      margin: 5px;
+                      font-size: 22px;
+                    }
+                  }
+                }
+              }
+            }
+            .pre-border,
+            .next-border {
+              width: 40px;
+              height: 40px;
+              position: absolute;
+              background: #8888;
+              top: 34%;
+              z-index: 99;
+              border-radius: 4em;
+              outline: none;
+              .icon-btn {
+                color: rgb(255, 255, 255);
+                text-align: center;
+                line-height: 38px;
+                cursor: pointer;
+              }
+            }
+            .pre-border {
+              left: -9px;
+            }
+            .pre-border:hover {
+              background: #666;
+            }
+            .next-border {
+              right: 10px;
+            }
+            .next-border:hover {
+              background: #666;
+            }
+          }
+        }
+        .draw-box {
+          width: 576px;
+        }
+        .draw-box-title {
+          text-align: left;
+          margin-top: -3px;
+          .btn-css {
+            position: relative;
+            left: 514px;
+            margin-bottom: 3px;
+          }
+        }
+      }
+    }
+    .bottom-right::-webkit-scrollbar {
+      width: 0 !important;
+    }
+  }
+
+  .add-btn {
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+    cursor: pointer;
+  }
+  .add-btn:hover {
+    color: #2249b4;
+  }
+  .nocamera-css {
+    cursor: not-allowed;
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+  }
+  .task-tip {
+    font-family: PingFangSC-Regular;
+    font-size: 12px;
+    color: #cccccc;
+    margin-top: 10%;
+    margin-left: 38%;
+  }
+
+  .marker {
+    display: inline-block;
+    width: 8px;
+    height: 8px;
+    border-radius: 10px;
+    margin-right: 7px;
+    background: #3d68e1;
+  }
+  .loadingClass {
+    text-align: center;
+  }
+  .el-loading-spinner-div {
+  }
+}
+</style>
+<style lang="scss" scoped>
+.el-dropdown-menu {
+  width: 200px;
+  .el-dropdown-menu__item {
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+}
+.el-loading-spinner {
+  background: url("../../assets/gif/loading.gif") no-repeat;
+  top: 50%;
+  margin-top: -21px;
+  width: calc(100% - 260px) !important;
+  text-align: center;
+  position: absolute;
+  margin-left: 260px;
+  .el-loading-text {
+    color: #3d68e1;
+    margin: 3px 0;
+    font-size: 14px;
+    text-align: left;
+    margin-top: 22px !important;
+    padding-left: 30px;
+  }
+}
+</style>
diff --git a/src/components/camera/SystemInfo.vue b/src/components/camera/SystemInfo.vue
new file mode 100644
index 0000000..0b79772
--- /dev/null
+++ b/src/components/camera/SystemInfo.vue
@@ -0,0 +1,212 @@
+<template>
+  <div :class="showClass">
+    <div class="card-box" :style="`width:${borderWidth}`">
+      <ul>
+        <li style="max-width:30px;" v-if="ShowLocalVedio">
+          <div class="total-box">
+            <div style="width:100%;margin-top:28px;">
+              <div class="top-text">
+                <em>{{"鎬荤畻鍔�"}}</em>
+              </div>
+              <div class="mid-text">
+                <em>{{` ${PollData.channelTotal}`}}</em>
+              </div>
+            </div>
+          </div>
+        </li>
+        <li style="max-width:120px" v-if="showRealPoll">
+          <DataStackCard
+            style="width:95%"
+            title="瀹炴椂绠楀姏"
+            fourTip="鏁呴殰瀵艰嚧鏈鐞�"
+            fourIcon="iconicon-test21"
+            :total="`${PollData.RealTimeValidCount}璺痐"
+            :ValidCount="`${PollData.RealTimeSum}璺痐"
+            :InValidCount="`${PollData.RealTimeInvalid}璺痐"
+            :RunningCount="`${PollData.RealTimeRun}璺痐"
+            :NoDeal="`${PollData.RealTimeNoDeal}璺痐"
+          />
+        </li>
+        <li style="max-width:120px" v-if="showRealPoll">
+          <DataStackCard
+            title="杞绠楀姏"
+            fourTip="绛夊緟杞澶勭悊"
+            fourIcon="iconicon-test2"
+            style="width:95%"
+            :total="`${PollData.PollValidCount}璺痐"
+            :ValidCount="`${PollData.PollSum}璺痐"
+            :InValidCount="`${PollData.PollInvalid}璺痐"
+            :RunningCount="`${PollData.PollRun}璺痐"
+            :NoDeal="`${PollData.PollNoDeal}璺痐"
+          />
+        </li>
+        <li style="max-width:120px" v-if="ShowLocalVedio">
+          <!-- <local-vedio-card
+            title="鏈湴绠楀姏"
+            style="width:95%"
+            :total="`${PollData.localVideo}閫氶亾`"
+            :success="`${PollData.PollRun}璺痐"
+            :warning="`${PollData.PollInvalid}璺痐"
+          />-->
+          <DataStackCard
+            title="鏁版嵁鏍堢畻鍔�"
+            style="width:95%"
+            fourTip="鏈煡鍘熷洜瀵艰嚧鏈鐞�"
+            fourIcon="iconicon-test5"
+            :total="`${PollData.stackChannelCount}璺痐"
+            :ValidCount="`${PollData.stackTotal}璺痐"
+            :InValidCount="`${PollData.stackInvalidCount}璺痐"
+            :RunningCount="`${PollData.stackRunningCount}璺痐"
+            :NoDeal="`${PollData.stackNoDeal}璺痐"
+          ></DataStackCard>
+        </li>
+      </ul>
+    </div>
+    <!-- <div :class="marginTop" :style="`width:${liquidWidth};`">
+      <ul>
+        <li>
+          <liquid-fill-chart title="鍐呭瓨" :value="PollData.MemUsedPercent" :size="75" />
+        </li>
+        <li>
+          <liquid-fill-chart title="绠楀姏" :value="PollData.GpuUsedPercent" :size="75" />
+        </li>
+        <li>
+          <liquid-fill-chart title="CPU" :value="PollData.CpuUsedPercent" :size="75" />
+        </li> 
+      </ul>
+    </div>-->
+    <div class="eCharts-box" :style="`width:${liquidWidth}`">
+      <eChartsBar ref="cpuMeneryCharts" :xAxisData="PollData.barCharts"></eChartsBar>
+    </div>
+  </div>
+</template>
+
+<script>
+import DataStackCard from "@/components/subComponents/DataStackCard"
+import BoardCard from "@/components/subComponents/BoardCard"
+import LocalVedioCard from "@/components/subComponents/LocalVedioCard"
+import LiquidFillChart from "@/components/subComponents/chartLiquid"
+import SliderVedio from '@/components/camera/slider-vedio'
+import eChartsBar from '@/components/subComponents/eChartsBar'
+
+export default {
+  name: "SystemInfo",
+  components: {
+    DataStackCard,
+    // BoardCard,
+    // LocalVedioCard,
+    // LiquidFillChart,
+    // SliderVedio
+    eChartsBar,
+  },
+  props: {
+    showTask: {
+      type: Boolean,
+      default: false
+    },
+    showClass: {
+      type: String,
+      default: 'sysinfo-box flex-box'
+    },
+    ShowLocalVedio: {
+      type: Boolean,
+      default: false
+    },
+    showRealPoll: {
+      type: Boolean,
+      default: true
+    },
+    marginTop: {
+      type: String,
+      default: 'ma'
+    },
+    borderWidth: {
+      type: String,
+      default: '70%'
+    },
+    liquidWidth: {
+      type: String,
+      default: '30%'
+    }
+  },
+  methods: {
+    initCpuCharts() {
+      this.$forceUpdate();
+    }
+  },
+}
+</script>
+<style lang="scss">
+.sysinfo-box {
+  height: 100%;
+  .card-box {
+    width: 50%;
+    @media screen and (min-width: 1280px) and (max-width: 1440px) {
+      width: 65%;
+    }
+    @media screen and (max-width: 1279px) {
+      width: 70%;
+    }
+    .total-box {
+      height: 120px;
+      width: 100%;
+      display: inline-block;
+      margin: 10px 5px;
+      background: #ffffff;
+      border: 1px solid #e2e2e2;
+      box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+      border-radius: 4px;
+      cursor: pointer;
+      .top-text {
+        line-height: 30px;
+        font-family: PingFangSC-Medium;
+        font-size: 14px;
+        color: #222222;
+      }
+      .mid-text {
+        margin-bottom: 18px;
+        font-family: PingFangSC-Medium;
+        font-size: 18px;
+        color: #ff7733;
+      }
+      .bottom-text {
+        position: relative;
+        top: 3px;
+        left: 1px;
+        color: #666666;
+        font-size: 13px;
+      }
+      em {
+        font-weight: 700;
+      }
+    }
+  }
+  .eCharts-box {
+    width: 50%;
+    height: 100%;
+    margin-left: 5px;
+    @media screen and (min-width: 1280px) and (max-width: 1440px) {
+      width: 35%;
+    }
+    @media screen and (max-width: 1279px) {
+      width: 30%;
+    }
+  }
+  .chart-box {
+    float: left;
+    width: 50%;
+    margin-top: 20px;
+    margin-left: 20px;
+  }
+  ul {
+    list-style: none;
+    display: table;
+    width: 100%;
+    li {
+      display: table-cell;
+      text-align: center;
+      vertical-align: top;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/camera/TimeSlider.vue b/src/components/camera/TimeSlider.vue
new file mode 100644
index 0000000..73cfa13
--- /dev/null
+++ b/src/components/camera/TimeSlider.vue
@@ -0,0 +1,226 @@
+<template>
+  <div class="sub-time-box">
+    <div class="btn-control">
+      <div class="el-tabs-edit">
+        <span v-if="!editSlider" class="add-btn" @click="handleTabsEdit('','edit')">
+          <i class="el-icon-edit"></i>
+          缂栬緫
+        </span>
+        <span v-else class="add-btn" @click="handleTabsEdit('','lock')">
+          <i class="el-icon-lock"></i>
+          閿佸畾
+        </span>
+      </div>
+      <div class="el-tabs-add">
+        <span class="add-btn" @click="handleTabsEdit('','add')">
+          <i class="iconfont iconhebingxingzhuang"></i>
+          鏂板
+        </span>
+      </div>
+    </div>
+    <el-tabs v-model="activeTab" type="border-card" editable @edit="handleTabsEdit">
+      <el-tab-pane v-for="item in VideoManageData.TimeRules" :key="item.id" :name="item.id">
+        <span slot="label" @click="tabClick(item)" style="width:100px">{{item.name}}</span>
+        <multi-range-slider
+          :timeData="JSON.parse(item.time_rule)"
+          :mainId="`${item.id}_${type}`"
+          :itemId="item.id"
+          :itemName="item.name"
+          :edit="editSlider"
+          @range-update="updateTimeRule"
+        ></multi-range-slider>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import MultiRangeSlider from "../subComponents/MultiRangeSlider";
+import { saveTimeRule, deleteTimeRule } from "@/api/timeRule";
+
+export default {
+  name: "TimeSlider",
+  components: {
+    MultiRangeSlider
+  },
+  props: {
+    type: {
+      default: "",
+      type: String
+    }
+  },
+  data() {
+    return {
+      editSlider: false,
+      activeTab: "",
+      activeIndex: 0,
+      cavasLength: 800,
+      allDay: [
+        { day: 1, time_range: [{ start: "00:00", end: "24:00" }] },
+        { day: 2, time_range: [{ start: "00:00", end: "24:00" }] },
+        { day: 3, time_range: [{ start: "00:00", end: "24:00" }] },
+        { day: 4, time_range: [{ start: "00:00", end: "24:00" }] },
+        { day: 5, time_range: [{ start: "00:00", end: "24:00" }] },
+        { day: 6, time_range: [{ start: "00:00", end: "24:00" }] },
+        { day: 7, time_range: [{ start: "00:00", end: "24:00" }] }
+      ]
+    };
+  },
+  mounted() {
+    // window.addEventListener('resize', this.windowSizeChange)
+  },
+  methods: {
+    handleTabsEdit(tabId, action) {
+      let tabs = this.VideoManageData.TimeRules;
+      if (action === "add") {
+        let newRule = {
+          id: "",
+          name: "鏃堕棿娈�" + this.VideoManageData.TimeRules.length,
+          time_rule: this.allDay
+        };
+        this.updateTimeRule(newRule);
+      }
+      if (action === "remove") {
+        this.$confirm(
+          "姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ヨ鍒�, 鎵�鍏宠仈鐨勪换鍔″皢浼氬け鏁堬紝鏄惁缁х画?",
+          {
+            center: true,
+            confirmButtonText: "纭畾",
+            cancelButtonText: "鍙栨秷",
+          }
+        ).then(() => {
+          deleteTimeRule({ id: tabId }).then(rsp => {
+            if (rsp && rsp.success) {
+              this.VideoManageData.getTimeRule();
+              // this.VideoManageData.TimeRules.splice(2, 1)
+              this.activeTab = this.VideoManageData.TimeRules[0].id;
+              this.$notify({
+                type: "success",
+                message: "鍒犻櫎鎴愬姛!"
+              });
+            }
+          });
+        }).catch(() => { });
+      }
+      if (action == "edit") {
+        this.editSlider = true;
+      }
+      if (action == "lock") {
+        this.editSlider = false;
+      }
+    },
+    windowSizeChange() {
+      let timeSlideWidth = document.querySelector(".sub-time-box").clientWidth
+      this.cavasLength = timeSlideWidth
+      console.log("鏃堕棿缁勪欢瀹藉害锛�", timeSlideWidth)
+    },
+    updateTimeRule(rule) {
+      saveTimeRule(rule).then(rsp => {
+        if (rsp && rsp.success) {
+          this.VideoManageData.getTimeRule();
+          this.activeTab = rsp.data.id;
+        }
+      });
+    },
+    tabClick(item) {
+      if (this.activeTab === item.id) {
+        this.$prompt("", "淇敼鍚嶇О", {
+          confirmButtonText: "纭畾",
+          cancelButtonText: "鍙栨秷",
+          inputValue: item.name,
+          inputPattern: /^[\S]{1,16}$/,
+          inputErrorMessage: "鍚嶇О涓嶈兘鍖呭惈绌烘牸"
+        }).then(({ value }) => {
+          this.updateTimeRule({
+            id: item.id,
+            name: value,
+            time_rule: JSON.parse(item.time_rule)
+          });
+          this.$notify({
+            type: "success",
+            message: "鏃堕棿瑙勫垯鍚嶇О淇敼鎴愬姛"
+          });
+        }).catch(() => { });
+      }
+    }
+  }
+};
+</script>
+<style lang='scss'>
+.sub-time-box {
+  width: 660px;
+  position: relative;
+  /* height: calc(100% - 32px);
+  width: 100%;
+  padding: 5px; */
+  /* box-sizing: border-box; */
+  /* border-right: 1px solid #ccc;
+  border-top: 1px solid #ccc;
+  border-bottom: 1px solid #ccc; */
+  .btn-control{
+    position: absolute;
+    margin-top: -27px;
+    top: 0;
+    right: 0;
+    display: flex;
+    i{
+      font-size: 16px;
+    }
+  }
+  .el-tabs__item {
+    border-right-color: #e2e2e2 !important;
+    border-left-color: #e2e2e2 !important;
+    border-top-color: #e2e2e2 !important;
+  }
+  .el-tab-pane {
+    height: calc(100% - 50px);
+  }
+  // .el-tabs__new-tab {
+  //   margin: 15px 19px 9px 10px;
+  // }
+  .el-tabs {
+    height: 100%;
+  }
+
+  .el-tabs__header {
+    margin: 0px !important;
+    height: 45px !important;
+    border-top: 1px solid #e2e2e2 !important;
+    border-bottom: 1px solid #e2e2e2 !important;
+    background-color: #fff !important;
+    .is-active {
+      border-bottom-color: #fff !important;
+    }
+    .el-tabs__item {
+      line-height: 45px !important;
+    }
+  }
+  .el-tabs__content {
+    overflow: auto !important;
+    height: calc(100% - 51px) !important;
+    padding: 13px 0px !important;
+  }
+  .el-tabs__new-tab {
+    visibility: hidden;
+    // width: 130px;
+  }
+  // .el-tabs-add {
+  //   position: relative;
+  //   display: flex;
+  //   width: 70px;
+  //   top: 32px;
+  //   left: 88%;
+  //   z-index: 1;
+  // }
+  // .el-tabs-edit {
+  //   position: relative;
+  //   display: -webkit-box;
+  //   display: -ms-flexbox;
+  //   display: flex;
+  //   width: 70px;
+  //   top: 47px;
+  //   left: 79%;
+  //   z-index: 1;
+  // }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/camera/infoCard.vue b/src/components/camera/infoCard.vue
new file mode 100644
index 0000000..c650a5d
--- /dev/null
+++ b/src/components/camera/infoCard.vue
@@ -0,0 +1,75 @@
+<template>
+    <el-row class="infoCard">
+        <el-col :span="8">
+            <p>
+                <i class="iconfont iconshishichuli"></i><span class="fontClass">瀹炴椂绠楀姏</span>
+            </p>
+            <p><span style="color: #f49d37;font-family: 'PingFangSC-Regular';font-size:28px;font-weight: 600;">{{realtime}}</span></p>
+        </el-col>
+        <el-col style="width: 1px;height: 80%;margin-top: 10px;background: #DCDFE6">
+        </el-col>
+        <el-col :span="8">
+            <p>
+                <i class="iconfont iconrolling"></i><span class="fontClass">杞绠楀姏</span>
+            </p>
+            <p><span style="color: #f49d37;font-family: 'PingFangSC-Regular';font-size:28px;font-weight: 600;">{{polling}}</span></p>
+        </el-col>
+        <el-col style="width: 1px;height: 80%;margin-top: 10px;background: #DCDFE6">
+        </el-col>
+        <el-col :span="7">
+            <p>
+                <i class="iconfont iconshuju"></i><span class="fontClass">鏁版嵁鏍堢畻鍔�</span>
+            </p>
+            <p><span style="color: #f49d37;font-family: 'PingFangSC-Regular';font-size:28px;font-weight: 600;">{{dataStack}}</span></p>
+        </el-col>
+    </el-row>      
+</template>
+
+<script>
+export default {
+    props: {
+        realtime: {
+            type: Number,
+            default: 10
+        },
+        polling: {
+            type: Number,
+            default: 0
+        },
+        dataStack: {
+            type: Number,
+            default: 0
+        },
+    }
+}
+</script>
+<style lang="scss">
+    .infoCard {
+        width: 100%;
+        height: 100px;
+        border: 1px solid #e2e2e2;
+        box-shadow: 0px 0px 10px 5px rgba(0,0,0,0.1);
+        border-radius: 3px;
+        i {
+            float: left;
+            margin-left:10px;
+            font-size: 28px;
+            font-weight: 600;
+            color: #3d68e1;
+        }
+        p {
+            height: 45px;
+            line-height: 45px;
+            vertical-align: middle
+        }
+        .fontClass {
+            float: left;
+            margin-left: 10px;
+            font-family: "PingFangSC-Regular";
+            text-align: left;
+            font-size: 14px;
+            color: #222222;
+            font-weight: 600;
+        }
+    }
+</style>
\ No newline at end of file
diff --git a/src/components/camera/localSeparate.vue b/src/components/camera/localSeparate.vue
new file mode 100644
index 0000000..e1663f8
--- /dev/null
+++ b/src/components/camera/localSeparate.vue
@@ -0,0 +1,729 @@
+<template>
+  <div class="s-linkage-rules">
+    <div class="top">
+      <p style="text-align:left;margin-bottom: 14px;">
+        <b style="font-size: 14px;line-height: 18px;">宸查�夌畻娉�</b>
+        <!-- 鏂板浠诲姟 -->
+        <el-dropdown trigger="click" size="small" placement="bottom" @command="taskAdd">
+          <el-tooltip effect="dark" content="閫夋嫨绠楁硶" placement="bottom" popper-class="atooltip">
+            <span :class="currentCarmeras.cameraId?'add-btn':'nocamera-css'" style="margin-right: 28px;">
+              <i class="iconfont iconxuanzeziyuan" style="font-size:16px"></i>
+            </span>
+          </el-tooltip>
+          <el-dropdown-menu v-if="currentCarmeras.cameraId" slot="dropdown" style="left:315px !important;">
+            <el-dropdown-item
+              v-for="(item, index) in sepTasks"
+              :key="index"
+              :command="item"
+              :divided="index > 0"
+            >
+              <span
+                style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;width: 170px;display: block;"
+                :title="item.task.taskname"
+              >
+                <el-icon
+                  class="iconfont iconxingzhuangcopy"
+                  style="color: #3D68E1;margin-right: 12px;"
+                ></el-icon>
+                {{item.task.taskname}}
+              </span>
+            </el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </p>
+      
+      <swiper :options="swiperTaskOption" class="swiper-box-container">
+        <span class="task-tip" v-show="currentCarmeras.selectTask.length == 0 ">鏆傛棤绠楁硶,璇烽�夋嫨绠楁硶</span>
+
+        <swiper-slide v-for="(item, index) in currentCarmeras.selectTask" :key="index">
+          <div
+            class="item-card"
+            :style="`${isActiveTask(index) ? 'border-color:#ff7733' : ''}`"
+            @click="item.isEdit ? '': showRuleList(item.task.taskid, index)"
+          >
+            <p style="text-align: right; width:100%; height:25px;">
+              <el-tooltip content="鏈厤缃鍒�" placement="top" popper-class="atooltip">
+                <i
+                  class="el-icon-warning-outline"
+                  style="font-size:16px; color:orange; position:relative; top:-9px; left: 8px;"
+                  v-show="!item.hasRule"
+                ></i>
+              </el-tooltip>
+              <el-dropdown size="small" placement="bottom" @command="updateTaskStatus($event,item)">
+                <span class="el-dropdown-link">
+                  <i
+                    class="iconfont iconbianji1"
+                    style="font-size: 28px;float:right; margin:0px 5px "
+                  ></i>
+                </span>
+                <el-dropdown-menu slot="dropdown" style="margin-top:-3px;width:60px">
+                  <el-dropdown-item divided :command="0">缂栬緫</el-dropdown-item>
+                  <el-dropdown-item style="color:red;" :command="2">鍒犻櫎</el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </p>
+            <el-icon
+              class="iconfont iconxingzhuangcopy"
+              :style="item.task.enable ? 'color: #0066EB;font-size: 35.5px;' : 'font-size: 35.5px;'"
+            ></el-icon>
+            <p
+              v-if="!item.isEdit"
+              :style="item.task.enable ? 'color: #0066EB;padding-top: 20px;' : 'padding-top: 20px;'"
+            >
+              <b>{{ item.task.taskname }}</b>
+            </p>
+            <el-input
+              size="small"
+              style="padding-top: 25px;z-index: 9999;"
+              v-if="item.isEdit"
+              v-model="item.task.taskname"
+              :maxlength="15"
+              v-focus
+              @blur="updateTaskName(item)"
+            ></el-input>
+          </div>
+        </swiper-slide>
+      </swiper>
+
+      <div class="pre-border" v-show="currentCarmeras.selectTask.length > 4 ">
+        <div class="icon-btn" slot="button-prev">
+          <i class="iconfont iconzuo"></i>
+        </div>
+      </div>
+      <div class="next-border" v-show="currentCarmeras.selectTask.length > 4 ">
+        <div class="icon-btn" slot="button-next">
+          <i class="iconfont iconyou1"></i>
+        </div>
+      </div>
+
+      <!-- 绯荤粺淇℃伅 -->
+      <div class="top-right">
+        <sysinfo v-if="showSysInfo" :showRealPoll="false" :ShowLocalVedio="true"
+         style="margin-left: 25px;margin-top: -10px;" />
+      </div>
+    </div>
+
+    <div class="bottom">
+      <div style="width: calc(100% + 100px);height: 10px;background-color: #E9EBF2;position:relative;left:-40px"></div>
+      <div class="bottom-right">
+        <div class="draw-and-time-box">
+          <div class="draw-box">
+            <div class="draw-box-title">
+              <b style="font-size: 14px">缁樺埗鍖哄煙</b>
+              <span
+                class="el-dropdown-link"
+                @click="drawBaseImg"
+                style="position: relative;top: 5px; cursor:pointer"
+              >
+                <i class="iconfont iconbianji1" style="font-size: 28px; "></i>
+              </span>
+              <el-button class="btn-css" type="primary"
+                :disabled="currentCarmeras.rules.length===0"
+                @click="ToAll" 
+                size="mini">搴旂敤鍒板叏閮�</el-button>
+            </div>
+            <div class="img-box">
+
+              <!-- swiper 灞曠ず -->
+              <swiper
+                ref="localVideoSwiper"
+                :options="swiperOption"
+                @slideChange="swiperSlideChange"
+                class="swiper-box-container2"
+              >
+                <swiper-slide v-for="(data, index) in swipercanvasData" :key="index">
+                  <b class="video-title" style="font-size:14px;margin-top:-10px">{{ data.name }}</b>
+                  <polygon-canvas
+                    ref="canvas"
+                    v-loading="loading"
+                    element-loading-text="鍒锋柊涓紝璇风◢绛�..."
+                    element-loading-spinner="el-loading-spinner-div"
+                    element-loading-background="rgba(0, 0, 0, 0.8)"
+                    :isShowDrawArrow="false"
+                    :isLink="false"
+                    :disabled="false"
+                    :snapshot_url="data.baseImg"
+                    :canvasDataShow="data.canvasData"
+                    :currentCameraId="data.cameraId"
+                    :loading="data.loading"
+                    @changeLoading="changeLoading"
+                    @fromCanvas="getCanvasData"
+                  ></polygon-canvas>
+                </swiper-slide>
+              </swiper>
+              <div class="swiper-local-prev" v-show="swipercanvasData.length>1">
+                <div class="icon-btn" slot="button-prev">
+                  <i class="iconfont iconzuo"></i>
+                </div>
+              </div>
+              <div class="swiper-local-next" v-show="swipercanvasData.length>1">
+                <div class="icon-btn" slot="button-next">
+                  <i class="iconfont iconyou1"></i>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div style="float:left;width:calc(10% - 90px);height:100%;"></div>
+          <div class="time-box" style="width:calc(90% + 90px - 576px);overflow-x:auto;overflow-y:hidden">
+            <p style="text-align:left;padding: 10px;box-sizing: border-box">
+              <b style="font-size: 14px">甯冮槻鏃堕棿</b>
+            </p>
+            <time-slider ref="timeSlider" :type="'link'" />
+          </div>
+        </div>
+        <!-- 浠诲姟瑙勫垯 -->
+        <rule-editor
+          ref="ruleEditor"
+          :Carmeras="Carmeras"
+          :isLinkRule="false"
+          :tableRuleList="currentCarmeras.rules"
+          :activeTaskIndex="activeTaskIndex"
+          :onSubmitRule="submitRule"
+          @changeTask="changeTask"
+          @delete-rule="showRuleList(activeTaskId, activeTaskIndex)"
+        ></rule-editor>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  getLinkRules,
+  saveLinkRule,
+  deleteCameraRules,
+  
+  fetchCameraRulesByTask,
+  deleteCameraTask,
+  saveCameraRules,
+  updateCameraTask,
+  updateRuleDefence,
+  updateAlarmLevel,
+  addCameraTask
+} from "@/api/camera";
+import VideoRuleData from "@/Pool/VideoRuleData";
+import { savePolygon } from "@/api/polygon";
+import { ruleApply2All } from "@/api/localVedio";
+
+import polygonCanvas from "@/components/canvas";
+import RuleEditor from "./RuleEditor";
+import TimeSlider from "./TimeSlider";
+import Sysinfo from "./SystemInfo"
+
+export default {
+  components: {
+    TimeSlider,
+    polygonCanvas,
+    RuleEditor,
+    Sysinfo
+  },
+  data() {
+    return {
+      loading: false,
+      Carmeras: [],
+      currentCarmeras: {
+        selectTask: [],
+        rules: [],
+        polygonData: [],
+        cameraId: "",
+        canvasData: {},
+        baseImg: "",
+        cameraName: "",
+        camearInfo: {},
+        loading: false,
+        analytics: false,
+        dealWay: false,
+        runServerName: "",
+      },
+      tasksTable: [],
+      swipercanvasData: [],
+      seqNumber: 0,
+      tableRuleList: [],
+      swiperIndex: 0,
+      swiperOption: {
+        grabCursor: true,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        navigation: {
+          nextEl: ".swiper-local-next",
+          prevEl: ".swiper-local-prev"
+        }
+      },
+      swiperTaskOption: {
+        slidesPerView: 4,
+        spaceBetween: 10,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        navigation: {
+          nextEl: ".next-border",
+          prevEl: ".pre-border"
+        }
+      },
+      activeTaskIndex: 0,
+      activeTaskId: "",
+      showSysInfo: false
+    };
+  },
+  watch: {
+    Carmeras: {
+      handler(newVal, oldVal) {
+        this.showTasks();
+        this.setSwiperData();
+      },
+      deep: true
+    }
+  },
+  computed: {
+    sepTasks() {
+      let list =this.VideoManageData.SepTasks.map(i=>{
+        i.isEdit = false
+        return i
+      })
+      return list;
+    }
+  },
+  methods: {
+    drawBaseImg() {
+      console.log(this.$refs,this.$refs.localVideoSwiper.canvas,'drawBaseImg')
+      this.$refs.canvas[this.swiperIndex].showModal();
+    },
+    swiperSlideChange() {
+      this.swiperIndex = this.$refs.localVideoSwiper.swiper.activeIndex;
+      // console.log(this.swiperIndex,'鍒囨崲鏈湴瑙嗛')
+      this.currentCarmeras = this.Carmeras[this.swiperIndex];
+      this.showTasks();
+    },
+    initCameraData() {
+      this.Carmeras = [];
+      this.loading = false;
+      this.showSysInfo = true
+      // console.log(this.TreeDataPool.checkedLocalVedio,'this.TreeDataPool.checkedLocalVedio')
+      this.TreeDataPool.checkedLocalVedio.forEach(camera => {
+        this.Carmeras.push(new VideoRuleData(camera.id));
+      });
+      if(this.Carmeras.length !== 0){
+        this.currentCarmeras = this.Carmeras[this.swiperIndex];
+        if(this.currentCarmeras.selectTask.length !== 0){
+          this.activeTaskId = this.currentCarmeras.selectTask[this.activeTaskIndex].task.taskid
+        }
+        // console.log(this.Carmeras,'this.Carmeras',this.currentCarmeras)
+        this.showRules();
+      }
+    },
+    isSelectTask(item) {
+      for (let i = 0; i < this.tasksTable.length; i++) {
+        if (this.tasksTable.taskid === item.taskid) {
+          return true;
+        }
+      }
+    },
+    showTasks() {
+      let tasks = [];
+      if (this.Carmeras[this.swiperIndex]) {
+        this.tasksTable = this.Carmeras[this.swiperIndex].selectTask.forEach(
+          t => {
+            tasks.push(t.task);
+          }
+        );
+        this.tasksTable = tasks;
+      } else {
+        this.tasksTable = [];
+      }
+      console.log(this.tasksTable,'this.tasksTable')
+      this.$refs.timeSlider.activeTab = this.VideoManageData.TimeRules[0].id;
+    },
+    setSwiperData() {
+      let swipers = [];
+      let carmeras = this.Carmeras;
+      console.log(carmeras,'carmeras')
+      for (let i = 0; i < carmeras.length; i++) {
+        swipers = swipers.concat({
+          cameraId: carmeras[i].cameraId,
+          // name: carmeras[i].camearInfo.name,
+          name: "215鎽勫儚鏈篲_4823148102934521.mp4",
+          // baseImg: carmeras[i].baseImg ? carmeras[i].baseImg : undefined ,
+          baseImg: "httpImage/192.168.5.23:6086/681,2c7b272064d78f",
+          canvasData: carmeras[i].canvasData,
+          loading: carmeras[i].loading,
+        });
+      }
+      this.swipercanvasData = swipers;
+      console.log(this.swipercanvasData,'setSwiperData')
+    },
+    getCanvasData(data) { 
+      let polyon = { ...data };
+      polyon.camera_id = this.currentCarmeras.cameraId;
+      savePolygon(polyon).then(rsp => {
+        this.currentCarmeras.getPolygon();
+      });
+    },
+    showRules() {
+      this.tableRuleList = [];
+      this.$refs.ruleEditor.cleanRule();
+      if (this.currentCarmeras.selectTask[0] && this.currentCarmeras.selectTask[0].task) {
+          this.showRuleList(this.currentCarmeras.selectTask[0].task.taskid, 0);
+        } else {
+          this.tableRuleList = [];
+        }
+    },
+    submitRule(groupRule) {
+      let ids = this.TreeDataPool.checkedLocalVedio.map(i=>{
+        return i.id
+      })
+      console.log(ids,'宸查�夌殑瑙嗛')
+      const payload = {
+        // camera_ids: [this.currentCarmeras.cameraId],
+        camera_ids: ids,
+        group_id: groupRule.group_id,
+        group_rule: groupRule.rules,
+        group_text: groupRule.group_text,
+        set_type: "batchTask",
+        task_id: this.activeTaskId ? this.activeTaskId : this.currentCarmeras.selectTask[this.activeTaskIndex].task.taskid
+      };
+      console.log(this.activeTaskId,'submitRule',this.currentCarmeras.selectTask[this.activeTaskIndex].task.taskid)
+      saveCameraRules(payload).then(rsp => {
+        if (rsp && rsp.success) {
+          this.$refs.ruleEditor.cleanRule();
+          this.showRuleList(this.activeTaskId, this.activeTaskIndex);
+          this.$notify({
+            type: "success",
+            message: "浠诲姟淇濆瓨鎴愬姛锛�"
+          });
+        }
+      });
+    },
+    changeLoading(params){
+      this.loading = params
+    },
+    taskAdd(item) {
+      console.log(this.tasksTable,'taskAdd')
+      for (let i = 0; i < this.tasksTable.length; i++) {
+        if (this.currentCarmeras.selectTask[i].task.taskid === item.task.taskid) {
+          this.$notify({
+            showClose: true,
+            message: "璇峰嬁閲嶅娣诲姞浠诲姟锛�",
+            type: "warning"
+          });
+          return;
+        }
+      }
+      addCameraTask({
+        cameraId: this.currentCarmeras.cameraId,
+        taskId: item.task.taskid
+      }).then(() => {
+        // 鏇存柊鏍戠姸鎬�
+        this.TreeDataPool.fetchTreeData();
+      });
+
+      // 鏂版坊鍔犱换鍔¢粯璁ゅ叧闂�
+      this.currentCarmeras.selectTask.push(item);
+      // 娣诲姞骞跺垵濮嬪寲瑙勫垯鏄剧ず
+      this.activeTaskIndex = this.currentCarmeras.selectTask.length - 1;
+      this.activeTaskId = item.task.taskid;
+      this.tableRuleList = [];
+      // 娓呯┖缂栬緫瑙勫垯
+      this.$refs.ruleEditor.cleanRule();
+    },
+    isActiveTask(index) {
+      return this.activeTaskIndex === index;
+    },
+    updateTaskStatus(action, item) {
+      console.log(action, item, 'updateTaskStatus')
+      //淇敼鍚嶇О
+      if (action == "0") {
+        this.$set(item, 'isEdit', true)
+        this.$forceUpdate()
+        console.log(item, 'updateTaskStatus')
+      }
+      // 鍒犻櫎
+      if (action == "2") {
+        this.taskDelete(this.activeTaskIndex);
+      }
+    },
+    // 鏇存柊浠诲姟鍚嶇О
+    async updateTaskName(data) {
+      console.log(data, 'updateTaskName')
+      let json = {
+        taskId: data.task.taskid,
+        taskName: data.task.taskname
+      };
+      let res = await updateTaskName(json);
+
+      this.$notify({
+        title: res.success ? "鎴愬姛" : "澶辫触",
+        message: res.msg,
+        type: res.success ? "success" : "error"
+      });
+      if (res && res.success) {
+        this.$set(data, "isEdit", false);
+        this.currentCarmeras.getCameraTask()
+        this.$forceUpdate()
+      }
+    },
+    taskDelete(index) {
+      this.$confirm("鎻愮ず锛氬垹闄ゅ悗锛屾鎽勫儚鏈轰腑姝ょ畻娉曟秹鍙婄殑鎵�鏈夎鍒欏皢涓�璧峰垹闄わ紝鏄惁鍒犻櫎锛�", {
+        center: true,
+        cancelButtonClass: "comfirm-class-cancle",
+        confirmButtonClass: "comfirm-class-sure"
+      })
+        .then(() => {
+          deleteCameraTask(
+            this.currentCarmeras.cameraId,
+            this.currentCarmeras.selectTask[index].task.taskid
+          ).then(res => {
+            if (res && res.success) {
+              this.currentCarmeras.selectTask.splice(index, 1);
+
+              if (this.currentCarmeras.selectTask.length > 0) {
+                this.showRuleList(this.currentCarmeras.selectTask[0].task.taskid, 0);
+              } else {
+                this.TreeDataPool.fetchTreeData();
+              }
+              this.$notify({
+                type: "success",
+                message: "鍒犻櫎鎽勫儚鏈轰换鍔℃垚鍔�"
+              });
+            } else {
+              this.$notify({
+                type: "error",
+                message: "鍒犻櫎澶辫触锛�"
+              });
+            }
+          });
+        })
+        .catch(() => {
+          // console.log("鍙栨秷鍒犻櫎");
+        });
+    },
+    showRuleList(task, index) {
+      this.activeTaskId = task;
+      this.activeTaskIndex = index;
+      // 娓呯┖缂栬緫
+      this.currentCarmeras.getCameraTask();
+      
+    },
+    changeTask(taskid){
+      console.log("浠诲姟id",taskid)
+      this.activeTaskId = taskid
+      this.currentCarmeras.selectTask.forEach((el,index) => {
+        console.log("panklei",el,index)
+        if (el.task.taskid === taskid) {
+          console.log("婵�娲籭d",index)
+          this.activeTaskIndex = index
+          this.$refs.ruleEditor.sdksOption = this.currentCarmeras.selectTask[
+            this.activeTaskIndex
+          ].sdks;
+        }
+      })
+    },
+    async ToAll(){
+      // console.log(this.currentCarmeras.cameraId, '褰撳墠閫変腑鏂囦欢id')
+      let res = await ruleApply2All({
+        camera_id: this.currentCarmeras.cameraId
+      })
+      // console.log(res,'搴旂敤鍒板叏閮�')
+      if(res && res.success){
+        this.$notify({
+          type:"success",
+          message:"搴旂敤鍒板叏閮ㄦ垚鍔�!"
+        })
+        this.TreeDataPool.findAllFile({});
+      }
+    }
+  },
+  destroyed() {
+    this.Carmeras = [];
+    this.currentCarmeras = {
+      selectTask: [],
+      rules: [],
+      polygonData: [],
+      cameraId: "",
+      canvasData: {},
+      baseImg: "",
+      cameraName: "",
+      camearInfo: {},
+      loading: false,
+      analytics: false,
+      dealWay: false,
+      runServerName: "",
+    };
+    this.tasksTable = [];
+    this.tableRuleList = [];
+  },
+};
+</script>
+<style lang="scss">
+.s-linkage-rules {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  .top {
+    width: 100%;
+    height: 174px;
+    border-bottom: 1px solid #ccc;
+    position: relative;
+    
+    .top-right {
+      float: right;
+      width: 58%;
+      height: 124px;
+    }
+
+    .pre-border {
+      left: 0px;
+      top: 40%;
+    }
+    .next-border {
+      left: 40%;
+      top: 40%;
+    }
+  }
+  .bottom {
+    width: 100%;
+    height: calc(100% - 174px);
+    position: absolute;
+    top: 174px;
+    //left: -38px;
+    .bottom-side {
+      height: 100%;
+      width: 250px;
+      float: left;
+      overflow: auto;
+      border-right: 1px solid #ccc;
+      border-bottom: 1px solid #ccc;
+      padding: 10px;
+      box-sizing: border-box;
+      .selectTask {
+        margin: 10px auto;
+        width: 140px;
+        padding: 10px;
+        box-sizing: border-box;
+        border: 1px solid #ccc;
+        position: relative;
+        .selectTaskDelete {
+          position: absolute;
+          right: 10px;
+          font-size: 18px;
+          cursor: pointer;
+        }
+      }
+    }
+    .bottom-right {
+      width: calc(100% + 30px);
+      height: 100%;
+      float: left;
+      overflow: auto;
+      padding: 10px 38px;
+      box-sizing: border-box;
+      .draw-and-time-box {
+        height: 430px;
+        width: 100%;
+        padding-bottom: 5px;
+        .draw-box,
+        .time-box {
+          float: left;
+          width: 50%;
+          height: 100%;
+          .img-box {
+            height: calc(100% - 32px);
+            width: 100%;
+            box-sizing: border-box;
+            display: flex;
+            position: relative;
+            overflow: hidden;
+            .refresh-btn {
+              position: absolute;
+              right: 10px;
+              top: 10px;
+            }
+            img {
+              width: 90%;
+              padding: 5px;
+              box-sizing: border-box;
+            }
+            .swiper-box-container2 {
+              max-width: 690px;
+            }
+          }
+        }
+        .draw-box {
+          width: 576px;
+        }
+        .draw-box-title {
+          text-align: left;
+          margin-top: -3px;
+          .btn-css {
+            position: relative;
+            left: 556px;
+            margin-bottom: 1px;
+          }
+        }
+      }
+    }
+  }
+
+  .add-btn {
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+    cursor: pointer;
+  }
+  .add-btn:hover {
+    color: #2249b4;
+  }
+  .nocamera-css {
+    cursor: not-allowed;
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+  }
+  .task-tip {
+    font-family: PingFangSC-Regular;
+    font-size: 12px;
+    color: #cccccc;
+    margin-top: 10%;
+    margin-left: 38%;
+  }
+}
+
+.swiper-local-prev,
+.swiper-local-next {
+  width: 40px;
+  height: 40px;
+  position: absolute;
+  background: #8888;
+  top: 48%;
+  z-index: 99;
+  border-radius: 4em;
+  outline: none;
+  .icon-btn {
+    color: rgb(255, 255, 255);
+    text-align: center;
+    line-height: 38px;
+    cursor: pointer;
+  }
+}
+.swiper-local-prev {
+  left: 2px;
+}
+.swiper-local-prev:hover {
+  background: #666;
+}
+.swiper-local-next {
+  right: 3px;
+}
+.swiper-local-next:hover {
+  background: #666;
+}
+.task-tip {
+  font-family: PingFangSC-Regular;
+  font-size: 12px;
+  color: #cccccc;
+  margin-top: 10%;
+  margin-left: 38%;
+}
+</style>
diff --git a/src/components/camera/slider-vedio.vue b/src/components/camera/slider-vedio.vue
new file mode 100644
index 0000000..4645cc3
--- /dev/null
+++ b/src/components/camera/slider-vedio.vue
@@ -0,0 +1,268 @@
+<template>
+<div class="flex-box slider-css">
+  <div class="channelTotal">
+    <span>鎬婚�氶亾{{channelTotal}}绠楀姏</span>
+  </div>
+  <div class="slider">
+    <vue-slider v-model="PollData.sliderList"
+    ref="sliderVideo"
+    @change="changeSlider"
+     v-bind="options" ></vue-slider>
+  </div>
+</div>
+</template>
+<script>
+import VueSlider from 'vue-slider-component'
+import 'vue-slider-component/theme/default.css'
+
+export default {
+  name: "slider",
+  props: {
+    channelTotal: {
+      type:Number,
+      default:16
+    },
+    list: {
+      type:Array,
+      default:()=>{
+        //棣栧熬琛ㄧず婊戝潡鎬婚暱搴︼紝涓棿锛氬疄鏃躲�佽疆璇€�佹湰鍦拌棰戙�佹湰鍦板浘鐗囥�佹湰鍦伴煶棰�
+        return []
+      }
+    }
+  },
+  components: {
+    VueSlider
+  },
+  computed: {
+    
+  },
+  watch: {
+    list: {
+      handler(newVal, oldVal){
+        if(newVal !== oldVal){
+          this.dataList = newVal
+        }
+      },
+      deep:true
+    },
+    "PollData.sliderList": {
+      handler(newVal, oldVal){
+        if(newVal !== oldVal){
+          // console.log(newVal,"watch sliderList",oldVal);
+          if(this.PollData.sliderList[2] < this.PollData.channelTotal){
+            this.PollData.sliderList.push(this.PollData.channelTotal)
+          }
+        }
+      },
+      deep: true
+    }
+  },
+  data() {
+    return {
+      dataList: [],
+      options: {
+        dotSize: 14,
+        width: 'auto',
+        heght: 4,
+        contained: false,
+        direction: 'ltr',
+	      data: null,
+        min: 0,
+        max: 16,
+        interval: 1,
+        disabled: false,
+        clickable: true,
+        duration: 0.5,
+        adsorb: false,
+        lazy: false,
+        tooltip: 'focus',
+        tooltipPlacement: 'top',
+        tooltipFormatter: val => {
+          let index = this.PollData.sliderList.indexOf(val)
+          if(index == 0){
+            return val
+          }else if(index == 1){
+            return `瀹炴椂:${val - this.PollData.sliderList[index-1]}`
+          }else if(index == 2){
+            return `杞:${val - this.PollData.sliderList[index-1]}`
+          }else if(index == 3){
+            return `鏈湴瑙嗛:${val - this.PollData.sliderList[index-1]}`
+          }else if(index == 4){
+            return `鏈湴鍥剧墖:${val - this.PollData.sliderList[index-1]}`
+          }else if(index == 5){
+            return `鏈湴闊抽:${val - this.PollData.sliderList[index-1]}`
+          }
+        },
+        useKeyboard: false,
+        enableCross: false, //鏄惁鍏佽婊戝潡浜ゅ弶
+        fixed: false,
+        minRange: void 0,
+        maxRange: void 0,
+        order: true,
+        marks: false,
+        dotOptions: [
+          {
+            disabled:true,
+            style: {
+              'height':'4px',
+              'width':'4px',
+              'position':'relative',
+              'top':'5px',
+              'left':'-3px',
+              'background-color': '#fff',
+              'box-shadow': 'none'
+            }
+          },
+          {
+            disabled:true,
+            tooltip: 'always',
+            tooltipStyle: {
+              'background-color': 'red',
+              'border-color': 'red',
+              'font-size': '10px',
+              'z-index': '10'
+            },
+            style: {
+              'background-color': 'red',
+              'z-index': 10
+            }
+          },
+          {
+            disabled:false,
+            tooltip: 'always',
+            tooltipStyle: {
+              'background-color': '#3D68E1',
+              'border-color': '#3D68E1',
+              'font-size': '10px',
+              'z-index': '9'
+            },
+            style: {
+              'background-color': '#3D68E1',
+              'z-index': 9
+            }
+          },
+          {
+            disabled:false,
+            tooltip: 'always',
+            tooltipStyle: {
+              'background-color': '#2882CE',
+              'border-color': '#2882CE',
+              'font-size': '10px',
+              'z-index': 8
+            },
+            style: {
+              'background-color': '#2882CE',
+              'z-index': 8
+            },
+            disabledStyle: {
+              'z-index': 8
+            }
+          },
+          {
+            disabled:false,
+            tooltip: 'always',
+            tooltipStyle: {
+              'background-color': '#F0B27A',
+              'border-color': '#F0B27A',
+              'font-size': '10px',
+              'z-index': 2
+            },
+            style: {
+              'background-color': '#F0B27A',
+              'z-index': 2
+            },
+            disabledStyle: {
+              'z-index': 2
+            }
+          },
+          {
+            disabled:true,
+            tooltip: 'always',
+            tooltipStyle: {
+              'background-color': '#73C6B6',
+              'border-color': '#73C6B6',
+              'font-size': '10px',
+              'z-index': 1
+            },
+            style: {
+              'background-color': '#73C6B6',
+              'z-index': 1
+            },
+            disabledStyle: {
+              'z-index': 1
+            }
+          },
+          // {
+          //   //绗叚娈碉細鏈潵鏄綔涓虹粓鐐圭殑锛岀幇鍦ㄦ槸鍥哄畾鏈湴闊抽涓嶅姩
+          //   disabled:true,
+          //   style: {
+          //     'height':'4px',
+          //     'width':'4px',
+          //     'position':'relative',
+          //     'top':'5px',
+          //     'left':'10px',
+          //     'background-color': '#fff',
+          //     'box-shadow': 'none'
+          //   }
+          // }
+        ],
+        process: dotsPos => [
+          [dotsPos[4], dotsPos[5], { backgroundColor: '#73C6B6' }],
+          [dotsPos[3], dotsPos[4], { backgroundColor: '#F0B27A' }],
+          [dotsPos[2], dotsPos[3], { backgroundColor: '#2882CE' }],
+          [dotsPos[1], dotsPos[2], { backgroundColor: '#3D68E1' }],
+          [dotsPos[0], dotsPos[1], { backgroundColor: 'red' }],
+          // [dotsPos[2], dotsPos[6], { backgroundColor: 'orange' }],
+          // [dotsPos[3], dotsPos[4], { backgroundColor: '#F0B27A' }],
+          // [dotsPos[4], dotsPos[5], { backgroundColor: '#73C6B6' }],
+        ],
+        dotStyle: void 0,
+        railStyle: void 0,
+        processStyle: void 0,
+        tooltipStyle: void 0,
+        stepStyle: void 0,
+        stepActiveStyle: void 0,
+        labelStyle: void 0,
+        labelActiveStyle: void 0,
+      }
+    }
+  },
+  methods: {
+    changeSlider(val){
+      //[0, 20, 44, 60, 70, 84, 100, __ob__: Observer] "婊戝潡鍊煎彉鍔�"
+      // console.log(val,'婊戝潡鍊煎彉鍔�')
+      if(val[val.length -1] < this.PollData.channelTotal){
+        val.push(this.PollData.channelTotal)
+      }
+      this.$emit('changeSlider',val)
+    },
+    getIndex(){
+      let index = this.$refs.sliderVideo.getIndex(2);
+      console.log(index,'鐐瑰嚮鐨勭储寮�')
+    }
+  },
+  mounted() {
+    this.datalist = this.list
+  },
+  created() {
+    console.log(this.list,'slider-count')
+  },
+  destroyed() {
+    
+  }
+}
+</script>
+<style lang="scss">
+.slider-css {
+  position: relative;
+  top: 5px;
+}
+.channelTotal{
+  width: 50px;
+  margin-top: 14px;
+}
+.slider{
+  width: calc(95% - 60px);
+  padding: 20px;
+}
+</style>
diff --git a/src/components/canvas/Dialog.vue b/src/components/canvas/Dialog.vue
new file mode 100644
index 0000000..f275172
--- /dev/null
+++ b/src/components/canvas/Dialog.vue
@@ -0,0 +1,1362 @@
+<template>
+  <div>
+    <p class="title">
+      <el-input
+        ref="remarksName"
+        v-model="delCursor.remarksName"
+        size="mini"
+        style="margin-left: 90px;margin-top: 15px; width: 150px; position:relation;"
+        placeholder="鍥惧舰澶囨敞"
+        @change="changeName"
+      ></el-input>
+    </p>
+    <el-row style="margin-top:10px">
+      <el-col :span="2" style="position:relative;margin-top:10px">
+        <el-tooltip content="鍒囨崲鍒版鐘舵�佸悗鍙�変腑宸茬敾鍥惧舰" placement="left" popper-class="atooltip">
+          <el-button
+            class="btn"
+            @click="changeType('0')"
+            :disabled="disableSelect"
+            :style="type == '0'? 'border:2px solid #0066eb':''"
+          >
+            <i class="iconfont iconshou"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip
+          content="鐩寸嚎"
+          placement="left"
+          popper-class="atooltip"
+          :style="type == '1'? 'border:2px solid #0066eb':''"
+        >
+          <el-button class="btn" @click="changeType('1')" :disabled="disableLine">
+            <i class="iconfont iconzhixian"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip
+          content="鐭╁舰"
+          placement="left"
+          popper-class="atooltip"
+          :style="type == '2'? 'border:2px solid #0066eb':''"
+        >
+          <el-button class="btn" @click="changeType('2')" :disabled="disableRect">
+            <i class="iconfont iconlegend-base"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip
+          content="绠ご"
+          placement="left"
+          popper-class="atooltip"
+          :style="type == '4'? 'border:2px solid #0066eb':''"
+        >
+          <el-button class="btn" @click="changeType('4')" :disabled="disableArrow">
+            <i class="iconfont iconrighttop"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip
+          content="澶氳竟褰細鍙屽嚮缁撴潫缁樺埗"
+          placement="left"
+          popper-class="atooltip"
+          :style="type == '5'? 'border:2px solid #0066eb':''"
+        >
+          <el-button @click="changeType('5')" class="btn" :disabled="disablePolygon">
+            <i class="iconfont iconduobianxing"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip content="閫変腑鍥惧舰鍐嶇紪杈戦噸缁橈紝閲嶇粯鐨勫浘褰繚鐣欎箣鍓嶇殑鍚嶇О" placement="left" popper-class="atooltip">
+          <el-button class="btn" @click="edit()" :disabled="disableSelect">
+            <i class="iconfont iconxiugaitubiao1"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip content="鍏堥�変腑鍥惧舰锛屽啀鍒犻櫎" placement="left" popper-class="atooltip">
+          <el-button class="btn" @click="del()" :disabled="disableSelect">
+            <i class="iconfont iconshanchu5"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip content="娓呯┖鎵�鏈夊凡鐢诲浘褰紝姝ゆ搷浣滀笉鍙挙閿�" placement="left" popper-class="atooltip">
+          <el-button class="btn" @click="clear()" :disabled="disableSelect">
+            <i class="iconfont iconqingkong"></i>
+          </el-button>
+        </el-tooltip>
+        <el-tooltip content="鎾ら攢涓婁竴姝ユ搷浣�" placement="left" popper-class="atooltip">
+          <el-button class="btn" @click="del()" :disabled="disableSelect" style="border:0px">
+            <i class="iconfont iconfanhui1" style="font-size: 2rem"></i>
+          </el-button>
+          <!-- <span
+            class="iconfont iconfanhui1"
+            @click="undo"
+            :disabled="disableSelect"
+            style="position:absolute;left:25px;top:400px;font-size:2rem;cursor:pointer"
+          ></span> -->
+        </el-tooltip>
+        <!-- <el-button type="default" @click="undo()">鎾ら攢</el-button> -->
+      </el-col>
+      <el-col :span="22" style="position:relative;width:980px;padding-left:10px">
+        <canvas
+          id="canvasDialog"
+          ref="canvasDialog"
+          width="960"
+          height="540"
+          :style="
+            `position:static;background:url(${
+              snapshot_url
+                ? `/httpImage/${snapshot_url}`
+                : backImg
+            }) 0% 0%/960px 540px no-repeat;`
+          "
+        ></canvas>
+        <p
+          style="position:absolute;width:350px;left:80px;top:90px;color:white;font-size:1.5rem"
+          :style="disabled ? `display:block;` : `display:none;`"
+        >鎵归噺閰嶇疆鏂瑰紡涓嶅厑璁哥粯鍒跺尯鍩燂紝璇烽�夋嫨鎽勫儚鏈鸿繘琛屽尯鍩熺粯鍒�</p>
+        <!-- <span
+          class="iconfont icongengxin"
+          @click="refresh"
+          style="position:absolute;left:930px;font-size:2.5rem;cursor:pointer;color:white"
+        ></span> -->
+      </el-col>
+    </el-row>
+  </div>
+</template>
+<script>
+export default {
+  name: "canvasDialog",
+  data() {
+    return {
+      backImg: require("../../assets/baseimg.png"),
+      url: "", // canvas鍥剧墖鐨勪簩杩涘埗鏍煎紡杞负dataURL鏍煎紡
+      type: "0", // 缁樺浘鐘舵�� '0'涓洪�変腑鍒犻櫎锛�'1'涓虹敾绾匡紝鈥�2鈥欎负鐢荤煩褰紝鈥�4鈥欎负鐢荤澶达紝鈥�5鈥欎负鐢诲杈瑰舰
+      points: [], // 璁板綍缁樺埗澶氳竟褰㈡椂鐨勫悇鐐瑰潗鏍囷紝缁樺埗澶氳竟褰㈡椂鐢变簬涓嶆槸涓�绗斿畬鎴愶紝浠ユ暟缁勬暟鎹仛濮嬬粓闂悎鐨勫浘褰紝鍙屽嚮鍚庡綍鎴愬揩鐓э紝鎶婃暟缁勫唴瀹硅浆绉诲埌鏈�缁堟暟鎹腑锛岀劧鍚庢竻绌烘暟缁�
+      pointsUndo: [], // 鎾ら攢澶氳竟褰㈡椂淇濊瘉瀹炴椂鍙樺寲锛屼笉闇�瑕乵ove涔嬪悗鎵嶈兘鍝嶅簲杩囨潵銆傚叾鍊间负points杩炴帴浜嗙Щ鍔ㄥ潗鏍囧悗鐨勬暟缁�
+      delCursor: { type: -1, index: -1, remarksName: "", id: "" }, // 鍒犻櫎鎴栬�呬慨鏀规父鏍囷紝璁板綍浜嗙偣鍑婚�変腑鐨勫厓绱犵殑绫诲瀷鍜屾墍鍦ㄦ暟缁勭殑绱㈠紩浠ヤ究鍒犻櫎
+      editObj: {},
+      lineIndex: 0, // 鐢熸垚鍥惧舰澶囨敞鎵�鐢ㄧ殑绱㈠紩锛屼緷娆�++
+      rectIndex: 0,
+      arrowIndex: 0,
+      polygonIndex: 0,
+      disableSelect: false,
+      disableLine: false,
+      disableRect: false,
+      disableArrow: false,
+      disablePolygon: false,
+      canvasData: {
+        // 鏈�缁堜紶閫掔粰鍚庡彴鐨勬暟鎹�
+        line: [],
+        rect: [], // {id:'uuid', name: '鐭╁舰1', location: [{ x: 20, y: 30 }, { x: 20, y: 60 }, { x: 100, y: 60 }, { x: 100, y: 30 }] }
+        arrow: [],
+        polygon: []
+      },
+      // canvasData: this.canvasDataToChild, // 鏈�缁堣緭鍑虹殑鐢诲竷鍧愭爣鏁版嵁
+      originX: null, // 褰撳墠鐐瑰嚮鐐箈
+      originY: null, // 褰撳墠鐐瑰嚮鐐箉
+      canvasPic: new Image(), // 鎾ら攢鐢ㄧ殑鍥剧墖
+      flag: false, // 鏄惁寮�鍚粯鍒�
+      canvasHistory: [], // 鍘嗗彶鏁版嵁锛屼互渚涙挙閿�浣跨敤
+      step: -1, // 璁板綍绱㈠紩锛屼互渚涙挙閿�浣跨敤
+      c: null,
+      ctx: null,
+      inputWidth: 80,
+      oldName: "" // 鐢ㄦ潵鏆傚瓨鏇存敼涔嬪墠鐨剅emarksName,鏂逛究鏀捐繘鎾ら攢闃熷垪閲�
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  watch: {
+    delCursor: {
+      handler(newVal, oldVal) {
+        if (newVal.remarksName) {
+          this.inputWidth = newVal.remarksName.length * 20;
+        }
+        this.oldName = oldVal.remarksName;
+      },
+      deep: true
+    },
+    snapshot_url: {
+      handler(newVal, oldVal) {
+        if (newVal !== oldVal) {
+          // console.log(newVal, 'canvasDialog')
+        }
+      }
+    },
+    canvasDataToChild: {
+      handler(newVal, oldVal) {
+        // console.log(newVal, '鎵撳紑缁樺埗鍚庢帴鏀跺埌鐨勬暟鎹�')
+        this.canvasHistory.length = 0;
+        this.step = -1;
+        this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
+        this.clickSelect(this.canvasData);
+        this.indexInit();
+        // 鍏堝綍涓揩鐓э紝涓嶇劧涓�鐢荤嚎灏辨病浜�
+        this.step++;
+        this.canvasHistory.push({
+          type: 0,
+          src: this.c.toDataURL("image/png")
+        });
+      },
+      deep: true
+    }
+    // canvasDataToChild: function(newVal, oldVal) {
+    //   this.init()
+    // }
+  },
+  methods: {
+    // 鍒濆鍖栧嚱鏁�
+    init() {
+      this.c = document.querySelector("#canvasDialog");
+      this.ctx = this.c.getContext("2d");
+      this.drawCanvasInit();
+      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
+      this.clickSelect(this.canvasData);
+      this.indexInit();
+      // 鍏堝綍涓揩鐓э紝涓嶇劧涓�鐢荤嚎灏辨病浜�
+      this.step++;
+      this.canvasHistory.push({
+        type: 0,
+        src: this.c.toDataURL("image/png")
+      });
+      this.delCursor = { type: -1, index: -1, remarksName: "", id: "" }
+      
+      console.log("鐢诲竷鍒濆鍖�");
+    },
+    // 鍙栨秷鐢诲竷娓呴櫎鐘舵�佸嚱鏁�
+    cancel() {
+      this.changeType('0')
+      this.undisabled()
+      this.delCursor = {}
+      this.canvasHistory.length = 0;
+      this.step = -1;
+      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild));
+      this.clickSelect(this.canvasData);
+      this.indexInit();
+      // 鍏堝綍涓揩鐓э紝涓嶇劧涓�鐢荤嚎灏辨病浜�
+      this.step++;
+      this.canvasHistory.push({
+        type: 0,
+        src: this.c.toDataURL("image/png")
+      });
+    },
+    // 涓荤洃鍚祦绋�
+    drawCanvasInit() {
+      window.addEventListener("keydown", e => {
+        let keyID = e.keyCode ? e.keyCode : e.which;
+        if (keyID === 82) {
+          // r閿�
+          this.undo();
+        }
+      });
+      this.c.addEventListener("mousedown", e => {
+        if (this.type !== "0") {
+          this.flag = true;
+          this.originX = e.offsetX; // 榧犳爣钀戒笅鏃剁殑X
+          this.originY = e.offsetY; // 榧犳爣钀戒笅鏃剁殑Y
+          if (this.type === "5") {
+            // 缁樺埗澶氳竟褰�
+            this.points.push({
+              x: this.originX,
+              y: this.originY
+            });
+          }
+        } else {
+          this.clickSelect(e);
+        }
+      });
+      this.c.addEventListener("mousemove", e => {
+        switch (this.type) {
+          case "1":
+            this.drawLine(e)
+            break;
+          case "2":
+            this.drawRect(e)
+            break;
+          case "4":
+            this.drawArrow(e)
+            break;
+          case "5":
+            this.drawPolygon(e)
+            break;
+        }
+      });
+      this.c.addEventListener("mouseup", e => {
+        switch (this.type) {
+          case "1":
+            // 鐩寸嚎
+            this.lineMouseUp(e);
+            break;
+          case "2":
+            // 鐭╁舰
+            this.rectMouseUp(e);
+            break;
+          case "4":
+            // 绠ご
+            this.arrowMouseUp(e);
+            break;
+        }
+      });
+      this.c.addEventListener("dblclick", e => {
+        if (this.type === "5") {
+          // 缁樺埗澶氳竟褰�
+          this.polygonDblclick(e);
+        }
+      });
+    },
+    // 娓呴櫎鐢诲竷鍑芥暟
+    clear() {
+      // console.log("娓呴櫎");
+      this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+      // 娓呯┖淇濆瓨鐨勭姸鎬�
+      this.url = "";
+      this.canvasData.line.length = 0;
+      this.canvasData.rect.length = 0;
+      this.canvasData.arrow.length = 0;
+      this.canvasData.polygon.length = 0;
+      this.canvasHistory.length = 0;
+
+      this.indexInit()
+      this.freedEdit()
+      this.delCursor = {}
+      this.step = -1;
+    },
+    // 淇敼鍥惧舰鍚嶇О
+    changeName() {
+      if (this.delCursor.remarksName.length <= 6) {
+        switch (this.delCursor.type) {
+          case "1":
+            this.oldName = this.canvasData.line[this.delCursor.index].name;
+            this.canvasData.line[
+              this.delCursor.index
+            ].name = this.delCursor.remarksName;
+            break;
+          case "2":
+            this.oldName = this.canvasData.rect[this.delCursor.index].name;
+            this.canvasData.rect[
+              this.delCursor.index
+            ].name = this.delCursor.remarksName;
+            break;
+          case "4":
+            this.oldName = this.canvasData.arrow[this.delCursor.index].name;
+            this.canvasData.arrow[
+              this.delCursor.index
+            ].name = this.delCursor.remarksName;
+            break;
+          case "5":
+            this.oldName = this.canvasData.polygon[this.delCursor.index].name;
+            this.canvasData.polygon[
+              this.delCursor.index
+            ].name = this.delCursor.remarksName;
+            break;
+        }
+        this.clickSelect();
+        this.step++;
+        this.canvasHistory.push({
+          type: this.delCursor.type,
+          src: this.c.toDataURL("image/png"),
+          index: this.delCursor.index,
+          name: this.oldName
+        });
+      } else {
+        this.$notify({
+          type: "warning",
+          message: "鍛藉悕闀垮害涓嶈兘瓒呰繃6涓瓧锛�"
+        });
+        switch (this.delCursor.type) {
+          case "1":
+            this.delCursor.remarksName = this.canvasData.line[
+              this.delCursor.index
+            ].name;
+            break;
+          case "2":
+            this.delCursor.remarksName = this.canvasData.rect[
+              this.delCursor.index
+            ].name;
+            break;
+          case "4":
+            this.delCursor.remarksName = this.canvasData.arrow[
+              this.delCursor.index
+            ].name;
+            break;
+          case "5":
+            this.delCursor.remarksName = this.canvasData.polygon[
+              this.delCursor.indexhhhhhhhhhhh
+            ].name;
+            break;
+        }
+      }
+    },
+    // 宸︿笂瑙掕緭鍏ユ澶卞幓鐒︾偣鍚庝繚瀛樹竴寮犲揩鐓т互浣滄挙閿�涔嬬敤
+    saveUrl() {
+      // console.log("淇濆瓨涓�寮犲揩鐓�");
+      let delEle = {};
+      this.clickSelect();
+      this.step++;
+      this.canvasHistory.push({
+        type: this.delCursor.type,
+        src: this.c.toDataURL("image/png"),
+        index: this.delCursor.index,
+        data: delEle
+      });
+    },
+    // 鍒犻櫎鍏冪礌
+    del() {
+      let delEle = {};
+      switch (this.delCursor.type) {
+        case "1":
+          delEle = this.canvasData.line[this.delCursor.index];
+          this.canvasData.line.splice(this.delCursor.index, 1);
+          break;
+        case "2":
+          delEle = this.canvasData.rect[this.delCursor.index];
+          this.canvasData.rect.splice(this.delCursor.index, 1);
+          break;
+        case "4":
+          delEle = this.canvasData.arrow[this.delCursor.index];
+          this.canvasData.arrow.splice(this.delCursor.index, 1);
+          break;
+        case "5":
+          delEle = this.canvasData.polygon[this.delCursor.index];
+          this.canvasData.polygon.splice(this.delCursor.index, 1);
+          break;
+      }
+      this.clickSelect();
+      this.step++;
+      this.canvasHistory.push({
+        type: this.delCursor.type,
+        src: this.c.toDataURL("image/png"),
+        index: this.delCursor.index,
+        deleteLength: 0, // 鍒犻櫎鐨勮瘽deleteLength涓�0
+        data: delEle
+      });
+      // console.log(this.canvasHistory, "鍒犻櫎涔嬪悗鐨勬挙閿�闃熷垪");
+    },
+    edit() {
+      let delEle = {};
+      switch (this.delCursor.type) {
+        case "1":
+          delEle = {
+            id: this.canvasData.line[this.delCursor.index].id,
+            name: this.canvasData.line[this.delCursor.index].name,
+            location: this.canvasData.line[this.delCursor.index].location
+          }
+          // this.canvasData.line.splice(this.delCursor.index, 1);
+          this.canvasData.line[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }]
+          break;
+        case "2":
+          delEle = {
+            id: this.canvasData.rect[this.delCursor.index].id,
+            name: this.canvasData.rect[this.delCursor.index].name,
+            location: this.canvasData.rect[this.delCursor.index].location
+          }
+          // this.canvasData.rect.splice(this.delCursor.index, 1); 
+          this.canvasData.rect[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }]
+          break;
+        case "4":
+          delEle = {
+            id: this.canvasData.arrow[this.delCursor.index].id,
+            name: this.canvasData.arrow[this.delCursor.index].name,
+            location: this.canvasData.arrow[this.delCursor.index].location
+          }
+          // this.canvasData.arrow.splice(this.delCursor.index, 1); 
+          this.canvasData.arrow[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }]
+          break;
+        case "5":
+          delEle = {
+            id: this.canvasData.polygon[this.delCursor.index].id,
+            name: this.canvasData.polygon[this.delCursor.index].name,
+            location: this.canvasData.polygon[this.delCursor.index].location
+          }
+          // this.canvasData.polygon.splice(this.delCursor.index, 1);  
+          this.canvasData.polygon[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }]
+          break;
+      }
+      this.clickSelect();
+      this.step++;
+      this.canvasHistory.push({
+        type: this.delCursor.type,
+        src: this.c.toDataURL("image/png"),
+        index: this.delCursor.index,
+        deleteLength: 1,      // 缂栬緫鐨勮瘽deleteLength涓�1
+        data: delEle
+      });
+      this.editObj = {
+        id: this.delCursor.id,
+        type: this.delCursor.type,
+        index: this.delCursor.index,
+        remarksName: this.delCursor.remarksName
+      }
+      this.disabledOthers(this.delCursor.type)
+      // 鍒囨崲褰撳墠鐘舵��
+      this.changeType(this.delCursor.type)
+      this.$notify({
+        type: "warning",
+        message: "宸叉摝闄ゆ棫鐨勫尯鍩燂紝璇风洿鎺ョ粯鍒跺尯鍩�"
+      })
+    },
+    // 鐐瑰嚮閫変腑鍙樿壊 灏嗗綋鍓嶉〉闈㈡墍鏈夎矾寰勯噸缁樺垽鏂綋鍓嶉紶鏍囩殑鍧愭爣鍦ㄥ摢涓浘褰㈠唴 濡傛灉涓嶄紶鍧愭爣鍙傛暟灏辨槸鍥炴樉鐨勬柟娉�
+    clickSelect(e) {
+      this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+      // console.log("褰撳墠鏁版嵁锛�",this.canvasData)
+      this.ctx.lineWidth = "2";
+      let _this = this; // 闆嗗悎涓亶鍘嗛渶瑕佸皢this杞瓨涓�涓嬩娇鐢�
+      _this.canvasData.line.forEach(function (v, i) {
+        _this.ctx.strokeStyle = "yellow";
+        _this.ctx.beginPath();
+        _this.ctx.moveTo(v.location[0].x, v.location[0].y);
+        _this.ctx.lineTo(v.location[1].x, v.location[1].y);
+        _this.ctx.stroke();
+        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
+        _this.c.style.cursor = "pointer";
+        if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+          // 濡傛灉褰撳墠鐜瑕嗙洊浜嗚鍧愭爣锛屽氨灏嗗浘褰㈢殑index鏀惧埌鏁扮粍閲�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "1";
+          _this.delCursor.index = i;
+          _this.delCursor.remarksName = v.name;
+          _this.delCursor.id = v.id;
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          _this.ctx.beginPath();
+          _this.ctx.moveTo(v.location[0].x, v.location[0].y);
+          _this.ctx.lineTo(v.location[1].x, v.location[1].y);
+          _this.ctx.stroke();
+          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
+          _this.c.style.cursor = "pointer";
+        }
+      });
+      _this.canvasData.rect.forEach(function (v, i) {
+        _this.ctx.strokeStyle = "yellow";
+        _this.ctx.beginPath();
+        _this.ctx.moveTo(v.location[0].x, v.location[0].y);
+        _this.ctx.lineTo(v.location[1].x, v.location[1].y);
+        _this.ctx.lineTo(v.location[2].x, v.location[2].y);
+        _this.ctx.lineTo(v.location[3].x, v.location[3].y);
+        _this.ctx.lineTo(v.location[0].x, v.location[0].y);
+        _this.ctx.stroke();
+        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
+        _this.c.style.cursor = "pointer";
+        if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "2";
+          _this.delCursor.index = i;
+          _this.delCursor.remarksName = v.name;
+          _this.delCursor.id = v.id;
+          // console.log("褰撳墠閫変腑鍏冪礌锛�",_this.delCursor)
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          _this.ctx.beginPath();
+          _this.ctx.moveTo(v.location[0].x, v.location[0].y);
+          _this.ctx.lineTo(v.location[1].x, v.location[1].y);
+          _this.ctx.lineTo(v.location[2].x, v.location[2].y);
+          _this.ctx.lineTo(v.location[3].x, v.location[3].y);
+          _this.ctx.lineTo(v.location[0].x, v.location[0].y);
+          _this.ctx.stroke();
+          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
+          _this.selectedId = v.id;
+          _this.c.style.cursor = "pointer";
+        }
+      });
+      _this.canvasData.arrow.forEach(function (v, i) {
+        _this.ctx.strokeStyle = "yellow";
+        // _this.ctx.beginPath()
+        // _this.ctx.moveTo(v.location[0].x, v.location[0].y)
+        // _this.ctx.lineTo(v.location[1].x, v.location[1].y)
+        // _this.ctx.stroke()
+        _this.drawArrowUtil(
+          _this.ctx,
+          v.location[0].x,
+          v.location[0].y,
+          v.location[1].x,
+          v.location[1].y,
+          20,
+          _this.twoPointDistance({ x: v.location[0].x, y: v.location[0].y }, { x: v.location[1].x, y: v.location[1].y }) * 0.1,
+          2,
+          "yellow"
+        ); // 缁樺埗鏂规硶
+        _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false);
+        //_this.c.style.cursor = "pointer";
+        if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�  && _this.ctx.isPointInPath(e.offsetX, e.offsetY)
+          // 濡傛灉褰撳墠鐜瑕嗙洊浜嗚鍧愭爣锛屽氨灏嗗浘褰㈢殑index鏀惧埌鏁扮粍閲�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "4";
+          _this.delCursor.index = i;
+          _this.delCursor.remarksName = v.name;
+          _this.delCursor.id = v.id;
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          //   _this.ctx.beginPath()
+          //   _this.ctx.moveTo(v.location[0].x, v.location[0].y)
+          //   _this.ctx.lineTo(v.location[1].x, v.location[1].y)
+          //   _this.ctx.stroke()
+          _this.drawArrowUtil(
+            _this.ctx,
+            v.location[0].x,
+            v.location[0].y,
+            v.location[1].x,
+            v.location[1].y,
+            20,
+            _this.twoPointDistance({ x: v.location[0].x, y: v.location[0].y }, { x: v.location[1].x, y: v.location[1].y }) * 0.1,
+            2,
+            "red"
+          ); // 缁樺埗鏂规硶
+          _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true);
+          _this.c.style.cursor = "pointer";
+        }
+      });
+      _this.canvasData.polygon.forEach(function (v, i) {
+        if (v.location.length !== 0) {
+          _this.ctx.strokeStyle = "yellow";
+          _this.ctx.beginPath();
+          _this.ctx.moveTo(v.location[0].x, v.location[0].y);
+          for (let i = 1; i < v.location.length; i++) {
+            _this.ctx.lineTo(v.location[i].x, v.location[i].y);
+          }
+          _this.ctx.closePath();
+          _this.ctx.stroke();
+          _this.showRemarks(
+            v.location[0].x,
+            v.location[0].y,
+            v.name,
+            false
+          );
+          _this.c.style.cursor = "pointer";
+          if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) {
+            // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+            // 濡傛灉褰撳墠鐜瑕嗙洊浜嗚鍧愭爣锛屽氨灏嗗浘褰㈢殑index鏀惧埌鏁扮粍閲�
+            // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+            _this.type = "0";
+            _this.delCursor.type = "5";
+            _this.delCursor.index = i;
+            _this.delCursor.remarksName = v.name;
+            _this.delCursor.id = v.id;
+            // 灏嗗綋鍓嶅厓绱犳爣绾�
+            _this.ctx.strokeStyle = "red";
+            _this.ctx.beginPath();
+            _this.ctx.moveTo(v.location[0].x, v.location[0].y);
+            for (let i = 1; i < v.location.length; i++) {
+              _this.ctx.lineTo(v.location[i].x, v.location[i].y);
+            }
+            _this.ctx.closePath();
+            _this.ctx.stroke();
+            _this.showRemarks(
+              v.location[0].x,
+              v.location[0].y,
+              v.name,
+              true
+            );
+            _this.c.style.cursor = "pointer";
+          }
+        }
+      });
+      // console.log("鍒氶�変腑鐨勫浘褰細",_this.delCursor)
+    },
+    // 鎾ら攢
+    undo() {
+      if (this.type === "5" && this.flag) {
+        // 姝e湪鐢诲杈瑰舰锛屾殏瀛樻暟缁勯噷鏈夊潗鏍囨暟鎹紝鍙竴姝ヤ竴姝ユ挙閿�
+        if (this.points.length > 0) {
+          if (this.points.length === 1) {
+            this.type = "0"; // 涓嶅垏鎹㈡垚鈥�0鈥欐妸澶氳竟褰㈡挙閿�涔嬪悗鏃犳硶缁х画鎾ら攢鍏朵粬鍥惧舰
+            this.flag = false;
+            this.originX = null;
+            this.originY = null;
+          }
+          this.points.pop();
+          this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+          this.loadImage();
+          this.pointsUndo.splice(this.pointsUndo.length - 2, 1);
+          this.drawPolygonUtil(this.pointsUndo);
+        }
+      } else {
+        // 澶氳竟褰㈠凡缁忓畬鎴愭垨鑰呮槸鍦ㄧ敾鍒殑鍥惧舰
+        if (this.step >= 0) {
+          if (this.canvasHistory[this.step].data !== undefined) {
+            // 缂栬緫鍒犻櫎姝ラ鐨勬挙閿�   涔嬪墠鍒犻櫎鐨勬暟鎹師璺鍥炲幓
+            switch (this.canvasHistory[this.step].type) {
+              case "1":
+                this.canvasData.line.splice(
+                  this.canvasHistory[this.step].index,
+                  this.canvasHistory[this.step].deleteLength,
+                  this.canvasHistory[this.step].data
+                );
+                break;
+              case "2":
+                this.canvasData.rect.splice(
+                  this.canvasHistory[this.step].index,
+                  this.canvasHistory[this.step].deleteLength,
+                  this.canvasHistory[this.step].data
+                );
+                break;
+              case "4":
+                this.canvasData.arrow.splice(
+                  this.canvasHistory[this.step].index,
+                  this.canvasHistory[this.step].deleteLength,
+                  this.canvasHistory[this.step].data
+                );
+                break;
+              case "5":
+                this.canvasData.polygon.splice(
+                  this.canvasHistory[this.step].index,
+                  this.canvasHistory[this.step].deleteLength,
+                  this.canvasHistory[this.step].data
+                );
+                break;
+            }
+            this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+            let canvasPic = new Image();
+            canvasPic.src = this.canvasHistory[this.step - 1].src;
+            let ctx = this.ctx;
+            canvasPic.addEventListener("load", function () {
+              ctx.drawImage(canvasPic, 0, 0);
+            });
+            this.step--;
+          } else if (this.canvasHistory[this.step].name !== undefined) {
+            // 淇敼鍥惧舰澶囨敞鐨勬挙閿�
+            switch (this.canvasHistory[this.step].type) {
+              case "1":
+                this.canvasData.line[
+                  this.canvasHistory[this.step].index
+                ].name = this.canvasHistory[this.step].name;
+                break;
+              case "2":
+                this.canvasData.rect[
+                  this.canvasHistory[this.step].index
+                ].name = this.canvasHistory[this.step].name;
+                break;
+              case "4":
+                this.canvasData.arrow[
+                  this.canvasHistory[this.step].index
+                ].name = this.canvasHistory[this.step].name;
+                break;
+              case "5":
+                this.canvasData.polygon[
+                  this.canvasHistory[this.step].index
+                ].name = this.canvasHistory[this.step].name;
+                break;
+            }
+            this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+            let canvasPic = new Image();
+            canvasPic.src = this.canvasHistory[this.step - 1].src;
+            let ctx = this.ctx;
+            canvasPic.addEventListener("load", function () {
+              ctx.drawImage(canvasPic, 0, 0);
+            });
+            this.step--;
+          } else {
+            // 姝e父鐨勬挙閿�
+            this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+            let canvasPic = new Image();
+            if (this.step > 0) {
+              canvasPic.src = this.canvasHistory[this.step - 1].src;
+            }
+            // 涓嶇煡涓轰綍鐩存帴浼犺繘鍘籺his.ctx浼氭槸undefind锛屾墍浠ュ湪澶栭潰杞瓨涓�涓�
+            let ctx = this.ctx;
+            canvasPic.addEventListener("load", function () {
+              ctx.drawImage(canvasPic, 0, 0);
+            });
+            // 鎾ら攢鏈�缁堟暟鎹�
+            switch (this.canvasHistory[this.step].type) {
+              case "1":
+                this.canvasData.line.pop();
+                break;
+              case 2:
+                this.canvasData.rect.pop();
+                break;
+              case 4:
+                this.canvasData.arrow.pop();
+                break;
+              case 5:
+                this.canvasData.polygon.pop();
+                this.points.length = 0;
+                break;
+              case 0:
+                // 灏嗗洖鏄炬暟鎹竻绌猴紝鐩稿綋浜庢竻绌洪〉闈�
+                // console.log("鎾ら攢鍘熷鏁版嵁");
+                this.clear();
+                break;
+            }
+            this.step--;
+          }
+        } else {
+          this.$notify({
+            type: "warning",
+            message: "涓嶈兘鍐嶇户缁挙閿�浜�"
+          });
+        }
+      }
+      // console.log("鎾ら攢锛�",this.canvasData);
+    },
+    disabledOthers(type){
+      console.log("褰撳墠type:",type)
+      switch (type) {
+        case "1":
+          this.disableLine = false
+          this.disableRect = true
+          this.disableArrow = true
+          this.disablePolygon = true
+          this.disableSelect = true
+          break
+        case "2":
+          this.disableLine = true
+          this.disableRect = false
+          this.disableArrow = true
+          this.disablePolygon = true
+          this.disableSelect = true
+          break
+        case "4":
+          this.disableLine = true
+          this.disableRect = true
+          this.disableArrow = false
+          this.disablePolygon = true
+          this.disableSelect = true
+          break
+        case "5":
+          this.disableLine = true
+          this.disableRect = true
+          this.disableArrow = true
+          this.disablePolygon = false  
+          this.disableSelect = true
+          break
+      }
+      console.log("绂佺敤鐩寸嚎锛�",this.disableLine)
+      console.log("绂佺敤鐭╁舰锛�",this.disableRect)
+      console.log("绂佺敤绠ご锛�",this.disableArrow)
+      console.log("绂佺敤澶氳竟褰細",this.disablePolygon)
+    },
+    undisabled() {
+      this.disableLine = false
+      this.disableRect = false
+      this.disableArrow = false
+      this.disablePolygon = false
+      this.disableSelect = false
+    },
+    // 鍒锋柊搴曞浘
+    refresh() {
+      this.$emit("refresh");
+      // this.$notify({
+      //   type: 'success',
+      //   message: '搴曞浘宸插埛鏂�'
+      // })
+    },
+    // 绠ご缁樺埗鍑芥暟
+    drawArrowUtil(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {
+      // ctx锛欳anvas缁樺浘鐜
+      // fromX, fromY锛氳捣鐐瑰潗鏍囷紙涔熷彲浠ユ崲鎴恜1锛屽彧涓嶈繃瀹冩槸涓�涓暟缁勶級
+      // toX, toY锛氱粓鐐瑰潗鏍� (涔熷彲浠ユ崲鎴恜2锛屽彧涓嶈繃瀹冩槸涓�涓暟缁�)
+      // theta锛氫笁瑙掓枩杈逛竴鐩寸嚎澶硅
+      // headlen锛氫笁瑙掓枩杈归暱搴�
+      // width锛氱澶寸嚎瀹藉害
+      // color锛氱澶撮鑹�
+
+      theta = typeof theta !== "undefined" ? theta : 30;
+      headlen = typeof theta !== "undefined" ? headlen : 10;
+      width = typeof width !== "undefined" ? width : 1;
+      // color = typeof color !== 'undefined' ? color : 'yellow'
+      // 璁$畻鍚勮搴﹀拰瀵瑰簲鐨凱2,P3鍧愭爣
+      let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
+      let angle1 = ((angle + theta) * Math.PI) / 180;
+      let angle2 = ((angle - theta) * Math.PI) / 180;
+      let topX = headlen * Math.cos(angle1);
+      let topY = headlen * Math.sin(angle1);
+      let botX = headlen * Math.cos(angle2);
+      let botY = headlen * Math.sin(angle2);
+
+      ctx.save();
+      ctx.beginPath();
+      let arrowX = fromX - topX;
+      let arrowY = fromY - topY;
+      ctx.moveTo(arrowX, arrowY);
+      ctx.moveTo(fromX, fromY);
+      ctx.lineTo(toX, toY);
+      arrowX = toX + topX;
+      arrowY = toY + topY;
+      ctx.moveTo(arrowX, arrowY);
+      ctx.lineTo(toX, toY);
+      arrowX = toX + botX;
+      arrowY = toY + botY;
+      ctx.lineTo(arrowX, arrowY);
+      ctx.strokeStyle = color;
+      ctx.lineWidth = width;
+      ctx.stroke();
+      ctx.restore();
+    },
+    // 鑾峰彇鐩稿鍧愭爣(鏆備笉鐢�)
+    getLocation(x, y, c) {
+      let bbox = c.getBoundingClientRect();
+      return {
+        x: (x - bbox.left) * (c.width / bbox.width),
+        y: (y - bbox.top) * (c.height / bbox.height)
+        /*
+          * 姝ゅ涓嶇敤涓嬮潰涓よ鏄负浜嗛槻姝娇鐢–SS鍜孞S鏀瑰彉浜哻anvas鐨勯珮瀹戒箣鍚庢槸琛ㄩ潰绉媺澶ц�屽疄闄�
+          * 鏄剧ず鍍忕礌涓嶅彉鑰岄�犳垚鐨勫潗鏍囪幏鍙栦笉鍑嗙殑鎯呭喌
+          x: (x - bbox.left),
+          y: (y - bbox.top)
+        */
+      };
+    },
+    // 鐢熸垚鍥惧舰澶囨敞
+    remarks(x, y, type) {
+      this.ctx.moveTo(x, y - 20);
+      this.ctx.fillStyle = "green"; // 璁剧疆濉厖棰滆壊涓虹豢鑹�
+      this.ctx.font = '20px "寰蒋闆呴粦"'; // 璁剧疆瀛椾綋
+      this.ctx.textBaseline = "bottom"; // 璁剧疆瀛椾綋搴曠嚎瀵归綈缁樺埗鍩虹嚎
+      this.ctx.textAlign = "left"; // 璁剧疆瀛椾綋瀵归綈鐨勬柟寮�
+      let name = "";
+      switch (type) {
+        case "1":
+          this.lineIndex++;
+          name = "鐩寸嚎" + this.lineIndex;
+          break;
+        case "2":
+          this.rectIndex++;
+          name = "鐭╁舰" + this.rectIndex;
+          break;
+        case "4":
+          this.arrowIndex++;
+          name = "绠ご" + this.arrowIndex;
+          break;
+        case "5":
+          this.polygonIndex++;
+          name = "澶氳竟褰�" + this.polygonIndex;
+          break;
+      }
+      this.ctx.fillText(name, x, y - 20); // 濉厖鏂囧瓧
+      return name;
+    },
+    // 鍥炴樉鍥惧舰澶囨敞
+    showRemarks(x, y, remarks, isHightlight) {
+      this.ctx.moveTo(x, y - 20);
+      if (isHightlight) {
+        this.ctx.fillStyle = "#8ae22e"; // 璁剧疆濉厖棰滆壊涓虹豢鑹�
+      } else {
+        this.ctx.fillStyle = "green"; // 璁剧疆濉厖棰滆壊涓虹豢鑹�
+      }
+      this.ctx.font = '20px "寰蒋闆呴粦"'; // 璁剧疆瀛椾綋
+      this.ctx.textBaseline = "bottom"; // 璁剧疆瀛椾綋搴曠嚎瀵归綈缁樺埗鍩虹嚎
+      this.ctx.textAlign = "left"; // 璁剧疆瀛椾綋瀵归綈鐨勬柟寮�
+      this.ctx.fillText(remarks, x, y - 20); // 濉厖鏂囧瓧
+    },
+    // 閲嶇幇淇濆瓨鐢婚潰
+    loadImage() {
+      if (this.step > -1) {
+        let img = new Image();
+        img.src = this.canvasHistory[this.step].src;
+        this.ctx.drawImage(img, 0, 0, this.c.width, this.c.height);
+      }
+    },
+    // 鍒囨崲鐢荤嚎绫诲瀷
+    changeType(num) {
+      if (num === '0') {
+        this.c.style.cursor = "pointer";
+      } else {
+        this.c.style.cursor = "crosshair"
+      }
+      this.type = num;
+    },
+    // 缁樺埗澶氳竟褰㈡柟娉�
+    drawPolygonUtil(points) {
+      this.ctx.strokeStyle = "yellow";
+      this.ctx.lineWidth = 2;
+      this.ctx.beginPath();
+      this.ctx.moveTo(points[0].x, points[0].y);
+      for (let i = 1; i < points.length; i++) {
+        this.ctx.lineTo(points[i].x, points[i].y);
+      }
+      this.ctx.closePath();
+      this.ctx.stroke();
+    },
+    // 鐢荤洿绾跨Щ鍔ㄥ嚱鏁�
+    drawLine(e) {
+      if (this.flag) {
+        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+        this.loadImage();
+        this.ctx.beginPath();
+        this.ctx.strokeStyle = "yellow";
+        this.c.style.cursor = "default";
+        this.ctx.lineWidth = 2;
+        this.ctx.moveTo(this.originX, this.originY);
+        this.ctx.lineTo(e.offsetX, e.offsetY);
+        this.ctx.stroke(); // 缁樺埗
+      }
+    },
+    // 鐢荤煩褰㈢Щ鍔ㄥ嚱鏁�
+    drawRect(e) {
+      if (this.flag) {
+        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+        this.loadImage();
+        this.ctx.beginPath();
+        this.ctx.strokeStyle = "yellow";
+        this.ctx.lineWidth = 2;
+        this.ctx.strokeRect(
+          this.originX,
+          this.originY,
+          e.offsetX - this.originX,
+          e.offsetY - this.originY
+        ); // 缁樺埗鏂规硶
+      }
+    },
+    // 鐢荤澶寸Щ鍔ㄥ嚱鏁�
+    drawArrow(e) {
+      if (this.flag) {
+        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+        this.loadImage();
+        this.ctx.lineWidth = 2;
+        this.drawArrowUtil(
+          this.ctx,
+          this.originX,
+          this.originY,
+          e.offsetX,
+          e.offsetY,
+          20,
+          this.twoPointDistance({ x: this.originX, y: this.originY }, { x: e.offsetX, y: e.offsetY }) * 0.1,
+          2,
+          "yellow"
+        ); // 缁樺埗鏂规硶
+      }
+    },
+    twoPointDistance(p1, p2) {
+      let dep = Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2));
+      return dep;
+    },
+    // 鐢诲杈瑰舰绉诲姩鍑芥暟
+    drawPolygon(e) {
+      if (this.flag) {
+        this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+        this.loadImage();
+        this.pointsUndo = this.points.concat({
+          x: e.offsetX,
+          y: e.offsetY
+        });
+        this.drawPolygonUtil(
+          this.points.concat({
+            // concat杩斿洖杩炴帴鍚庣殑鏁扮粍锛屽師鏁扮粍涓嶅彉锛岀浉褰撲簬鎶婄Щ鍔ㄧ殑鍧愭爣浣滀负涓�涓櫄鍋囩殑鍧愭爣杩藉姞鍦ㄥ悗闈�,缁濓紒
+            x: e.offsetX,
+            y: e.offsetY
+          })
+        );
+      }
+    },
+    // 鐢荤洿绾挎姮璧�
+    lineMouseUp(e) {
+      if (
+        Math.abs(this.originX - e.offsetX) < 5 &&
+        Math.abs(this.originY - e.offsetY) < 5
+      ) {
+        this.flag = false;
+        return;
+      }
+      this.flag = false;
+      let Id
+      let fileName
+      let coordinate = [];
+      coordinate.push({
+        x: this.originX,
+        y: this.originY
+      });
+      coordinate.push({
+        x: e.offsetX,
+        y: e.offsetY
+      });
+      // console.log("line鐨別ditObj:",this.editObj)
+      if (this.editObj.id == undefined) {
+        Id = this.getUuid()
+        fileName = this.remarks(this.originX, this.originY, "1");
+        this.canvasData.line.push({
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      } else {
+        Id = this.editObj.id
+        fileName = this.editObj.remarksName
+        this.canvasData.line.splice(this.delCursor.index, 1, {
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      }
+      this.clickSelect()
+      this.undisabled()
+      this.c.style.cursor = "crosshair"
+      // 灏嗗綋鍓嶅垰鐢诲畬鐨勫浘褰㈠姞鍏ュ垹鏀规父鏍囷紝鍙互灏嗗垰鐢诲畬鐨勫浘褰㈠悕绉版樉绀哄湪宸︿笂瑙�
+      this.delCursor = {
+        id: this.getUuid(),
+        remarksName: fileName,
+        type: "1",
+        index: this.lineIndex - 1
+      };
+      this.url = this.c.toDataURL(); // 姣忔 mouseup 閮戒繚瀛樹竴娆$敾甯冪姸鎬�
+      this.step++;
+      this.canvasHistory.length = this.step; // 鎴柇鏁扮粍
+      this.canvasHistory.push({ type: 1, src: this.c.toDataURL("image/png") }); // 灏嗗揩鐓т繚瀛樺埌鍘嗗彶璁板綍涓互渚涙挙閿�涔嬬敤
+      // this.changeType('0')
+      this.freedEdit()
+    },
+    // 鐢荤煩褰㈡姮璧�
+    rectMouseUp(e) {
+      if (
+        Math.abs(this.originX - e.offsetX) < 5 &&
+        Math.abs(this.originY - e.offsetY) < 5
+      ) {
+        this.flag = false;
+        return;
+      }
+      this.flag = false;
+      let coordinate = [];
+      // 閫嗘椂閽堢畻鍑虹煩褰㈠洓瑙掑潗鏍�
+      coordinate.push({
+        x: this.originX,
+        y: this.originY
+      });
+      coordinate.push({
+        x: this.originX,
+        y: e.offsetY
+      });
+      coordinate.push({
+        x: e.offsetX,
+        y: e.offsetY
+      });
+      coordinate.push({
+        x: e.offsetX,
+        y: this.originY
+      });
+      let Id
+      let fileName
+      // console.log("rect鐨別ditObj:",this.editObj)
+      if (this.editObj.id == undefined) {
+        Id = this.getUuid()
+        fileName = this.remarks(this.originX, this.originY, "2");
+        this.canvasData.rect.push({
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      } else {
+        Id = this.editObj.id
+        fileName = this.editObj.remarksName
+
+        this.canvasData.rect.splice(this.delCursor.index, 1, {
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      }
+      this.clickSelect()
+      this.undisabled()
+      this.c.style.cursor = "crosshair"
+      this.delCursor = {
+        id: Id,
+        remarksName: fileName,
+        type: "2",
+        index: this.rectIndex - 1
+      };
+      // console.log("鍒氱敾瀹岀殑鐭╁舰鏍囧織锛�",this.delCursor)
+      this.url = this.c.toDataURL(); // 姣忔 mouseup 閮戒繚瀛樹竴娆$敾甯冪姸鎬�
+      this.step++;
+      this.canvasHistory.length = this.step; // 鎴柇鏁扮粍
+      this.canvasHistory.push({ type: 2, src: this.c.toDataURL("image/png") }); // 灏嗗揩鐓т繚瀛樺埌鍘嗗彶璁板綍涓互渚涙挙閿�涔嬬敤
+
+      this.freedEdit()
+    },
+    // 鐢荤澶存椂鎶捣
+    arrowMouseUp(e) {
+      if (
+        Math.abs(this.originX - e.offsetX) < 5 &&
+        Math.abs(this.originY - e.offsetY) < 5
+      ) {
+        this.flag = false;
+        return;
+      }
+      this.flag = false;
+      let Id
+      let fileName
+      let coordinate = [];
+      coordinate.push({
+        x: this.originX,
+        y: this.originY
+      });
+      coordinate.push({
+        x: e.offsetX,
+        y: e.offsetY
+      });
+      // console.log("arrow鐨別ditObj:",this.editObj)
+      if (this.editObj.id == undefined) {
+        Id = this.getUuid()
+        fileName = this.remarks(this.originX, this.originY, "4");
+        this.canvasData.arrow.push({
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      } else {
+        Id = this.editObj.id
+        fileName = this.editObj.remarksName
+        this.canvasData.arrow.splice(this.delCursor.index, 1, {
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      }
+      this.clickSelect()
+      this.undisabled()
+      this.c.style.cursor = "crosshair"
+      // 灏嗗綋鍓嶅垰鐢诲畬鐨勫浘褰㈠姞鍏ュ垹鏀规父鏍囷紝鍙互灏嗗垰鐢诲畬鐨勫浘褰㈠悕绉版樉绀哄湪宸︿笂瑙�
+      this.delCursor = {
+        id: this.getUuid(),
+        remarksName: fileName,
+        type: "4",
+        index: this.arrowIndex - 1
+      };
+      this.url = this.c.toDataURL(); // 姣忔 mouseup 閮戒繚瀛樹竴娆$敾甯冪姸鎬�
+      this.step++;
+      this.canvasHistory.length = this.step; // 鎴柇鏁扮粍
+      this.canvasHistory.push({ type: 4, src: this.c.toDataURL("image/png") }); // 灏嗗揩鐓т繚瀛樺埌鍘嗗彶璁板綍涓互渚涙挙閿�涔嬬敤
+      // this.changeType('0')
+      this.freedEdit()
+    },
+    // 鐢诲杈瑰舰缁撴潫鏃跺弻鍑�
+    polygonDblclick(e) {
+      this.flag = false;
+      this.points.pop(); // 鍙屽嚮涔嬪悗澶氫竴涓偣鐨勯噸澶嶅潗鏍囷紝闇�瑕佸垹闄�
+      let Id
+      let fileName
+      let coordinate = [];
+      this.points.map((item, index) => {
+        coordinate.push(item);
+      });
+      // console.log("polygon鐨別ditObj:",this.editObj)
+      if (this.editObj.id == undefined) {
+        Id = this.getUuid()
+        fileName = this.remarks(this.points[0].x, this.points[0].y, "5");
+        this.canvasData.polygon.push({
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      } else {
+        Id = this.editObj.id
+        fileName = this.editObj.remarksName
+        this.canvasData.polygon.splice(this.delCursor.index, 1, {
+          id: Id,
+          name: fileName,
+          location: coordinate
+        });
+      }
+      this.clickSelect()
+      this.undisabled()
+      this.c.style.cursor = "crosshair";
+      this.points.length = 0;
+      // 灏嗗綋鍓嶅垰鐢诲畬鐨勫浘褰㈠姞鍏ュ垹鏀规父鏍囷紝鍙互灏嗗垰鐢诲畬鐨勫浘褰㈠悕绉版樉绀哄湪宸︿笂瑙�
+      this.delCursor = {
+        id: this.getUuid(),
+        remarksName: fileName,
+        type: "5",
+        index: this.polygonIndex - 1
+      };
+      this.url = this.c.toDataURL();
+      this.step++;
+      this.canvasHistory.length = this.step; // 鎴柇鏁扮粍
+      this.canvasHistory.push({ type: 5, src: this.c.toDataURL("image/png") }); // 灏嗗揩鐓т繚瀛樺埌鍘嗗彶璁板綍涓互渚涙挙閿�涔嬬敤
+      // this.changeType('0')
+      // console.log("鎬绘暟鎹細",this.canvasData)
+      this.freedEdit()
+    },
+    // 閲婃斁缂栬緫鐘舵��
+    freedEdit() {
+      this.editObj = {}
+    },
+    // 鍥炴樉鍘嗗彶鏁版嵁鏃惰绠椾竴涓嬪洖鏄剧殑姣忕鍏冪礌鐨勬暟閲忎互渚跨敓鎴愬浘褰㈡敞瑙f椂鑾峰緱姝g‘鐨勫紑澶�
+    indexInit() {
+      this.lineIndex = this.canvasData.line.length;
+      this.rectIndex = this.canvasData.rect.length;
+      this.arrowIndex = this.canvasData.arrow.length;
+      this.polygonIndex = this.canvasData.polygon.length;
+    },
+    // 鐢熸垚uuid
+    getUuid() {
+      let originStr = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
+      let originChar = "0123456789abcdef";
+      let len = originChar.length;
+      return originStr.replace(/x/g, function (match) {
+        return originChar.charAt(Math.floor(Math.random() * len));
+      });
+    },
+    // 鍒ゆ柇涓�涓偣鏄惁绂讳竴涓浘褰㈢殑鏈�灏忚窛绂讳负n鍍忕礌浠ュ唴
+    minDistance(x, y, locations, n) {
+      let flag = false
+      for (let i = 0; i < locations.length; i++) {
+        if (i == locations.length - 1) {
+          if (this.point2Line(x, y, locations[i].x, locations[i].y, locations[0].x, locations[0].y) < n) {
+            flag = true
+          }
+        } else {
+          if (this.point2Line(x, y, locations[i].x, locations[i].y, locations[i + 1].x, locations[i + 1].y) < n) {
+            flag = true
+          }
+        }
+      }
+      return flag
+    },
+    point2Line(x, y, x1, y1, x2, y2) {
+      let cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1); // |AB| * |AC|*cos(x)
+      if (cross <= 0)
+        return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1) + 0.0);
+      let d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); // |AB|
+      if (cross >= d2)
+        return Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2) + 0.0);
+
+      let r = cross / d2;
+      let px = x1 + (x2 - x1) * r;  // C鍦� AB涓婄殑鍨傝冻鐐癸紙px锛宲y锛�
+      let py = y1 + (y2 - y1) * r;
+      return Math.sqrt((x - px) * (x - px) + (y - py) * (y - py) + 0.0); //涓ょ偣闂磋窛绂诲叕寮�
+    }
+  },
+  props: {
+    isGB28181: {
+      default: false,
+      type: Boolean
+    },
+    // isShowDrawArrow: {
+    //   default: false,
+    //   type: Boolean
+    // },
+    disabled: {
+      default: false,
+      type: Boolean
+    },
+    canvasDataToChild: {
+      default: () => {
+        return {
+          line: [],
+          rect: [],
+          arrow: [],
+          polygon: []
+        };
+      },
+      type: Object
+    },
+    snapshot_url: {
+      type: String,
+      default: ""
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.title {
+  margin-top: -32px;
+  margin-left: 12px;
+}
+.btn {
+  margin: 5px 10px;
+  width: 60px;
+  height: 40px;
+  padding: 8px;
+  i {
+    font-size: 20px;
+  }
+}
+</style>
diff --git a/src/components/canvas/index.vue b/src/components/canvas/index.vue
new file mode 100644
index 0000000..ba2e0d7
--- /dev/null
+++ b/src/components/canvas/index.vue
@@ -0,0 +1,510 @@
+<template>
+  <div class="s-cavas">
+    <canvas
+      ref="myCanvas"
+      :width="canvasWidth"
+      :height="canvasHeight"
+      :style="`background:url(${snapshot_url ? `/httpImage/${snapshot_url}` : blackImg}) 100% 100% / 576px 324px; no-repeat; background-size: contain;`"
+    ></canvas>
+
+    <el-tooltip content="鍒锋柊搴曞浘" placement="bottom" popper-class="atooltip">
+      <span class="iconfont icongengxin" @click="refresh"></span>
+    </el-tooltip>
+    <p class="tip" :style="disabled ? `display:block;` : `display:none;`">鎵归噺閰嶇疆鏂瑰紡涓嶅厑璁哥粯鍒跺尯鍩燂紝璇烽�夋嫨鎽勫儚鏈鸿繘琛屽尯鍩熺粯鍒�</p>
+    <el-dialog
+      title
+      :visible.sync="visible"
+      width="1150px"
+      append-to-body
+      :before-close="cancelFunc"
+    >
+      <canvas-dialog
+        ref="bigCanvas"
+        :canvasDataToChild="canvasData"
+        :snapshot_url="snapshot_url"
+        @refresh="refresh"
+      ></canvas-dialog>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="cancelFunc" size="small">鍙� 娑�</el-button>
+        <el-button type="primary" @click="handleOk" size="small">纭� 瀹�</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import canvasDialog from "./Dialog";
+import { updateSnapshot } from "@/api/camera";
+export default {
+  name: "myCanvas",
+  components: {
+    canvasDialog
+  },
+  props: {
+    divId: {
+      default: "my-canvas",
+      type: String
+    },
+    isGB28181: {
+      default: false,
+      type: Boolean
+    },
+    isShowDrawArrow: {
+      default: false,
+      type: Boolean
+    },
+    disabled: {
+      default: false,
+      type: Boolean
+    },
+    canvasDataShow: {
+      default: () => {
+        return { line: [], rect: [], arrow: [], polygon: [] };
+      },
+      type: Object
+    },
+    currentCameraId: {
+      type: String,
+      default: ""
+    },
+    snapshot_url: {
+      type: String,
+      default: ""
+    },
+    isLink: {
+      type: Boolean,
+      default: false
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    },
+    canvasWidth: {
+      type: Number,
+      default: 576
+    },
+    canvasHeight: {
+      type: Number,
+      default: 324
+    }
+  },
+  data() {
+    return {
+      blackImg: require("../../assets/baseimg.png"),
+      canvasData: {
+        line: [],
+        rect: [],
+        arrow: [],
+        polygon: []
+      }, // 鏈�缁堣緭鍑虹殑鐢诲竷鍧愭爣鏁版嵁
+      canvasPic: new Image(), // 鎾ら攢鐢ㄧ殑鍥剧墖
+      canvasHistory: [], // 鍘嗗彶鏁版嵁锛屼互渚涙挙閿�浣跨敤
+      step: -1, // 璁板綍绱㈠紩锛屼互渚涙挙閿�浣跨敤
+      c: null,
+      ctx: null,
+      visible: false,
+      baseImg: undefined,
+      showProportion: 1.71
+    };
+  },
+  watch: {
+    loading: {
+      handler(newVal, oldVal) {
+        // console.log(newVal,'loading')
+        if (newVal) {
+          this.baseImg = "";
+          this.refresh();
+        }
+      },
+      deep: true
+    },
+    canvasDataShow: {
+      handler(newVal, oldVal) {
+        // console.log(newVal, "canvasDataShow newVal");
+        this.canvasData.line = newVal.line;
+        this.canvasData.rect = newVal.rect;
+        this.canvasData.arrow = newVal.arrow;
+        this.canvasData.polygon = newVal.polygon;
+        this.clickSelect(this.canvasData);
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.$nextTick(() => {
+      // this.c = document.querySelector("#" + this.divId);
+      this.c = this.$refs.myCanvas;
+      this.ctx = this.c.getContext("2d");
+      this.canvasData = JSON.parse(JSON.stringify(this.canvasDataShow));
+      this.clickSelect(this.canvasData);
+    });
+  },
+  methods: {
+    // 鑾峰彇canvas搴曞浘
+    async getCanvasPic() {
+      // this.$emit('changeBaseImg',this.currentCameraId)
+      this.$emit('changeLoading', true)
+      if (this.currentCameraId) {
+        await updateSnapshot(this.currentCameraId)
+          .then(res => {
+            if (res.data.cameraId === this.currentCameraId) {
+              this.baseImg = res.data.snapshotUrl;
+              this.$emit('refresh',res.data.snapshotUrl)
+              this.$forceUpdate()
+              this.$notify({
+                type: "success",
+                message: "搴曞浘宸插埛鏂�"
+              });
+            }
+          })
+          .catch(err => {
+            this.$notify({
+              type: "error",
+              message: "搴曞浘鍒锋柊澶辫触"
+            });
+          });
+        this.$emit('changeLoading', false)
+      }
+    },
+    showModal() {
+      // console.log(this.canvasData, "鐐瑰嚮缁樺埗鐨勬椂鍊欎紶閫掕繃鍘荤殑鏁版嵁");
+      this.visible = true;
+      this.$nextTick(() => {
+        // this.$refs.bigCanvas.delCursor = {}
+      })
+    },
+    cancelFunc() {
+      this.visible = false;
+      this.$refs.bigCanvas.cancel()
+      // console.log("鍏抽棴浜�");
+    },
+    handleOk() {
+      // 鍒ゆ柇鍥惧舰鐨勫悕瀛楁槸鍚﹂噸澶�
+      // console.log("ok");
+      this.$refs.bigCanvas.changeType('0')
+      let repeatName = this.isRepeat();
+      if (repeatName !== "") {
+        this.$notify({
+          type: "error",
+          message: repeatName + "鍥惧舰鍚嶇О閲嶅锛岃鏇存锛�"
+        });
+        return;
+      }
+      this.$notify({
+        type: "success",
+        message: "宸蹭繚瀛樼粯鍒讹紒"
+      });
+      // 姣忔淇濆瓨鍏抽棴妯℃�佺獥鏃堕兘瑕佹妸妯℃�佺獥鐨勬暟鎹啓鍒扮埗缁勪欢閲屾潵
+      this.canvasData = this.$refs.bigCanvas.canvasData;
+      // 椤轰究鐢╁埌鏇村灞傚幓
+      this.$emit("fromCanvas", this.$refs.bigCanvas.canvasData);
+      // console.log("浣犲ソ", this.canvasData);
+      this.clickSelect(this.canvasData);
+      this.visible = false;
+    },
+    // 鍥炴樉cavas鏁版嵁
+    // 鐐瑰嚮閫変腑鍙樿壊 灏嗗綋鍓嶉〉闈㈡墍鏈夎矾寰勯噸缁樺垽鏂綋鍓嶉紶鏍囩殑鍧愭爣鍦ㄥ摢涓浘褰㈠唴 濡傛灉涓嶄紶鍧愭爣鍙傛暟灏辨槸鍥炴樉鐨勬柟娉�
+    clickSelect(e) {
+      this.ctx.clearRect(0, 0, this.c.width, this.c.height);
+      let _this = this; // 闆嗗悎涓亶鍘嗛渶瑕佸皢this杞瓨涓�涓嬩娇鐢�
+      _this.canvasData.line.forEach(function (v, i) {
+        _this.ctx.strokeStyle = "yellow";
+        _this.ctx.beginPath();
+        _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+        _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion);
+        _this.ctx.stroke();
+        _this.showRemarks(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion,
+          v.name
+        );
+        _this.c.style.cursor = "default";
+        if (e && _this.ctx.isPointInStroke(e.offsetX, e.offsetY)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+          // 濡傛灉褰撳墠鐜瑕嗙洊浜嗚鍧愭爣锛屽氨灏嗗浘褰㈢殑index鏀惧埌鏁扮粍閲�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "1";
+          _this.delCursor.index = i;
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          _this.ctx.beginPath();
+          _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+          _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion);
+          _this.ctx.stroke();
+          _this.showRemarks(
+            v.location[0].x / _this.showProportion,
+            v.location[0].y / _this.showProportion,
+            v.name
+          );
+          _this.c.style.cursor = "pointer";
+        }
+      });
+      _this.canvasData.rect.forEach(function (v, i) {
+        _this.ctx.strokeStyle = "yellow";
+        _this.ctx.beginPath();
+        _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+        _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion);
+        _this.ctx.lineTo(v.location[2].x / _this.showProportion, v.location[2].y / _this.showProportion);
+        _this.ctx.lineTo(v.location[3].x / _this.showProportion, v.location[3].y / _this.showProportion);
+        _this.ctx.lineTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+        _this.ctx.stroke();
+        _this.showRemarks(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion,
+          v.name
+        );
+        _this.c.style.cursor = "default";
+        if (e && _this.ctx.isPointInPath(e.offsetX, e.offsetY)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "2";
+          _this.delCursor.index = i;
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          _this.ctx.beginPath();
+          _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+          _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion);
+          _this.ctx.lineTo(v.location[2].x / _this.showProportion, v.location[2].y / _this.showProportion);
+          _this.ctx.lineTo(v.location[3].x / _this.showProportion, v.location[3].y / _this.showProportion);
+          _this.ctx.lineTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+          _this.ctx.stroke();
+          _this.showRemarks(
+            v.location[0].x / _this.showProportion,
+            v.location[0].y / _this.showProportion,
+            v.name
+          );
+          _this.c.style.cursor = "pointer";
+        }
+      });
+      _this.canvasData.arrow.forEach(function (v, i) {
+        _this.ctx.strokeStyle = "yellow";
+        // _this.ctx.beginPath()
+        // _this.ctx.moveTo(v.location[0].x / 2, v.location[0].y / 2)
+        // _this.ctx.lineTo(v.location[1].x / 2, v.location[1].y / 2)
+        // _this.ctx.stroke()
+        _this.drawArrow(
+          _this.ctx,
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion,
+          v.location[1].x / _this.showProportion,
+          v.location[1].y / _this.showProportion,
+          20,
+          30,
+          "yellow"
+        ); // 缁樺埗鏂规硶
+        _this.showRemarks(
+          v.location[0].x / _this.showProportion,
+          v.location[0].y / _this.showProportion,
+          v.name
+        );
+        _this.c.style.cursor = "default";
+        if (e && _this.ctx.isPointInStroke(e.offsetX, e.offsetY)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+          // 濡傛灉褰撳墠鐜瑕嗙洊浜嗚鍧愭爣锛屽氨灏嗗浘褰㈢殑index鏀惧埌鏁扮粍閲�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "4";
+          _this.delCursor.index = i;
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          //   _this.ctx.beginPath()
+          //   _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion)
+          //   _this.ctx.lineTo(v.location[1].x / _this.showProportion, v.location[1].y / _this.showProportion)
+          //   _this.ctx.stroke()
+          _this.drawArrow(
+            _this.ctx,
+            v.location[0].x / _this.showProportion,
+            v.location[0].y / _this.showProportion,
+            v.location[1].x / _this.showProportion,
+            v.location[1].y / _this.showProportion,
+            20,
+            30,
+            "red"
+          ); // 缁樺埗鏂规硶
+          _this.showRemarks(
+            v.location[0].x / _this.showProportion,
+            v.location[0].y / _this.showProportion,
+            v.name
+          );
+          _this.c.style.cursor = "pointer";
+        }
+      });
+      _this.canvasData.polygon.forEach(function (v, i) {
+        if (v.location.length === 0) {
+          return;
+        }
+        _this.ctx.strokeStyle = "yellow";
+        _this.ctx.beginPath();
+        _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+        for (let i = 1; i < v.location.length; i++) {
+          _this.ctx.lineTo(v.location[i].x / _this.showProportion, v.location[i].y / _this.showProportion);
+        }
+        _this.ctx.closePath();
+        _this.ctx.stroke();
+        _this.showRemarks(
+          v.location[v.location.length - 1].x / _this.showProportion,
+          v.location[v.location.length - 1].y / _this.showProportion,
+          v.name
+        );
+        _this.c.style.cursor = "default";
+        if (e && _this.ctx.isPointInPath(e.offsetX, e.offsetY)) {
+          // 濡傛灉浼犲叆浜嗕簨浠跺潗鏍囷紝灏辩敤isPointInStroke鍒ゆ柇涓�涓�
+          // 濡傛灉褰撳墠鐜瑕嗙洊浜嗚鍧愭爣锛屽氨灏嗗浘褰㈢殑index鏀惧埌鏁扮粍閲�
+          // 褰撻紶鏍囩Щ鍏ヤ箣鍚庡皢褰撳墠鐨勬ā寮忓垏鎹负閫変腑妯″紡
+          _this.type = "0";
+          _this.delCursor.type = "5";
+          _this.delCursor.index = i;
+          // 灏嗗綋鍓嶅厓绱犳爣绾�
+          _this.ctx.strokeStyle = "red";
+          _this.ctx.beginPath();
+          _this.ctx.moveTo(v.location[0].x / _this.showProportion, v.location[0].y / _this.showProportion);
+          for (let i = 1; i < v.location.length; i++) {
+            _this.ctx.lineTo(v.location[i].x / _this.showProportion, v.location[i].y / _this.showProportion);
+          }
+          _this.ctx.closePath();
+          _this.ctx.stroke();
+          _this.showRemarks(
+            v.location[v.location.length - 1].x / _this.showProportion,
+            v.location[v.location.length - 1].y / _this.showProportion,
+            v.name
+          );
+          _this.c.style.cursor = "pointer";
+        }
+      });
+    },
+    // 鍥炴樉鍥惧舰澶囨敞
+    showRemarks(x, y, remarks) {
+      this.ctx.moveTo(x, y - 10); // 鍥犱负鏀惧ぇ涔嬪悗鏄痽-20锛屾墍浠ョ缉灏忕増鐨勪负y-10
+      this.ctx.fillStyle = "green"; // 璁剧疆濉厖棰滆壊涓虹豢鑹�
+      this.ctx.font = '10px "寰蒋闆呴粦"'; // 璁剧疆瀛椾綋
+      this.ctx.textBaseline = "bottom"; // 璁剧疆瀛椾綋搴曠嚎瀵归綈缁樺埗鍩虹嚎
+      this.ctx.textAlign = "left"; // 璁剧疆瀛椾綋瀵归綈鐨勬柟寮�
+      this.ctx.fillText(remarks, x, y - 10); // 濉厖鏂囧瓧
+    },
+    // 绠ご缁樺埗鍑芥暟
+    drawArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {
+      // ctx锛欳anvas缁樺浘鐜
+      // fromX, fromY锛氳捣鐐瑰潗鏍囷紙涔熷彲浠ユ崲鎴恜1锛屽彧涓嶈繃瀹冩槸涓�涓暟缁勶級
+      // toX, toY锛氱粓鐐瑰潗鏍� (涔熷彲浠ユ崲鎴恜2锛屽彧涓嶈繃瀹冩槸涓�涓暟缁�)
+      // theta锛氫笁瑙掓枩杈逛竴鐩寸嚎澶硅
+      // headlen锛氫笁瑙掓枩杈归暱搴�
+      // width锛氱澶寸嚎瀹藉害
+      // color锛氱澶撮鑹�
+      theta = typeof theta !== "undefined" ? theta : 30;
+      headlen = typeof theta !== "undefined" ? headlen : 10;
+      width = typeof width !== "undefined" ? width : 1;
+      color = typeof color !== "undefined" ? color : "yellow";
+      // 璁$畻鍚勮搴﹀拰瀵瑰簲鐨凱2,P3鍧愭爣
+      let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI;
+      let angle1 = ((angle + theta) * Math.PI) / 180;
+      let angle2 = ((angle - theta) * Math.PI) / 180;
+      let topX = headlen * Math.cos(angle1);
+      let topY = headlen * Math.sin(angle1);
+      let botX = headlen * Math.cos(angle2);
+      let botY = headlen * Math.sin(angle2);
+
+      ctx.save();
+      ctx.beginPath();
+      let arrowX = fromX - topX;
+      let arrowY = fromY - topY;
+      ctx.moveTo(arrowX, arrowY);
+      ctx.moveTo(fromX, fromY);
+      ctx.lineTo(toX, toY);
+      arrowX = toX + topX;
+      arrowY = toY + topY;
+      ctx.moveTo(arrowX, arrowY);
+      ctx.lineTo(toX, toY);
+      arrowX = toX + botX;
+      arrowY = toY + botY;
+      ctx.lineTo(arrowX, arrowY);
+      ctx.strokeStyle = color;
+      ctx.lineWidth = width;
+      ctx.stroke();
+      ctx.restore();
+    },
+    async refresh() {
+      // console.log(this.loading,'鍒锋柊搴曞浘',this.snapshot_url)
+      if (!this.currentCameraId) {
+        return false;
+      }
+      // await this.$emit('changeLoading', true)
+      this.getCanvasPic();
+    },
+    // 鍒ゆ柇鍥惧舰鍚嶇О鏄惁閲嶅
+    isRepeat() {
+      let _this = this; // 闆嗗悎涓亶鍘嗛渶瑕佸皢this杞瓨涓�涓嬩娇鐢�
+      let nameArray = [];
+      for (const v of _this.$refs.bigCanvas.canvasData.line) {
+        for (const item of nameArray) {
+          if (v.name === item) {
+            return v.name;
+          }
+        }
+        nameArray.push(v.name);
+      }
+      for (const v of _this.$refs.bigCanvas.canvasData.arrow) {
+        for (const item of nameArray) {
+          if (v.name === item) {
+            return v.name;
+          }
+        }
+        nameArray.push(v.name);
+      }
+      for (const v of _this.$refs.bigCanvas.canvasData.rect) {
+        for (const item of nameArray) {
+          if (v.name === item) {
+            return v.name;
+          }
+        }
+        nameArray.push(v.name);
+      }
+      for (const v of _this.$refs.bigCanvas.canvasData.polygon) {
+        for (const item of nameArray) {
+          if (v.name === item) {
+            return v.name;
+          }
+        }
+        nameArray.push(v.name);
+      }
+      return "";
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.s-cavas {
+  width: 576px;
+  height: 324px;
+  margin-top: 10px;
+  position: relative;
+  overflow: auto;
+  @media screen {
+  }
+  .tip {
+    position: absolute;
+    width: 350px;
+    left: 80px;
+    top: 90px;
+    color: white;
+    font-size: 1.5rem;
+  }
+  span {
+    position: relative;
+    left: 265px;
+    top: 6px;
+    font-size: 2.5rem;
+    cursor: pointer;
+    color: #3d68e1;
+  }
+}
+.img-icon {
+  width: 600px;
+  height: 480px;
+  background-size: cover;
+  /* 鎶戝埗閫変腑 */
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  user-select: none;
+}
+</style>
diff --git a/src/components/scene/Editor.vue b/src/components/scene/Editor.vue
new file mode 100644
index 0000000..4497130
--- /dev/null
+++ b/src/components/scene/Editor.vue
@@ -0,0 +1,1675 @@
+<template>
+  <div class="edit-rules-box">
+    <p style="padding: 0">
+      <b style="font-size: 14px; line-height: 28px;">绛栫暐閰嶇疆</b>
+    </p>
+    <div class="sub-rules-box">
+      <div style=" text-align: left;">
+        <!-- <div style="margin-left:10px;margin-top: 4px;" v-show="index > 0">
+          <el-select v-model="rule.rule_with_pre" placeholder="骞跺垪鍏崇郴" size="mini">
+            <el-option
+              v-for="subitem in VideoManageData.Dictionary.RULECOMPUTEBETWEEN"
+              :key="subitem.id"
+              :label="subitem.name"
+              :value="subitem.value"
+              :title="subitem.name"
+            ></el-option>
+          </el-select>
+        </div>-->
+        <div class="sdk-group">
+          <transition-group name="fade" mode="out-in" appear>
+            <div
+              class="config-item"
+              :class="{ init: index == 0 }"
+              v-cloak
+              v-for="(sdkItem, index) in sdkGroup"
+              :key="index"
+            >
+              <div class="connection" v-if="index !== 0">
+                <el-select
+                  v-model="sdkItem.rule_with_pre"
+                  size="mini"
+                  placeholder="閫夊叧绯�"
+                  @change="selConnection(sdkItem)"
+                >
+                  <el-option value="&&" title="and/涓�" label="and/涓�"></el-option>
+                  <el-option value="||" title="or/鎴�" label="or/鎴�"></el-option>
+                  <el-option value="=>" title="鈥�>/瑙﹀彂" label="鈥�>/瑙﹀彂"></el-option>
+                </el-select>
+                <el-checkbox
+                  v-show="sdkItem.rule_with_pre == '=>'"
+                  v-model="sdkItem.is_save_anyhow"
+                  style="margin-left:30px"
+                >淇濆瓨杩囩▼鏁版嵁</el-checkbox>
+              </div>
+              <div class="top-line">
+                <div class="left">
+                  <div class="init-sdk">
+                    <el-select
+                      v-model="sdkItem.sdkObj"
+                      value-key="id"
+                      placeholder="閫夋嫨绠楁硶"
+                      size="mini"
+                      @change="selectSDKOption(sdkItem, true, index)"
+                    >
+                      <el-option
+                        v-for="item in TaskMange.list1"
+                        :key="item.id"
+                        :label="item.sdk_name"
+                        :value="item"
+                        :title="item.sdk_name"
+                        v-show="!item.del_flag"
+                      ></el-option>
+                    </el-select>
+                  </div>
+                  <div class="init-polygon">
+                    <el-select
+                      v-model="sdkItem.polygonObj"
+                      v-if="!isTemplate"
+                      value-key="polygonId"
+                      placeholder="閫夋嫨鍖哄煙"
+                      size="mini"
+                      @change="selectPolygonOption(sdkItem)"
+                    >
+                      <el-option
+                        v-for="subitem in allPolygonData"
+                        :key="subitem.id"
+                        :label="subitem.name"
+                        :value="subitem"
+                        :title="subitem.name"
+                      ></el-option>
+                    </el-select>
+                  </div>
+                </div>
+                <div class="right">
+                  <span class="del" v-show="!hideDel" @click="delConfigItem(index)">
+                    <i class="iconfont iconshanchu"></i>
+                  </span>
+                  <span class="collapse" @click="collapseLine(index)">
+                    <i
+                      :class="
+                        sdkItem.isSpread
+                          ? 'el-icon-arrow-up'
+                          : 'el-icon-arrow-down'
+                      "
+                    ></i>
+                  </span>
+                </div>
+              </div>
+
+              <div class="argums derive-line" v-show="sdkItem.isSpread">
+                <div v-for="(arg, index) in sdkItem.defaultArg" :key="arg.sort">
+                  <div class="argums-item" v-if="arg.config.isShow">
+                    <div class="arg-name">
+                      <!-- <el-input
+                        v-model="arg.name"
+                        size="mini"
+                        :disabled="true"
+                      ></el-input>-->
+                      <el-select v-model="arg.name" size="mini" :disabled="true">
+                        <el-option :label="arg.name" :title="arg.name" :value="arg"></el-option>
+                      </el-select>
+                    </div>
+                    <div class="operator-name">
+                      <!-- <el-input
+                        v-if="arg.operators.length == 1"
+                        v-model="arg.operators[0].operator"
+                        :disabled="true"
+                        size="mini"
+                      ></el-input>-->
+                      <el-select
+                        :disabled="arg.operators.length==1"
+                        v-model="arg.operator"
+                        size="mini"
+                        @change="selOperator(sdkItem)"
+                      >
+                        <el-option
+                          v-for="operator in arg.operators"
+                          :key="operator.operator"
+                          :value="operator.operator"
+                          :label="operator.name"
+                          :title="operator.name"
+                        ></el-option>
+                      </el-select>
+                    </div>
+                    <div class="arg-val">
+                      <div v-if="arg.operator == 'range'">
+                        <el-input
+                          class="range-min"
+                          v-model="arg.min"
+                          @blur="validateArgVal(arg, $event)"
+                        ></el-input>
+                        <span class="devide"></span>
+                        <el-input
+                          class="range-max"
+                          v-model="arg.max"
+                          @blur="validateArgVal(arg, $event)"
+                        ></el-input>
+                        <span>{{ arg.unit }}</span>
+                      </div>
+                      <div v-else>
+                        <el-select v-if="arg.type == 'option'" v-model="arg.sdk_arg_value">
+                          <el-option>璇烽�夋嫨</el-option>
+                        </el-select>
+                        <el-input
+                          v-if="arg.type == 'value'"
+                          v-model="arg.sdk_arg_value"
+                          :placeholder="
+                            arg.default_value ? arg.default_value : ''
+                          "
+                          size="mini"
+                          :style="{ borderColor: tipColor }"
+                          @blur="validateArgVal(arg, $event)"
+                        ></el-input>
+                        <span>{{ arg.unit }}</span>
+                      </div>
+                    </div>
+                    <div
+                      class="optional"
+                      v-if="
+                        sdkItem.initAddOptional &&
+                          index == sdkItem.defaultArg.length - 1
+                      "
+                    >
+                      <span class="btn" @click="addOptionalArg(sdkItem)">
+                        <i class="iconfont iconhebingxingzhuang" style="font-size:16px"></i>
+                      </span>
+                    </div>
+                  </div>
+                </div>
+                <div
+                  class="argums-item optional-line"
+                  v-for="optArgItem in sdkItem.optArg"
+                  :key="optArgItem.sort"
+                >
+                  <div class="arg-name">
+                    <el-input
+                      v-if="sdkItem.optNames.length == 1"
+                      v-model="sdkItem.optNames[0].name"
+                      size="mini"
+                      :disabled="true"
+                    ></el-input>
+                    <el-select
+                      v-if="sdkItem.optNames.length > 1"
+                      v-model="optArgItem.name"
+                      size="mini"
+                      @change="selOptionalArg(sdkItem, optArgItem)"
+                    >
+                      <el-option
+                        v-for="optName in sdkItem.optNames"
+                        :disabled="optName.isSelected"
+                        :key="optName.sort"
+                        :label="optName.name"
+                        :title="optName.name"
+                        :value="optName.name"
+                      ></el-option>
+                    </el-select>
+                  </div>
+                  <div class="operator-name">
+                    <!-- <el-input
+                      v-model="optArgItem.operators[0].operator"
+                      :disabled="true"
+                      size="mini"
+                    ></el-input>-->
+
+                    <el-select
+                      v-model="optArgItem.operator"
+                      size="mini"
+                      @change="selOperator(optArgItem)"
+                    >
+                      <el-option
+                        v-for="operatorItem in optArgItem.operators"
+                        :key="operatorItem.operator"
+                        :value="operatorItem.operator"
+                        :label="operatorItem.name"
+                        :title="operatorItem.name"
+                      ></el-option>
+                    </el-select>
+                  </div>
+                  <div class="arg-val">
+                    <el-select
+                      v-if="optArgItem.type == 'option'"
+                      v-model="optArgItem.sdk_arg_value"
+                      :multiple="optArgItem.config.isMulti"
+                      collapse-tags
+                      size="mini"
+                    >
+                      <el-option
+                        v-for="one in optArgItem.valueOptions"
+                        :key="one.value"
+                        :value="one.value"
+                        :label="one.name"
+                        :title="one.name"
+                      ></el-option>
+                    </el-select>
+                    <el-input
+                      v-if="optArgItem.type == 'value'"
+                      v-model="optArgItem.sdk_arg_value"
+                      size="mini"
+                      @blur="$event => validateArgVal(optArgItem, $event)"
+                    ></el-input>
+                    <span>{{ optArgItem.unit }}</span>
+                  </div>
+                  <div class="optional">
+                    <span class="btn" @click="addOptionalArg(sdkItem)" v-show="sdkItem.isAddable">
+                      <i class="iconfont iconhebingxingzhuang" style="font-size:16px"></i>
+                    </span>
+                    <span class="btn" @click="delOptionalArg(sdkItem, optArgItem)">
+                      <i class="iconfont iconshanchu11" style="font-size:16px"></i>
+                    </span>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </transition-group>
+        </div>
+        <div class="btn-add" v-show="isAdd && this.sdkGroup.length < 4">
+          <el-button size="mini" @click="addSdkItem">+ 娣诲姞绠楁硶</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import {
+  deleteCameraRules,
+  updateRuleDefence,
+  updateAlarmLevel
+} from '@/api/camera'
+
+export default {
+  name: 'SceneRuleEditor',
+  props: {
+    Cameras: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
+    isTemplate: {
+      type: Boolean,
+      default: false
+    },
+    isLinkRule: {
+      type: Boolean,
+      default: false
+    },
+    includeSdks: {
+      type: Array
+    },
+    ruleList: {
+      type: String,
+      default: ''
+    },
+    onSubmitRule: {
+      type: Function,
+      default: () => false
+    }
+  },
+  // computed: {
+  //   allPolygonData() {
+  //     let polygon = []
+  //     let cameras = [...this.Cameras]
+
+  //     for (let i = 0; i < cameras.length; i++) {
+  //       let polyOpt = cameras[i].polygonData.map(p => {
+  //         return {
+  //           defence_state: p.defence_state,
+  //           polygonId: p.id,
+  //           name: this.isLinkRule
+  //             ? cameras[i].cameraName + ':' + p.name
+  //             : p.name,
+
+  //           cameraId: cameras[i].cameraId
+  //         }
+  //       })
+
+  //       polygon = polygon.concat(polyOpt)
+  //     }
+  //     //娣诲姞鍦烘櫙鍒濆鍖栧尯鍩熼�夐」涓�'鍏ㄩ儴鍖哄煙'
+  //     if (polygon.length > 0 && this.ruleList.length == 0) {
+  //       this.polygonObj = polygon[0];
+  //       this.sdkGroup[0].polygonObj = JSON.parse(JSON.stringify(this.polygonObj));
+  //       this.selectPolygonOption(this.sdkGroup[0])
+  //     }
+  //     return polygon
+  //   }
+  // },
+  watch: {
+    Cameras: {
+      handler(n, o) {
+        debugger
+        let polygon = []
+        let cameras = [...n]
+
+        for (let i = 0; i < cameras.length; i++) {
+          let polyOpt = cameras[i].polygonData.map(p => {
+            return {
+              defence_state: p.defence_state,
+              polygonId: p.id,
+              name: this.isLinkRule
+                ? cameras[i].cameraName + ':' + p.name
+                : p.name,
+
+              cameraId: cameras[i].cameraId
+            }
+          })
+          polygon = polygon.concat(polyOpt)
+
+          this.allPolygonData = polygon
+          //娣诲姞鍦烘櫙鍒濆鍖栧尯鍩熼�夐」涓�'鍏ㄩ儴鍖哄煙'
+          debugger
+          // if (polygon.length > 0 && this.ruleList == '') {
+          //   this.polygonObj = polygon[0]
+          //   this.sdkGroup[0].polygonObj = JSON.parse(
+          //     JSON.stringify(this.polygonObj)
+          //   )
+
+          //   this.selectPolygonOption(this.sdkGroup[0])
+          // }
+        }
+      },
+      deep: true
+    },
+    sdkGroup: {
+      handler(newV, oldV) {
+        if (newV) {
+          debugger
+          newV.forEach(sdk => {
+            let rangeOne = sdk.defaultArg.find(
+              arg => arg.operators[0].operator == 'range'
+            )
+            if (rangeOne) {
+              debugger
+              if (rangeOne.min.trim() && rangeOne.max.trim()) {
+                if (Number(rangeOne.min) >= Number(rangeOne.max)) {
+                  this.$notify({
+                    type: 'error',
+                    message: '鍖洪棿宸︿晶涓嶈兘澶т簬鎴栫瓑浜庡尯闂村彸渚х殑鍊�'
+                  })
+                  rangeOne.valid = false
+                }
+                rangeOne.sdk_arg_value = rangeOne.min + ',' + rangeOne.max
+              } else {
+                rangeOne.sdk_arg_value = false;
+              }
+
+
+            }
+          })
+          let res = newV.find(item => {
+            return JSON.stringify(item.sdkObj) == '{}'
+          })
+          if (!res) {
+            this.isAdd = true
+            this.hideDel = false
+          } else {
+            this.isAdd = false
+            if (this.sdkGroup.length == 1) {
+              this.hideDel = true
+            } else {
+              this.hideDel = false
+            }
+          }
+        }
+      },
+      deep: true
+    }
+    // ruleList: {
+    //   handler(newVal, oldVal) {
+    //     debugger
+    //     this.editHandle(newVal)
+    //   }
+
+    // }
+  },
+  mounted() {
+    this.TaskMange.findAllSdk()
+    //this.TaskMange.list1 = sdkJson.data;
+
+    //this.editHandle(this.ruleList)
+  },
+  data() {
+    return {
+      // rule: {
+      //   sdk_id:'',
+      //   sdkObj: {},
+      //   polygonObj: {},
+      //   argDef: []
+      // },
+      hideDel: true,
+      //isAddable: true,
+      allPolygonData: [],
+      group_id: '',
+      baseSdkItem: {
+        sdkObj: {},
+        polygonObj: {},
+        is_save_anyhow: true,
+        rule_with_pre: '',
+        isSpread: true,
+        argDef: [],
+        initAddOptional: false,
+        defaultArg: [],
+        optionalArg: [],
+        optArg: [],
+        optNames: [],
+        isAddable: true
+      },
+      sdkGroup: [
+        {
+          sdkObj: {},
+          polygonObj: {},
+          is_save_anyhow: true,
+          isSpread: true,
+          argDef: [],
+          initAddOptional: false,
+          defaultArg: [],
+          optionalArg: [],
+          optArg: [],
+          optNames: [],
+          isAddable: true
+        }
+      ],
+      polygonObj: {},
+      isSpread: true,
+      isAdd: false,
+      tipColor: 'yellow',
+      tasksTable: {},
+      groupRules: [],
+      sdksOption: [],
+      baseRule: {
+        camera_id: '',
+        id: '',
+        operator: '',
+        operator_type: '',
+        polygon_id: '',
+        rule_with_pre: '',
+        sdk_id: '',
+        sdk_arg_alias: '',
+        sdk_arg_value: '',
+        sdk_arg_defaultValue: '',
+        select_time_rule: '',
+        sdk_arg_type: '',
+        // task_id: "",
+
+        polygonObj: {},
+        taskObj: '',
+
+        sdkObj: {},
+        argObj: {},
+        operatorObj: {},
+        valueObj: {},
+
+        sdksOptions: [],
+        argsOptions: [],
+        argType: '',
+        computeOptions: [],
+        valueOptions: [],
+
+        sdkDesc: '',
+        argDesc: '',
+        operatorDesc: '',
+        typeDesc: '',
+        valueDesc: '',
+
+        unit: '',
+        value: '',
+        valid: true
+      }
+    }
+  },
+  methods: {
+    selConnection(sdkItem) {
+      debugger
+
+    },
+    addSdkItem() {
+      let itemTemp = JSON.parse(JSON.stringify(this.baseSdkItem));
+      //鍒濆鍖栧尯鍩�
+      itemTemp.polygonObj = JSON.parse(JSON.stringify(this.allPolygonData[0]))
+      this.selectPolygonOption(itemTemp)
+      this.sdkGroup.push(itemTemp)
+    },
+    delConfigItem(index) {
+      debugger
+      // if(index != 0){
+      //   this.sdkGroup.splice(index,1);
+      // }else{
+      //   //this.sdkGroup[0] = JSON.parse(JSON.stringify(this.baseSdkItem));
+      //   this.sdkGroup.splice(0,1,JSON.parse(JSON.stringify(this.baseSdkItem)));
+      // }
+
+      //鍒犻櫎閫昏緫锛氬綋鍙湁涓�涓畻娉曟椂锛屽垹闄や細鍥炲埌鍒濆鐘舵�侊紱鏈夊涓畻娉曟椂锛屽垹闄ゆ棦绉婚櫎鏁翠釜绠楁硶椤�
+      if (this.sdkGroup.length == 1) {
+        let itemTemp = JSON.parse(JSON.stringify(this.baseSdkItem))
+        itemTemp.polygonObj = JSON.parse(JSON.stringify(this.allPolygonData[0]));
+        this.selectPolygonOption(itemTemp)
+        this.sdkGroup.splice(index, 1, itemTemp)
+      } else {
+        this.sdkGroup.splice(index, 1)
+      }
+    },
+    collapseLine(index) {
+      // let one = this.sdkGroup.find(sdk=>{
+      //   return sdk.sdk_id == sdkId;
+      // });
+
+      this.sdkGroup[index].isSpread = !this.sdkGroup[index].isSpread
+    },
+    addOptionalArg(sdkItem) {
+      debugger
+      sdkItem.initAddOptional = false
+      sdkItem.optArg.forEach(arg => {
+        sdkItem.optNames.forEach(name => {
+          if (arg.sort == name.sort) {
+            name.isSelected = true
+          }
+        })
+      }) //鎵惧埌鍙�塻dkItem.optNames鐨勭涓�涓搴旂殑sdkItem.optionalArg聽push鍒皊dkItem.optArg
+      let oneNotSelected = sdkItem.optNames.find(name => !name.isSelected)
+      if (oneNotSelected) {
+        oneNotSelected.isSelected = true;
+      }
+
+      let argTemp = sdkItem.optionalArg.find(arg => {
+        return arg.sort == oneNotSelected.sort
+      })
+
+      let copyArgTemp = JSON.parse(JSON.stringify(argTemp))
+      if (copyArgTemp.type == 'option') {
+        // let alias = copyArgTemp.alias;
+        // console.log( this.VideoManageData.Dictionary[alias])
+        // copyArgTemp.valueOptions = this.VideoManageData.Dictionary[alias].map(r => {
+        //   return {
+        //     name: r.name,
+        //     value: r.value
+        //   }
+        // })
+
+        this.setOptArgValueOptions(copyArgTemp)
+      }
+
+      if (copyArgTemp.default_value) {
+        this.$set(copyArgTemp, 'sdk_arg_value', copyArgTemp.default_value)
+      }
+      sdkItem.optArg.push(copyArgTemp);
+      if (sdkItem.optArg.length < sdkItem.optionalArg.length) {
+        sdkItem.isAddable = true;
+      } else {
+        sdkItem.isAddable = false;
+      }
+    },
+    delOptionalArg(sdkItem, optArgItem) {
+      let index = sdkItem.optArg.findIndex(arg => arg.sort == optArgItem.sort)
+      sdkItem.optArg.splice(index, 1)
+      sdkItem.optNames.forEach(name => {
+        if (name.sort == optArgItem.sort) {
+          name.isSelected = false
+        }
+      })
+      sdkItem.initAddOptional = sdkItem.optArg.length == 0 ? true : false;
+      if (sdkItem.optArg.length < sdkItem.optionalArg.length) {
+        sdkItem.isAddable = true;
+      } else {
+        sdkItem.isAddable = false;
+      }
+    },
+    selOptionalArg(sdkItem, optArgItem) {
+      debugger
+      let newSort = 0
+      sdkItem.optNames.forEach(name => {
+        if (name.name == optArgItem.name) {
+          //鏂板垏鎹㈢殑鍙傛暟鍚�
+          name.isSelected = true
+          newSort = name.sort
+        } else if (name.sort == optArgItem.sort) {
+          //鍒囨崲鍓嶇殑鍙傛暟鍚�
+          name.isSelected = false
+        }
+      })
+      //鏍规嵁鏂扮殑鍙傛暟sort鎵惧埌鍏跺搴旈厤缃璞�
+      let argObj = sdkItem.optionalArg.find(arg => arg.sort == newSort)
+      if (argObj.type == 'option') {
+        this.setOptArgValueOptions(argObj);
+      }
+      debugger
+      //鏇挎崲鏂扮殑鍙傛暟閰嶇疆瀵硅薄
+      sdkItem.optArg.forEach((arg, index) => {
+        if (arg.sort == optArgItem.sort) {
+          this.$set(sdkItem.optArg, index, JSON.parse(JSON.stringify(argObj)))
+        }
+      })
+
+      console.log(argObj.valueOptions)
+    },
+    setOptArgValueOptions(optArg) {
+      let alias = optArg.alias;
+      console.log(this.VideoManageData.Dictionary[alias])
+      optArg.valueOptions = this.VideoManageData.Dictionary[alias].map(r => {
+        return {
+          name: r.name,
+          value: r.value
+        }
+      });
+    },
+    validateArgVal(sdkArgItem, e) {
+      debugger
+      if (typeof (sdkArgItem.sdk_arg_value) == 'string' && sdkArgItem.sdk_arg_value == '') {
+        this.$notify({
+          type: 'warning',
+          message: '鍙傛暟璁惧畾鍊间笉鑳戒负绌�!'
+        })
+        sdkArgItem.valid = false
+
+        return false
+      }
+      //杈撳叆闈炴暟瀛�
+
+      //鑼冨洿鏄惁鍚堟硶
+      if (sdkArgItem.range) {
+        let leftHand = sdkArgItem.range.substr(0, 1)
+        let rightHand = sdkArgItem.range.substr(sdkArgItem.range.length - 1, 1)
+        let reg = /.*(\d+),(\d+).*/
+        let res = sdkArgItem.range.match(reg)
+        let min = Number(res[1]),
+          max = Number(res[2])
+        debugger
+
+        //鍒ゆ柇闈炲尯闂寸被
+        if (sdkArgItem.sdk_arg_value && sdkArgItem.operator != 'range') {
+          if (leftHand == '(' && rightHand == ')') {
+            if (
+              Number(sdkArgItem.sdk_arg_value) <= min ||
+              Number(sdkArgItem.sdk_arg_value) >= max
+            ) {
+              sdkArgItem.valid = false
+
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟璁惧畾鍊奸』澶т簬${min},灏忎簬${max}`
+              })
+              return false
+            }
+          } else if (leftHand == '[' && rightHand == ')') {
+            if (
+              Number(sdkArgItem.sdk_arg_value) < min ||
+              Number(sdkArgItem.sdk_arg_value) >= max
+            ) {
+              sdkArgItem.valid = false
+
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟璁惧畾鍊奸』澶т簬绛変簬${min},灏忎簬${max}`
+              })
+              return false
+            }
+          } else if (leftHand == '(' && rightHand == ']') {
+            if (
+              Number(sdkArgItem.sdk_arg_value) <= min ||
+              Number(sdkArgItem.sdk_arg_value) > max
+            ) {
+              sdkArgItem.valid = false
+
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟璁惧畾鍊奸』澶т簬${min},灏忎簬绛変簬${max}`
+              })
+              return false
+            }
+          } else if (leftHand == '[' && rightHand == ']') {
+            if (
+              Number(sdkArgItem.sdk_arg_value) < min ||
+              Number(sdkArgItem.sdk_arg_value) > max
+            ) {
+              sdkArgItem.valid = false
+              this.showErrorColor(e)
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟璁惧畾鍊奸』澶т簬绛変簬${min},灏忎簬绛変簬${max}`
+              })
+              return false
+            }
+          }
+        } else if (sdkArgItem.min || sdkArgItem.max) {
+          //鍒ゆ柇鍖洪棿绫�
+          if (leftHand == '(' && rightHand == ')') {
+            if (
+              Number(sdkArgItem.min) <= min ||
+              Number(sdkArgItem.min) >= max
+            ) {
+              sdkArgItem.valid = false
+
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟鍖洪棿璁惧畾鍊奸』澶т簬${min},灏忎簬${max}`
+              });
+              return false
+            }
+          } else if (leftHand == '[' && rightHand == ')') {
+            if (Number(sdkArgItem.min) < min || Number(sdkArgItem.max) >= max) {
+              sdkArgItem.valid = false
+
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟鍖洪棿璁惧畾鍊奸』澶т簬绛変簬${min},灏忎簬${max}`
+              })
+              return false
+            }
+          } else if (leftHand == '(' && rightHand == ']') {
+            if (Number(sdkArgItem.min) <= min || Number(sdkArgItem.max) > max) {
+              sdkArgItem.valid = false
+
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟鍖洪棿璁惧畾鍊奸』澶т簬${min},灏忎簬绛変簬${max}`
+              })
+              return false
+            }
+          } else if (leftHand == '[' && rightHand == ']') {
+            if (Number(sdkArgItem.min) < min || Number(sdkArgItem.max) > max || Number(sdkArgItem.min) > max || Number(sdkArgItem.max) < min) {
+              sdkArgItem.valid = false
+              this.showErrorColor(e)
+              this.$notify({
+                type: 'warning',
+                message: `鍙傛暟鍖洪棿璁惧畾鍊奸』澶т簬绛変簬${min},灏忎簬绛変簬${max}`
+              })
+              return false
+            }
+          }
+        }
+      }
+      e.currentTarget.style.borderColor = ''
+      return true
+    },
+    showErrorColor(e) {
+      this.$nextTick(() => {
+        e.currentTarget.style.borderColor = 'red'
+      })
+    },
+    setSdksOptions(rule) {
+      rule.sdksOptions = this.includeSdks
+    },
+    setOperator(rule) {
+      rule.operator = rule.operatorObj.value
+      rule.operatorDesc = rule.operatorObj.name
+    },
+    setValue(rule) {
+      rule.valid = true
+
+      if (rule.operator_type === 'option') {
+        rule.sdk_arg_value = rule.valueObj.value ? rule.valueObj.value : ''
+        rule.typeDesc = '琚�夐」'
+        rule.valueDesc = rule.valueObj.name ? rule.valueObj.name : ''
+      } else {
+        rule.typeDesc = '鍊�'
+        rule.valueDesc = rule.sdk_arg_value
+      }
+      this.valideArgValue(rule)
+    },
+    selectPolygonOption(rule) {
+      debugger
+      rule.polygon_id = rule.polygonObj.polygonId
+        ? rule.polygonObj.polygonId
+        : rule.polygon_id
+      rule.camera_id = rule.polygonObj.cameraId
+        ? rule.polygonObj.cameraId
+        : rule.camera_id
+      rule.group_id = this.group_id
+    },
+    //閫夋嫨绠楁硶 resetArgs涓簍rue鏄坊鍔犱负false鏄垵濮嬪寲缂栬緫
+    selectSDKOption(sdkItem, resetArgs) {
+      debugger
+      //sdkItem.sdk_id = sdkItem.sdkObj.id;
+      if (resetArgs) {
+        sdkItem.argDef = JSON.parse(sdkItem.sdkObj.argDef)
+        console.log(sdkItem.argDef)
+        //鍙栧嚭榛樿鍙傛暟
+        sdkItem.defaultArg = sdkItem.argDef.filter(
+          arg => !arg.config.isOptional
+        )
+        //璧嬮粯璁perator/鍊�
+        sdkItem.defaultArg.forEach(arg => {
+          if (arg.operators.length == 1) {
+            this.$set(arg, 'operator', arg.operators[0].operator)
+
+            if (arg.operators[0].operator == 'range') {
+              //鍖洪棿鍊肩殑澶勭悊
+              debugger
+              //this.$set(arg, 'sdk_arg_value', arg.min+','+arg.max)
+              //this.$set(arg, 'sdk_arg_value', arg.range.substring(1,arg.range.length-1));
+            }
+          }
+
+          if (arg.default_value) {
+            //arg.sdk_arg_value = arg.default_value
+            this.$set(arg, 'sdk_arg_value', arg.default_value)
+          }
+        })
+        sdkItem.defaultArg
+        //鍙栧嚭鍙�夊弬鏁�
+        sdkItem.optionalArg = sdkItem.argDef.filter(
+          arg => arg.config.isOptional
+        )
+        sdkItem.optNames = sdkItem.optionalArg.map(arg => ({
+          name: arg.name,
+          sort: arg.sort,
+          isSelected: false
+        }))
+        debugger
+        sdkItem.initAddOptional = sdkItem.optionalArg.length > 0 ? true : false
+        sdkItem.optArg = []
+      }
+
+      //娣诲姞鍦烘櫙鏃�,濡傛灉鍦烘櫙鍚嶇О涓虹┖,灏卞皢閫夋嫨鐨勭涓�涓畻娉曞悕鍚屾鍒板満鏅悕绉�
+      if (this.sdkGroup[0] && resetArgs) {
+        debugger
+        this.$emit('sdkNameChange', this.sdkGroup[0].sdkObj.sdk_name)
+      }
+
+      // 閫夐」鍒囨崲鏃堕渶瑕佸埛鏂癮rg鑿滃崟椤�
+      this.selectArgTypeOption(sdkItem, resetArgs)
+    },
+
+    selectArgTypeOption(rule, resetAlias) {
+      if (rule.sdk_arg_type == '') {
+        return
+      }
+
+      if (resetAlias) {
+        rule.sdk_arg_alias = ''
+      }
+
+      rule.argsOptions = rule.sdkObj.args
+
+      // 鏍规嵁arg绫诲瀷鏄剧ず鍙傛暟, 褰撳墠鍏ㄩ儴褰掍负 target
+      // if (rule.sdkObj.args) {
+      //   rule.argsOptions = rule.sdkObj.args.filter(ele => {
+      //     return ele.arg_type === rule.sdk_arg_type
+      //   });
+      // } else {
+      //   rule.argsOptions = [];
+      // }
+
+      rule.argObj = {}
+    },
+    //閫夋嫨绠楁硶閰嶇疆
+    selOperator(rule) {
+      debugger
+    },
+    selectArgsOption(rule, resetArgValue) {
+      // rule.operator_type = "";
+      // console.log(rule, '閫夋嫨绠楁硶鍙傛暟')
+      rule.sdk_arg_alias = rule.argObj.alias
+      rule.argDesc = rule.argObj.name
+      rule.sdk_arg_defaultValue = rule.argObj.default_value
+      rule.unit = rule.argObj.unit ? rule.argObj.unit : ''
+      //rule.default_value = rule.argObj.default_value ? Number(rule.argObj.default_value) : 0;
+
+      //console.log("缃俊搴︾殑榛樿鍊间负",rule.sdk_arg_defaultValue)
+      // 淇濆瓨鍊肩被鍨�
+      rule.argType = rule.argObj.type
+      if (rule.argType === 'option') {
+        rule.operator_type = 'option'
+        // 璁剧疆榛樿鏉′欢鍊�
+        this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+          if (opt.value == '==') {
+            rule.operatorObj = opt
+          }
+        })
+
+        this.setOperator(rule)
+
+        this.selectValueOption(rule)
+      } else {
+        // 璁剧疆榛樿鏉′欢鍊�
+        rule.operator_type = 'value'
+        if (resetArgValue) {
+          rule.sdk_arg_value = ''
+
+          this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+            if (opt.value == '>=') {
+              rule.operatorObj = opt
+            }
+          })
+        } else {
+          // 缂栬緫瑙勫垯鍖归厤
+          this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+            if (opt.value == rule.operator) {
+              rule.operatorObj = opt
+            }
+          })
+        }
+        this.setOperator(rule)
+      }
+    },
+    selectValueOption(rule) {
+      if (rule.sdk_arg_alias === 'time_rule') {
+        rule.valueOptions = this.VideoManageData.TimeRules.map(r => {
+          return {
+            name: r.name,
+            value: r.id
+          }
+        })
+      } else if (rule.sdk_arg_alias === 'compareBase') {
+        rule.valueOptions = this.VideoManageData.TagList.map(r => {
+          return {
+            name: r.tableName,
+            value: r.id
+          }
+        })
+      } else {
+        let ops = this.VideoManageData.Dictionary[rule.sdk_arg_alias]
+        if (ops && ops instanceof Array) {
+          rule.valueOptions = ops.map(r => {
+            return {
+              name: r.name,
+              value: r.value
+            }
+          })
+        }
+      }
+    },
+
+    valideArgValue(rule) {
+      if (rule.sdk_arg_value == '') {
+        this.$notify({
+          type: 'warning',
+          message: '鍙傛暟璁惧畾鍊间笉鑳戒负绌�!'
+        })
+        rule.valid = false
+        return false
+      }
+
+      if (rule.argObj && rule.argObj.range) {
+        // 濡傛灉璁剧疆浜嗙畻娉曢粯璁ゅ�硷紝鍒欏垽鏂笉鑳藉皬浜庤鍊�
+        if (rule.argObj.default_value) {
+          if (
+            parseInt(rule.sdk_arg_value) < parseInt(rule.sdk_arg_defaultValue)
+          ) {
+            rule.valid = false
+            this.$notify({
+              type: 'warning',
+              message:
+                '鍙傛暟璁惧畾鍊间笉鑳藉皬浜庣畻娉曞弬鏁伴粯璁ゅ�� ' + rule.sdk_arg_defaultValue
+            })
+            rule.valueDesc = rule.sdk_arg_value = rule.argObj.default_value
+            rule.valid = false
+            return false
+          }
+        }
+
+        // let re = /(?<=,).*?(?=]|\))/
+        let re = /.*,(\d+)/
+        let max = rule.argObj.range.match(re)[1]
+        // console.log(max,'鑾峰彇鑼冨洿鏈�澶у��')
+        if (Number(rule.sdk_arg_value) > Number(max)) {
+          rule.valid = false
+          this.$notify({
+            type: 'warning',
+            message: '鍙傛暟璁惧畾鍊间笉鑳藉ぇ浜�' + max
+          })
+          return false
+        }
+      }
+
+      return true
+    },
+    parataxis(rule_with_pre) {
+      let relation = ''
+      this.VideoManageData.Dictionary.RULECOMPUTEBETWEEN.forEach(pre => {
+        if (pre.value === rule_with_pre) {
+          relation = pre.name
+        }
+      })
+
+      return relation
+    },
+
+    generatDescription() {
+      let desc = ''
+      this.groupRules.forEach((r, index) => {
+        // console.log(r,index,'鎷兼帴')
+        if (index === 0) {
+          desc += r.sdkDesc + r.argDesc + r.operatorDesc + r.valueDesc + r.unit
+        } else {
+          desc +=
+            '&nbsp;&nbsp;&nbsp;' +
+            this.parataxis(r.rule_with_pre) +
+            '&nbsp;&nbsp;&nbsp;' +
+            r.sdkDesc +
+            r.argDesc +
+            r.operatorDesc +
+            r.valueDesc +
+            r.unit
+        }
+      })
+      // console.log(desc,'鎷兼帴')
+      return desc
+    },
+    createRule() {
+      if (!this.isTemplate && this.Cameras.length > 0) {
+        // 鏈�変腑鎽勫儚鏈烘垨鑰呮湭閫変腑鎽勫儚鏈轰换鍔★紝涓嶆墽琛屽垱寤�
+        if (!this.Cameras[0].cameraId) return false
+      }
+      this.group_id = ''
+      //this.addRule(0);
+    },
+
+    //娓呯┖閰嶇疆骞跺垵濮嬪寲
+    cleanRule() {
+      this.group_id = ''
+      this.sdkGroup.splice(0, this.sdkGroup.length)
+      this.addSdkItem();
+    },
+    addRule(index) {
+      let newRule = JSON.parse(JSON.stringify(this.baseRule))
+      newRule.sdksOptions = this.includeSdks
+      if (!this.isLinkRule) {
+        // 璁剧疆榛樿鍏ㄩ儴鍖哄煙
+        // if (!this.isTemplate) {
+        //   newRule.polygonObj = this.allPolygonData[0];
+        //   this.selectPolygonOption(newRule)
+        // }
+        // 璁剧疆绠楁硶
+        // newRule.sdksOptions = this.includeSdks;
+        // 璁剧疆榛樿绠楁硶
+        // newRule.sdkObj = newRule.sdksOptions[0]
+        // this.selectSDKOption(newRule, false)
+        // newRule.sdk_arg_type = "target"
+        // this.selectArgTypeOption(newRule, true)
+      }
+
+      // this.groupRules.push(newRule);
+      // 鎻掑叆鍒版寚瀹氫綅缃�
+      this.groupRules.splice(index + 1, 0, newRule)
+    },
+    editHandle(ruleTxt) {
+      debugger
+      // if (ruleTxt.length < 1) {
+      //   return
+      // }
+      let ruleInfo = JSON.parse(ruleTxt);
+      debugger;
+
+      //let ruleInfo = JSON.parse(ruleTxt)
+      this.editRule(ruleInfo)
+      // 濡傛灉鏄仈鍔ㄤ换鍔�, 鏌ヨ鑱斿姩鎽勫儚鏈哄垪琛�, 灏嗘爲閫変腑鐨勫垪琛ㄦ洿鏀逛负璇ユ潯瑙勫垯鎵�闇�瑕佺殑鎽勫儚鏈�, 骞跺浠藉綋鍓嶇殑閫変腑鐘舵��, 瑙勫垯淇濆瓨鍚庢仮澶�
+      // if (this.isLinkRule) {
+      //   this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule = [...this.TreeDataPool.selectedNodes]
+      //   this.VideoRuleData.editLinkRuleRow = { ...ruleInfo }
+
+      //   this.TreeDataPool.selectedNodes = ruleInfo.group_rules.map(r => {
+      //     return r.camera_id
+      //   })
+      //   this.$nextTick(() => {
+      //     setTimeout(() => {
+      //       this.editRule(ruleInfo)
+      //     }, 1000)
+      //   })
+      // } else {
+      //   this.editRule(ruleInfo)
+      // }
+    },
+    editRule(ruleGroup) {
+      debugger
+      this.sdkGroup = []
+      this.group_id = ''
+
+      // this.sdkGroup = ruleGroup;
+      //  sdkGroup: [
+      //   {
+      //     sdkObj: {},
+      //     polygonObj: {},
+      //     is_save_anyhow: true,
+      //     isSpread: true,
+      //     argDef: [],
+      //     initAddOptional: false,
+      //     defaultArg: [],
+      //     optionalArg: [],
+      //     optArg: [],
+      //     optNames: []
+      //   }
+      // ],
+      ruleGroup.forEach(rule => {
+        debugger
+        let tempObj = {}
+
+        if (rule.group_id && rule.group_id != '') {
+          this.group_id = rule.group_id
+        }
+
+        // 濉厖鍖哄煙閫夐」鍒楄〃
+        this.allPolygonData.forEach(p => {
+          if (p.polygonId === rule.polygon_id) {
+            rule.polygonObj = p
+          }
+        })
+
+        if (!rule.polygonObj) {
+          rule.polygonObj = {
+            cameraId: rule.camera_id,
+            defence_state: 1,
+            name: '鏈煡鍖哄煙',
+            polygonId: rule.polygon_id
+          }
+        }
+        console.log(rule)
+
+        // 璁剧疆鍖哄煙
+        this.selectPolygonOption(rule)
+
+        //绠楁硶瀵硅薄,绠楁硶鍙傛暟閰嶇疆鏁扮粍,(鐢ㄤ簬鏁版嵁澶勭悊鐨�)榛樿鍙傛暟鏁扮粍, 鍙�夊弬鏁版暟缁�, 宸查厤缃殑鍙�夊弬鏁版暟缁�, (鐢ㄤ簬鍘婚噸鍒ゆ柇)瀛樻斁鍙�夊弬鏁板悕鐨勬暟缁�
+        let sdkObj = {},
+          argDef = [],
+          defaultArg = [],
+          optionalArg = [],
+          optArg = [],
+          optNames = []
+
+        sdkObj = this.TaskMange.list1.find(sdk => sdk.id == rule.sdk_id)
+
+        argDef = JSON.parse(sdkObj.argDef)
+        defaultArg = argDef.filter(arg => !arg.config.isOptional)
+        optionalArg = argDef.filter(arg => arg.config.isOptional)
+
+        rule.sdk_set.forEach(arg => {
+          let optItem = optionalArg.find(oarg => {
+            debugger
+            if (oarg.sort == arg.sort) {
+              return oarg
+            }
+          })
+          if (optItem) {
+            if (optItem.operators.length > 1) {
+              optItem.operator = arg.operator
+              //this.selOperator(optItem)
+            }
+
+            //璧嬪��
+            optItem.sdk_arg_value = arg.sdk_arg_value
+            //if(arg.sdk_arg_value.indexOf(',')>0){
+            //鍒ゆ柇鏄惁鏄閫夊�肩被鍨嬬殑鍙傛暟
+            let isMultiOne = optionalArg.find(oarg => oarg.sort == optItem.sort && optItem.config.isMulti)
+            if (isMultiOne) {
+              optItem.sdk_arg_value = arg.sdk_arg_value.split(',');
+            }
+
+            if (optItem.type == 'option') {
+              this.setOptArgValueOptions(optItem)
+            }
+            optArg.push(optItem)
+          } else {
+            defaultArg.forEach(d => {
+              if (d.sort == arg.sort) {
+                if (arg.sdk_arg_value.indexOf(',') > 0) {
+                  //鍖洪棿鍊�
+                  d.min = arg.sdk_arg_value.split(',')[0];
+                  d.max = arg.sdk_arg_value.split(',')[1];
+                  d.operator = 'range'
+                } else {
+                  d.sdk_arg_value = arg.sdk_arg_value
+                }
+                d.operator = arg.operator;
+              }
+            })
+          }
+        })
+        optNames = optionalArg.map(arg => ({
+          name: arg.name,
+          sort: arg.sort,
+          isSelected: false
+        }))
+
+        tempObj = {
+          sdkObj,
+          polygonObj: rule.polygonObj,
+          rule_with_pre: rule.rule_with_pre,
+          is_save_anyhow: rule.is_save_anyhow,
+          isSpread: true,
+          argDef,
+          initAddOptional: false,
+          optionalArg,
+          optArg,
+          defaultArg,
+          optNames,
+          isAddable: true,
+          camera_id: rule.camera_id,
+          polygon_id: rule.polygon_id
+        }
+        //鍥炴樉鏄惁鏄剧ず娣诲姞鍙�夊弬鏁�
+        tempObj.initAddOptional =
+          tempObj.optArg.length == 0 && tempObj.optionalArg.length > 0
+            ? true
+            : false;
+        debugger
+        //鍥炴樉鏄惁鏄剧ず鍙�夊弬鏁版坊鍔犳寜閽�
+        if (tempObj.optArg.length < tempObj.optionalArg.length) {
+          tempObj.isAddable = true;
+        } else {
+          tempObj.isAddable = false;
+        }
+        //this.selectSDKOption(tempObj, false)
+        debugger
+        this.sdkGroup.push(tempObj)
+        //璁剧疆绠楁硶
+      })
+      //this.$nextTick(() => {})
+    },
+    delRule(rule) {
+      this.$confirm('鎻愮ず锛氬垹闄ゅ悗锛岃鏉¤鍒欏皢澶辨晥锛屾槸鍚﹀垹闄わ紵', {
+        center: true,
+        cancelButtonClass: 'comfirm-class-cancle',
+        confirmButtonClass: 'comfirm-class-sure'
+      })
+        .then(() => {
+          deleteCameraRules({ groupId: rule.group_id }).then(res => {
+            if (res && res.success) {
+              this.$notify({
+                type: 'success',
+                message: '鍒犻櫎鎴愬姛'
+              })
+              this.$emit('delete-rule')
+            } else {
+              this.$notify({
+                type: 'error',
+                message: '鍒犻櫎澶辫触锛�'
+              })
+            }
+          })
+        })
+        .catch(() => { })
+    },
+    submitRule() {
+      debugger
+      let groupRule = { rules: [] }
+
+      let group_text = ''
+      let validateFlag = false
+
+      if (this.isTemplate) {
+        groupRule.rules = this.groupRules.map(r => {
+          return {
+            sdk_id: r.sdk_id,
+            sdk_arg_alias: r.sdk_arg_alias,
+            operator: r.operator,
+            operator_type: r.operator_type,
+            sdk_arg_value: r.sdk_arg_value,
+            sort: 1,
+            rule_with_pre: r.rule_with_pre
+          }
+        })
+      } else {
+        //鏍¢獙蹇呭~椤�
+        let undefinished = this.sdkGroup.some((sdk, index) => {
+          debugger
+          //娌℃湁閰嶇疆绠楁硶
+          if (Object.keys(sdk.sdkObj).length == 0) {
+            return sdk
+          }
+          //澶氫簬涓ら」绠楁硶鏃�,绠楁硶鍏崇郴涓嶈兘涓虹┖
+          if (sdk.rule_with_pre === '' && index != 0) {
+            return sdk
+          }
+          //琛ㄥ崟鎻愪氦鍓嶆牎楠�:鎵�鏈夌畻娉曠殑鍙傛暟鍊间笉鑳戒负绌�,(鏈塺ange鐨�,瑕佸湪range鑼冨洿鍐�)澶辩劍鏃舵牎楠�
+          let defaultArgFlag = sdk.defaultArg.find(arg => !arg.sdk_arg_value)
+          if (defaultArgFlag) {
+            return sdk
+          }
+          //鏌ユ壘鍙�夊弬鏁板�兼槸鍚﹂兘璁剧疆(澶氶�夊�间负鏁扮粍绫诲瀷)
+          let optionalArgFlag = sdk.optArg.find(arg => {
+            if (arg.sdk_arg_value instanceof Array) {
+              if (arg.sdk_arg_value.length == 0) {
+                return arg
+              }
+            } else {
+              //鍖洪棿绫诲弬鏁板�兼渶灏�,鏈�澶у�兼槸鍚﹂兘璁剧疆
+              if (arg.operator == 'range') {
+                debugger
+                if (!arg.min.trim() && arg.max.trim()) {
+                  return arg
+                }
+              }
+              if (!arg.sdk_arg_value) {
+                return arg
+              }
+            }
+          });
+
+          if (optionalArgFlag) {
+            return sdk
+          }
+        });
+        if (undefinished) {
+          this.$notify({
+            type: 'error',
+            message: '绠楁硶鍙傛暟鏈畬鍠�,璇峰畬鍠勫悗鍐嶄繚瀛�'
+          });
+          return
+        }
+
+        //鏍¢獙鑻ョ畻娉曞叧绯讳负瑙﹀彂,鍒欑畻娉曞悕涓嶈兘閲�
+        let sameSdk = this.sdkGroup.some((sdk, index) => {
+          debugger
+          if (sdk.index != 0 && sdk.rule_with_pre == '=>') {
+            debugger
+            if (sdk.sdkObj.id == this.sdkGroup[index - 1].sdkObj.id) {
+              return sdk
+            }
+          }
+        });
+
+        if (sameSdk) {
+          this.$notify({
+            type: 'error',
+            message: '绠楁硶鍏崇郴涓鸿Е鍙戞椂,绠楁硶鍚嶄笉鑳介噸澶�'
+          });
+          return
+        }
+
+        if (!validateFlag && !sameSdk) {
+          validateFlag = true
+        }
+
+        this.sdkGroup.forEach(sdk => {
+          let tempObj = {
+            sdk_id: sdk.sdkObj.id,
+            camera_id: sdk.camera_id,
+            group_id: '',
+            is_save_anyhow: sdk.is_save_anyhow,
+            polygon_id: sdk.polygon_id,
+            rule_with_pre: sdk.rule_with_pre,
+            sdk_set: []
+          }
+
+          let defaultArgs = sdk.defaultArg.map(arg => ({
+            operator: arg.operator,
+            operator_type: arg.type,
+            sdk_arg_alias: arg.alias,
+            sdk_arg_value: arg.sdk_arg_value,
+            sort: arg.sort
+          }))
+
+          let defaultArgDesc = '( '
+          sdk.defaultArg.forEach(arg => {
+            if (arg.operator == 'range') {
+              let valRange = '';
+              debugger
+              valRange = arg.sdk_arg_value.replace(',', '-');
+              defaultArgDesc += `${arg.name}${arg.operators[0].name}${valRange}${arg.unit || ''}, `
+            } else {
+              defaultArgDesc += `${arg.name}${arg.operators[0].name}${
+                arg.sdk_arg_value
+                }${arg.unit || ''}, `
+            }
+
+          });
+          debugger;
+          defaultArgDesc = defaultArgDesc.substring(0, defaultArgDesc.length - 2)
+          //defaultArgDesc = defaultArgDesc.substring(0,defaultArgDesc.length-3)+defaultArgDesc.substring(defaultArgDesc.length-1,defaultArgDesc.length);
+          //defaultArgDesc = defaultArgDesc.substring(0,defaultArgDesc.length-1);
+
+          //澶勭悊鍙�夐」鍙傛暟
+
+          let optArgs = sdk.optArg.map(arg => ({
+            operator: arg.operator,
+            operator_type: arg.type,
+            sdk_arg_alias: arg.alias,
+            sdk_arg_value: arg.sdk_arg_value,
+            sort: arg.sort
+          }));
+          //灏嗗閫夐」鐨勫�兼嫾鎴愬瓧绗︿覆
+          optArgs.forEach(one => {
+            if (one.sdk_arg_value instanceof Array) {
+              one.sdk_arg_value = one.sdk_arg_value.join();
+            }
+          });
+          let optArgDesc = ' '
+          sdk.optArg.forEach(arg => {
+            let val = '';
+            let valRange = '';
+
+
+            //澶勭悊涓嬫媺閫夊�肩被鍨�
+            if (arg.type == 'option') {
+              if (arg.sdk_arg_value instanceof Array) {
+                //澶氶�夊��
+                let multiNames = '';
+                arg.sdk_arg_value.forEach(val => {
+                  let opV = arg.valueOptions.find(opt => opt.value == val);
+                  multiNames += opV.name + ' ';
+                })
+                val = multiNames;
+
+              } else {
+                let res = arg.valueOptions.find(
+                  opt => opt.value == arg.sdk_arg_value
+                );
+
+                val = res.name;
+              }
+              //optArgDesc += `,${arg.name}${arg.operators[0].operator}${val}${arg.unit || ''}, `
+            } else {
+              //optArgDesc += `,${arg.name}${arg.operators[0].operator}${ arg.sdk_arg_value }${arg.unit || ''}, `
+            }
+
+            let operatorSelected = arg.operators.find(opr => opr.operator == arg.operator)
+            optArgDesc += `,${arg.name}${operatorSelected.name}${
+              arg.type == 'option' ? val : arg.sdk_arg_value
+              }${arg.unit || ''}, `
+          })
+          optArgDesc = optArgDesc.substring(0, optArgDesc.length - 2) + optArgDesc.substring(optArgDesc.length - 1, optArgDesc.length);
+          optArgDesc += ')'
+          tempObj.sdk_set = defaultArgs.concat(optArgs)
+
+          groupRule.rules.push(tempObj)
+
+          let rule_with_pre = ''
+          if (sdk.rule_with_pre) {
+            switch (sdk.rule_with_pre) {
+              case '&&':
+                rule_with_pre = ' and '
+                break
+              case '||':
+                rule_with_pre = ' or '
+                break
+              case '=>':
+                rule_with_pre = ' -> '
+                break
+              default:
+                rule_with_pre = ''
+            }
+          }
+          debugger;
+          group_text += `${rule_with_pre ? "<br/>" + rule_with_pre + "<br/>" : ""} <span style="background-color:RGB(183,183,183);">${
+            sdk.sdkObj.sdk_name
+            }</span>  ${
+            sdk.polygonObj.name
+            }  ${defaultArgDesc}${optArgDesc}`;
+
+          if (
+            group_text.charAt(group_text.length - 3) == ',' &&
+            group_text.charAt(group_text.length - 2) == ' ' &&
+            group_text.charAt(group_text.length - 1) == ')'
+          ) {
+            group_text =
+              group_text.substring(0, group_text.length - 3) +
+              group_text.substring(group_text.length - 2, group_text.length)
+          }
+          debugger
+        })
+        console.log(group_text)
+      }
+
+      groupRule.text = group_text
+      groupRule.id = this.group_id
+      return groupRule
+
+      if (this.isLinkRule) {
+        // 鍒ゆ柇瑙勫垯涓嚦灏戝寘鍚袱鎽勫儚鏈�
+        let cameraIds = Array.from(
+          new Set(
+            this.sdkGroup.map(r => {
+              return r.camera_id
+            })
+          )
+        )
+        if (cameraIds.length < 2) {
+          this.$notify({
+            type: 'error',
+            //message: '闇�瑕�2涓笉鍚屾憚鍍忔満鎵嶈兘缁勬垚鑱斿姩瑙勫垯'
+            message: '闇�瑕佽嚦灏�2涓笉鍚屾憚鍍忔満鎵嶈兘缁勬垚鑱斿姩鍦烘櫙'
+          })
+          return
+        }
+
+        // 鑱斿姩瑙勫垯缂栬緫鍚庯紝鎭㈠涔嬪墠閫変腑鐨勬憚鍍忔満
+        // if (this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule.length) {
+        //   this.TreeDataPool.selectedNodes = this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule
+        //   this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule = []
+        // }
+      }
+      //if(validateFlag){
+      this.onSubmitRule(payload)
+      //}
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.edit-rules-box {
+  width: 100%;
+  padding: 0px;
+  box-sizing: border-box;
+  .sub-rules-box {
+    width: 71%;
+    min-width: 1127.4px;
+    min-height: 50px;
+    border-top: 1px solid #eee;
+    padding-top: 7px;
+
+    box-sizing: border-box;
+    padding-bottom: 38px;
+    .task-rules-button {
+      text-align: right;
+      margin: 15px;
+    }
+    .config-item {
+      background: #f8f9f8;
+      padding: 15px 25px;
+      margin-bottom: 52px;
+      position: relative;
+      .el-select {
+        width: 225px !important;
+      }
+      .init-sdk {
+        margin-right: 30px;
+      }
+      .connection {
+        background: #fff;
+        position: absolute;
+        width: 100%;
+        top: -40px;
+      }
+      .top-line {
+        height: 30px;
+        .left {
+          float: left;
+          display: flex;
+        }
+        .right {
+          float: right;
+          cursor: pointer;
+          .del {
+            margin-right: 10px;
+            color: rgb(231, 76, 60);
+          }
+          .collapse {
+            font-size: 13px;
+            display: inline-block;
+            padding: 5px;
+            cursor: pointer;
+          }
+        }
+      }
+      .argums {
+        position: relative;
+        // width: calc(100% - 25px);
+        // top: 43px;
+        // left: 0;
+        // padding-left: 25px;
+        // background: #f8f9f8;
+        .argums-item {
+          display: flex;
+          align-items: center;
+          margin: 7px 0;
+          .arg-name,
+          .operator-name {
+            margin-right: 30px;
+          }
+          .arg-val {
+            width: 245px;
+            span {
+              margin-left: 6px;
+            }
+            .range-min,
+            .range-max {
+              width: 88px;
+              .el-input__inner {
+                height: 28px;
+              }
+            }
+            .devide {
+              display: inline-block;
+              width: 30px;
+              height: 1px;
+              background: #c5c5c5;
+              vertical-align: top;
+              margin: 14px 10px 0;
+            }
+          }
+        }
+        .el-input {
+          width: 225px;
+        }
+      }
+    }
+    .btn-add {
+      margin: 0 25px 15px;
+      margin-top: -38px;
+      .el-button {
+        width: 370px;
+        cursor: pointer;
+      }
+    }
+  }
+
+  .el-button--text {
+    text-decoration: unset;
+  }
+  .el-input.is-disabled .el-input__inner {
+    background: #fafafa;
+    color: #606266;
+  }
+  p {
+    text-align: left;
+    // padding: 10px;
+    box-sizing: border-box;
+  }
+
+  .task-blank {
+    float: left;
+    font-family: PingFangSC-Regular;
+    font-size: 12px;
+    color: #cccccc;
+    margin-top: 5px;
+  }
+
+  .btn {
+    cursor: pointer;
+    color: #3d68e1;
+    margin-left: 10px;
+    font-size: 14px;
+  }
+}
+</style>
diff --git a/src/components/scene/SlideScene.vue b/src/components/scene/SlideScene.vue
new file mode 100644
index 0000000..45bf329
--- /dev/null
+++ b/src/components/scene/SlideScene.vue
@@ -0,0 +1,285 @@
+<template>
+  <div class="swiper-box">
+    <swiper ref="sceneSwiper" v-if="sceneData.length>=1" :options="swiperOption" class="swiper-box-container">
+      <!-- <span class="task-tip" v-show="Camera.rules.length == 0 ">鏆傛棤鍦烘櫙,璇峰紑濮嬪垱寤�</span> -->
+      <swiper-slide v-for="item in sceneData" :key="item.id+'s'">
+        <div class="wrap-box" >
+          <div class="inner">
+            <div class="scenario-icon">
+              <div class="single" v-if="item.rules.length==1">
+                <div class="svg-wrap">
+                  <svg class="icon" aria-hidden="true" style="font-size:4rem;">
+                    <use :xlink:href="`#${item.rules[0].icon}`" />
+                  </svg>
+                </div>
+              </div>
+              <div class="double" v-else-if="item.rules.length==2">
+                <div class="svg-wrap" v-for="(rule,index) in item.rules" :key="index">
+                  <svg class="icon" aria-hidden="true" style="font-size:2rem;">
+                    <use :xlink:href="`#${rule.icon}`" />
+                  </svg>
+                </div>
+              </div>
+              <div class="third" v-else-if="item.rules.length==3">
+                <div class="svg-wrap" v-for="(rule,index) in item.rules" :key="'t'+index">
+                  <svg class="icon" aria-hidden="true" style="font-size:2rem;">
+                    <use :xlink:href="`#${rule.icon}`" />
+                  </svg>
+                </div>
+              </div>
+              <div class="four" v-else-if="item.rules.length==4">
+                <div class="svg-wrap" v-for="(rule,index) in item.rules" :key="'f'+index">
+                  <svg class="icon" aria-hidden="true" style="font-size:2rem;">
+                    <use :xlink:href="`#${rule.icon}`" />
+                  </svg>
+                </div>
+              </div>
+            </div>
+            <div class="scenario-name">{{item.scene_name}}</div>
+          </div>
+        </div>
+      </swiper-slide>
+    </swiper>
+    <div class="swiper-pre-border" v-show="sceneData.length > 4 ">
+      <div class="icon-btn" slot="button-prev">
+        <i class="iconfont iconzuo"></i>
+      </div>
+    </div>
+    <div class="swiper-next-border" v-show="sceneData.length > 4 ">
+      <div class="icon-btn" slot="button-next">
+        <i class="iconfont iconyou1"></i>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props:[
+    // 'swiperOption',
+    'sceneData'
+  ],
+  
+  data() {
+    return {
+      // mockSceneData: [
+      //   { scenename: "name1", id:1, icon: ["iconrenlianjiance", "icongetijingzhi"] },
+      //   { scenename: "name2", id:2, icon: ["iconchouyan-copy"] },
+      //   {
+      //     scenename: "name3",
+      //     id:3,
+      //     icon: [
+      //       "iconrenshukouzhao",
+      //       "iconchouyan-copy",
+      //       "iconrenlianjiance",
+      //       "icongetijingzhi"
+      //     ]
+      //   },
+      //   {
+      //     scenename: "name4",
+      //     id:4,
+      //     icon: ["iconchouyan-copy", "iconrenlianjiance", "icongetijingzhi"]
+      //   },
+      //   { scenename: "name5", id:5, icon: ["icongetijingzhi"] },
+      //   { scenename: "name6", id:6, icon: ["iconrenshukouzhao", "icongetijingzhi"] },
+      //   { scenename: "name7", id:7, icon: ["iconrenlianjiance"] }
+      // ],
+      swiperOption: {
+        slidesPerView: 4,
+        spaceBetween: 0,
+        pagination: {
+          el: ".swiper-pagination",
+          clickable: true
+        },
+        navigation: {
+          nextEl: ".swiper-next-border",
+          prevEl: ".swiper-pre-border"
+        },
+        observer:true,//淇敼swiper鑷繁鎴栧瓙鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+        observeParents:true,//淇敼swiper鐨勭埗鍏冪礌鏃讹紝鑷姩鍒濆鍖杝wiper
+      },
+      mySwiper: {}
+    }
+  },
+  mounted(){
+    // this.mySwiper = this.$refs.sceneSwiper.swiper;
+   
+  },
+  methods:{
+    //鎷嗗垎浜岀淮鏁扮粍
+    chunk(arr,size = 1){
+      if(arr.length == 0) return;
+      const tempContainer = [];
+      let innerArr = [];
+      arr.forEach(item => {
+        if(innerArr.length == 0){
+          tempContainer.push(innerArr);
+        }
+        innerArr.push(item);
+        if(innerArr.length == size){
+          innerArr = [];
+        }
+      });
+      return tempContainer;
+    }
+  },
+  computed: {
+    slides() {
+      return this.chunk(this.mockSceneData,5);
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+
+.wrap-box {
+  width: 100%;
+  display: inline-block;
+  .inner {
+    width: 90%;
+    box-sizing: border-box;
+    position: relative;
+    font-size: 14px;
+    padding: 7px 0 48px;
+    transition: all 1s;
+    background: #ffffff;
+    border: 1px solid #e2e2e2;
+    box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+    border-radius: 4px;
+    margin: auto;
+    &:hover {
+      .mask {
+        display: block;
+      }
+    }
+    .mask {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background: rgba(0, 0, 0, 0.65);
+      backdrop-filter: blur(1px) brightness(100%);
+      text-align: center;
+      z-index: 1;
+      border-radius: 3px;
+      display: none;
+      .tool {
+        position: absolute;
+        top: 49%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+        i {
+          font-size: 50px;
+        }
+        i:nth-of-type(1) {
+          margin-right: 30px;
+        }
+        i:nth-of-type(2) {
+          color: red;
+        }
+      }
+    }
+    .scenario-icon {
+      display: flex;
+      width: 85%;
+      height: 85%;
+      margin: auto;
+      justify-content: center;
+      align-content: center;
+      align-items: center;
+      .single,
+      .double,
+      .third,
+      .four {
+        width: 80%;
+        padding-top: 80%;
+        position: relative;
+        margin: auto;
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+        .svg-wrap {
+          width: 47%;
+          position: absolute;
+          height: 0;
+          padding-top: 47%;
+          text-align: center;
+          box-shadow: 0 0 3px 2px rgb(247, 247, 247) inset;
+          svg {
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+          }
+        }
+      }
+      .single {
+        margin: auto;
+        .svg-wrap {
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+          box-shadow: none;
+        }
+      }
+      .double {
+        .svg-wrap:nth-of-type(1) {
+          top: 50%;
+          transform: translateY(-50%);
+          left: 0;
+        }
+        .svg-wrap:nth-of-type(2) {
+          top: 50%;
+          transform: translateY(-50%);
+          right: 0;
+        }
+      }
+      .third {
+        .svg-wrap:nth-of-type(1) {
+          top: 0;
+          left: 0;
+        }
+        .svg-wrap:nth-of-type(2) {
+          top: 0;
+          right: 0;
+        }
+        .svg-wrap:nth-of-type(3) {
+          top: 50%;
+          left: 50%;
+          transform: translateX(-50%);
+        }
+      }
+      .four {
+        .svg-wrap:nth-of-type(1) {
+          top: 0;
+          left: 0;
+        }
+        .svg-wrap:nth-of-type(2) {
+          top: 0;
+          right: 0;
+        }
+        .svg-wrap:nth-of-type(3) {
+          top: 50%;
+          left: 0;
+        }
+        .svg-wrap:nth-of-type(4) {
+          top: 50%;
+          right: 0;
+        }
+      }
+    }
+    .scenario-name {
+      width: 100%;
+      height: 30px;
+      box-sizing: border-box;
+      padding: 0 4px;
+      text-align: center;
+      position: absolute;
+      bottom: 10px;
+      left: 0;
+    }
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/cameraAccess/index/App.vue b/src/pages/cameraAccess/index/App.vue
new file mode 100644
index 0000000..d06b1f3
--- /dev/null
+++ b/src/pages/cameraAccess/index/App.vue
@@ -0,0 +1,307 @@
+<template>
+  <div class="s-video-manage">
+    <el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
+      <el-tab-pane
+        :label="firstLabeName"
+        name="camera-info"
+        v-if="this.TreeDataPool.treeActiveName == 'camera' && isShow('VIDEOCAMERA:camera:info')"
+      >
+        <camera-info ref="cameraInfo" />
+      </el-tab-pane>
+      <el-tab-pane
+        :label="firstLabeName"
+        name="camera-info"
+        v-if="this.TreeDataPool.treeActiveName == 'dataStack' && isShow('VIDEOCAMERA:dataStack:stackInfo')"
+      >
+        <data-stack-info ref="dataStackInfo" />
+      </el-tab-pane>
+      <el-tab-pane
+        label="鐙珛鍦烘櫙"
+        name="separate-rule"
+        v-if="this.TreeDataPool.treeActiveName == 'camera' && isShow('VIDEOCAMERA:camera:selfRule')"
+      >
+        <separate-rules ref="sepRule" />
+        <!-- <local-separate ref="localSeparate" v-else></local-separate> -->
+      </el-tab-pane>
+      <el-tab-pane
+        label="鐙珛鍦烘櫙"
+        name="separate-rule"
+        v-if="this.TreeDataPool.treeActiveName == 'dataStack' && isShow('VIDEOCAMERA:dataStack:selfRule')"
+      >
+        <separate-rules ref="sepRule" />
+        <!-- <local-separate ref="localSeparate" v-else></local-separate> -->
+      </el-tab-pane>
+      <el-tab-pane
+        label="鑱斿姩鍦烘櫙"
+        name="linkage-rule"
+        v-if="(isShow('VIDEOCAMERA:camera:linkRule') || isShow('VIDEOCAMERA:dataStack:linkRule')) && this.TreeDataPool.treeActiveName == 'camera'"
+      >
+        <linkage-rule ref="linkRule" />
+      </el-tab-pane>
+      <el-tab-pane
+        label="绠楀姏閰嶇疆"
+        name="poll-setting"
+        v-if="this.TreeDataPool.treeActiveName == 'camera' && isShow('VIDEOCAMERA:camera:resourceCalc')"
+      >
+        <poll-setting ref="pullSetting" />
+      </el-tab-pane>
+      <el-tab-pane
+        label="绠楀姏閰嶇疆"
+        name="poll-setting"
+        v-if="this.TreeDataPool.treeActiveName == 'dataStack' && isShow('VIDEOCAMERA:dataStack:resourceCalc')"
+      >
+        <poll-setting ref="pullSetting" />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+import CameraInfo from "@/components/camera/CameraInfo";
+import DataStackInfo from "@/components/camera/DataStackInfo"
+import SeparateRules from "@/components/camera/SeparateRules";
+import LinkageRule from "@/components/camera/LinkageRule";
+import PollSetting from "@/components/camera/PollSetting";
+// import fTemplate from "@/components/common/fTemplate";
+// import localSeparate from "@/components/camera/localSeparate";
+
+//import bus from "@/main";
+import TreeDataPool from "@/Pool/TreeData";
+
+export default {
+  components: {
+    CameraInfo,
+    DataStackInfo,
+    SeparateRules,
+    LinkageRule,
+    PollSetting
+  },
+  data() {
+    return {
+      activeName: "camera-info",
+      buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
+      intervalTimer: null
+    };
+  },
+  computed: {
+    isAdmin() {
+      if (
+        sessionStorage.getItem("userInfo") &&
+        sessionStorage.getItem("userInfo") !== ""
+      ) {
+        let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
+        return loginName === "superadmin" || loginName === "basic";
+      }
+      return false;
+    },
+    firstLabeName() {
+      return this.TreeDataPool.treeActiveName === "camera" ? "鎽勫儚鏈轰俊鎭�" : "鏁版嵁鏍堜俊鎭�"
+    }
+  },
+  watch: {
+    // 鏁版嵁鏍堜笉鏄剧ず鑱斿姩瑙勫垯锛岄槻姝㈠湪閫変腑鑱斿姩瑙勫垯tab涓垏鎹㈠埌鏁版嵁鏍�
+    "TreeDataPool.treeActiveName": function (val) {
+      if (val === "dataStack" && this.activeName === "linkage-rule") {
+        this.activeName = "camera-info";
+      }
+    },
+    "TreeDataPool.selectedNode": function (node) {
+      if (this.activeName == "camera-info") {
+        if (this.TreeDataPool.treeActiveName == 'camera') {
+          this.$refs.cameraInfo.selectCamera(node);
+        }
+      } else if (this.activeName === "separate-rule") {
+        this.$refs.sepRule.Camera = {}
+        this.$refs.sepRule.initCameraData(node.id);
+      }
+    },
+    "TreeDataPool.selectedNodes": {
+      handler(nodes) {
+        if (this.activeName == "linkage-rule") {
+          this.$refs.linkRule.initCameraData();
+        }
+      },
+      deep: true
+    },
+    "DataStackPool.selectedDir": {
+      handler(node, oldNode) {
+        console.log(this.activeName)
+        console.log(node, '鍕鹃�夋湰鍦拌棰�')
+        if (this.TreeDataPool.treeActiveName !== 'dataStack') {
+          return
+        }
+        this.$nextTick(() => {
+          if (this.activeName == "camera-info") {
+            console.log("dataStackInfo.selectDir(node)")
+            this.$refs.dataStackInfo.selectDir(node);
+          } else if (this.activeName == "separate-rule" && node.length !== 0) {
+            this.$refs.sepRule.initCameraData(node.id);
+          }
+        })
+      },
+      deep: true
+    }
+  },
+  created() {
+    if (this.TreeDataPool.treeActiveName == 'camera') {
+      if (this.isShow('VIDEOCAMERA:camera:info')) {
+        this.activeName = "camera-info"
+      } else if (this.isShow('VIDEOCAMERA:camera:selfRule') || this.isShow('VIDEOCAMERA:datastack:selfRule')) {
+        this.activeName = "separate-rule"
+      } else if (this.isShow('VIDEOCAMERA:camera:linkRule') || this.isShow('VIDEOCAMERA:datastack:linkRule')) {
+        this.activeName = "linkage-rule"
+      } else if (this.isShow('VIDEOCAMERA:camera:resourceCalc') || this.isShow('VIDEOCAMERA:datastack:resourceCalc')) {
+        this.activeName = "poll-setting"
+      }
+    } else {
+      if (this.isShow('VIDEOCAMERA:camera:info')) {
+        this.activeName = "camera-info"
+      } else if (this.isShow('VIDEOCAMERA:camera:selfRule') || this.isShow('VIDEOCAMERA:datastack:selfRule')) {
+        this.activeName = "separate-rule"
+      } else if (this.isShow('VIDEOCAMERA:camera:linkRule') || this.isShow('VIDEOCAMERA:datastack:linkRule')) {
+        this.activeName = "linkage-rule"
+      } else if (this.isShow('VIDEOCAMERA:camera:resourceCalc') || this.isShow('VIDEOCAMERA:datastack:resourceCalc')) {
+        this.activeName = "poll-setting"
+      }
+    }
+    this.TreeDataPool.readonly = true;
+    this.TreeDataPool.gbReadonly = true;
+    this.TreeDataPool.multiple = false;
+    this.TreeDataPool.selectedNode = "";
+    this.selectedNodes = [];
+    this.VideoManageData.init();
+  },
+  beforeDestroy() {
+    clearInterval(this.intervalTimer);
+    //this.TreeDataPool.treeActiveName = "camera";
+  },
+  mounted() {
+    this.$nextTick(() => {
+    //   bus.$on("addCameraOnTree", node => {
+    //     this.handAddDevice(node);
+    //   });
+    //   bus.$on("addDirOnTree", node => {
+    //     this.handAddDIr(node);
+    //   });
+    //   this.TreeDataPool.clean();
+    });
+
+    let _this = this
+    this.intervalTimer = setInterval(() => {
+      _this.PollData.statisticTaskInfo();
+    }, 10000)
+  },
+  methods: {
+    isShow(authority) {
+      if (this.isAdmin) {
+        return true;
+      } else if (this.buttonAuthority.indexOf("," + authority + ",") > -1) {
+        return true;
+      } else if ("videoCamera:pollSetting" === authority) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    handAddDevice(node) {
+      let _this = this;
+      setTimeout(() => {
+        _this.$refs.cameraInfo.addDevice(node);
+        _this.activeName = "camera-info";
+      }, 100);
+    },
+    handAddDIr(node) {
+      let _this = this;
+      setTimeout(() => {
+        _this.$refs.dataStackInfo.addDir(node);
+        _this.activeName = "camera-info";
+      }, 100);
+    },
+    handleClick(tab, event) {
+      this.TreeDataPool.multiple = tab.name === "linkage-rule";
+      if (tab.name === "camera-info") {
+        if (this.TreeDataPool.treeActiveName == 'camera') {
+          this.$refs.cameraInfo.selectCamera(this.TreeDataPool.selectedNode);
+        } else if (this.TreeDataPool.treeActiveName == 'dataStack') {
+          this.$refs.dataStackInfo.selectDir(this.DataStackPool.selectedDir);
+        }
+      } else if (tab.name === "separate-rule") {
+        if (this.TreeDataPool.treeActiveName == 'camera') {
+          this.$refs.sepRule.initCameraData(this.TreeDataPool.selectedNode.id);
+        } else if (this.TreeDataPool.treeActiveName == 'dataStack') {
+          this.$refs.sepRule.initCameraData(this.DataStackPool.selectedDir.id);
+        }
+      } else if (this.activeName == "linkage-rule") {
+        this.$refs.linkRule.initCameraData();
+      } else if (this.activeName == "poll-setting") {
+        this.$nextTick(() => {
+          this.$refs.pullSetting.initLineChart();
+        })
+      }
+    }
+  }
+};
+</script>
+<style lang="scss">
+.s-video-manage {
+  width: 100%;
+  height: 100%;
+  float: right;
+  box-sizing: border-box;
+  padding: 16px;
+  background-color: #e9ebf2;
+  .el-tabs--border-card {
+    box-shadow: none;
+    -webkit-box-shadow: none;
+    border: none;
+  }
+  // .s-video-manage-breadcrumb {
+  //   height: 5%;
+  //   -webkit-box-sizing: border-box;
+  //   border: 1px solid #e4e7ed;
+  //   -webkit-box-shadow: #e4e7ed 0px 0px 9px inset;
+  //   box-shadow: #e4e7ed 0px 0px 9px inset;
+  //   border-radius: 5px;
+  // }
+  .el-tabs--border-card {
+    height: 100%;
+    width: 100%;
+    .el-tabs__header {
+      .is-active {
+        color: #3d68e1 !important;
+      }
+      .el-tabs__item:not(.is-disabled):hover {
+        color: #3d68e1 !important;
+      }
+      height: 52px;
+      border-bottom: none;
+      background-color: #f8f9fb;
+      .el-tabs__nav-wrap,
+      .el-tabs__nav-scroll,
+      .el-tabs__nav,
+      .el-tabs__item {
+        height: calc(100% + 1px);
+      }
+      .el-tabs__item {
+        line-height: 52px;
+        width: 144px;
+        border-right-color: transparent;
+        border-left-color: transparent;
+        font-family: PingFangSC-Medium;
+        font-size: 14px;
+        color: #222222;
+      }
+    }
+  }
+  .el-tabs__content {
+    width: 100%;
+    height: calc(100% - 52px);
+    box-sizing: border-box;
+    padding: 13px 38px;
+  }
+  .el-tab-pane {
+    width: 100%;
+    height: 100%;
+  }
+}
+</style>
diff --git a/src/pages/cameraAccess/index/main.ts b/src/pages/cameraAccess/index/main.ts
new file mode 100644
index 0000000..80f18a4
--- /dev/null
+++ b/src/pages/cameraAccess/index/main.ts
@@ -0,0 +1,11 @@
+import Vue from 'vue'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import App from './App.vue'
+
+Vue.use(ElementUI)
+
+new Vue({
+  el: '#app',
+  render: h => h(App)
+})
diff --git a/src/pages/cameraAccess/index/mixins.ts b/src/pages/cameraAccess/index/mixins.ts
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/pages/cameraAccess/index/mixins.ts
diff --git a/src/pages/desktop/index/mock/userData.json b/src/pages/desktop/index/mock/userData.json
index 48afd61..300a8ea 100644
--- a/src/pages/desktop/index/mock/userData.json
+++ b/src/pages/desktop/index/mock/userData.json
@@ -32,7 +32,7 @@
         "src": "../../images/app-mid/camera-access.png",
         "alt": "camera-access",
         "type": "2",
-        "url": "/view/camera",
+        "url": "/view/cameraAccess",
         "name": "鎽勫儚鏈烘帴鍏�"
       },
       {
@@ -59,14 +59,7 @@
         "url": "/view/datapush",
         "name": "鏁版嵁鎺ㄩ��"
       },
-      {
-        "id": "6",
-        "src": "../../images/app-mid/scene-config.png",
-        "alt": "鍦烘櫙閰嶇疆",
-        "type": "2",
-        "url": "/view/scene",
-        "name": "鍦烘櫙閰嶇疆"
-      },
+    
       {
         "id": "7",
         "src": "../../images/app-mid/library.png",

--
Gitblit v1.8.0