wangmengwei hace 1 día
padre
commit
c3dfa26c4e
Se han modificado 25 ficheros con 9000 adiciones y 0 borrados
  1. 18 0
      ruoyi-ui/src/api/index.js
  2. BIN
      ruoyi-ui/src/assets/dog.jpeg
  3. BIN
      ruoyi-ui/src/assets/images/ceshi.png
  4. BIN
      ruoyi-ui/src/assets/images/huabu.png
  5. BIN
      ruoyi-ui/src/assets/images/icon_htgl_rljr.png
  6. BIN
      ruoyi-ui/src/assets/images/icon_hthp_kj_cssz.png
  7. BIN
      ruoyi-ui/src/assets/images/icon_hthp_kj_ssjc.png
  8. BIN
      ruoyi-ui/src/assets/images/icon_lby_gdtc_bj.png
  9. BIN
      ruoyi-ui/src/assets/images/icon_lby_gdtc_del.png
  10. BIN
      ruoyi-ui/src/assets/images/icon_lby_gx_normal.png
  11. BIN
      ruoyi-ui/src/assets/images/icon_lby_gx_selcted.png
  12. BIN
      ruoyi-ui/src/assets/images/pic_hp_zwsj.png
  13. BIN
      ruoyi-ui/src/assets/images/pic_htgl_zwxx.png
  14. BIN
      ruoyi-ui/src/assets/images/pic_spgj_spkx_normal.png
  15. BIN
      ruoyi-ui/src/assets/images/pic_spgj_spkx_selected.png
  16. BIN
      ruoyi-ui/src/assets/images/recording_20250626_210102_169_离岗.mp4
  17. 1419 0
      ruoyi-ui/src/views/shipinggaoj/shebecanshu/index - 副本.vue
  18. 430 0
      ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (2).vue
  19. 489 0
      ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (3).vue
  20. 1867 0
      ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (4).vue
  21. 1383 0
      ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (5).vue
  22. 440 0
      ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本.vue
  23. 1345 0
      ruoyi-ui/src/views/shipinggaoj/shishi/index - 副本.vue
  24. 1601 0
      ruoyi-ui/src/views/shipinggaoj/shishi/index.vue
  25. 8 0
      ruoyi-ui/src/views/shishijianc.vue

+ 18 - 0
ruoyi-ui/src/api/index.js

@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 统计
+export function warnManageIndex(query) {
+  return request({
+    url: '/manage/index/warnManageIndex',
+    method: 'get',
+    params: query
+  })
+}
+
+export function warnManageIndexYear(query) {
+  return request({
+    url: '/manage/index/warnManageIndexYear/' + query,
+    method: 'get',
+  })
+}
+

BIN
ruoyi-ui/src/assets/dog.jpeg


BIN
ruoyi-ui/src/assets/images/ceshi.png


BIN
ruoyi-ui/src/assets/images/huabu.png


BIN
ruoyi-ui/src/assets/images/icon_htgl_rljr.png


BIN
ruoyi-ui/src/assets/images/icon_hthp_kj_cssz.png


BIN
ruoyi-ui/src/assets/images/icon_hthp_kj_ssjc.png


BIN
ruoyi-ui/src/assets/images/icon_lby_gdtc_bj.png


BIN
ruoyi-ui/src/assets/images/icon_lby_gdtc_del.png


BIN
ruoyi-ui/src/assets/images/icon_lby_gx_normal.png


BIN
ruoyi-ui/src/assets/images/icon_lby_gx_selcted.png


BIN
ruoyi-ui/src/assets/images/pic_hp_zwsj.png


BIN
ruoyi-ui/src/assets/images/pic_htgl_zwxx.png


BIN
ruoyi-ui/src/assets/images/pic_spgj_spkx_normal.png


BIN
ruoyi-ui/src/assets/images/pic_spgj_spkx_selected.png


BIN
ruoyi-ui/src/assets/images/recording_20250626_210102_169_离岗.mp4


+ 1419 - 0
ruoyi-ui/src/views/shipinggaoj/shebecanshu/index - 副本.vue

@@ -0,0 +1,1419 @@
+<template>
+  <div class="app-container" style="padding-top: 20px;height: 120vh;" >
+    <div class="ntgs">
+    <el-row :gutter="10" class="mb8">
+     <div class="iuer" style="margin-bottom:10px;">
+       <!-- <div style="display: flex;align-items: center; " class="ingaqe">
+            <el-select v-model="queryParams.name" placeholder="请选监控名称" clearable>
+              <el-option
+                v-for="dict in postList"
+                :key="dict.indexCode"
+                :label="dict.name"
+                :value="dict.name"
+              />
+            </el-select>
+			<div class="ksfpofg" @click="handleQuery">
+						  搜索
+						  </div>
+       </div> -->
+	   <!-- <div class="ite">
+	      <div class="ksfpo" @click="osge"  v-hasPermi="['system:camera:openDz']">
+			  <img src="../../../assets/images/icon_ssjk_kman_open.png" alt="" style="width:10px;height: 10px;">
+			  开门</div>
+		  <div class="ksfpo ksfpok" @click="osgef" v-hasPermi="['system:camera:closeDz']">
+		  			  <img src="../../../assets/images/icon_ssjk_kman_close.png" alt="" style="width:10px;height: 10px;">
+		  			  关门</div>
+	   </div> -->
+<!--  -->
+     </div>
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['investigate:table:add']"
+        >新增</el-button>
+      </el-col>
+
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['investigate:table:remove']"
+        >删除</el-button>
+      </el-col> -->
+     <!-- <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['investigate:table:export']"
+        >导出</el-button>
+      </el-col> -->
+      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
+    </el-row>
+
+	<div>
+		<el-row :gutter="20">
+          <!-- postList -->
+					<el-col :span='5'>
+						<div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 100vh;">
+              <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">通道列表</p>
+              <div :class="ishge == index ? 'anche' : ''" style=" height: 36px;;line-height: 36px;margin-top: 10px;padding: 0 10px ;"v-for="(item,index) in channelNumberList" :key="index">
+                              <div  @click="ishg(item,index)" style="display: flex;align-items: center;justify-content: space-between;">
+                                <div style="font-size: 16px;
+              color: #333333;"> {{item.channelNum == null?'暂无数据' : item.channelNum}}</div>
+                                <img src="../../../assets/images/icon_htgl_zd.png" alt="" style="width: 10px;height: 12px;">
+                              </div>
+                          </div>
+              <div>
+
+              </div>
+
+            </div>
+					</el-col>
+        <!-- v-if="isshoe" -->
+        <el-col :span='19' style="padding-left: 30px; background-color: #fff;border-radius: 10px;padding: 20px; height: 100vh;" >
+          <div style="display: flex;align-items: center;justify-content: space-between;margin-bottom: 18px;">
+            <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">实时预览
+              <span style="font-size: 12px; color: red;cursor: pointer;" @click="xiazag">下载插件</span>
+              </p>
+            </p>
+            <div>
+
+              <!-- <el-button type="danger" plain>删除</el-button>
+              <el-button type="warning" plain>置顶</el-button> -->
+              <!-- <el-button type="success" plain>关闭</el-button> -->
+
+
+            </div>
+          </div>
+
+         <div style="width: 100%; height: 480px;">
+           <div v-if="isfse" id="divPlugin" style="width: 100%; height: 440px;" ></div>
+         </div>
+
+
+          <!-- <img src="../../../assets/images/pic_ssyl_lt.png" alt="" style="width: 100%; margin-top: 20px;"> -->
+          <!-- 344 -->
+          <!-- <video id="video" controls autoplay muted width="100%" height="480px"style="margin-top: 20px;"></video> -->
+        						<!-- <video
+        						      class="videosmall"
+        						      ref="videosmallone"
+        						      preload="auto"
+        						      muted
+        						      autoplay
+        							  width="95%"
+        						      type="rtmp/flv"
+        						    >
+        						      <source src="" />
+        						    </video> -->
+        					</el-col>
+
+
+			<!-- <el-col :span="24">
+				<div class="ihgswq wrapper"  ref="wrapper" style=" overflow: hidden;">
+						  <div class="fijge content nhgwesvq" ref="content" style="width:1610px;">
+									<div class='shotw '   v-for="(item,index) in postList" :key="index" @click="isfgw(item)" >
+											  <img src="../../../assets/images/fengm.png" alt="">
+												<img src="../../../assets/images/icon_spjk_play.png" alt="" class="iges">
+											  <p style="font-size: 14px;">{{item.name}}</p>
+									</div>
+						  </div>
+				</div>
+			</el-col> -->
+		</el-row>
+
+
+	  <!-- <pagination
+	     v-show="total>0"
+	     :total="total"
+	     :page.sync="queryParams.pageNo"
+	     :limit.sync="queryParams.pageSize"
+	     @pagination="getList"
+	   /> -->
+	</div>
+
+
+	</div>
+
+    <!-- 添加或修改岗位对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+
+    </el-dialog>
+
+    <el-dialog :title="titles" :visible.sync="opens" width="1000px" append-to-body>
+    </el-dialog>
+
+	<el-dialog title="页面二维码" :visible.sync="opent" width="200px" style="padding: 0;" class="nhgrls" append-to-body>
+	  <div v-show="opent" style="display: flex;justify-content: center;align-items: center;">
+		  <!-- <span>{{'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg}}</span> -->
+			   <!-- <vue-qr   :text="'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg" :size="200"></vue-qr> -->
+	  </div>
+	</el-dialog>
+  </div>
+</template>
+
+<script>
+  import { listChannelNumber, listChannelNumbernopa,getChannelNumber, delChannelNumber, addChannelNumber, updateChannelNumber } from "@/api/system/channelNumber"
+  import { listWarnManage, getWarnManage, delWarnManage, addWarnManage, updateWarnManage } from "@/api/manage/warnManage"
+// import { listPost, getPost, delPost, addPost, updatePost,updateFs,updateGx } from "@/api/kaoch/renyuan";
+// import { listReservat,camera,cameraIndexCode, listReservatd, getReservat, delReservat, addReservat, updateReservat,setPass,delReservathx,openDz,closeDz } from "@/api/tonggi/houtai";
+// import vueQr from "vue-qr";
+// import videojs from 'video.js'
+// import 'video.js/dist/video-js.css'
+// import {videoPlayer} from 'vue-video-player'
+// import 'videojs-flash'
+// import flvjs from 'flv.js/dist/flv.min.js'
+// import flvjs from "flv.js";
+import mqtt from 'mqtt';
+import { MqttClient } from 'mqtt'
+// 状态变量
+ // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
+ var client = MqttClient||null
+import Bscroll from "better-scroll";
+export default {
+  name: "Post",
+  dicts: ['sys_normal_disable','sys_yes_no','youke','tjzh','youkes','lafafen','fange','jluly'],
+  // components: {
+  //     vueQr,
+	 //  videoPlayer
+  //   },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+	  opent:false,
+	  bg:null,
+    titles:'',
+	editableTabsValue:'6',
+    opens:false,
+    // 通道管理表格数据
+    channelNumberList: [],
+	  imageUrl:'@/assets/logo/logo.png',
+	  printObj: {
+	           id: "nhgrew", // 这里是要打印元素的ID
+	           popTitle: "", // 打印的标题
+	         },
+	  pickerOptions:{
+	            disabledDate (time) {
+	              //disabledDate 文档上:设置禁用状态,参数为当前日期,要求返回 Boolean
+	              // return time.getTime() > Date.now()//选当前时间之前的时间
+	              return time.getTime() < Date.now()  - 8.64e7;//选当前时间之后的时间
+	            }
+	        },
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+	  checkedScoreDataDetails: [],
+	  scoreDataDetailsList:[],
+	  tabPosition:'left',
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 岗位表格数据
+      postList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize:500,
+		    name:null,
+        postCode: undefined,
+        postName: undefined,
+        status: undefined,
+        reservatType:undefined
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        receptionId: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+
+
+      },
+      ruless:{
+        visitName: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitPhone: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitNum: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitDate: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitTime: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+
+      },
+      forms:{},
+			tableMaxHeight:'200',
+      kje:0,
+      ksjegsg:[],
+	   Scroll: null,
+	   videoShow: false,
+	flvPlayer:null,
+	player: null,
+	name:null,
+	isshiwa:false,
+	isjfwe:{},
+	isshoe:false,
+   webRtcServer: null,
+   camera_ip: '127.0.0.1:8000',
+   g_iWndIndex:0,
+   iRtspPort:'',//预览中的ip
+   szDeviceIdentify:'',//ip_port,
+   isfse:false,
+
+   g_bEnableDraw:false,
+    // 所有绘制的图形
+    shapes: [],
+    // 禁用
+    isdisflag:false,
+    connectionStatus:'',
+    isConnected:false,
+    connecting:false,
+    messages:[{ type: 'sent' , content: '', timestamp: '' }],
+    messageToSend:[],
+    mqttConfig:{
+    	url: 'ws://13.229.167.76:1884/mqtt',
+    	topic: 'detection/rect'
+    },
+    mqttThemeName:{
+    	url: 'ws://13.229.167.76:1884/mqtt',
+    	topic: 'detection/rect'
+    },
+    ishge:0
+
+    };
+  },
+  created() {
+    this.isfse = false
+    // this.getList();
+    this.getListtd()
+  window.onresize = () => {
+  	      this.changeTableMaxHeight()
+  	    }
+  	    this.changeTableMaxHeight()
+
+  },
+  mounted() {
+  // this.toggleConnection()
+     // this.webRtcServer = new WebRtcStreamer('video', location.protocol + '//' + this.camera_ip)
+     //      //需要查看的rtsp地址,根据自己的摄像头传入对应的rtsp地址即可。注意:视频编码格式必须是H264的,否则无法正常显示,编码格式可在摄像头的后台更改
+     //      this.webRtcServer.connect('rtsp://admin:zxy123456@192.168.101.64:554/h264/ch1/main/av_stream')
+  	window.onresize = () => {
+  	          this.changeTableMaxHeight()
+  	        }
+  	        this.changeTableMaxHeight()
+
+		this.$nextTick(() => {
+		        this.initScroll()
+		    })
+  },
+
+   beforeDestroy() {
+      // this.destoryVideo()
+      if(WebVideoCtrl){
+        console.log(this.szDeviceIdentify)
+      	WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+        WebVideoCtrl.I_StopAllPlay()
+      	WebVideoCtrl.I_DestroyPlugin()
+        WebVideoCtrl.I_Resize()
+      }
+    },
+  methods: {
+    /** 查询通道管理列表 */
+    getListtd() {
+      this.loading = true
+      let queryParams = {}
+      listChannelNumbernopa().then(response => {
+        this.channelNumberList = response.rows
+        if(this.channelNumberList.length !=0){
+                  let snghs = this.channelNumberList[0].videoAddress.split('@')
+                  let snghst = snghs[1].split(':')
+                  let snsgduan = snghst[1].split('/')
+                   console.log(snghs,snghst,snsgduan)
+                  let sgse={'ip':snghst[0],'duank':snsgduan[0],
+                  'account':this.channelNumberList[0].account,
+                  'password':this.channelNumberList[0].password,
+                  'port':this.channelNumberList[0].port
+                  }
+           this.getVideo(sgse)
+           WebVideoCtrl.I_ShowPlugin()
+           this.loading = false
+        }
+        // getWarnManage(this.$route.query.id).then(response => {
+          // this.form = response.data
+        this.loading = false
+      })
+    },
+    clickEnableDraw() {
+        WebVideoCtrl.I_SetDrawStatus(true).then(() => {
+            this.g_bEnableDraw = true;
+            // showOPInfo("启用绘制成功!");
+        }, (oError) => {
+            // showOPInfo("启用绘制失败!", oError.errorCode, oError.errorMsg);
+        });
+    },
+    getdrawFn(){
+      this.isdisflag=!this.isdisflag;
+      if(this.isdisflag){
+        this.clickDisableDraw()
+      }else{
+        this.clickEnableDraw()
+      }
+    },
+    // 禁用多边形绘制
+    clickDisableDraw() {
+        WebVideoCtrl.I_SetDrawStatus(false).then(() => {
+            this.g_bEnableDraw = false;
+            // showOPInfo("禁用绘制成功!");
+            this.clickAddSnapPolygon()
+        }, (oError) => {
+            // showOPInfo("禁用绘制失败!", oError.errorCode, oError.errorMsg);
+        });
+    },
+    clickGetSnapPolygon() {
+      var that=this;
+        WebVideoCtrl.I_GetSnapPolygonInfo(this.g_iWndIndex).then((szXml) => {
+            console.log('获取图形:', szXml);
+            that.getpoint(szXml)
+        });
+    },
+    //获取x,y轴
+    getpoint(xmlString){
+      var that=this;
+        const parser = new DOMParser();
+            const xmlDoc = parser.parseFromString(xmlString, "text/xml");
+
+            // 获取所有 SnapPolygon 节点
+            const polygonNodes = xmlDoc.querySelectorAll("SnapPolygon");
+             var newArr=[];
+             var arr1=JSON.parse(JSON.stringify(this.shapes))
+            // 提取每个多边形的 id 和坐标点
+            this.polygons = Array.from(polygonNodes).map((polygonNode) => {
+              const id = polygonNode.querySelector("id").textContent;
+              const pointNodes = polygonNode.querySelectorAll("point");
+
+              const points = Array.from(pointNodes).map((pointNode) => ({
+                x: pointNode.querySelector("x").textContent,
+                y: pointNode.querySelector("y").textContent,
+              }));
+              var newobj={
+                id:id,
+                points:points
+              }
+              newArr.push(newobj)
+              // return { id, points };
+            });
+           this.shapes = arr1.map(item1 => {
+             const matchedItem = newArr.find(item2 => item2.id == item1.id);
+             return {
+               id: item1.id,
+               points: matchedItem ? matchedItem.points : item1.points
+             };
+           });
+        // this.shapes=JSON.parse(JSON.stringify(newArr))
+        this.messageToSend = this.shapes
+        this.sendMessage()
+        console.log(this.shapes)
+    },
+    toggleConnection(){
+      if (this.isConnected) {
+        // 断开连接
+        client.end()
+        this.isConnected= false
+        this.connectionStatus = 'Disconnected'
+        return
+      }
+
+      // 建立连接
+      this.connecting = true
+      try {
+        client= mqtt.connect(this.mqttConfig.url, {
+          clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
+          keepalive: 60,
+          clean: true,
+          connectTimeout: 4000,
+          reconnectPeriod: 1000
+        })
+        client.on('connect', () => {
+          this.isConnected = true
+          this.connectionStatus= 'Connected'
+          this.connecting = false
+          console.log(3)
+          // 订阅主题
+          client.subscribe(this.mqttConfig.topic, (err) => {
+            if (err) {
+              console.error('Subscribe error:', err)
+            }else{
+               console.log('成功订阅 detection/rect 主题!')
+            }
+
+          })
+        })
+        client.on('message', (topic, message) => {
+          // 接受信息
+          console.log(topic,message)
+          this.messages.unshift({
+            type: 'received',
+            content: message.toString(),
+            timestamp: new Date().toLocaleTimeString()
+          })
+        })
+        client.on('error', (err) => {
+          console.error('MQTT Error:', err)
+          this.connectionStatus= 'Error'
+          this.connecting = false
+        })
+      } catch (error) {
+        console.error('Connection error:', error)
+        this.connectionStatus= 'Error'
+        this.connecting = false
+      }
+    },
+    sendMessage(){
+      if (!client || !this.messageToSend) return
+      this.messageToSend = JSON.stringify(this.messageToSend)
+      console.log(this.messageToSend)
+      client.publish(this.mqttConfig.topic, this.messageToSend)
+      this.messages.unshift({
+        type: 'sent',
+        content: this.messageToSend,
+        timestamp: new Date().toLocaleTimeString()
+      })
+      this.messageToSend = []
+    },
+    // 添加图形,最多不超过16个图形
+    clickAddSnapPolygon() {
+      var that=this;
+        if (!this.g_bEnableDraw) {
+            return;
+        }
+        var shapes=JSON.parse(JSON.stringify(this.shapes))
+        let szId = 1; // 默认从 1 开始
+        if(shapes&&shapes.length>0){
+          const ids  = shapes.map(item => item.id).sort((a, b) => a - b);
+          for (const id of ids) {
+            if (id > szId) {
+              // 如果当前 id > szId,说明 szId 未被使用
+              break;
+            }
+            szId = Number(id) + 1; // 否则,继续检查下一个
+          }
+        }
+        if (!/^[1-9]\d*$/.test(szId)) {
+            alert("图形ID只能为正整数!");
+            return
+        }
+        if (Number(szId) > 32) {
+            alert("图形ID范围1-32!");
+            return
+        }
+        console.log(szId)
+        // var szName = encodeString($("#snapName").val());
+        var szName = '';
+        var szInfo={
+
+        }
+        var szInfo = "<?xml version='1.0' encoding='utf-8'?>";
+        szInfo += "<SnapPolygonList>";
+        szInfo += "<SnapPolygon>";
+        szInfo += "<id>" + szId + "</id>";          // [1, 32]
+        szInfo += "<polygonType>0</polygonType>"; //如果想绘制多边形,polygonType指需要改为1
+        szInfo += "<PointNumMax>17</PointNumMax>";  // [MinClosed, 17]
+        szInfo += "<MinClosed>4</MinClosed>";       // [4, 17]
+        szInfo += "<tips>#" + szId + "#" + szName + "</tips>";
+        szInfo += "<isClosed>false</isClosed>";
+        szInfo += "<color><r>0</r><g>255</g><b>0</b></color>";
+        szInfo += "<pointList/>";
+        szInfo += "</SnapPolygon>";
+        szInfo += "</SnapPolygonList>";
+
+        WebVideoCtrl.I_SetSnapPolygonInfo(this.g_iWndIndex, szInfo).then(() => {
+            // showOPInfo("添加图形成功!");
+            var obj={
+              id:szId,
+              points:[]
+            }
+            if(this.shapes&&this.shapes.length){
+              this.shapes.splice(Number(szId)-1,0,obj)
+            }else{
+              this.shapes.push(obj)
+            }
+        });
+        WebVideoCtrl.I_SetSnapDrawMode(this.g_iWndIndex, 2);
+    },
+    //删除图形
+    clickDelSnapPolygon(szId,idx) {
+        if (!this.g_bEnableDraw) {
+            return;
+        }
+
+        var aShapes = [];
+        aShapes.push({
+            polygonType: 0,
+            id: szId
+        });
+        this.shapes.splice(idx,1)
+        WebVideoCtrl.I_ClearSnapInfo(this.g_iWndIndex, aShapes);
+    },
+    // 清空图形
+    clickDelAllSnapPolygon() {
+        if (!this.g_bEnableDraw) {
+            return;
+        }
+        WebVideoCtrl.I_ClearSnapInfo(this.g_iWndIndex).then(() => {
+            // showOPInfo("清空图形成功!");
+             this.shapes=[];
+        }, (oError) => {
+            // showOPInfo("清空图形失败!", oError.errorCode, oError.errorMsg);
+        });
+    },
+
+
+
+    // 通道点击
+    ishg(val,row){
+      this.ishge = row
+      this.isfse = false
+      if(WebVideoCtrl){
+        console.log(this.szDeviceIdentify)
+        this.clickDelAllSnapPolygon()
+      	WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+        WebVideoCtrl.I_StopAllPlay()
+      	WebVideoCtrl.I_DestroyPlugin()
+        WebVideoCtrl.I_Resize()
+      }
+      let snghs = val.videoAddress.split('@')
+             let snghst = snghs[1].split(':')
+             let snsgduan = snghst[1].split('/')
+              console.log(snghs,snghst,snsgduan)
+             let sgse={'ip':snghst[0],'duank':snsgduan[0],
+             'account':val.account,
+             'password':val.password,
+             'port':val.port
+             }
+      this.getVideo(sgse)
+      WebVideoCtrl.I_ShowPlugin()
+      // this.clickStartRealPlay('192.168.101.64', '80',1, 0, 1);
+
+    },
+
+
+	  init(val) { //这个val 就是一个地址,例如: http://192.168.2.201:85/live/9311272c49b845baa2b2810ad9bf3f68.flv 这是个服务器返回给我的一个监控视频流地址
+	        setTimeout(() => { //使用定时器是因为,在mounted声明周期里调用,可能会出现DOM没加载出来的原因
+	          var videoElement = this.$refs.videosmallone; // 获取到html中的video标签
+			  this.isshiwa = true
+	          if (flvjs.isSupported()) {
+	          //因为我这个是复用组件,进来先判断 player是否存在,如果存在,销毁掉它,不然会占用TCP名额
+	            if (this.player !== null) {
+	              this.player.pause();
+	              this.player.unload();
+	              this.player.detachMediaElement();
+	              this.player.destroy();
+	              this.player = null;
+	            }
+	            this.player = flvjs.createPlayer( //创建直播流,加载到DOM中去
+	              {
+	                type: "flv",
+	                url: val, //你的url地址
+	                isLive: true, //数据源是否为直播流
+	                hasAudio: false, //数据源是否包含有音频
+	                hasVideo: true, //数据源是否包含有视频
+	                enableStashBuffer: true, //是否启用缓存区
+	              },
+	              {
+	                enableWorker: false, //不启用分离线程
+	                enableStashBuffer: false, //关闭IO隐藏缓冲区
+	                autoCleanupSourceBuffer: true, //自动清除缓存
+	                lazyLoad: false,
+	              }
+	            );
+				this.isshoe = true
+	            this.player.attachMediaElement(videoElement); //放到dom中去
+
+	            //!!!!!!这里需要注意,有的时候load加载完成不一定可以播放,要是播放不成功,用settimeout 给下面的this.player.play() 延时几百毫秒再播放
+	            // setTimeout(this.player.play(), 48000);
+				setTimeout(() =>{
+					//到时间时只执行一次就停止
+					this.player.load();//准备完成
+					this.player.play()
+					console.log('播放')
+				},900)
+	          }
+	        }, 500);
+	      },
+
+	  createVideo() {
+	        if (flvjs.isSupported()) {
+				console.log(1)
+	          var videoElement = document.getElementById('myFlvVideo')
+			  console.log(videoElement,flvjs)
+	          this.flvPlayer = flvjs.createPlayer(
+	            {
+	              type: 'application/x-mpegURL',
+	              isLive: true,
+	              hasAudio: false,
+	              url:'https://stream1.freetv.fun/86d463c0006da643e45e26b34875df87059dcba13e69d0a5471b185793c122a2.m3u8'
+	            },
+	            {
+	              cors: true, // 是否跨域
+	              enableWorker: false, // 是否多线程工作
+	              enableStashBuffer: false, // 是否启用缓存
+	              stashInitialSize: 400, // 缓存大小(kb)  默认384kb
+	              autoCleanupSourceBuffer: true // 是否自动清理缓存
+	            }
+	          )
+	          this.flvPlayer.attachMediaElement(videoElement)
+	          this.flvPlayer.load()
+	          this.flvPlayer.play()
+			  console.log(1244)
+	          // 报错重连
+	          this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
+	            console.log('errorType:', errType)
+	            console.log('errorDetail:', errDetail)
+	            if (this.flvPlayer) {
+	              this.destoryVideo()
+	              this.createVideo()
+	            }
+	          })
+	        }
+
+			console.log(this.flvPlayer.play())
+	      },
+	      destoryVideo() {
+	        this.player.pause()
+	        this.player.unload()
+	        this.player.detachMediaElement()
+	        this.player.destroy()
+	        this.player = null
+	      },
+
+	  initScroll() {
+	    	  // 给内层盒子设置宽度,不设置宽度的话无法滚动
+	    	  // let width = this.goods.length * 60
+	    	  // // 如果有外边距,可以这样写。需要去掉最后一个元素的外边距,在后面减一下
+	    	  // let width = this.goodslength * (60 + 10) - 10
+			  let width = 6 * (200 + 10) - 10
+	        // this.$refs.content.style.width = width + 'px'
+	        this.$nextTick(()=>{
+	          if(!this.Scroll) {
+	            this.Scroll = new Bscroll(this.$refs.wrapper,{
+	              click: true,      // 配置允许点击事件
+	              scrollX: true,    // 开启横向滚动
+	              eventPassthrough: 'vertical',  // 当设置 eventPassthrough 为 'vertical' 的时候,scrollY 无效
+				  mouseWheel: true,
+				  scrollbar: { // 滚动条, 要加相对位置
+				              fade: true
+				            }
+	            })
+	          } else {
+	            this.Scroll.refresh()     // 重新计算 better-scroll,当 DOM 结构发生变化的时确保滚动效果正常
+	          }
+	        })
+	      },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+	  this.opens = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+		receptionId:undefined,
+        receptionPhone:undefined,
+        // postSort: 0,
+        // status: "0",
+        receptionName: undefined
+      };
+      this.resetForm("form");
+    },
+
+	iszheg(event){
+	 console.log(event);
+
+
+	 // 校验身份证:
+	 console.log(reg.test(this.form.idCard),23741)
+	 		if ( reg.test(this.form.idCard)|| _IDre15.test(this.form.idCard)) {
+	 			// this.idea();
+	 			this.go(this.form.idCard);
+	 			// callback()
+	 		} else {
+	   if(ncjsle.test(this.form.idCard) || nhyeli.test(this.form.idCard)){
+	      console.log(3)
+	   }else{
+	     if(gnse.test(this.form.idCard)  ){
+	         console.log(4)
+	     }else{
+	       if(tw.test(this.form.idCard) || twe.test(this.form.idCard)){
+	         console.log(5)
+	       }else{
+	         this.$message.error('证件格式不正确');
+	       }
+	     }
+
+	   }
+	 		}
+	},
+	erw(row){
+		this.$router.push({
+		  path: '/reny/ewm',
+		  query:{
+			   'tenantId':row.investigateTableId
+			  }
+		})
+	},
+
+	hussar_17Click(val) {
+	        const _this = this
+	        var url =process.env.VUE_APP_BASE_API + 'pages/index/index?id=' + val.investigateTableId;
+			 console.log(url,this.$refs.canvas,6)
+			this.opent = true
+	        QRCode.toCanvas(
+	                      canvas,
+	                      url,//生成二维码的数据
+	                      {width: 100, height:100, margin: 1.5},//margin调整二维码的白边大小
+	                      function (error) {
+	                        if (error) {
+	                          console.log(error);
+	                        }
+	                      }
+	                    );
+
+	        // console.log(qrcode,987)
+	      },
+	/** 成绩_子添加按钮操作 */
+	handleAddScoreDataDetails() {
+
+	  let obj = {};
+	  obj.duty = "";
+	  obj.idCard = "";
+	  obj.phonenumber = "";
+	  obj.userName = "";
+	  this.scoreDataDetailsList.push(obj);
+	  console.log(this.scoreDataDetailsList)
+	},
+	/** 成绩_子删除按钮操作 */
+	handleDeleteScoreDataDetails() {
+	  if (this.checkedScoreDataDetails.length == 0) {
+	    this.$modal.msgError("请先选择要删除的数据");
+	  } else {
+	    const scoreDataDetailsList = this.scoreDataDetailsList;
+	    const checkedScoreDataDetails = this.checkedScoreDataDetails;
+	    this.scoreDataDetailsList = scoreDataDetailsList.filter(function(item) {
+	      return checkedScoreDataDetails.indexOf(item.index) == -1
+	    });
+	  }
+	},
+	/** 复选框选中数据 */
+	handleScoreDataDetailsSelectionChange(selection) {
+	  this.checkedScoreDataDetails = selection.map(item => item.index)
+	},
+	/** 成绩_子序号 */
+	rowScoreDataDetailsIndex({ row, rowIndex }) {
+	  row.index = rowIndex + 1;
+	},
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const postIds = row.recordId || this.ids;
+      delReservat(postIds).then(response => {
+       this.$modal.msgSuccess("操作成功");
+        this.getList();
+      });
+
+      // this.$modal.confirm('是否确认删除数据项?').then(function() {
+      //   return delPost(postIds);
+      // }).then(() => {
+      //   this.getList();
+      //   this.$modal.msgSuccess("删除成功");
+      // }).catch(() => {});
+    },
+    handleDeletehx(row) {
+      const postIds = row.reservatId || this.ids;
+      let nhg={}
+      nhg.reservatId = postIds
+      delReservathx(nhg).then(response => {
+       this.$modal.msgSuccess("操作成功");
+        this.getList();
+      });
+
+      // this.$modal.confirm('是否确认删除数据项?').then(function() {
+      //   return delPost(postIds);
+      // }).then(() => {
+      //   this.getList();
+      //   this.$modal.msgSuccess("删除成功");
+      // }).catch(() => {});
+    },
+	// 发送短信
+	handleUpdatefas(row){
+		updateFs(row).then(response => {
+		 this.$modal.msgSuccess("发送成功");
+		  // this.getList();
+		});
+	},
+	handleDeletegx(row){
+		updateGx(row).then(response => {
+		  this.$modal.msgSuccess("发送成功");
+		  // this.getList();
+		});
+	},
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('system/reservat/export', {
+        ...this.queryParams
+      }, `预约人员.xlsx`)
+    },
+		// 获取屏幕高度
+		showFilterForm () {
+		      this.filterActive = !this.filterActive
+		      this.changeTableMaxHeight()
+		    },
+		    changeTableMaxHeight () {
+		      let height = document.body.offsetHeight // 网页可视区域高度
+		      // if (this.filterActive) {
+		      //   this.tableMaxHeight = height - 320
+		      // } else {
+		        this.tableMaxHeight = height - 350
+		      // }
+		      console.log(height)
+		    },
+    // 播放摄像头
+    getVideo(row) {
+    	var that=this;
+       this.isfse  = true
+       console.log(row)
+    	this.initVideoPlay(row.ip, row.port, row.account, row.password,'divPlugin')
+    },
+    // 有插件
+    initVideoPlay(ip, port, username, password,id) {
+    	var that = this;
+    	var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
+    	var g_oLocalConfig = null; //本地配置
+    	// let ip = this.szIP //硬盘录像机ip
+    	// let port = this.szPort //默认为80端口
+    	// let username = this.szUsername //账号:
+    	// let password = this.szPassword // 密码
+    	var iRtspPort = ''
+    	// 1.初始化插件参数及插入插件
+    	WebVideoCtrl.I_InitPlugin({
+    		bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
+    		iWndowType: 1,
+    		bDebugMode: true,
+    		cbSelWnd: function(xmlDoc) {
+    			g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
+    			const szInfo = "当前选择的窗口编号:" + g_iWndIndex;
+    			this.g_iWndIndex = g_iWndIndex;
+    			console.log(szInfo, "szInfo");
+    		},
+    		cbDoubleClickWnd: function(iWndIndex, bFullScreen) {
+    			let szInfo = "当前放大的窗口编号:" + iWndIndex;
+    			if (!bFullScreen) {
+    				szInfo = "当前还原的窗口编号:" + iWndIndex;
+    			}
+    			// console.log(szInfo, "szInfo");
+    		},
+    		cbEvent: function(iEventType, iParam1, iParam2) {
+    			if (2 == iEventType) {
+    				// 回放正常结束
+    				console.log("窗口" + iParam1 + "回放结束!");
+    			} else if (-1 == iEventType) {
+    				console.log("设备" + iParam1 + "网络错误!");
+    			} else if (3001 == iEventType) {
+    				clickStopRecord(g_szRecordType, iParam1);
+    			}
+    		},
+    		//2.登录摄像头
+    		cbInitPluginComplete: function() {
+    			const oLiveView = {
+    				iProtocol: 1, // protocol 1:http, 2:https
+    				szIP: ip, // protocol ip
+    				szPort: port, // protocol port
+    				szUsername: username, // device username
+    				szPassword: password, // device password
+    				iStreamType: 1, // stream 1:main stream  2:sub-stream  3:third stream  4:transcode stream
+    				iChannelID: 1, // channel no
+    				bZeroChannel: false, // zero channel
+    			};
+    			// var swidth=Number((that.width*Number(that.scale))).toFixed(2)
+    			// var sheight=Number((that.height*Number(that.scale))).toFixed(2)
+    			// that.swidth=swidth
+    			// that.sheight=sheight
+    			WebVideoCtrl.I_InsertOBJECTPlugin(id).then(
+    				() => {
+    					// setTimeout(function(){
+    					// 	WebVideoCtrl.I_Resize(swidth,sheight)
+    					// },300)
+    					WebVideoCtrl.I_Login(
+    						oLiveView.szIP,
+    						oLiveView.iProtocol,
+    						oLiveView.szPort,
+    						oLiveView.szUsername,
+    						oLiveView.szPassword, {
+    							timeout: 3000,
+    							async: false,
+    							success: function(xmlDoc) {
+    								console.log(" 登录成功!");
+    								let a = ip
+    								let b = port
+    								setTimeout(function() {
+    									//延迟方法
+    									setTimeout(function() {
+    										//调用预览摄像头这里可以循环创建
+    										that.clickStartRealPlay(a, b,1, 0, 1);
+    										// that.clickStartRealPlay(a, b, 1, 1,2);
+    										// that.clickStartRealPlay(a, b, 1, 2,3);
+    										// clickStartRealPlay(a,b, 1, 3, 4);
+    										// clickStartRealPlay(a,b, 1, 4, 5);
+    										// clickStartRealPlay(a,b, 1, 5, 6);
+    										// clickStartRealPlay(a,b, 1, 6, 7);
+    										// clickStartRealPlay(a,b, 1, 7, 8);
+    									}, 1000);
+
+
+    									setTimeout(function() {
+    										// 获取通道 (如果多个摄像头需要获取多个通道需要调用)
+    										// getChannelInfo(a);
+    										//获取端口 (在这里获取RTSP 端口号 预览时传入)
+    										getDevicePort(a);
+    									}, 10)
+
+    								}, 10);
+    							},
+    							error: function(oError) {
+    								console.log(" 登录失败!", oError);
+    							},
+    						}
+    					);
+    					// 检查插件是否最新
+    					WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {
+    						if (bFlag) {
+    							alert(
+    								"检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!"
+    							);
+
+    						}
+    					});
+    				},
+    				() => {
+    					alert(
+    						"插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!"
+    					);
+
+    				}
+    			);
+
+    		},
+    	});
+    	// 3.获取通道
+    	function getChannelInfo(a) {
+    		var szDeviceIdentify = a,
+    			oSel = null; //通道列表
+    		if (null == szDeviceIdentify) {
+    			return;
+    		}
+
+    		// 模拟通道 有
+    		WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("VideoInputChannel");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text();
+    					if ("" == name) {
+    						name = "Camera " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+
+    					// console.log(id + "通道id是")
+    					// console.log(name + "通道name是")
+    				});
+    				console.log(szDeviceIdentify + " 获取模拟通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取模拟通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    		// 数字通道
+    		WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text(),
+    						online = $(this).find("online").eq(0).text();
+    					if ("false" == online) { // 过滤禁用的数字通道
+    						return true;
+    					}
+    					if ("" == name) {
+    						name = "IPCamera " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+    				});
+    				console.log(szDeviceIdentify + " 获取数字通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取数字通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    		// 零通道
+    		WebVideoCtrl.I_GetZeroChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("ZeroVideoChannel");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text();
+    					if ("" == name) {
+    						name = "Zero Channel " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+    					if ("true" == $(this).find("enabled").eq(0).text()) { // 过滤禁用的零通道
+
+    					}
+    				});
+    				console.log(szDeviceIdentify + " 获取零通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取零通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    	};
+
+    	//4.获取端口
+    	function getDevicePort(a) {
+    		var szDeviceIdentify = a;
+
+    		if (null == szDeviceIdentify) {
+    			return;
+    		}
+    		WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then((oPort) => {
+    			// console.log(oPort.iDevicePort + "iDevicePort的值是")
+    			// console.log(oPort.iRtspPort + "iRtspPort的值是")
+    			console.log(szDeviceIdentify + " 获取端口成功!");
+    			iRtspPort = oPort.iRtspPort
+    			that.iRtspPort = iRtspPort
+    		}, (oError) => {
+    			var szInfo = "获取端口失败!";
+    			console.log(szDeviceIdentify + szInfo, oError.errorCode, oError.errorMsg);
+    		});
+    	};
+    },
+    // 5.开始预览
+    clickStartRealPlay(szIP, szPort, iStreamType, iWndIndex, iChannelID) {
+      var that=this;
+    	var oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex),
+    		szDeviceIdentify = szIP + "_" + szPort, //ip
+    		iChannelID = iChannelID,
+    		bZeroChannel = false,
+    		iPort = this.iRtspPort,
+    		szInfo = "";
+    	iStreamType = iStreamType;
+    	if (null == szDeviceIdentify) {
+    		return null;
+    	}
+    	this.szDeviceIdentify = szDeviceIdentify;
+    	var startRealPlay = function() {
+    		WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
+    			iStreamType: iStreamType,
+    			iChannelID: iChannelID,
+    			bZeroChannel: bZeroChannel,
+    			iWndIndex: iWndIndex, //要播放的窗口
+    			iPort: iPort, //如果多个摄像头需要必填 (RTSP 端口号)
+    			success: function() {
+    				szInfo = "开始预览窗口" + iWndIndex + "成功!";
+    				console.log(szDeviceIdentify + " " + szInfo);
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 开始预览窗口" + iWndIndex + "失败!", oError
+    					.errorCode, oError.errorMsg);
+    			}
+    		});
+    	};
+
+    	if (oWndInfo != null) { // 已经在播放了,先停止
+    		WebVideoCtrl.I_Stop({
+    			success: function() {
+    				startRealPlay();
+    			}
+    		});
+    	} else {
+    		startRealPlay();
+    	}
+    },
+    xiazag(){
+    var loadUrl = 'http://172.28.195.154:15010/prod-api/profile/HCWebSDKPluginsUserSetup.exe'
+    window.open(loadUrl, );
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+	.isjses{
+		.el-tabs--left .el-tabs__nav-wrap.is-left::after{
+			width:6px;
+		}
+		.el-tabs--left .el-tabs__active-bar.is-left,{
+			width:6px;
+		}
+	}
+	.ingaqe{
+		.el-input--medium{
+			width:100%;
+		}
+	}
+	.nhgrls{
+		.el-dialog__body{
+			padding: 0;
+		}
+	}
+  .hyr{
+    span{
+      text-decoration:underline;
+    }
+  }
+</style>
+<style scoped lang="scss">
+	.nghwgq{
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		margin-top: 90px;
+		div{
+			color:#aaa;
+		}
+	}
+	.ihgswq{
+		// width:100%;
+		// overflow-x: hidden;
+		// margin-top: 30px;
+	}
+	.fijge{
+		// width: 110%;
+		display: flex;
+		display: -webkit-flex;
+		justify-content: space-between;
+		.shotw{
+			position: relative;
+			// width:32%;
+			width: 238px;
+			height: 140px;
+			margin-left: 0;
+			margin-right: 20px;
+			margin-bottom: 15px;
+			img{
+				height: 100%;
+				cursor:pointer;
+			}
+		  p{
+			  // bottom:-10px;
+			  margin: 0;
+			  font-weight: bold;
+			  font-size: 16px;
+			   padding: 5px  10px;
+			   cursor:pointer;
+		  }
+		  .iges{
+			position: absolute;
+			top:50%;
+			left:50%;
+			width:30px;
+			height: 30px;
+			transform: translate(-50%,-50%);
+			cursor:pointer;
+		  }
+		}
+	}
+	.nhgwesvq{
+		width:1610px !important;
+	}
+	.shotw{
+		position: relative;
+		margin-left: -20px;
+		margin-right: -20px;
+		img{
+			width:100%;
+			height: 80vh;
+		}
+	  p{
+	     position: absolute;
+		 bottom: 0;
+		 left:0;
+		 background-color: rgba(0, 0, 0, .5);
+		 width: 100%;
+		 padding: 13px  5px;
+		 color:#fff;
+		 font-weight: bold;
+		 font-size: 18px;
+	  }
+	  .p{
+		  top:0px;
+		  height: 60px;
+		  margin: 0;
+		  padding-left: 20px;
+	  }
+	}
+
+
+	.ksfpo{
+		background-color: #3464EB;
+		padding: 6px 12px;
+		border-radius: 4px ;
+		color:#fff;
+		cursor:pointer;
+	}
+	.ksfpok{
+		background-color: #FFFFFF;
+		padding: 5px 11px;
+		border-radius: 4px;
+		color:#3464EB;
+		border: 1px solid #3464EB;
+		margin-left: 10px;
+		cursor:pointer;
+	}
+	.ksfpofg{
+		background-color: #75DB75;
+		padding: 5px 11px;
+		border-radius: 4px;
+		color:#FFFFFF;
+		border: 1px solid #75DB75;
+		margin-left: 10px;
+		cursor:pointer;
+	}
+  .iuer{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .ite{
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      p{
+        cursor:pointer;
+        margin: 0;
+        font-size: 15px;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color:#666666;
+        padding: 4px 12px;
+        background: #Fff;
+        border-radius: 4px;
+        margin-right: 20px;
+		position: relative;
+      }
+      .actt{
+        background: #fff;
+        // border-bottom: 3px solid #5974E0;
+        // border-radius: 0;
+		// border-bottom-right-radius: 4px;
+        color: #5974E0;
+      }
+	  .actt{
+		    &::after {
+		          content: "";
+		          width: 40%;
+		          height: 5px;
+				  border-radius: 3px;
+		          transform: translate(-50%);
+		          background-color: #5974E0;
+		          position: absolute;
+		          left: 50%;
+		          bottom:-3px;
+		        }
+
+	  }
+
+    }
+  }
+  .lqw{
+    padding: 0 10px;
+    margin: 0;
+    margin-bottom: 20px;
+  }
+.nhgel{
+  height: 170px;
+  background-color: #313b61;
+  width: 100%;
+  position: absolute;
+  top:0;
+  left:0;
+  z-index: 0;
+}
+	.app-container{
+		background-color: #f3f4f6;
+		padding-top: 10px;
+		height: 180vh;
+
+	}
+	.ntgs{
+	position: relative;
+		// background-color: #fff;
+		padding: 5px;
+		// border-radius: 5px;
+		padding-top: 10px;
+	     padding: 10px 20px;
+		.pagination-container{
+			height: 50px;
+		}
+	}
+	.nghfs{
+	position: relative;
+		background-color: #fff;
+		padding-top: 18px !important;
+		padding: 5px;
+		// border-radius: 5px;
+		// margin-bottom: 20px;
+	}
+	.ksf{
+		img{
+			width:100%;
+			height: 100%;
+		}
+	}
+   .ingwfaq{
+	   font-weight: bold;
+	   font-size: 16px;
+   }
+.dflex{display: flex;}
+.dflext{display: flex;align-items: flex-start;}
+.drawings-list{width: 100%;flex: 0 0 auto;padding-left: 10px;line-height:36px ;
+  .delimg{width: 15px;height: 15px;margin-left: 5px;}
+  .txt{font-size: 12px;padding-left: 5px;flex: 1;}
+  .tflex{display: flex;align-items: center;}
+}
+.disbtn{display: flex;align-items: center;flex: 0 0 auto;min-height: 34px;cursor: pointer;
+  img{width: 14px;height: 14px;margin-right: 10px;}
+  font-weight: 500;
+  font-size: 14px;
+  color: #444444;
+}
+.anche{
+  background: #E7F1EE !important;
+  border-radius: 4px  !important;
+}
+</style>

+ 430 - 0
ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (2).vue

@@ -0,0 +1,430 @@
+<template>
+  <div>
+    <div id="test" style="user-select: none;">
+      <!-- <button @click="fangda">放大</button>
+       <button @click="suoxiao">缩小</button> -->
+       <button @click="gai" v-show="isTrue">添加</button>
+       <button @click="mouseOver2" >移动</button>
+
+       <div class="content">
+         <div
+           :style="{
+             transform: 'scale(' + num + ')',
+             position: 'relative',
+             width: '100%',
+             height: '100%',
+           }"
+           @mousedown="moveMouse"
+           @click="getOffect"
+         >
+           <div
+             :class="
+               'biaozhu' + index == 'biaozhu' + b_i
+                 ? 'biaozhu b_border'
+                 : 'biaozhu'
+             "
+             :ref="'biaozhu' + index"
+             @mousedown.stop="move"
+             @click="handelClick(index)"
+             v-for="(item, index) in boxArry"
+             :key="index"
+             :style="{
+               width: item.width + 'px',
+               height: item.height + 'px',
+               position: 'absolute',
+               left: item.left + 'px',
+               top: item.top + 'px',
+               background: 'rgba(43,100,206,0.3)',
+               border: 'none',
+             }"
+           >
+             <div class="r_b" @mousedown="mouseMove11" v-if="b_i == index"></div>
+           </div>
+           <div
+             :style="{
+               height: biaozhuHeight + 'px',
+               width: biaozhuWidth + 'px',
+               top: biaozhuTop + 'px',
+               left: biaozhuLeft + 'px',
+               position: 'absolute',
+               background: 'rgba(43,100,206,0.3)',
+             }"
+           ></div>
+           <img
+             style="width: 100%; height: 100%; pointer-events: none;"
+             src="https://img1.baidu.com/it/u=3898911181,4093953224&fm=253&fmt=auto&app=138&f=JPEG?w=600&h=400"
+             alt=""
+             @mousedown="isTrue ? null : move"
+           />
+         </div>
+       </div>
+    </div>
+  </div>
+</template>
+<script>
+// import mqttHandle from "../../../utils/mqttHandler.js"
+import mqtt from 'mqtt';
+import { MqttClient } from 'mqtt'
+// 状态变量
+ // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
+ var client = MqttClient||null
+ export default {
+  data() {
+    return {
+      num: 1,
+      boxArry: [],
+      boxArryzs:[],
+      isTrue: false,
+      width: "",
+      height: "",
+      left: "",
+      top: "",
+      b_i: "",
+      biaozhuHeight: 0,
+      biaozhuWidth: 0,
+      biaozhuTop: 0,
+      biaozhuLeft: 0,
+    };
+  },
+
+  methods: {
+    getVuex() {
+      console.log(this.$store.state.treeData);
+    },
+    commitVuex() {
+      this.$store.commit("changeTreeData", { a: 1, b: 2 });
+
+    },
+    mouseOver2(e) {
+      document.onmousedown = (e) => {
+        let odiv = e.target; //获取目标元素
+        //算出鼠标相对元素的位置
+        let disX = e.clientX - odiv.offsetLeft;
+        let disY = e.clientY - odiv.offsetTop;
+        let left = e.clientX - disX;
+        let top = e.clientY - disY;
+        //绑定元素位置到positionX和positionY上面
+        this.positionX = top;
+        this.positionY = left;
+        console.log(this.boxArry,this.boxArryzs, this.dragsIndex);
+        //移动当前元素
+        this.boxArry[this.b_i].width = left;
+        this.boxArry[this.b_i].height = top;
+      };
+    },
+    drags(e) {
+      console.log(e);
+    },
+    mouseMove11(e) {
+      // console.log(e,index)
+      let odiv = e.target; //获取目标元素
+
+      //算出鼠标相对元素的位置
+      let disX = e.clientX - odiv.offsetLeft;
+      let disY = e.clientY - odiv.offsetTop;
+      // debugger;
+      e.target.onmousemove = (e) => {
+        //鼠标按下并移动的事件
+        //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
+        // console.log('aaaaaaaaaaaaa',e)
+        let left = e.clientX - disX;
+        let top = e.clientY - disY;
+
+        //绑定元素位置到positionX和positionY上面
+        this.positionX = top;
+        this.positionY = left;
+        // console.log(this.boxArry,this.dragsIndex)
+        //移动当前元素
+        this.boxArry[this.b_i].width = left;
+        this.boxArry[this.b_i].height = top;
+        e.target.onmouseup = (e) => {
+          e.target.onmousemove = null;
+
+          // document.onmouseup = null;
+        };
+      };
+    },
+    gai() {
+      this.isTrue = !this.isTrue;
+    },
+    getOffect(e) {
+      console.log(e);
+      document.onmouseup = null;
+      // this.left=e.offsetX
+      //     this.top=e.offsetY
+    },
+    moveMouse(e) {
+      let odiv = e.target; //获取目标元素
+
+      //算出鼠标相对元素的位置
+      let disX = e.clientX - odiv.offsetLeft;
+      let disY = e.clientY - odiv.offsetTop;
+      console.log(disX, disY);
+      if (this.isTrue) {
+        // 拖动
+        document.onmousemove = (e) => {
+          //鼠标按下并移动的事件
+          //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
+          let left = e.clientX - disX;
+          let top = e.clientY - disY;
+
+          //绑定元素位置到positionX和positionY上面
+          this.positionX = top;
+          this.positionY = left;
+
+          //移动当前元素
+          odiv.style.left = left + "px";
+          odiv.style.top = top + "px";
+        };
+        document.onmouseup = (e) => {
+          document.onmousemove = null;
+          document.onmouseup = null;
+        };
+      } else {
+        // 添加div
+
+        console.log(e);
+        document.onmousemove = (e) => {
+          //鼠标按下并移动的事件
+          //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
+
+          let left = disX - odiv.getBoundingClientRect().x;
+          let top = disY - odiv.getBoundingClientRect().y;
+
+          console.log(e.target.offsetLeft);
+          this.width = (e.clientX - disX) / this.num;
+          this.height = (e.clientY - disY) / this.num;
+          this.biaozhuWidth = this.width;
+          this.biaozhuHeight = this.height;
+          this.biaozhuLeft = left;
+          this.biaozhuTop = top;
+          document.onmouseup = (e) => {
+            let left = disX - odiv.getBoundingClientRect().x;
+            let top = disY - odiv.getBoundingClientRect().y;
+            this.width = (e.clientX - disX) / this.num;
+            this.height = (e.clientY - disY) / this.num;
+            console.log(e.target.getBoundingClientRect(), disX, disY);
+            if (this.width > 5 && this.height > 5) {
+              this.boxArry.push({
+                width: this.width,
+                height: this.height,
+                left: left,
+                top: top,
+              });
+              let szId = 1; // 默认从 1 开始
+              if (this.boxArryzs && this.boxArryzs.length > 0) {
+                const ids = this.boxArryzs.map(item => item.id).sort((a, b) => a - b);
+                for (const id of ids) {
+                  if (id > szId) {
+                    // 如果当前 id > szId,说明 szId 未被使用
+                    break;
+                  }
+                  szId = Number(id) + 1; // 否则,继续检查下一个
+                }
+              }
+              console.log(szId)
+              let obj = {
+                points:{},
+                id:szId,
+                width: this.width,
+                height: this.height,
+                left: left,
+                top: top,
+              }
+              if (this.boxArryzs && this.boxArryzs.length) {
+                this.boxArryzs.splice(Number(szId) - 1, 0, obj)
+              } else {
+                this.boxArryzs.push(obj)
+              }
+            }
+
+            this.biaozhuWidth = 0;
+            this.biaozhuHeight = 0;
+            this.biaozhuLeft = 0;
+            this.biaozhuTop = 0;
+            document.onmousemove = null;
+            document.onmouseup = null;
+          };
+        };
+      }
+    },
+    move(e) {
+      let odiv = e.target; //获取目标元素
+
+      //算出鼠标相对元素的位置
+      let disX = e.clientX - odiv.offsetLeft;
+      let disY = e.clientY - odiv.offsetTop;
+      document.onmousemove = (e) => {
+        //鼠标按下并移动的事件
+        //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
+        let left = e.clientX - disX;
+        let top = e.clientY - disY;
+
+        //绑定元素位置到positionX和positionY上面
+        this.positionX = top;
+        this.positionY = left;
+
+        //移动当前元素
+        odiv.style.left = left + "px";
+        odiv.style.top = top + "px";
+      };
+      document.onmouseup = (e) => {
+        document.onmousemove = null;
+        document.onmouseup = null;
+      };
+    },
+
+    fangda() {
+      this.num += 0.1;
+    },
+    suoxiao() {
+      this.num -= 0.1;
+    },
+    tianjia() {
+      this.boxArry.push({
+        width: 100,
+        height: 100,
+        left: 20,
+        top: 20,
+      });
+    },
+    handelClick(i) {
+      this.b_i = i;
+      console.log(i);
+    },
+    dragstart(event, data) {
+      // console.log('drag')
+      // event.dataTransfer.setData('item', data)
+    },
+    dragend(event) {
+      // event.dataTransfer.clearData()
+    },
+  },
+  savePoints() {
+    // 将画布坐标数据转换成提交数据
+    let objectPoints = [];
+    // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+    objectPoints = this.drawedPoints.map((area) => {
+      let polygon = {};
+      area.forEach((point, i) => {
+        polygon[`x${i + 1}`] = Math.round(point[0] * this.ratio);
+        polygon[`y${i + 1}`] = Math.round(point[1] * this.ratio);
+      });
+      // console.log(polygon)
+      return {
+        polygon: polygon,
+      };
+    });
+    this.submitData = objectPoints;
+    console.log("最终提交数据", objectPoints);
+    this.messageToSend = this.submitData
+    // this.sendMessage()
+    // this.$router.go(-1)
+  },
+  directives: {
+    drag: function (el) {
+      let dragBox = el; //获取当前元素
+      dragBox.onmousedown = (e) => {
+        //算出鼠标相对元素的位置
+        let disX = e.clientX - dragBox.offsetLeft;
+        let disY = e.clientY - dragBox.offsetTop;
+        console.log(disX, disY);
+        document.onmousemove = (e) => {
+          //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
+          let left = e.clientX - disX;
+          let top = e.clientY - disY;
+          //移动当前元素
+          dragBox.style.left = left + "px";
+          dragBox.style.top = top + "px";
+          console.log(left, top, "111111111");
+        };
+        document.onmouseup = (e) => {
+          //鼠标弹起来的时候不再移动
+          document.onmousemove = null;
+          //预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
+          document.onmouseup = null;
+        };
+      };
+    },
+  },
+ };
+
+</script>
+<style lang="scss" scoped>
+  #test {
+   .el-dialog__body {
+     padding: 10px 20px !important;
+   }
+   .content {
+     width: 800px;
+     height: 500px;
+     background: red;
+     margin: 0 auto;
+     overflow: hidden;
+     position: relative;
+
+     .drag_box {
+       width: 150px;
+       height: 90px;
+       border: 1px solid #666;
+       background-color: #ccc;
+       /* 使用定位,脱离文档流 */
+       position: relative;
+       top: 100px;
+       left: 100px;
+       /* 鼠标移入变成拖拽手势 */
+       cursor: move;
+       z-index: 3000;
+     }
+     .b_border {
+       border: 1px solid red !important;
+     }
+     .biaozhu {
+       z-index: 9999999;
+     }
+     .r_b {
+       position: absolute;
+       right: 0;
+       bottom: 0;
+       width: 20px;
+       height: 20px;
+       background: red;
+     }
+     .r_b:hover {
+       cursor: se-resize;
+     }
+   }
+  }
+.tool-box {
+  width: 98%;
+  height: 40px;
+  padding: 5px 30px;
+  margin: 20px auto 0;
+  box-sizing: border-box;
+  text-align: right;
+}
+.canvas-wrap {
+  // width: 80vw;
+  // height: 45vw;
+  width:88%;
+  height: 33.75vw;
+  margin: 0px auto;
+  background-color: #000; //#fff;
+  border: 3px;
+  border-color: #333;
+  position: relative;
+}
+#imgCanvas,
+#drawCanvas,
+#saveCanvas {
+  background: rgba(255, 0, 255, 0);
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+#drawCanvas {
+  z-index: 2;
+}
+</style>
+

+ 489 - 0
ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (3).vue

@@ -0,0 +1,489 @@
+<template>
+  <div>
+    <div class="tool-box" style="display: flex;justify-content: space-between;align-items: center;">
+      <div>
+        <p style="margin: 0;font-size: 13px;color: #FF6969;">点击绘制按钮开始绘制(黑边框内不可绘制,需在图片内绘制),单击鼠标左键即是当前点绘制完成可绘制下一个点, 双击鼠标左键即本次绘制完成。</p>
+      </div>
+      <div>
+        <el-button
+          size="mini"
+          :type="isDrawing ? 'warning' : 'primary'"
+          @click="startDraw"
+          >绘制区域</el-button
+        >
+
+        <el-button
+          size="mini"
+          type="danger"
+          :disabled="isDrawing"
+          @click="clearAll"
+          >全部清除</el-button
+        >
+        <el-button
+          size="mini"
+          type="success"
+          :disabled="isDrawing"
+          @click="savePoints"
+          >保存</el-button
+        >
+      </div>
+    </div>
+    <div class="canvas-wrap" style="width: 650px;height: 70vh;">
+      <canvas class="anseca" id="imgCanvas"   ref="canvaxbox"></canvas>
+      <!--用来和鼠标进行交互操作的canvas-->
+      <canvas
+        id="drawCanvas"
+        ref="canvas"
+        class="anseca"
+        :style="{ cursor: isDrawing ? 'crosshair ' : 'default' }"
+      >
+      </canvas>
+      <!--存储已生成的点线,避免被清空-->
+      <canvas  class="anseca"  id="saveCanvas" ref="canvasSave"></canvas>
+    </div>
+  </div>
+</template>
+<script>
+// import mqttHandle from "../../../utils/mqttHandler.js"
+import mqtt from 'mqtt';
+import { MqttClient } from 'mqtt'
+// 状态变量
+ // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
+ var client = MqttClient||null
+export default {
+  data() {
+    return {
+      imgUrl: "../../../assets/images/pic_ssyl_lt.png",
+      isDrawing: false, // 是否正在绘制
+      ratio: 1,
+      imgWidth: 3020,
+      imgHeight: 1080,
+      wrapWidth: 600,
+      wrapHeight: 300,
+      canvasWidth: 600,
+      canvasHeight: 300,
+      drawingPoints: [],
+      drawedPoints: [],
+      imgCanvas: null,
+      imgCtx: null,
+      drawCanvas: null,
+      drawCtx: null,
+      saveCanvas: null,
+      saveCtx: null,
+      submitData: [
+        // {"polygon":{"x1":0,"y1":0,"x2":1920,"y2":0,"x3":1920,"y3":1080,"x4":0,"y4":1080}},
+        // {
+        //   polygon: {
+        //     x1: 700,
+        //     y1: 273,
+        //     x2: 975,
+        //     y2: 278,
+        //     x3: 1107,
+        //     y3: 368,
+        //     x4: 718,
+        //     y4: 354,
+        //   },
+        // },
+        // {
+        //   polygon: {
+        //     x1: 49,
+        //     y1: 32,
+        //     x2: 183,
+        //     y2: 35,
+        //     x3: 181,
+        //     y3: 100,
+        //     x4: 55,
+        //     y4: 97,
+        //   },
+        // },
+        // {
+        //   polygon: {
+        //     x1: 433,
+        //     y1: 250,
+        //     x2: 706,
+        //     y2: 253,
+        //     x3: 707,
+        //     y3: 392,
+        //     x4: 435,
+        //     y4: 393,
+        //   },
+        // },
+        // {
+        //   polygon: {
+        //     x1: 45,
+        //     y1: 539,
+        //     x2: 193,
+        //     y2: 538,
+        //     x3: 192,
+        //     y3: 622,
+        //     x4: 41,
+        //     y4: 623,
+        //     x5: 42,
+        //     y5: 623,
+        //   },
+        // },
+      ],
+      connectionStatus:'',
+      isConnected:false,
+      connecting:false,
+      messages:[{ type: 'sent' , content: '', timestamp: '' }],
+      messageToSend:[],
+      mqttConfig:{
+      	url: 'ws://13.229.167.76:1884/mqtt',
+      	topic: 'detection/rect'
+      },
+      mqttThemeName:{
+      	url: 'ws://13.229.167.76:1884/mqtt',
+      	topic: 'detection/rect'
+      },
+      // [
+      //   {"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354}}
+      // ]
+    };
+  },
+  created() {
+
+    // console.log(JSON.parse(this.$route.query.src))
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.initCanvas();
+      this.getImage();
+    });
+    // this.toggleConnection()
+    // this.mqttzz()
+    // setTimeout(() => {
+    // }, 500);
+  },
+  methods: {
+    // 创mqtt最终版
+    mqttzz(){
+      // 创建一个连接到MQTT broker的客户端实例
+         // 连接成功后,订阅一个主题
+         client.on('connect', function () {
+           client.subscribe('detection/rect', function (err) {
+             if (!err) {
+               console.log('成功订阅 detection/rect 主题!')
+             }
+           })
+         })
+
+         // 监听订阅主题上的消息
+         client.on('message', function (topic, message) {
+           // 处理接收到的消息
+           console.log('收到主题 ' + topic + ' 的消息: ' + message.toString())
+         })
+    },
+    initCanvas() {
+      // 初始化canvas画布
+
+      let canvasWrap = document.getElementsByClassName("canvas-wrap");
+      this.wrapWidth = canvasWrap[0].clientWidth;
+      this.wrapHeight = canvasWrap[0].clientHeight;
+
+      this.imgCanvas = document.getElementById("imgCanvas");
+      this.imgCtx = this.imgCanvas.getContext("2d");
+
+      // 绘制canvas
+      this.drawCanvas = document.getElementById("drawCanvas");
+      this.drawCtx = this.drawCanvas.getContext("2d");
+
+      // 保存绘制区域 saveCanvas
+      this.saveCanvas = document.getElementById("saveCanvas");
+      this.saveCtx = this.saveCanvas.getContext("2d");
+      // this.initImgCanvas()
+    },
+    initImgCanvas() {
+      // 计算宽高比
+      let ww = this.wrapWidth; // 画布宽度
+      let wh = this.wrapHeight; // 画布高度
+      let iw = this.imgWidth; // 图片宽度
+      let ih = this.imgHeight; // 图片高度
+
+      if (iw / ih < ww / wh) {
+        // 以高为主
+        this.ratio = ih / wh;
+        this.canvasHeight = wh;
+        this.canvasWidth = (wh * iw) / ih;
+        console.log(this.ratio,this.canvasHeight,this.canvasWidth,wh,ih,iw)
+      } else {
+        // 以宽为主
+        this.ratio = iw / ww;
+        this.canvasWidth = ww;
+        this.canvasHeight = (ww * ih) / iw;
+        console.log(this.ratio,this.canvasHeight,this.canvasWidth,wh,ih,iw,ww)
+      }
+      // 初始化画布大小
+      // this.imgCanvas.width = this.canvasWidth;
+      // this.imgCanvas.height = this.canvasHeight;
+      // this.drawCanvas.width = this.canvasWidth;
+      // this.drawCanvas.height = this.canvasHeight;
+      // this.saveCanvas.width = this.canvasWidth;
+      // this.saveCanvas.height = this.canvasHeight;
+
+      // 图片加载绘制
+      let img = document.createElement("img");
+      img.src = this.imgUrl;
+      console.log(this.imgUrl)
+      img.onload = () => {
+        console.log("图片已加载");
+        this.imgCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);
+        this.renderDatas(); // 渲染原有数据
+      };
+    },
+    startDraw() {
+      // 绘制区域
+      if (this.isDrawing) return;
+      this.isDrawing = true;
+      // 绘制逻辑
+      this.drawCanvas.addEventListener("click", this.drawImageClickFn);
+      this.drawCanvas.addEventListener("dblclick", this.drawImageDblClickFn);
+      this.drawCanvas.addEventListener("mousemove", this.drawImageMoveFn);
+    },
+    clearAll() {
+      // 清空所有绘制区域
+      this.saveCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+      this.drawedPoints = [];
+    },
+    getImage() {
+      // 这里请求接口 ...
+      this.imgUrl = "https://img1.baidu.com/it/u=3898911181,4093953224&fm=253&fmt=auto&app=138&f=JPEG?w=600&h=400";
+      // this.imgWidth = 1920;
+      // this.imgHeight = 1080;
+      // this.imgUrl =JSON.parse(this.$route.query.src)
+      this.imgWidth = 660;
+      this.imgHeight = 380;
+      this.imgUrl && this.initImgCanvas();
+    },
+    drawImageClickFn(e) {
+      let drawCtx = this.drawCtx;
+      if (e.offsetX || e.layerX) {
+        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+        let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
+        if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
+          this.drawingPoints.push([pointX, pointY]);
+        }
+      }
+    },
+    drawImageMoveFn(e) {
+      let drawCtx = this.drawCtx;
+      if (e.offsetX || e.layerX) {
+        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+        // 绘制
+        drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+
+        // 绘制点
+        drawCtx.fillStyle = "blue";
+        this.drawingPoints.forEach((item, i) => {
+          drawCtx.beginPath();
+          drawCtx.arc(...item, 6, 0, 180);
+          drawCtx.fill(); //填充
+        });
+
+        // 绘制动态区域
+        drawCtx.save();
+        drawCtx.beginPath();
+        this.drawingPoints.forEach((item, i) => {
+          drawCtx.lineTo(...item);
+        });
+        drawCtx.lineTo(pointX, pointY);
+        drawCtx.lineWidth = "3";
+        drawCtx.strokeStyle = "blue";
+        drawCtx.fillStyle = "rgba(255, 0, 0, 0.3)";
+        drawCtx.stroke();
+        drawCtx.fill(); //填充
+        drawCtx.restore();
+      }
+    },
+    drawImageDblClickFn(e) {
+      let drawCtx = this.drawCtx;
+      let saveCtx = this.saveCtx;
+      if (e.offsetX || e.layerX) {
+        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+        let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
+        if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
+          this.drawingPoints.push([pointX, pointY]);
+        }
+      }
+      // 清空绘制图层
+      drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+      // 绘制区域至保存图层
+      this.drawSaveArea(this.drawingPoints);
+
+      this.drawedPoints.push(this.drawingPoints);
+      this.drawingPoints = [];
+      this.isDrawing = false;
+
+      // 绘制结束逻辑
+      this.drawCanvas.removeEventListener("click", this.drawImageClickFn);
+      this.drawCanvas.removeEventListener("dblclick", this.drawImageDblClickFn);
+      this.drawCanvas.removeEventListener("mousemove", this.drawImageMoveFn);
+    },
+    drawSaveArea(points) {
+      // console.log(points, "points");
+      if (points.length === 0) return;
+      this.saveCtx.save();
+      this.saveCtx.beginPath();
+      points.forEach((item, i) => {
+        this.saveCtx.lineTo(...item);
+      });
+      this.saveCtx.closePath();
+      this.saveCtx.lineWidth = "2";
+      this.saveCtx.fillStyle = "rgba(255,0, 255, 0.3)";
+      this.saveCtx.strokeStyle = "red";
+      this.saveCtx.stroke();
+      this.saveCtx.fill(); //填充
+      this.saveCtx.restore();
+    },
+
+    savePoints() {
+      // 将画布坐标数据转换成提交数据
+      let objectPoints = [];
+      // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+      console.log(this.drawedPoints)
+      objectPoints = this.drawedPoints.map((area) => {
+        let polygon = {};
+        area.forEach((point, i) => {
+          polygon[`x${i + 1}`] = Math.round(point[0] * this.ratio);
+          polygon[`y${i + 1}`] = Math.round(point[1] * this.ratio);
+        });
+        // console.log(polygon)
+        return {
+          polygon: polygon,
+        };
+      });
+      this.submitData = objectPoints;
+      console.log("最终提交数据", objectPoints);
+      this.messageToSend = this.submitData
+      // this.sendMessage()
+      // this.$router.go(-1)
+    },
+    toggleConnection(){
+      if (this.isConnected) {
+        // 断开连接
+        client.end()
+        this.isConnected= false
+        this.connectionStatus = 'Disconnected'
+        return
+      }
+
+      // 建立连接
+      this.connecting = true
+      try {
+        client= mqtt.connect(this.mqttConfig.url, {
+          clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
+          keepalive: 60,
+          clean: true,
+          connectTimeout: 4000,
+          reconnectPeriod: 1000
+        })
+        client.on('connect', () => {
+          this.isConnected = true
+          this.connectionStatus= 'Connected'
+          this.connecting = false
+          console.log(3)
+          // 订阅主题
+          client.subscribe(this.mqttConfig.topic, (err) => {
+            if (err) {
+              console.error('Subscribe error:', err)
+            }else{
+               console.log('成功订阅 detection/rect 主题!')
+            }
+
+          })
+        })
+        client.on('message', (topic, message) => {
+          // 接受信息
+          console.log(topic,message)
+          this.messages.unshift({
+            type: 'received',
+            content: message.toString(),
+            timestamp: new Date().toLocaleTimeString()
+          })
+        })
+        client.on('error', (err) => {
+          console.error('MQTT Error:', err)
+          this.connectionStatus= 'Error'
+          this.connecting = false
+        })
+      } catch (error) {
+        console.error('Connection error:', error)
+        this.connectionStatus= 'Error'
+        this.connecting = false
+      }
+    },
+    sendMessage(){
+      if (!client || !this.messageToSend) return
+      this.messageToSend = JSON.stringify(this.messageToSend)
+      console.log(this.messageToSend)
+      client.publish(this.mqttConfig.topic, this.messageToSend)
+      this.messages.unshift({
+        type: 'sent',
+        content: this.messageToSend,
+        timestamp: new Date().toLocaleTimeString()
+      })
+      this.messageToSend = []
+    },
+    renderDatas() {
+      // 将提交数据数据转换成画布坐标
+      this.drawedPoints = this.submitData.map((item) => {
+        let polygon = item.polygon;
+        let points = [];
+        for (let i = 1; i < Object.keys(polygon).length / 2 + 1; i++) {
+          if (!isNaN(polygon[`x${i}`]) && !isNaN(polygon[`y${i}`])) {
+            let sngjse={x: polygon[`x${i}`] / this.ratio,y:polygon[`y${i}`] / this.ratio}
+            // points.push([
+            //   polygon[`x${i}`] / this.ratio,
+            //   polygon[`y${i}`] / this.ratio,
+            // ]);
+            points.push(sngjse)
+          }
+        }
+        this.drawSaveArea(points);
+        return points;
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.tool-box {
+  width: 98%;
+  height: 40px;
+  padding: 5px 30px;
+  margin: 20px auto 0;
+  box-sizing: border-box;
+  text-align: right;
+}
+.canvas-wrap {
+  // width: 80vw;
+  // height: 45vw;
+  width:88%;
+  height: 33.75vw;
+  margin: 0px auto;
+  background-color: #000; //#fff;
+  border: 3px;
+  border-color: #333;
+  position: relative;
+}
+#imgCanvas,
+#drawCanvas,
+#saveCanvas {
+  background: rgba(255, 0, 255, 0);
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+#drawCanvas {
+  z-index: 2;
+}
+.anseca{
+  width: 100%;
+  height: 100%;
+}
+</style>
+

+ 1867 - 0
ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (4).vue

@@ -0,0 +1,1867 @@
+<template>
+  <div class="app-container" style="height: 100vh;">
+    <!-- v-loading="loading" -->
+    <!-- element-loading-text="拼命加载中" -->
+    <!-- element-loading-spinner="el-icon-loading" -->
+    <!-- element-loading-background="rgba(0, 0, 0, 0.8)" -->
+    <div class="ntgs" style="padding: 0;">
+      <el-row :gutter="10" class="mb8">
+        <div class="iuer" style="margin-bottom:10px;">
+        </div>
+      </el-row>
+      <div>
+        <el-row :gutter="20">
+          <!-- postList -->
+          <el-col :span='4'>
+            <div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 95vh;">
+              <p
+                style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">
+                通道管理</p>
+              <div :class="ishge == index ? 'anche' : ''"
+                style=" height: 36px;;line-height: 36px;margin-top: 10px;padding: 0 10px;"
+                v-for="(item,index) in channelNumberList" :key="index">
+                <div @click="ishg(item,index)"
+                  style="display: flex;align-items: center;justify-content: space-between;">
+                  <div style="font-size: 16px;
+              color: #333333;"> {{item.channelNum == null?'暂无数据' : item.channelNum}}</div>
+                  <img src="../../../assets/images/icon_htgl_zd.png" alt="" style="width: 10px;height: 12px;">
+                </div>
+              </div>
+
+
+            </div>
+          </el-col>
+          <!-- v-if="isshoe" -->
+          <el-col :span='14'
+            style="padding-left: 30px; background-color: #fff;border-radius: 10px;padding: 20px; height: 95vh;">
+            <div style="display: flex;align-items: center;justify-content: space-between;margin-bottom: 18px;">
+              <p
+                style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">
+                坐标点配置
+                <span style="font-size: 12px; color: red;cursor: pointer;" @click="xiazag">下载插件</span>
+              </p>
+              <div>
+                <!-- <el-button type="danger" plain>删除</el-button> -->
+                <span style="font-size: 12px; color: red;">(点击保存之前,请先确认参数配置和坐标点配置都完成)</span>
+                <el-button type="warning" plain @click="submitForm">保存</el-button>
+                <el-button type="success" plain>关闭</el-button>
+              </div>
+            </div>
+              <div>
+                <div class="tool-box" style="margin: 0;padding: 0;height: 80px;text-align: left;">
+
+                  <!-- <div>
+                    <el-button
+                      size="mini"
+                      :type="isDrawing ? 'warning' : 'primary'"
+                      @click="startDraw"
+                      >绘制区域</el-button
+                    >
+
+                    <el-button
+                      size="mini"
+                      type="danger"
+                      :disabled="isDrawing"
+                      @click="clearAll"
+                      >全部清除</el-button
+                    >
+                    <el-button
+                      size="mini"
+                      type="success"
+                      :disabled="isDrawing"
+                      @click="savePoints"
+                      >保存</el-button
+                    >
+                  </div> -->
+                  <div class=" ">
+                    <div style="display: flex;">
+                      <el-button :type="isDrawing ? 'warning' : 'primary'"  @click="startDraw">绘制区域</el-button>
+                      <el-button type="primary" plain @click="clearAll">全部清除</el-button>
+                      <el-button type="primary" :disabled="isDrawing" plain @click="savePoints">保存</el-button>
+                    </div>
+
+                    <!-- <div style="flex: 1;"></div> -->
+                    <!-- <el-button type="primary" plain @click="clickCapturePic">抓图</el-button> -->
+                  </div>
+                  <div style="margin-top: 5px;">
+                    <p style="text-align: left; margin: 0;font-size: 13px;color: #FF6969;">每次绘制前,点击绘制按钮开始绘制,单击鼠标左键即是当前点绘制完成可绘制下一个点, 双击鼠标左键即本次绘制完成。</p>
+                  </div>
+                </div>
+                <div class="canvas-wrap">
+                  <canvas id="imgCanvas" ref="canvaxbox"></canvas>
+                  <!--用来和鼠标进行交互操作的canvas-->
+                  <canvas
+                    id="drawCanvas"
+                    ref="canvas"
+                    :style="{ cursor: isDrawing ? 'crosshair' : 'default' }"
+                  >
+                  </canvas>
+                  <!--存储已生成的点线,避免被清空-->
+                  <canvas id="saveCanvas" ref="canvasSave"></canvas>
+                </div>
+              </div>
+            <!-- <div style="width: 100%; height: 70vh;">
+              <div v-if="isfse" id="divPlugin" style="width: 100%; height: 69vh;"></div>
+
+            </div> -->
+
+
+            <!-- <img src="../../../assets/images/pic_ssyl_lt.png" alt="" style="width: 100%; margin-top: 20px;"> -->
+            <!-- 344 -->
+            <!-- <video id="video" controls autoplay muted width="100%" height="480px"style="margin-top: 20px;"></video> -->
+            <!-- <video
+        						      class="videosmall"
+        						      ref="videosmallone"
+        						      preload="auto"
+        						      muted
+        						      autoplay
+        							  width="95%"
+        						      type="rtmp/flv"
+        						    >
+        						      <source src="" />
+        						    </video> -->
+          </el-col>
+          <el-col :span="6">
+            <div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 95vh;">
+              <p
+                style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">
+                参数配置</p>
+              <div>
+                <el-form ref="form" :model="form" :rules="rules" label-width="60px">
+                  <p style="margin: 0; margin-top: 10px; color:#03BF8A ; margin-bottom: 10px;">时间配置(分钟 <span
+                      style="font-size: 12px;color: #FEA71B;">只能输入正数</span>)</p>
+                  <el-form-item label="离岗" prop="leaveTime">
+                    <el-input :min="0" type="number" v-model="form.leaveTime" placeholder="请输入离岗时间设置 默认:10 分钟" />
+                  </el-form-item>
+                  <el-form-item label="玩手机" prop="playTime">
+                    <el-input :min="0" type="number" v-model="form.playTime" placeholder="请输入玩手机时间设置 默认:10 分钟" />
+                  </el-form-item>
+                  <p style="margin: 0; margin-top: 10px; color:#03BF8A ; margin-bottom: 10px;">相似度配置<span
+                      style="font-size: 12px;color: #FEA71B;">(只能输入正数)</span></p>
+                  <el-form-item label="离岗" prop="leaveRate">
+                    <el-input :min="0" :max="1" type="number" v-model="form.leaveRate"
+                      placeholder="请输入离岗时间相似度设置 默认:0.5" />
+                  </el-form-item>
+
+                  <el-form-item label="玩手机" prop="playRate">
+                    <el-input :min="0" :max="1" type="number" v-model="form.playRate"
+                      placeholder="请输入玩手机相似度设置 默认:0.5" />
+                  </el-form-item>
+                </el-form>
+              </div>
+              <p
+                style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">
+                绘制区域</p>
+              <div class="drawings-list">
+                <div class="tflex" v-for="(shape, index) in shapes" :key="index">
+                  <!-- :class="{ selected: selectedIndex === index }" -->
+                  <div class="txt">
+                    <el-popover placement="top-start" width="200" trigger="hover">
+                      <div v-for="(ite,idx) in shape.points">
+                        {{ite.x}},{{ite.y}}
+                      </div>
+                      <div slot="reference" class="snhseinu">
+                        <el-input v-model="shape.name" placeholder="请输入内容"></el-input>
+                      </div>
+                    </el-popover>
+                  </div>
+                <img class="delimg" src="../../../assets/images/del.png"
+                    @click.stop="clickDelSnapPolygon(shape.id,index)" />
+                </div>
+              </div>
+            </div>
+          </el-col>
+
+          <!-- <el-col :span="24">
+				<div class="ihgswq wrapper"  ref="wrapper" style=" overflow: hidden;">
+						  <div class="fijge content nhgwesvq" ref="content" style="width:1610px;">
+									<div class='shotw '   v-for="(item,index) in postList" :key="index" @click="isfgw(item)" >
+											  <img src="../../../assets/images/fengm.png" alt="">
+												<img src="../../../assets/images/icon_spjk_play.png" alt="" class="iges">
+											  <p style="font-size: 14px;">{{item.name}}</p>
+									</div>
+						  </div>
+				</div>
+			</el-col> -->
+        </el-row>
+
+
+        <!-- <pagination
+	     v-show="total>0"
+	     :total="total"
+	     :page.sync="queryParams.pageNo"
+	     :limit.sync="queryParams.pageSize"
+	     @pagination="getList"
+	   /> -->
+      </div>
+
+
+    </div>
+
+    <!-- 添加或修改岗位对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+
+    </el-dialog>
+
+    <el-dialog :title="titles" :visible.sync="opens" width="1000px" append-to-body>
+    </el-dialog>
+
+    <el-dialog title="页面二维码" :visible.sync="opent" width="200px" style="padding: 0;" class="nhgrls" append-to-body>
+      <div v-show="opent" style="display: flex;justify-content: center;align-items: center;">
+        <!-- <span>{{'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg}}</span> -->
+        <!-- <vue-qr   :text="'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg" :size="200"></vue-qr> -->
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import {
+    listChannelNumber,
+    listChannelNumbernopa,
+    getChannelNumber,
+    delChannelNumber,
+    addChannelNumber,
+    updateChannelNumber
+  } from "@/api/system/channelNumber"
+  import {
+    listWarnManage,
+    getWarnManage,
+    delWarnManage,
+    addWarnManage,
+    updateWarnManage
+  } from "@/api/manage/warnManage"
+  import {
+    listParameterSet,
+    getParameterSet,
+    delParameterSet,
+    addParameterSet,
+    updateParameterSet
+  } from "@/api/manage/parameterSet"
+  // import { listReservat,camera,cameraIndexCode, listReservatd, getReservat, delReservat, addReservat, updateReservat,setPass,delReservathx,openDz,closeDz } from "@/api/tonggi/houtai";
+  // import vueQr from "vue-qr";
+  // import videojs from 'video.js'
+  // import 'video.js/dist/video-js.css'
+  // import {videoPlayer} from 'vue-video-player'
+  // import 'videojs-flash'
+  // import flvjs from 'flv.js/dist/flv.min.js'
+  // import flvjs from "flv.js";
+  import mqtt from 'mqtt';
+  import {
+    MqttClient
+  } from 'mqtt'
+  // 状态变量
+  // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
+  var client = MqttClient || null
+  import Bscroll from "better-scroll";
+  export default {
+    name: "Post",
+    dicts: ['sys_normal_disable', 'sys_yes_no', 'youke', 'tjzh', 'youkes', 'lafafen', 'fange', 'jluly'],
+    // components: {
+    //     vueQr,
+    //  videoPlayer
+    //   },
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        opent: false,
+        bg: null,
+        titles: '',
+        editableTabsValue: '6',
+        opens: false,
+        // 通道管理表格数据
+        channelNumberList: [],
+        imageUrl: '@/assets/logo/logo.png',
+        printObj: {
+          id: "nhgrew", // 这里是要打印元素的ID
+          popTitle: "", // 打印的标题
+        },
+        pickerOptions: {
+          disabledDate(time) {
+            //disabledDate 文档上:设置禁用状态,参数为当前日期,要求返回 Boolean
+            // return time.getTime() > Date.now()//选当前时间之前的时间
+            return time.getTime() < Date.now() - 8.64e7; //选当前时间之后的时间
+          }
+        },
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        checkedScoreDataDetails: [],
+        scoreDataDetailsList: [],
+        tabPosition: 'left',
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 岗位表格数据
+        postList: [],
+        // 弹出层标题
+        title: "",
+        // 是否显示弹出层
+        open: false,
+        // 查询参数
+        queryParams: {
+          pageNo: 1,
+          pageSize: 500,
+          name: null,
+          postCode: undefined,
+          postName: undefined,
+          status: undefined,
+          reservatType: undefined
+        },
+        // 表单参数
+        form: {},
+        // 表单校验
+        rules: {
+          receptionId: [{
+            required: true,
+            message: "不能为空",
+            trigger: "blur"
+          }],
+        },
+        ruless: {
+          visitName: [{
+            required: true,
+            message: "不能为空",
+            trigger: "blur"
+          }],
+          visitPhone: [{
+            required: true,
+            message: "不能为空",
+            trigger: "blur"
+          }],
+          visitNum: [{
+            required: true,
+            message: "不能为空",
+            trigger: "blur"
+          }],
+          visitDate: [{
+            required: true,
+            message: "不能为空",
+            trigger: "blur"
+          }],
+          visitTime: [{
+            required: true,
+            message: "不能为空",
+            trigger: "blur"
+          }],
+
+        },
+        forms: {
+          parameterId: null,
+          channelId: null,
+          equipmentId: null,
+          equipmentNum: null,
+          equipmentName: null,
+          channelNum: null,
+          channelRange: null,
+          leaveTime: 10,
+          playTime: 10,
+          leaveRate: 0.5,
+          playRate: 0.5,
+          delFlag: null,
+          createBy: null,
+          createTime: null,
+          updateBy: null,
+          updateTime: null,
+          remark: null
+        },
+        tableMaxHeight: '200',
+        kje: 0,
+        ksjegsg: [],
+        Scroll: null,
+        videoShow: false,
+        flvPlayer: null,
+        player: null,
+        name: null,
+        isshiwa: false,
+        isjfwe: {},
+        isshoe: false,
+        webRtcServer: null,
+        camera_ip: '127.0.0.1:8000',
+        g_iWndIndex: 0,
+        iRtspPort: '', //预览中的ip
+        szDeviceIdentify: '', //ip_port,
+        isfse: false,
+
+        g_bEnableDraw: false,
+        // 所有绘制的图形
+        shapes: [],
+        // 禁用
+        isdisflag: false,
+        connectionStatus: '',
+        isConnected: false,
+        connecting: false,
+        messages: [{
+          type: 'sent',
+          content: '',
+          timestamp: ''
+        }],
+        messageToSend: [],
+        mqttConfig: {
+          url: 'ws://13.229.167.76:1884/mqtt',
+          topic: 'detection/rect'
+        },
+        mqttThemeName: {
+          url: 'ws://13.229.167.76:1884/mqtt',
+          topic: 'detection/rect'
+        },
+        ishge: 0,
+        ips: '',
+        isdesl: false,
+        imgUrl: "../../../assets/images/pic_ssyl_lt.png",
+        isDrawing: false, // 是否正在绘制
+        ratio: 1,
+        imgWidth: 3020,
+        imgHeight: 1080,
+        wrapWidth: 600,
+        wrapHeight: 300,
+        canvasWidth: 600,
+        canvasHeight: 300,
+        drawingPoints: [],
+        drawedPoints: [],
+        imgCanvas: null,
+        imgCtx: null,
+        drawCanvas: null,
+        drawCtx: null,
+        saveCanvas: null,
+        saveCtx: null,
+        submitData: [
+        ],
+        connectionStatus:'',
+        isConnected:false,
+        connecting:false,
+        messages:[{ type: 'sent' , content: '', timestamp: '' }],
+        messageToSend:[],
+      };
+    },
+    created() {
+      this.isfse = false
+      // this.getList();
+      this.getListtd()
+      window.onresize = () => {
+        this.changeTableMaxHeight()
+      }
+      this.changeTableMaxHeight()
+
+    },
+    mounted() {
+      // this.toggleConnection()
+      // this.webRtcServer = new WebRtcStreamer('video', location.protocol + '//' + this.camera_ip)
+      //      //需要查看的rtsp地址,根据自己的摄像头传入对应的rtsp地址即可。注意:视频编码格式必须是H264的,否则无法正常显示,编码格式可在摄像头的后台更改
+      //      this.webRtcServer.connect('rtsp://admin:zxy123456@192.168.101.64:554/h264/ch1/main/av_stream')
+      window.onresize = () => {
+        this.changeTableMaxHeight()
+        this.initCanvas();
+        this.getImage();
+      }
+      this.changeTableMaxHeight()
+      this.$nextTick(() => {
+        this.initScroll()
+        this.initCanvas();
+        this.getImage();
+      })
+
+    },
+
+    beforeDestroy() {
+      // this.destoryVideo()
+      if (WebVideoCtrl) {
+        console.log(this.szDeviceIdentify)
+        WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+        WebVideoCtrl.I_StopAllPlay()
+        WebVideoCtrl.I_DestroyPlugin()
+        WebVideoCtrl.I_Resize()
+      }
+    },
+    methods: {
+      /** 查询通道管理列表 */
+      getListtd() {
+        this.loading = true
+        let queryParams = {}
+        listChannelNumbernopa().then(response => {
+          this.channelNumberList = response.rows
+          if (this.channelNumberList.length != 0) {
+            getChannelNumber(this.channelNumberList[0].channelId).then(response => {
+              if (response.data.isChannel != 'N') {
+                this.shapes = JSON.parse(response.data.parameterSet.channelRange)
+                let sngseju = []
+                this.shapes.filter(rou=>{
+                  let sngsejutoe = []
+                  for(var i=0; i< rou.points.length;i++ ){
+                    let sngsejq = []
+                    sngsejq.push(rou.points[i].x,rou.points[i].y)
+                    sngsejutoe.push(sngsejq)
+                  }
+                  console.log(sngsejutoe)
+                  sngseju.push(sngsejutoe)
+                })
+
+                this.drawedPoints =  sngseju
+                let objectPoints = [];
+                // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+                objectPoints = this.drawedPoints.map((area) => {
+                  console.log(area)
+                  let polygon = {};
+                  area.forEach((point, i) => {
+                    console.log(point)
+                    polygon[`x${i + 1}`] = point[0];
+                    polygon[`y${i + 1}`] = point[1];
+                  });
+                  // console.log(polygon)
+                  return {
+                    polygon: polygon,
+                  };
+                });
+                this.submitData = objectPoints;
+                console.log("最终提交数据", objectPoints);
+                this.messageToSend = this.submitData
+                console.log(this.drawedPoints,this.submitData)
+                this.form = response.data.parameterSet
+                let result = (this.form.leaveTime / 60).toFixed(1);
+                let resultl = (this.form.playTime / 60).toFixed(1);
+                this.form.channelId = response.data.channelId
+                this.form.isChannel = response.data.isChannel
+                this.form.equipmentNum = response.data.equipmentNum
+                this.form.equipmentId = response.data.equipmentId
+                this.form.equipmentName = response.data.equipmentName
+                this.form.channelNum = response.data.channelNum
+                let snghs = response.data.videoAddress.split('@')
+                let snghst = snghs[1].split(':')
+                let snsgduan = snghst[1].split('/')
+                // console.log(snghs,snghst[0],snsgduan,8)
+                this.ips = response.data.equipmentIp
+                let sgse = {
+                  'ip': response.data.equipmentIp,
+                  'account': response.data.account,
+                  'password': response.data.password,
+                  'port': response.data.port
+                }
+                this.form.leaveTime = result
+                this.form.playTime = resultl
+                // WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+                // // WebVideoCtrl.I_StopAllPlay()
+                // // WebVideoCtrl.I_DestroyPlugin()
+                // // WebVideoCtrl.I_Resize()
+                // this.getVideo(sgse)
+                // this.clickAddSnapPolygon()
+                // var that = this
+                // setTimeout(function() {
+                //   that.clickEnableDraw() //娃娃消失
+                // }, 4000);
+                // WebVideoCtrl.I_ShowPlugin()
+                // this.clickEnableDraw()
+                this.renderDatas()
+                console.log(result)
+              } else {
+                this.form = {
+                  parameterId: null,
+                  channelId: response.data.channelId,
+                  equipmentId: response.data.equipmentId,
+                  equipmentNum: response.data.equipmentNum,
+                  equipmentName: response.data.equipmentName,
+                  channelNum: response.data.channelNum,
+                  channelRange: null,
+                  isChannel: response.data.isChannel,
+                  leaveTime: 10,
+                  playTime: 10,
+                  leaveRate: 0.5,
+                  playRate: 0.5,
+                  delFlag: null,
+                  createBy: null,
+                  createTime: null,
+                  updateBy: null,
+                  updateTime: null,
+                  remark: null
+                }
+                this.ips = response.data.equipmentIp
+                // let result = (this.form.leaveTime / 60).toFixed(1);
+                // let resultl = (this.form.playTime / 60).toFixed(1);
+                // this.form.leaveTime = result
+                // this.form.playTime = resultl
+                // WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+                let sgse = {
+                  'ip': response.data.equipmentIp,
+                  'account': response.data.account,
+                  'password': response.data.password,
+                  'port': response.data.port
+                }
+                // this.getVideo(sgse)
+                // this.clickAddSnapPolygon()
+                // var that = this
+                // setTimeout(function() {
+                //   that.clickEnableDraw() //娃娃消失
+                // }, 4000);
+                // WebVideoCtrl.I_ShowPlugin()
+              }
+
+            })
+          }
+          this.loading = false
+          // getWarnManage(this.$route.query.id).then(response => {
+          // this.form = response.data
+          this.loading = false
+        })
+      },
+      // 回显
+      nshgehuixw(){
+        let sngseju = []
+        this.shapes.filter(rou=>{
+          let sngsejutoe = []
+          for(var i=0; i< rou.points.length;i++ ){
+            let sngsejq = []
+            sngsejq.push(rou.points[i].x,rou.points[i].y)
+            sngsejutoe.push(sngsejq)
+          }
+          console.log(sngsejutoe)
+          sngseju.push(sngsejutoe)
+        })
+        this.drawedPoints =  sngseju
+        let objectPoints = [];
+        // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+        objectPoints = this.drawedPoints.map((area) => {
+          console.log(area)
+          let polygon = {};
+          area.forEach((point, i) => {
+            console.log(point)
+            polygon[`x${i + 1}`] = Math.round(point[0] * this.ratio);
+            polygon[`y${i + 1}`] = Math.round(point[1] * this.ratio);
+          });
+          // console.log(polygon)
+          return {
+            polygon: polygon,
+          };
+        });
+        this.submitData = objectPoints;
+        console.log("最终提交数据", objectPoints);
+        this.messageToSend = this.submitData
+        console.log(this.drawedPoints,this.submitData)
+        this.renderDatas()
+      },
+      // 画图
+      initCanvas() {
+        // 初始化canvas画布
+
+        let canvasWrap = document.getElementsByClassName("canvas-wrap");
+        this.wrapWidth = canvasWrap[0].clientWidth;
+        this.wrapHeight = canvasWrap[0].clientHeight;
+
+        this.imgCanvas = document.getElementById("imgCanvas");
+        this.imgCtx = this.imgCanvas.getContext("2d");
+
+        // 绘制canvas
+        this.drawCanvas = document.getElementById("drawCanvas");
+        this.drawCtx = this.drawCanvas.getContext("2d");
+
+        // 保存绘制区域 saveCanvas
+        this.saveCanvas = document.getElementById("saveCanvas");
+        this.saveCtx = this.saveCanvas.getContext("2d");
+        // this.initImgCanvas()
+      },
+      initImgCanvas() {
+        // 计算宽高比
+        let ww = this.wrapWidth; // 画布宽度
+        let wh = this.wrapHeight; // 画布高度
+        let iw = this.imgWidth; // 图片宽度
+        let ih = this.imgHeight; // 图片高度
+
+        if (iw / ih < ww / wh) {
+          // 以高为主
+          this.ratio = ih / wh;
+          this.canvasHeight = wh;
+          this.canvasWidth = (wh * iw) / ih;
+        } else {
+          // 以宽为主
+          this.ratio = iw / ww;
+          this.canvasWidth = ww;
+          this.canvasHeight = (ww * ih) / iw;
+        }
+        // 初始化画布大小
+        this.imgCanvas.width = this.canvasWidth;
+        this.imgCanvas.height = this.canvasHeight;
+        this.drawCanvas.width = this.canvasWidth;
+        this.drawCanvas.height = this.canvasHeight;
+        this.saveCanvas.width = this.canvasWidth;
+        this.saveCanvas.height = this.canvasHeight;
+
+        // 图片加载绘制
+        let img = document.createElement("img");
+        img.src = this.imgUrl;
+        console.log(this.imgUrl)
+        img.onload = () => {
+          console.log("图片已加载");
+          this.imgCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);
+          this.renderDatas(); // 渲染原有数据
+        };
+      },
+      startDraw() {
+        // 绘制区域
+        if (this.isDrawing) return;
+        this.isDrawing = true;
+        // 绘制逻辑
+        this.drawCanvas.addEventListener("click", this.drawImageClickFn);
+        this.drawCanvas.addEventListener("dblclick", this.drawImageDblClickFn);
+        this.drawCanvas.addEventListener("mousemove", this.drawImageMoveFn);
+      },
+      clearAll() {
+        // 清空所有绘制区域
+        this.saveCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+        this.drawedPoints = [];
+        this.shapes = []
+      },
+      getImage() {
+        // 这里请求接口 ...
+        this.imgUrl = "http://192.168.101.97:5000/video_feed";
+        // this.imgWidth = 1920;
+        // this.imgHeight = 1080;
+        // this.imgUrl =JSON.parse(this.$route.query.src)
+        this.imgWidth = 660;
+        this.imgHeight = 380;
+        this.imgUrl && this.initImgCanvas();
+      },
+      drawImageClickFn(e) {
+        let drawCtx = this.drawCtx;
+        if (e.offsetX || e.layerX) {
+          let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+          let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+          let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
+          if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
+            this.drawingPoints.push([pointX, pointY]);
+          }
+        }
+      },
+      drawImageMoveFn(e) {
+        let drawCtx = this.drawCtx;
+        if (e.offsetX || e.layerX) {
+          let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+          let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+          // 绘制
+          drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+          // 绘制点
+          drawCtx.fillStyle = "blue";
+          this.drawingPoints.forEach((item, i) => {
+            drawCtx.beginPath();
+            drawCtx.arc(...item, 6, 0, 180);
+            drawCtx.fill(); //填充
+            // console.log(item)
+          });
+
+          // 绘制动态区域
+          drawCtx.save();
+          drawCtx.beginPath();
+          this.drawingPoints.forEach((item, i) => {
+            drawCtx.lineTo(...item);
+          });
+          drawCtx.lineTo(pointX, pointY);
+          drawCtx.lineWidth = "3";
+          drawCtx.strokeStyle = "blue";
+          drawCtx.fillStyle = "rgba(255, 0, 0, 0.3)";
+          drawCtx.stroke();
+          drawCtx.fill(); //填充
+          drawCtx.restore();
+        }
+      },
+      drawImageDblClickFn(e) {
+        let drawCtx = this.drawCtx;
+        let saveCtx = this.saveCtx;
+        if (e.offsetX || e.layerX) {
+          let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+          let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+          let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
+          if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
+            this.drawingPoints.push([pointX, pointY]);
+          }
+        }
+        // 清空绘制图层
+        drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+        // 绘制区域至保存图层
+        this.drawSaveArea(this.drawingPoints);
+        this.drawedPoints.push(this.drawingPoints);
+        this.drawingPoints = [];
+        this.isDrawing = false;
+        // 绘制结束逻辑
+        this.drawCanvas.removeEventListener("click", this.drawImageClickFn);
+        this.drawCanvas.removeEventListener("dblclick", this.drawImageDblClickFn);
+        this.drawCanvas.removeEventListener("mousemove", this.drawImageMoveFn);
+      },
+      drawSaveArea(points) {
+        // console.log(points, "points");
+        if (points.length === 0) return;
+        this.saveCtx.save();
+        this.saveCtx.beginPath();
+        points.forEach((item, i) => {
+          this.saveCtx.lineTo(...item);
+        });
+        this.saveCtx.closePath();
+        this.saveCtx.lineWidth = "2";
+        this.saveCtx.fillStyle = "rgba(255,0, 255, 0.3)";
+        this.saveCtx.strokeStyle = "red";
+        this.saveCtx.stroke();
+        this.saveCtx.fill(); //填充
+        this.saveCtx.restore();
+      },
+
+      savePoints() {
+        // 将画布坐标数据转换成提交数据
+        let objectPoints = [];
+        // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+       console.log(this.drawedPoints)
+        objectPoints = this.drawedPoints.map((area,t) => {
+          console.log(t)
+          let polygon = [];
+          area.forEach((point, i) => {
+            let nsdfs = {x:null,y:null}
+            console.log(point,93)
+            nsdfs.x =  Math.round(point[0] * this.ratio)
+            nsdfs.y = Math.round(point[1] * this.ratio)
+            // polygon[`x${i + 1}`] = Math.round(point[0] * this.ratio);
+            // polygon[`y${i + 1}`] = Math.round(point[1] * this.ratio);
+            polygon.push(nsdfs)
+          });
+          console.log(polygon)
+          return {
+            points: polygon,
+            id:t+1,
+            name:'绘制区域' + (t+1),
+            ip:this.ips
+          };
+        });
+        this.submitData = objectPoints;
+        this.shapes = objectPoints
+
+        console.log("最终提交数据", objectPoints);
+        this.messageToSend = this.submitData
+        // this.sendMessage()
+        // this.$router.go(-1)
+      },
+      renderDatas() {
+        // 将提交数据数据转换成画布坐标
+        this.drawedPoints = this.submitData.map((item) => {
+          console.log(item.polygon,item,19)
+          let polygon = item.polygon;
+          let points = [];
+          for (let i = 1; i < Object.keys(polygon).length / 2 + 1; i++) {
+            if (!isNaN(polygon[`x${i}`]) && !isNaN(polygon[`y${i}`])) {
+              points.push([
+                polygon[`x${i}`] / this.ratio,
+                polygon[`y${i}`] / this.ratio,
+              ]);
+            }
+          }
+          console.log(points)
+          this.drawSaveArea(points);
+          return points;
+        });
+      },
+      //删除图形
+      clickDelSnapPolygon(szId, idx) {
+        console.log(3)
+        this.shapes.splice(idx, 1)
+        // this.shapes.splice(idx,1)
+        let shzou = []
+        // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+        for(var i = 0 ; i <this.shapes.length; i++){
+          this.shapes[i].id= i+ 1
+        }
+        this.saveCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+        this.nshgehuixw()
+        // this.submitData = this.shapes
+        // this.drawedPoints = this.shapes
+
+        // this.renderDatas()
+        console.log(this.shapes,shzou)
+
+      },
+      clickEnableDraw() {
+        WebVideoCtrl.I_SetDrawStatus(true).then(() => {
+          this.g_bEnableDraw = true;
+          // showOPInfo("启用绘制成功!");
+        }, (oError) => {
+          // showOPInfo("启用绘制失败!", oError.errorCode, oError.errorMsg);
+        });
+      },
+      getdrawFn() {
+        this.isdisflag = !this.isdisflag;
+        if (this.isdisflag) {
+          this.clickDisableDraw()
+        } else {
+          this.clickEnableDraw()
+        }
+      },
+      // 禁用多边形绘制
+      clickDisableDraw() {
+        WebVideoCtrl.I_SetDrawStatus(false).then(() => {
+          this.g_bEnableDraw = false;
+          // showOPInfo("禁用绘制成功!");
+          this.clickAddSnapPolygon()
+        }, (oError) => {
+          // showOPInfo("禁用绘制失败!", oError.errorCode, oError.errorMsg);
+        });
+      },
+      clickGetSnapPolygon() {
+        var that = this;
+        WebVideoCtrl.I_GetSnapPolygonInfo(this.g_iWndIndex).then((szXml) => {
+          console.log('获取图形:', szXml);
+          that.getpoint(szXml)
+        });
+      },
+      //获取x,y轴
+      getpoint(xmlString) {
+        var that = this;
+        const parser = new DOMParser();
+        const xmlDoc = parser.parseFromString(xmlString, "text/xml");
+        // 获取所有 SnapPolygon 节点
+        const polygonNodes = xmlDoc.querySelectorAll("SnapPolygon");
+        var newArr = [];
+        var arr1 = JSON.parse(JSON.stringify(this.shapes))
+        // 提取每个多边形的 id 和坐标点
+        this.polygons = Array.from(polygonNodes).map((polygonNode) => {
+          const id = polygonNode.querySelector("id").textContent;
+          const pointNodes = polygonNode.querySelectorAll("point");
+          const points = Array.from(pointNodes).map((pointNode) => ({
+            x: pointNode.querySelector("x").textContent,
+            y: pointNode.querySelector("y").textContent,
+          }));
+          var newobj = {
+            id: id,
+            points: points,
+            name: '区域' + id,
+            ip: this.ips
+          }
+          newArr.push(newobj)
+          // return { id, points };
+        });
+        this.shapes = arr1.map(item1 => {
+          const matchedItem = newArr.find(item2 => item2.id == item1.id);
+          return {
+            id: item1.id,
+            name: '区域' + item1.id,
+            ip: this.ips,
+            points: matchedItem ? matchedItem.points : item1.points,
+          };
+        });
+        console.log(this.shapes, 78)
+        // this.shapes=JSON.parse(JSON.stringify(newArr))
+        this.messageToSend = this.shapes
+
+        this.sendMessage()
+        console.log(this.shapes)
+      },
+      toggleConnection() {
+        if (this.isConnected) {
+          // 断开连接
+          client.end()
+          this.isConnected = false
+          this.connectionStatus = 'Disconnected'
+          return
+        }
+
+        // 建立连接
+        this.connecting = true
+        try {
+          client = mqtt.connect(this.mqttConfig.url, {
+            clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
+            keepalive: 60,
+            clean: true,
+            connectTimeout: 4000,
+            reconnectPeriod: 1000
+          })
+          client.on('connect', () => {
+            this.isConnected = true
+            this.connectionStatus = 'Connected'
+            this.connecting = false
+            console.log(3)
+            // 订阅主题
+            client.subscribe(this.mqttConfig.topic, (err) => {
+              if (err) {
+                console.error('Subscribe error:', err)
+              } else {
+                console.log('成功订阅 detection/rect 主题!')
+              }
+
+            })
+          })
+          client.on('message', (topic, message) => {
+            // 接受信息
+            console.log(topic, message)
+            this.messages.unshift({
+              type: 'received',
+              content: message.toString(),
+              timestamp: new Date().toLocaleTimeString()
+            })
+          })
+          client.on('error', (err) => {
+            console.error('MQTT Error:', err)
+            this.connectionStatus = 'Error'
+            this.connecting = false
+          })
+        } catch (error) {
+          console.error('Connection error:', error)
+          this.connectionStatus = 'Error'
+          this.connecting = false
+        }
+      },
+      sendMessage() {
+        if (!client || !this.messageToSend) return
+        this.messageToSend = JSON.stringify(this.messageToSend)
+        console.log(this.messageToSend)
+        client.publish(this.mqttConfig.topic, this.messageToSend)
+        this.messages.unshift({
+          type: 'sent',
+          content: this.messageToSend,
+          timestamp: new Date().toLocaleTimeString()
+        })
+        this.messageToSend = []
+      },
+      // 添加图形,最多不超过16个图形
+      clickAddSnapPolygon() {
+        var that = this;
+        if (!this.g_bEnableDraw) {
+          return;
+        }
+        var shapes = JSON.parse(JSON.stringify(this.shapes))
+        let szId = 1; // 默认从 1 开始
+        if (shapes && shapes.length > 0) {
+          const ids = shapes.map(item => item.id).sort((a, b) => a - b);
+          for (const id of ids) {
+            if (id > szId) {
+              // 如果当前 id > szId,说明 szId 未被使用
+              break;
+            }
+            szId = Number(id) + 1; // 否则,继续检查下一个
+          }
+        }
+        if (!/^[1-9]\d*$/.test(szId)) {
+          alert("图形ID只能为正整数!");
+          return
+        }
+        if (Number(szId) > 32) {
+          alert("图形ID范围1-32!");
+          return
+        }
+        console.log(szId)
+        // var szName = encodeString($("#snapName").val());
+        var szName = '';
+        var szInfo = {
+
+        }
+        var szInfo = "<?xml version='1.0' encoding='utf-8'?>";
+        szInfo += "<SnapPolygonList>";
+        szInfo += "<SnapPolygon>";
+        szInfo += "<id>" + szId + "</id>"; // [1, 32]
+        szInfo += "<polygonType>0</polygonType>"; //如果想绘制多边形,polygonType指需要改为1
+        szInfo += "<PointNumMax>17</PointNumMax>"; // [MinClosed, 17]
+        szInfo += "<MinClosed>4</MinClosed>"; // [4, 17]
+        szInfo += "<tips>#" + szId + "#" + szName + "</tips>";
+        szInfo += "<isClosed>false</isClosed>";
+        szInfo += "<color><r>0</r><g>255</g><b>0</b></color>";
+        szInfo += "<pointList/>";
+        szInfo += "</SnapPolygon>";
+        szInfo += "</SnapPolygonList>";
+
+        WebVideoCtrl.I_SetSnapPolygonInfo(this.g_iWndIndex, szInfo).then(() => {
+          // showOPInfo("添加图形成功!");
+          var obj = {
+            id: szId,
+            points: [],
+            'name': '区域' + szId,
+            'ip': this.ips
+          }
+          if (this.shapes && this.shapes.length) {
+            this.shapes.splice(Number(szId) - 1, 0, obj)
+          } else {
+            this.shapes.push(obj)
+          }
+          console.log(this.shapes)
+        });
+        WebVideoCtrl.I_SetSnapDrawMode(this.g_iWndIndex, 2);
+      },
+
+      // 通道点击
+      ishg(val, row) {
+        this.isfse = false
+        this.ishge = row
+        getChannelNumber(val.channelId).then(response => {
+          if (response.data.isChannel == 'Y') {
+            this.form = response.data.parameterSet
+            this.shapes = JSON.parse(this.form.channelRange)
+            this.form.channelId = response.data.channelId
+            this.form.isChannel = response.data.isChannel
+            this.form.equipmentNum = response.data.equipmentNum
+            this.form.equipmentId = response.data.equipmentId
+            this.form.equipmentName = response.data.equipmentName
+            this.form.channelNum = response.data.channelNum
+            let snghs = response.data.videoAddress.split('@')
+            let snghst = snghs[1].split(':')
+            let snsgduan = snghst[1].split('/')
+            // this.ips = snghst[0]
+            this.ips = response.data.equipmentIp
+            console.log(snghs, snghst, snsgduan)
+            let sgse = {
+              'ip': response.data.equipmentIp,
+              'account': response.data.account,
+              'password': response.data.password,
+              'port': response.data.port
+            }
+            WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+            WebVideoCtrl.I_StopAllPlay()
+            WebVideoCtrl.I_DestroyPlugin()
+            WebVideoCtrl.I_Resize()
+            this.getVideo(sgse)
+            // this.clickEnableDraw()
+            this.clickAddSnapPolygon()
+            var that = this
+            setTimeout(function() {
+              that.clickEnableDraw() //娃娃消失
+            }, 4000);
+            WebVideoCtrl.I_ShowPlugin()
+          } else {
+            this.form = {
+              parameterId: null,
+              channelId: response.data.channelId,
+              equipmentId: response.data.equipmentId,
+              equipmentNum: response.data.equipmentNum,
+              equipmentName: response.data.equipmentName,
+              channelNum: response.data.channelNum,
+              channelRange: null,
+              isChannel: response.data.isChannel,
+              leaveTime: 10,
+              playTime: 10,
+              leaveRate: 0.5,
+              playRate: 0.5,
+              delFlag: null,
+              createBy: null,
+              createTime: null,
+              updateBy: null,
+              updateTime: null,
+              remark: null
+            }
+            let snghs = response.data.videoAddress.split('@')
+            let snghst = snghs[1].split(':')
+            let snsgduan = snghst[1].split('/')
+            this.ips = response.data.equipmentIp
+            // this.ips = snghst[0]
+            console.log(snghs, snghst, snsgduan)
+            let sgse = {
+              'ip': response.data.equipmentIp,
+              'account': response.data.account,
+              'password': response.data.password,
+              'port': response.data.port
+            }
+            WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+            WebVideoCtrl.I_StopAllPlay()
+            WebVideoCtrl.I_DestroyPlugin()
+            WebVideoCtrl.I_Resize()
+            this.getVideo(sgse)
+            var that = this
+            setTimeout(function() {
+              that.clickEnableDraw() //娃娃消失
+            }, 4000);
+            // this.clickEnableDraw()
+            this.clickAddSnapPolygon()
+            WebVideoCtrl.I_ShowPlugin()
+          }
+        })
+
+        // this.clickStartRealPlay('192.168.101.64', '80',1, 0, 1);
+
+      },
+
+
+      init(
+      val) { //这个val 就是一个地址,例如: http://192.168.2.201:85/live/9311272c49b845baa2b2810ad9bf3f68.flv 这是个服务器返回给我的一个监控视频流地址
+        setTimeout(() => { //使用定时器是因为,在mounted声明周期里调用,可能会出现DOM没加载出来的原因
+          var videoElement = this.$refs.videosmallone; // 获取到html中的video标签
+          this.isshiwa = true
+          if (flvjs.isSupported()) {
+            //因为我这个是复用组件,进来先判断 player是否存在,如果存在,销毁掉它,不然会占用TCP名额
+            if (this.player !== null) {
+              this.player.pause();
+              this.player.unload();
+              this.player.detachMediaElement();
+              this.player.destroy();
+              this.player = null;
+            }
+            this.player = flvjs.createPlayer( //创建直播流,加载到DOM中去
+              {
+                type: "flv",
+                url: val, //你的url地址
+                isLive: true, //数据源是否为直播流
+                hasAudio: false, //数据源是否包含有音频
+                hasVideo: true, //数据源是否包含有视频
+                enableStashBuffer: true, //是否启用缓存区
+              }, {
+                enableWorker: false, //不启用分离线程
+                enableStashBuffer: false, //关闭IO隐藏缓冲区
+                autoCleanupSourceBuffer: true, //自动清除缓存
+                lazyLoad: false,
+              }
+            );
+            this.isshoe = true
+            this.player.attachMediaElement(videoElement); //放到dom中去
+
+            //!!!!!!这里需要注意,有的时候load加载完成不一定可以播放,要是播放不成功,用settimeout 给下面的this.player.play() 延时几百毫秒再播放
+            // setTimeout(this.player.play(), 48000);
+            setTimeout(() => {
+              //到时间时只执行一次就停止
+              this.player.load(); //准备完成
+              this.player.play()
+              console.log('播放')
+            }, 900)
+          }
+        }, 500);
+      },
+
+      createVideo() {
+        if (flvjs.isSupported()) {
+          console.log(1)
+          var videoElement = document.getElementById('myFlvVideo')
+          console.log(videoElement, flvjs)
+          this.flvPlayer = flvjs.createPlayer({
+            type: 'application/x-mpegURL',
+            isLive: true,
+            hasAudio: false,
+            url: 'https://stream1.freetv.fun/86d463c0006da643e45e26b34875df87059dcba13e69d0a5471b185793c122a2.m3u8'
+          }, {
+            cors: true, // 是否跨域
+            enableWorker: false, // 是否多线程工作
+            enableStashBuffer: false, // 是否启用缓存
+            stashInitialSize: 400, // 缓存大小(kb)  默认384kb
+            autoCleanupSourceBuffer: true // 是否自动清理缓存
+          })
+          this.flvPlayer.attachMediaElement(videoElement)
+          this.flvPlayer.load()
+          this.flvPlayer.play()
+          console.log(1244)
+          // 报错重连
+          this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
+            console.log('errorType:', errType)
+            console.log('errorDetail:', errDetail)
+            if (this.flvPlayer) {
+              this.destoryVideo()
+              this.createVideo()
+            }
+          })
+        }
+
+        console.log(this.flvPlayer.play())
+      },
+      destoryVideo() {
+        this.player.pause()
+        this.player.unload()
+        this.player.detachMediaElement()
+        this.player.destroy()
+        this.player = null
+      },
+
+      initScroll() {
+        // 给内层盒子设置宽度,不设置宽度的话无法滚动
+        // let width = this.goods.length * 60
+        // // 如果有外边距,可以这样写。需要去掉最后一个元素的外边距,在后面减一下
+        // let width = this.goodslength * (60 + 10) - 10
+        let width = 6 * (200 + 10) - 10
+        // this.$refs.content.style.width = width + 'px'
+        this.$nextTick(() => {
+          if (!this.Scroll) {
+            this.Scroll = new Bscroll(this.$refs.wrapper, {
+              click: true, // 配置允许点击事件
+              scrollX: true, // 开启横向滚动
+              eventPassthrough: 'vertical', // 当设置 eventPassthrough 为 'vertical' 的时候,scrollY 无效
+              mouseWheel: true,
+              scrollbar: { // 滚动条, 要加相对位置
+                fade: true
+              }
+            })
+          } else {
+            this.Scroll.refresh() // 重新计算 better-scroll,当 DOM 结构发生变化的时确保滚动效果正常
+          }
+        })
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.opens = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          receptionId: undefined,
+          receptionPhone: undefined,
+          // postSort: 0,
+          // status: "0",
+          receptionName: undefined
+        };
+        this.resetForm("form");
+      },
+
+      iszheg(event) {
+        console.log(event);
+
+
+        // 校验身份证:
+        console.log(reg.test(this.form.idCard), 23741)
+        if (reg.test(this.form.idCard) || _IDre15.test(this.form.idCard)) {
+          // this.idea();
+          this.go(this.form.idCard);
+          // callback()
+        } else {
+          if (ncjsle.test(this.form.idCard) || nhyeli.test(this.form.idCard)) {
+            console.log(3)
+          } else {
+            if (gnse.test(this.form.idCard)) {
+              console.log(4)
+            } else {
+              if (tw.test(this.form.idCard) || twe.test(this.form.idCard)) {
+                console.log(5)
+              } else {
+                this.$message.error('证件格式不正确');
+              }
+            }
+
+          }
+        }
+      },
+      erw(row) {
+        this.$router.push({
+          path: '/reny/ewm',
+          query: {
+            'tenantId': row.investigateTableId
+          }
+        })
+      },
+
+      hussar_17Click(val) {
+        const _this = this
+        var url = process.env.VUE_APP_BASE_API + 'pages/index/index?id=' + val.investigateTableId;
+        console.log(url, this.$refs.canvas, 6)
+        this.opent = true
+        QRCode.toCanvas(
+          canvas,
+          url, //生成二维码的数据
+          {
+            width: 100,
+            height: 100,
+            margin: 1.5
+          }, //margin调整二维码的白边大小
+          function(error) {
+            if (error) {
+              console.log(error);
+            }
+          }
+        );
+
+        // console.log(qrcode,987)
+      },
+      /** 成绩_子添加按钮操作 */
+      handleAddScoreDataDetails() {
+
+        let obj = {};
+        obj.duty = "";
+        obj.idCard = "";
+        obj.phonenumber = "";
+        obj.userName = "";
+        this.scoreDataDetailsList.push(obj);
+        console.log(this.scoreDataDetailsList)
+      },
+      /** 成绩_子删除按钮操作 */
+      handleDeleteScoreDataDetails() {
+        if (this.checkedScoreDataDetails.length == 0) {
+          this.$modal.msgError("请先选择要删除的数据");
+        } else {
+          const scoreDataDetailsList = this.scoreDataDetailsList;
+          const checkedScoreDataDetails = this.checkedScoreDataDetails;
+          this.scoreDataDetailsList = scoreDataDetailsList.filter(function(item) {
+            return checkedScoreDataDetails.indexOf(item.index) == -1
+          });
+        }
+      },
+      /** 复选框选中数据 */
+      handleScoreDataDetailsSelectionChange(selection) {
+        this.checkedScoreDataDetails = selection.map(item => item.index)
+      },
+      /** 成绩_子序号 */
+      rowScoreDataDetailsIndex({
+        row,
+        rowIndex
+      }) {
+        row.index = rowIndex + 1;
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        const postIds = row.recordId || this.ids;
+        delReservat(postIds).then(response => {
+          this.$modal.msgSuccess("操作成功");
+          this.getList();
+        });
+
+        // this.$modal.confirm('是否确认删除数据项?').then(function() {
+        //   return delPost(postIds);
+        // }).then(() => {
+        //   this.getList();
+        //   this.$modal.msgSuccess("删除成功");
+        // }).catch(() => {});
+      },
+      handleDeletehx(row) {
+        const postIds = row.reservatId || this.ids;
+        let nhg = {}
+        nhg.reservatId = postIds
+        delReservathx(nhg).then(response => {
+          this.$modal.msgSuccess("操作成功");
+          this.getList();
+        });
+
+        // this.$modal.confirm('是否确认删除数据项?').then(function() {
+        //   return delPost(postIds);
+        // }).then(() => {
+        //   this.getList();
+        //   this.$modal.msgSuccess("删除成功");
+        // }).catch(() => {});
+      },
+      // 发送短信
+      handleUpdatefas(row) {
+        updateFs(row).then(response => {
+          this.$modal.msgSuccess("发送成功");
+          // this.getList();
+        });
+      },
+      handleDeletegx(row) {
+        updateGx(row).then(response => {
+          this.$modal.msgSuccess("发送成功");
+          // this.getList();
+        });
+      },
+      /** 导出按钮操作 */
+      handleExport() {
+        this.download('system/reservat/export', {
+          ...this.queryParams
+        }, `预约人员.xlsx`)
+      },
+      // 获取屏幕高度
+      showFilterForm() {
+        this.filterActive = !this.filterActive
+        this.changeTableMaxHeight()
+      },
+      changeTableMaxHeight() {
+        let height = document.body.offsetHeight // 网页可视区域高度
+        // if (this.filterActive) {
+        //   this.tableMaxHeight = height - 320
+        // } else {
+        this.tableMaxHeight = height - 350
+        // }
+        console.log(height)
+      },
+      /** 提交按钮 */
+      submitForm() {
+        this.$refs["form"].validate(valid => {
+          if (valid) {
+            // console.log(this.form)
+            // return
+            this.form.leaveTime = (this.form.leaveTime - 0) * 60
+            this.form.playTime = (this.form.playTime - 0) * 60
+            this.form.channelRange = JSON.stringify(this.shapes)
+            if (this.form.isChannel != 'N') {
+              updateParameterSet(this.form).then(response => {
+                this.$modal.msgSuccess("修改成功")
+                this.open = false
+                let result = (this.form.leaveTime / 60).toFixed(1);
+                let resultl = (this.form.playTime / 60).toFixed(1);
+                this.form.leaveTime = result
+                this.form.playTime = resultl
+                // this.$router.go(-1)
+              })
+            } else {
+              addParameterSet(this.form).then(response => {
+                this.$modal.msgSuccess("新增成功")
+                this.open = false
+                // this.$router.go(-1)
+                let result = (this.form.leaveTime / 60).toFixed(1);
+                let resultl = (this.form.playTime / 60).toFixed(1);
+                this.form.leaveTime = result
+                this.form.playTime = resultl
+              })
+            }
+          }
+        })
+      },
+      xiazag() {
+        var loadUrl = 'http://172.28.195.154:15010/prod-api/profile/HCWebSDKPluginsUserSetup.exe'
+        window.open(loadUrl, );
+       // const x = new XMLHttpRequest()
+       //   x.open('GET', 'http://192.168.9.240:5010/profile/HCWebSDKPluginsUserSetup.zip', true)
+       //   x.responseType = 'blob'
+       //   x.onload = function() {
+       //     const url = window.URL.createObjectURL(x.response)
+       //     const a = document.createElement('a')
+       //     a.href = 'http://192.168.9.240:5010/profile/HCWebSDKPluginsUserSetup.zip'
+       //     a.download = ''
+       //     a.click()
+       //   }
+       //   x.send()
+      }
+    }
+  };
+</script>
+
+<style lang="scss">
+  .snhseinu {
+    .el-input--medium .el-input__inner {
+      border: none;
+    }
+  }
+
+  .isjses {
+    .el-tabs--left .el-tabs__nav-wrap.is-left::after {
+      width: 6px;
+    }
+
+    .el-tabs--left .el-tabs__active-bar.is-left,
+    {
+    width: 6px;
+  }
+  }
+
+  .ingaqe {
+    .el-input--medium {
+      width: 100%;
+    }
+  }
+
+  .nhgrls {
+    .el-dialog__body {
+      padding: 0;
+    }
+  }
+
+  .hyr {
+    span {
+      text-decoration: underline;
+    }
+  }
+</style>
+<style scoped lang="scss">
+  .tool-box {
+    width: 98%;
+    height: 40px;
+    padding: 5px 30px;
+    margin: 20px auto 0;
+    box-sizing: border-box;
+    text-align: right;
+  }
+  .canvas-wrap {
+    // width: 80vw;
+    // height: 45vw;
+    width:100%;
+    height: 69vh;
+    margin: 0px auto;
+    background-color: #fff; //#fff;
+    border: 3px;
+    border-color: #333;
+    position: relative;
+  }
+  #imgCanvas,
+  #drawCanvas,
+  #saveCanvas {
+    background: rgba(255, 0, 255, 0);
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+  }
+  #drawCanvas {
+    z-index: 2;
+  }
+  .nghwgq {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    margin-top: 90px;
+
+    div {
+      color: #aaa;
+    }
+  }
+
+  .ihgswq {
+    // width:100%;
+    // overflow-x: hidden;
+    // margin-top: 30px;
+  }
+
+  .fijge {
+    // width: 110%;
+    display: flex;
+    display: -webkit-flex;
+    justify-content: space-between;
+
+    .shotw {
+      position: relative;
+      // width:32%;
+      width: 238px;
+      height: 140px;
+      margin-left: 0;
+      margin-right: 20px;
+      margin-bottom: 15px;
+
+      img {
+        height: 100%;
+        cursor: pointer;
+      }
+
+      p {
+        // bottom:-10px;
+        margin: 0;
+        font-weight: bold;
+        font-size: 16px;
+        padding: 5px 10px;
+        cursor: pointer;
+      }
+
+      .iges {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        width: 30px;
+        height: 30px;
+        transform: translate(-50%, -50%);
+        cursor: pointer;
+      }
+    }
+  }
+
+  .nhgwesvq {
+    width: 1610px !important;
+  }
+
+  .shotw {
+    position: relative;
+    margin-left: -20px;
+    margin-right: -20px;
+
+    img {
+      width: 100%;
+      height: 80vh;
+    }
+
+    p {
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      background-color: rgba(0, 0, 0, .5);
+      width: 100%;
+      padding: 13px 5px;
+      color: #fff;
+      font-weight: bold;
+      font-size: 18px;
+    }
+
+    .p {
+      top: 0px;
+      height: 60px;
+      margin: 0;
+      padding-left: 20px;
+    }
+  }
+
+
+  .ksfpo {
+    background-color: #3464EB;
+    padding: 6px 12px;
+    border-radius: 4px;
+    color: #fff;
+    cursor: pointer;
+  }
+
+  .ksfpok {
+    background-color: #FFFFFF;
+    padding: 5px 11px;
+    border-radius: 4px;
+    color: #3464EB;
+    border: 1px solid #3464EB;
+    margin-left: 10px;
+    cursor: pointer;
+  }
+
+  .ksfpofg {
+    background-color: #75DB75;
+    padding: 5px 11px;
+    border-radius: 4px;
+    color: #FFFFFF;
+    border: 1px solid #75DB75;
+    margin-left: 10px;
+    cursor: pointer;
+  }
+
+  .iuer {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .ite {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+
+      p {
+        cursor: pointer;
+        margin: 0;
+        font-size: 15px;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color: #666666;
+        padding: 4px 12px;
+        background: #Fff;
+        border-radius: 4px;
+        margin-right: 20px;
+        position: relative;
+      }
+
+      .actt {
+        background: #fff;
+        // border-bottom: 3px solid #5974E0;
+        // border-radius: 0;
+        // border-bottom-right-radius: 4px;
+        color: #5974E0;
+      }
+
+      .actt {
+        &::after {
+          content: "";
+          width: 40%;
+          height: 5px;
+          border-radius: 3px;
+          transform: translate(-50%);
+          background-color: #5974E0;
+          position: absolute;
+          left: 50%;
+          bottom: -3px;
+        }
+
+      }
+
+    }
+  }
+
+  .lqw {
+    padding: 0 10px;
+    margin: 0;
+    margin-bottom: 20px;
+  }
+
+  .nhgel {
+    height: 170px;
+    background-color: #313b61;
+    width: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 0;
+  }
+
+  .app-container {
+    background-color: #f3f4f6;
+    padding-top: 10px;
+    height: 180vh;
+
+  }
+
+  .ntgs {
+    position: relative;
+    // background-color: #fff;
+    padding: 5px;
+    // border-radius: 5px;
+    padding-top: 10px;
+    padding: 10px 20px;
+
+    .pagination-container {
+      height: 50px;
+    }
+  }
+
+  .nghfs {
+    position: relative;
+    background-color: #fff;
+    padding-top: 18px !important;
+    padding: 5px;
+    // border-radius: 5px;
+    // margin-bottom: 20px;
+  }
+
+  .ksf {
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  .ingwfaq {
+    font-weight: bold;
+    font-size: 16px;
+  }
+
+  .dflex {
+    display: flex;
+  }
+
+  .dflext {
+    display: flex;
+    align-items: flex-start;
+  }
+
+  .drawings-list {
+    width: 100%;
+    flex: 0 0 auto;
+    padding-left: 10px;
+    line-height: 36px;
+
+    .delimg {
+      width: 15px;
+      height: 15px;
+      margin-left: 5px;
+    }
+
+    .txt {
+      font-size: 12px;
+      padding-left: 5px;
+      flex: 1;
+    }
+
+    .tflex {
+      display: flex;
+      align-items: center;
+    }
+  }
+
+  .disbtn {
+    display: flex;
+    align-items: center;
+    flex: 0 0 auto;
+    min-height: 34px;
+    cursor: pointer;
+
+    img {
+      width: 14px;
+      height: 14px;
+      margin-right: 10px;
+    }
+
+    font-weight: 500;
+    font-size: 14px;
+    color: #444444;
+  }
+
+  .anche {
+    background: #E7F1EE !important;
+    border-radius: 4px !important;
+    font-weight: 400;
+
+    div {
+      color: #03BF8A !important;
+    }
+  }
+</style>

+ 1383 - 0
ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本 (5).vue

@@ -0,0 +1,1383 @@
+<!--
+ * @Descripttion:
+ * @version:
+ * @Author: yangxing
+ * @Date: 2022-07-14 11:49:34
+ * @LastEditors: yangxing
+ * @LastEditTime: 2022-08-13 16:19:40
+-->
+
+<template>
+  <div style="width: 80vw">
+    <el-button-group>
+      <el-button size="mini" @click="selectTool(0)">矩形</el-button>
+      <el-button size="mini" @click="selectTool(1)">多边形</el-button>
+      <el-button size="mini" @click="selectTool(2)">保存</el-button>
+    </el-button-group>
+    <div id="map" ref="map"></div>
+  </div>
+</template>
+
+<script>
+import { text } from "body-parser";
+import Konva from "konva";
+export default {
+  name: "MyKonva",
+  data() {
+    return {
+      rect: false,
+      poly: false,
+      stage: null,
+      layer: null,
+      shape: null,
+      image: { src: null },
+      currentTool: "",
+      toolObject: [
+        {
+          name: "rect",
+          type: "rect",
+          /* 矩形颜色 */ color: "#75fb4c",
+          /* 边框颜色 */ lineColor: "#75fb4c",
+          /* 顶点颜色 */ anchorColor: "green",
+        },
+        {
+          name: "poly",
+          type: "poly",
+          /* 矩形颜色 */ color: "#E63F00",
+          /* 边框颜色 */ lineColor: "#E63F00 ",
+          /* 顶点颜色 */ anchorColor: "red",
+        },
+      ],
+      drawing: false, //一开始不能绘画
+      currentDrawingShape: null, //现在绘画的图形
+      rectPoints: [], //存储矩形的各个顶点的数组
+      polygonPoints: [], //存储绘画多边形各个顶点的数组
+      stageWidth: 0, //舞台宽
+      stageHeight: 0, //舞台高
+      scale: 1, //窗口变化的缩放比例
+      currentDel: null, //删除对象
+      currentCancel: null, //删除对象
+      mouseOffsetX: 0,
+      mouseOffsetY: 0,
+      mouseOffsetList: [],
+      label: "label", //标注
+    };
+  },
+  methods: {
+    //选择工具
+    selectTool(index) {
+      //如果还在绘画,但选择工具,则将正在绘画的图形删除
+      if (this.drawing) {
+        this.currentDrawingShape.getParent().destroy();
+        this.rectPoints = [];
+        this.polygonPoints = [];
+        this.drawing = false;
+        this.layer.draw();
+      }
+      this.currentTool = this.toolObject[index];
+      if(index == 2){
+        console.log(this.rectPoints)
+      }
+    },
+    //重新调整画布
+    resizeStage() {
+      this.scale = this.$refs.map.clientWidth / this.stageWidth;
+      this.stage.width(this.stageWidth * this.scale);
+      this.stage.height(this.stageHeight * this.scale);
+      this.stage.scale({ x: this.scale, y: this.scale });
+      //维持原来大小
+      this.layer.find("Circle").forEach((element) => {
+        element.setAttr("radius", 5 / this.scale / this.layer.scaleX());
+      });
+      this.layer.find("Label").forEach((element) => {
+        element.getText().setAttrs({
+          fontSize: 16 / this.scale / this.layer.scaleX(),
+          padding: 1 / this.scale / this.layer.scaleX(),
+        });
+      });
+      this.stage.draw();
+    },
+    /**
+     *初始化konva舞台
+     */
+    initKonvaStage() {
+      //1实例化stage层
+      this.stageWidth = this.$refs.map.clientWidth;
+      this.stageHeight = this.$refs.map.clientHeight;
+      this.stage = new Konva.Stage({
+        container: "map",
+        width: this.stageWidth,
+        height: this.stageHeight,
+        ignoreStroke: true,
+      });
+      this.stage.container().style.cursor = "crosshair";
+      var vc_this = this;
+      //2实例化layer层
+      this.layer = new Konva.Layer();
+      //3添加layer层
+      this.stage.add(this.layer);
+      var imageObj = new Image();
+      imageObj.onload = function () {
+        vc_this.shape = new Konva.Image({
+          image: imageObj,
+          width: vc_this.stageWidth,
+          height: vc_this.stageHeight,
+        });
+        vc_this.layer.add(vc_this.shape);
+      };
+      imageObj.src = require("../../../assets/dog.jpeg");
+      //给***舞台***绑定事件
+      this.stageBindEvent(this);
+    },
+    /**
+     * 舞台绑定的事件
+     * @param vc_this
+     */
+    stageBindEvent(vc_this) {
+      //鼠标按下
+      this.stage.on("mousedown", (e) => {
+        //鼠标左键开始
+        if (e.evt.button == 0) {
+          if (e.target === vc_this.stage) {
+            vc_this.$message({
+              message: "请选择图片!",
+              type: "warning",
+              center: true,
+              duration: 1000,
+            });
+            return;
+          }
+          //图形起始点只能在图片层上
+          if (e.target === vc_this.shape) {
+            //开始初始绘画
+            vc_this.stageMousedown(vc_this.currentTool, e);
+            return;
+          }
+          //允许后续点绘画在其他图形上
+          if (vc_this.drawing) {
+            vc_this.stageMousedown(vc_this.currentTool, e);
+            return;
+          }
+        } else if (e.evt.button == 2) {
+          if (vc_this.polygonPoints.length != 0) {
+            //最好使用konva提供的鼠标xy点坐标
+            var mousePos = vc_this.stage.getPointerPosition();
+            //考虑鼠标缩放
+            var x =
+                (mousePos.x / vc_this.scale - vc_this.layer.getAttr("x")) /
+                vc_this.layer.scaleX(),
+              y =
+                (mousePos.y / vc_this.scale - vc_this.layer.getAttr("y")) /
+                vc_this.layer.scaleY();
+            //group继续添加多边形的点
+            vc_this.drawCircle(
+              vc_this.currentTool,
+              x,
+              y,
+              vc_this.currentDrawingShape.getParent(),
+              vc_this.polygonPoints
+            );
+            vc_this.polygonPoints.push(x);
+            vc_this.polygonPoints.push(y);
+            //绘画多边形
+            vc_this.currentDrawingShape.setAttr("points", vc_this.polygonPoints);
+            //group继续添加多边形的边
+            vc_this.currentDrawingShape
+              .getParent()
+              .getChildren((node) => {
+                return node.getAttr("name") === vc_this.currentTool.name + "line";
+              })[0]
+              .setAttr("points", vc_this.polygonPoints);
+            //判断是否是只有两个点的多边形,如果起点和终点相同,不允许绘画
+            if (
+              vc_this.currentDrawingShape.points().length == 2 ||
+              vc_this.currentDrawingShape.points().length == 4
+            ) {
+              vc_this.drawing = false;
+              vc_this.currentDrawingShape.getParent().destroy();
+              vc_this.polygonPoints = [];
+              vc_this.$message({
+                message: "顶点数必须大于2个!",
+                type: "warning",
+                center: true,
+                duration: 1000,
+              });
+              return;
+            }
+            e.cancelBubble = true;
+            this.drawing = false;
+          }
+        }
+      });
+      //鼠标移动
+      this.stage.on("mousemove", (e) => {
+        if (vc_this.currentTool && vc_this.drawing) {
+          //绘画中
+          vc_this.stageMousemove(vc_this.currentTool);
+        }
+      });
+      //鼠标放开
+      vc_this.stage.on("mouseup", (e) => {
+        if (e.evt.button == 0) {
+          if (vc_this.currentTool && vc_this.drawing) {
+            vc_this.stageMouseup(vc_this.currentTool, e);
+          }
+        } else if (e.evt.button == 2) {
+          if (
+            vc_this.currentTool &&
+            !vc_this.drawing &&
+            vc_this.polygonPoints.length != 0
+          ) {
+            vc_this.stageMouseup(vc_this.currentTool, e);
+          }
+        }
+      });
+      //鼠标滚轮事件
+      vc_this.stage.on("wheel", (e) => {
+        if (vc_this.shape) {
+          var step = 0.03; // 每次缩放的比例
+          var mousePos = vc_this.stage.getPointerPosition();
+          var x = mousePos.x / vc_this.scale,
+            y = mousePos.y / vc_this.scale;
+          if (e.evt.wheelDelta > 0) {
+            vc_this.mouseOffsetX = x * step;
+            vc_this.mouseOffsetY = y * step;
+            // 放大
+            vc_this.layer.scaleX(vc_this.layer.scaleX() + step);
+            vc_this.layer.scaleY(vc_this.layer.scaleY() + step);
+            vc_this.layer.move({ x: -vc_this.mouseOffsetX, y: -vc_this.mouseOffsetY });
+            vc_this.mouseOffsetList.push(vc_this.mouseOffsetX, vc_this.mouseOffsetY);
+            //维持原来大小
+            vc_this.layer.find("Circle").forEach((element) => {
+              element.setAttr("radius", 5 / vc_this.scale / vc_this.layer.scaleX());
+            });
+            vc_this.layer.find("Label").forEach((element) => {
+              element.getText().setAttrs({
+                fontSize: 16 / vc_this.scale / vc_this.layer.scaleX(),
+                padding: 1 / vc_this.scale / vc_this.layer.scaleX(),
+              });
+            });
+            vc_this.stage.draw();
+          } else if (e.evt.wheelDelta < 0 && vc_this.mouseOffsetList.length != 0) {
+            vc_this.layer.scaleX(vc_this.layer.scaleX() - step);
+            vc_this.layer.scaleY(vc_this.layer.scaleY() - step);
+            vc_this.mouseOffsetY = vc_this.mouseOffsetList.pop();
+            vc_this.mouseOffsetX = vc_this.mouseOffsetList.pop();
+            vc_this.layer.move({ x: vc_this.mouseOffsetX, y: vc_this.mouseOffsetY });
+            //维持原来大小
+            vc_this.layer.find("Circle").forEach((element) => {
+              element.setAttr("radius", 5 / vc_this.scale / vc_this.layer.scaleX());
+            });
+            vc_this.layer.find("Label").forEach((element) => {
+              element.getText().setAttrs({
+                fontSize: 16 / vc_this.scale / vc_this.layer.scaleX(),
+                padding: 1 / vc_this.scale / vc_this.layer.scaleX(),
+              });
+            });
+            vc_this.stage.draw();
+          }
+        }
+      });
+      //舞台快捷键
+      var container = this.stage.container();
+      container.tabIndex = 1;
+      container.focus();
+      container.addEventListener("keydown", (e) => {
+        //删除的快捷键
+        if (e.keyCode === 46) {
+          if (this.currentDel) {
+            this.currentDel.destroy();
+            this.currentDel = null;
+            this.$message({
+              message: "删除成功!",
+              type: "success",
+              center: true,
+              duration: 1000,
+            });
+          }
+        }
+        vc_this.stage.container().style.cursor = "crosshair";
+        e.preventDefault();
+        vc_this.layer.draw();
+      });
+      container.addEventListener("keydown", (e) => {
+        //撤销的快捷键(ctrl+z)
+        if (e.ctrlKey == true && e.keyCode == 90) {
+          switch (this.currentTool.type) {
+            case "rect":
+              //正在绘画,直接删除group
+              if (this.drawing) {
+                this.currentDrawingShape.getParent().destroy();
+                this.rectPoints = [];
+                this.drawing = false;
+              } else {
+                //绘画完成,直接删除group
+                this.currentCancel.destroy();
+                this.rectPoints = [];
+                this.drawing = false;
+              }
+              break;
+            case "poly":
+              //删除点
+              var y = this.polygonPoints.pop();
+              var x = this.polygonPoints.pop();
+              //如果撤销的是第一个点,直接删除group
+              if (this.drawing && this.polygonPoints.length == 0) {
+                this.currentCancel.destroy();
+                this.drawing = false;
+              } //如果是已绘画完的多边形
+              else if (!this.drawing && this.polygonPoints.length == 0) {
+                if (this.currentCancel) {
+                  this.currentCancel.destroy();
+                  this.currentCancel = null;
+                  this.$message({
+                    message: "删除成功!",
+                    type: "success",
+                    center: true,
+                    duration: 1000,
+                  });
+                }
+              } else {
+                this.currentCancel
+                  .getChildren((node) => {
+                    return node.x() == x && node.y() == y;
+                  })[0]
+                  .destroy();
+                //重新绘画多边形
+                //最好使用konva提供的鼠标xy点坐标
+                var mousePos = this.stage.getPointerPosition();
+                //考虑鼠标缩放
+                var x =
+                    (mousePos.x / this.scale - this.layer.getAttr("x")) /
+                    this.layer.scaleX(),
+                  y =
+                    (mousePos.y / this.scale - this.layer.getAttr("y")) /
+                    this.layer.scaleY();
+                var tempPoints = this.polygonPoints.concat();
+                tempPoints.push(x);
+                tempPoints.push(y);
+                //修改多边形的点
+                this.currentCancel
+                  .find("." + this.currentTool.name + "poly")[0]
+                  .setAttr("points", tempPoints);
+                //重新绘画多边形的边
+                this.currentCancel
+                  .find("." + this.currentTool.name + "line")[0]
+                  .setAttr("points", tempPoints);
+              }
+              break;
+          }
+        }
+        vc_this.stage.container().style.cursor = "crosshair";
+        e.preventDefault();
+        vc_this.layer.draw();
+      });
+    },
+    /**
+     * 在舞台上鼠标点下发生的事件
+     * @param currentTool 当前选择的工具
+     * @param e 传入的event对象
+     */
+    stageMousedown(currentTool, e) {
+      if (currentTool.type == null) {
+        this.$message({
+          message: "请选择标注工具!",
+          type: "warning",
+          center: true,
+          duration: 1000,
+        });
+        return;
+      }
+      switch (currentTool.type) {
+        case "rect":
+          //最好使用konva提供的鼠标xy点坐标
+          var mousePos = this.stage.getPointerPosition();
+          //考虑鼠标缩放
+          var x =
+              (mousePos.x / this.scale - this.layer.getAttr("x")) / this.layer.scaleX(),
+            y = (mousePos.y / this.scale - this.layer.getAttr("y")) / this.layer.scaleY();
+          //拖拽组
+          var group = new Konva.Group({
+            name: currentTool.name + "group",
+            draggable: true,
+          });
+          //添加矩形的初始点
+          var rectTopLeft = this.drawCircle(currentTool, x, y, group, this.rectPoints);
+          //修改矩形顶点名称
+          rectTopLeft.name("rectTopLeft");
+          //绘制矩形
+          this.drawRect(currentTool, x, y, group);
+          //添加矩形的边
+          this.rectPoints.push(x);
+          this.rectPoints.push(y);
+          this.drawLine(currentTool, this.rectPoints, group);
+          this.layer.add(group);
+          this.currentCancel = group;
+          this.layer.draw();
+          //使所有顶点在顶层显示
+          this.stage.find("Circle").forEach((element) => {
+            element.moveToTop();
+          });
+          break;
+        case "poly":
+          //如果数组长度小于2,初始化多边形和顶点,使它们成为一组,否则什么都不做
+          if (this.polygonPoints.length < 2) {
+            //最好使用konva提供的鼠标xy点坐标
+            var mousePos = this.stage.getPointerPosition();
+            //考虑鼠标缩放
+            var x =
+                (mousePos.x / this.scale - this.layer.getAttr("x")) / this.layer.scaleX(),
+              y =
+                (mousePos.y / this.scale - this.layer.getAttr("y")) / this.layer.scaleY();
+            //拖拽组
+            var group = new Konva.Group({
+              name: currentTool.name + "group",
+              draggable: false,
+            });
+            this.polygonPoints = [x, y];
+            //添加多边形的点
+            this.drawCircle(currentTool, x, y, group, this.polygonPoints);
+
+            //绘画多边形
+            this.drawPolygon(currentTool, this.polygonPoints, group);
+            //添加多边形的边
+            this.drawLine(currentTool, this.polygonPoints, group);
+            this.layer.add(group);
+            this.currentCancel = group;
+            //添加标签
+            var label = this.drawLabel(currentTool, x, y, group, this.label);
+            label.hide();
+            //使所有顶点在顶层显示
+            this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+            this.layer.draw();
+          } //多边形增加顶点
+          else {
+            //最好使用konva提供的鼠标xy点坐标
+            var mousePos = this.stage.getPointerPosition();
+            //考虑鼠标缩放
+            var x =
+                (mousePos.x / this.scale - this.layer.getAttr("x")) / this.layer.scaleX(),
+              y =
+                (mousePos.y / this.scale - this.layer.getAttr("y")) / this.layer.scaleY();
+            //group继续添加多边形的点
+            this.drawCircle(
+              currentTool,
+              x,
+              y,
+              this.currentDrawingShape.getParent(),
+              this.polygonPoints
+            );
+            this.polygonPoints.push(x);
+            this.polygonPoints.push(y);
+            //绘画多边形
+            this.currentDrawingShape.setAttr("points", this.polygonPoints);
+            //group继续添加多边形的边
+            this.currentDrawingShape
+              .getParent()
+              .getChildren((node) => {
+                return node.getAttr("name") === currentTool.name + "line";
+              })[0]
+              .setAttr("points", this.polygonPoints);
+            //使所有顶点在顶层显示
+            this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+            this.layer.draw();
+          }
+          break;
+        default:
+          break;
+      }
+      this.drawing = true;
+    },
+    /**
+     * 鼠标在舞台上移动事件
+     * @param currentTool 当前选择的工具
+     * @param e 传入的event对象
+     */
+    stageMousemove(currentTool) {
+      switch (currentTool.type) {
+        case "rect":
+          this.stage.container().style.cursor = "crosshair";
+          //矩形初始化,鼠标移动操作
+          //最好使用konva提供的鼠标xy点坐标
+          var mousePos = this.stage.getPointerPosition();
+          //考虑鼠标缩放
+          var x =
+              (mousePos.x / this.scale - this.layer.getAttr("x")) / this.layer.scaleX(),
+            y = (mousePos.y / this.scale - this.layer.getAttr("y")) / this.layer.scaleY();
+          var point1 = [this.rectPoints[0], this.rectPoints[1]];
+          var point2 = [x, this.rectPoints[1]];
+          var point3 = [x, y];
+          var point4 = [this.rectPoints[0], y];
+          //如果矩形顶点不足创建顶点
+          if (this.rectPoints.length < 8) {
+            this.rectPoints = point1.concat(point2, point3, point4);
+            //删除第一个顶点
+            this.currentDrawingShape
+              .getParent()
+              .getChildren((element) => {
+                return element.getAttr("name") === "rectTopLeft";
+              })[0]
+              .destroy();
+            var rectTopLeft = this.drawCircle(
+              currentTool,
+              point1[0],
+              point1[1],
+              this.currentDrawingShape.getParent(),
+              this.rectPoints
+            );
+            rectTopLeft.name("rectTopLeft");
+            //添加标签
+            var label = this.drawLabel(
+              currentTool,
+              point1[0],
+              point1[1],
+              this.currentDrawingShape.getParent(),
+              this.label
+            );
+            label.hide();
+            var rectTopRight = this.drawCircle(
+              currentTool,
+              point2[0],
+              point2[1],
+              this.currentDrawingShape.getParent(),
+              this.rectPoints
+            );
+            rectTopRight.name("rectTopRight");
+            var rectBottomRight = this.drawCircle(
+              currentTool,
+              point3[0],
+              point3[1],
+              this.currentDrawingShape.getParent(),
+              this.rectPoints
+            );
+            rectBottomRight.name("rectBottomRight");
+            var rectBottomLeft = this.drawCircle(
+              currentTool,
+              point4[0],
+              point4[1],
+              this.currentDrawingShape.getParent(),
+              this.rectPoints
+            );
+            rectBottomLeft.name("rectBottomLeft");
+          }
+          //修改矩形的顶点
+          this.rectPoints[2] = point2[0];
+          this.rectPoints[3] = point2[1];
+
+          this.rectPoints[4] = point3[0];
+          this.rectPoints[5] = point3[1];
+
+          this.rectPoints[6] = point4[0];
+          this.rectPoints[7] = point4[1];
+          this.currentDrawingShape
+            .getParent()
+            .getChildren((node) => {
+              return node.getAttr("name") === "rectTopRight";
+            })[0]
+            .setAttrs({
+              x: point2[0],
+              y: point2[1],
+            });
+          this.currentDrawingShape
+            .getParent()
+            .getChildren((node) => {
+              return node.getAttr("name") === "rectBottomRight";
+            })[0]
+            .setAttrs({
+              x: point3[0],
+              y: point3[1],
+            });
+          this.currentDrawingShape
+            .getParent()
+            .getChildren((node) => {
+              return node.getAttr("name") === "rectBottomLeft";
+            })[0]
+            .setAttrs({
+              x: point4[0],
+              y: point4[1],
+            });
+          //添加矩形的边
+          this.currentDrawingShape
+            .getParent()
+            .getChildren((node) => {
+              return node.getAttr("name") === currentTool.name + "line";
+            })[0]
+            .setAttr("points", this.rectPoints);
+          this.currentDrawingShape.setAttrs({
+            width: x - this.rectPoints[0],
+            height: y - this.rectPoints[1],
+          });
+          //使所有顶点在顶层显示
+          this.stage.find("Circle").forEach((element) => {
+            element.moveToTop();
+          });
+          break;
+        case "poly":
+          this.stage.container().style.cursor = "crosshair";
+          //多边形初始化后,如果数组长度大于2,鼠标移动时,实时更新下一个点
+          if (this.polygonPoints.length >= 2) {
+            var mousePos = this.stage.getPointerPosition();
+            var x =
+                (mousePos.x / this.scale - this.layer.getAttr("x")) / this.layer.scaleX(),
+              y =
+                (mousePos.y / this.scale - this.layer.getAttr("y")) / this.layer.scaleY();
+            var tempPoints = this.polygonPoints.concat([]);
+            tempPoints.push(x);
+            tempPoints.push(y);
+            //更新多边形的线
+            this.currentDrawingShape
+              .getParent()
+              .getChildren((element) => {
+                return element.getAttr("name") === currentTool.name + "line";
+              })[0]
+              .setAttr("points", tempPoints);
+            //更新多边形
+            this.currentDrawingShape.setAttr("points", tempPoints);
+            //使所有顶点在顶层显示
+            this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+          }
+          break;
+        default:
+          break;
+      }
+      this.layer.draw();
+    },
+    /**
+     * 鼠标在舞台弹起
+     * @param currentTool 当前选择的工具
+     * @param e 传入的event对象
+     */
+    stageMouseup(currentTool, e) {
+      switch (currentTool.type) {
+        case "rect":
+          this.currentDrawingShape = this.currentDrawingShape.getParent();
+          if (
+            this.currentDrawingShape.getChildren((element) => {
+              return element.getClassName() === "Circle";
+            }).length < 4
+          ) {
+            this.drawing = false;
+            this.currentDrawingShape.destroy();
+            this.rectPoints = [];
+            this.$message({
+              message: "矩形过小!",
+              type: "warning",
+              center: true,
+              duration: 1000,
+            });
+            return;
+          } else {
+            //显示标签
+            this.currentDrawingShape
+              .getChildren((element) => {
+                return element.getAttr("name") === currentTool.name + "label";
+              })[0]
+              .show();
+            this.rectPoints = [];
+            this.drawing = false;
+            //使所有顶点在顶层显示
+            this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+          }
+          break;
+        case "poly":
+          if (e.evt.button == 2) {
+            this.currentDrawingShape = this.currentDrawingShape.getParent();
+            //显示标签
+            this.currentDrawingShape
+              .getChildren((element) => {
+                return element.getAttr("name") === currentTool.name + "label";
+              })[0]
+              .show();
+            //形成多边形直接发送数据
+            this.$message({
+              message: "成功!",
+              type: "success",
+              center: true,
+              duration: 1000,
+            });
+            //右键弹起
+            this.polygonPoints = [];
+            //使所有顶点在顶层显示
+            this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+          }
+          break;
+        default:
+          break;
+      }
+      this.layer.draw();
+    },
+    /**
+     * 多边形圆形
+     * @param //x x坐标
+     * @param //y y坐标
+     */
+    drawCircle(currentTool, x, y, group, shapePoints) {
+      var vc_this = this;
+      var circle = new Konva.Circle({
+        name: currentTool.name + "circle",
+        x: x,
+        y: y,
+        radius: 5 / this.scale / this.layer.scaleX(),
+        visible: true, //是否显示
+        fill: currentTool.anchorColor,
+        stroke: currentTool.anchorColor,
+        draggable: false,
+        strokeWidth: 0.5,
+        strokeScaleEnabled: false,
+        //增加点击区域
+        hitStrokeWidth: 8 / this.scale / this.layer.scaleX(),
+        //设置拖动区域,不能超过舞台大小
+        dragBoundFunc: function (pos) {
+          //左上角
+          if (pos.x < 0 && pos.y < 0) {
+            return {
+              x: 0,
+              y: 0,
+            };
+          } //左侧
+          else if (pos.x <= 0 && 0 <= pos.y && pos.y <= vc_this.stage.height()) {
+            return {
+              x: 0,
+              y: pos.y,
+            };
+          }
+          //左下角
+          else if (pos.x < 0 && pos.y > vc_this.stage.height()) {
+            return {
+              x: 0,
+              y: vc_this.stage.height(),
+            };
+          } //下侧
+          else if (
+            0 <= pos.x &&
+            pos.x <= vc_this.stage.width() &&
+            pos.y > vc_this.stage.height()
+          ) {
+            return {
+              x: pos.x,
+              y: vc_this.stage.height(),
+            };
+          } //右下角
+          else if (pos.x > vc_this.stage.width() && pos.y > vc_this.stage.height()) {
+            return {
+              x: vc_this.stage.width(),
+              y: vc_this.stage.height(),
+            };
+          }
+          //右侧
+          else if (
+            pos.x > vc_this.stage.width() &&
+            0 <= pos.y &&
+            pos.y <= vc_this.stage.height()
+          ) {
+            return {
+              x: vc_this.stage.width(),
+              y: pos.y,
+            };
+          }
+          //右上角
+          else if (pos.x > vc_this.stage.width() && pos.y < 0) {
+            return {
+              x: vc_this.stage.width(),
+              y: 0,
+            };
+          } //上侧
+          else if (0 <= pos.x && pos.x <= vc_this.stage.width() && pos.y < 0) {
+            return {
+              x: pos.x,
+              y: 0,
+            };
+          }
+        },
+      });
+      group.add(circle);
+      var xChange, yChange;
+      circle.on("mouseover", (e) => {
+        vc_this.stage.container().style.cursor = "pointer";
+      });
+      circle.on("mousedown", (e) => {
+        if (!vc_this.drawing) {
+          circle.draggable(true);
+          //将现在绘画的对象改为group
+          vc_this.currentDrawingShape = circle.getParent();
+        } else {
+          circle.draggable(false);
+        }
+        e.cancelBubble = true;
+      });
+      circle.on("mouseleave", (e) => {
+        vc_this.stage.container().style.cursor = "crosshair";
+      });
+      circle.on("dragstart", (e) => {
+        switch (currentTool.type) {
+          case "rect":
+            vc_this.currentDrawingShape = circle.getParent();
+            break;
+          case "poly":
+            //查找拖拽了多边形的哪个点
+            for (var i = 0; i < shapePoints.length; i += 2) {
+              if (
+                circle.getAttr("x") == shapePoints[i] &&
+                circle.getAttr("y") == shapePoints[i + 1]
+              ) {
+                xChange = i;
+                yChange = i + 1;
+                break;
+              }
+            }
+            break;
+          default:
+            break;
+        }
+      });
+      circle.on("dragmove", (e) => {
+        switch (currentTool.type) {
+          case "rect":
+            //查找拖拽了多边形的哪个点
+            var circleName = circle.name();
+            //修改点位置
+            var anchorX = circle.getX();
+            var anchorY = circle.getY();
+            switch (circleName) {
+              case "rectTopLeft":
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectTopRight";
+                  })[0]
+                  .y(anchorY);
+                //修改线
+                shapePoints[3] = anchorY;
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectBottomLeft";
+                  })[0]
+                  .x(anchorX);
+                shapePoints[6] = anchorX;
+                //更改拖拽点的位置来改变线段
+                shapePoints[0] = anchorX;
+                shapePoints[1] = anchorY;
+                break;
+              case "rectTopRight":
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectTopLeft";
+                  })[0]
+                  .y(anchorY);
+                shapePoints[1] = anchorY;
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectBottomRight";
+                  })[0]
+                  .x(anchorX);
+                shapePoints[4] = anchorX;
+                //更改拖拽点的位置来改变线段
+                shapePoints[2] = anchorX;
+                shapePoints[3] = anchorY;
+                break;
+              case "rectBottomRight":
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectBottomLeft";
+                  })[0]
+                  .y(anchorY);
+                shapePoints[7] = anchorY;
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectTopRight";
+                  })[0]
+                  .x(anchorX);
+                shapePoints[2] = anchorX;
+                //更改拖拽点的位置来改变线段
+                shapePoints[4] = anchorX;
+                shapePoints[5] = anchorY;
+                break;
+              case "rectBottomLeft":
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectBottomRight";
+                  })[0]
+                  .y(anchorY);
+                shapePoints[5] = anchorY;
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectTopLeft";
+                  })[0]
+                  .x(anchorX);
+                shapePoints[0] = anchorX;
+                //更改拖拽点的位置来改变线段
+                shapePoints[6] = anchorX;
+                shapePoints[7] = anchorY;
+                break;
+            }
+            //隐藏label
+            vc_this.currentDrawingShape
+              .getChildren((element) => {
+                return element.getAttr("name") === currentTool.name + "label";
+              })[0]
+              .hide();
+            //修改矩形位置和大小
+            vc_this.currentDrawingShape
+              .getChildren((element) => {
+                return element.getAttr("name") === currentTool.name + "rect";
+              })[0]
+              .position(
+                vc_this.currentDrawingShape
+                  .getChildren((element) => {
+                    return element.getAttr("name") === "rectTopLeft";
+                  })[0]
+                  .position()
+              );
+            var width =
+              vc_this.currentDrawingShape
+                .getChildren((element) => {
+                  return element.getAttr("name") === "rectTopRight";
+                })[0]
+                .getX() -
+              vc_this.currentDrawingShape
+                .getChildren((element) => {
+                  return element.getAttr("name") === "rectTopLeft";
+                })[0]
+                .getX();
+            var height =
+              vc_this.currentDrawingShape
+                .getChildren((element) => {
+                  return element.getAttr("name") === "rectBottomLeft";
+                })[0]
+                .getY() -
+              vc_this.currentDrawingShape
+                .getChildren((element) => {
+                  return element.getAttr("name") === "rectTopLeft";
+                })[0]
+                .getY();
+            if (width && height) {
+              vc_this.currentDrawingShape
+                .getChildren((element) => {
+                  return element.getAttr("name") === currentTool.name + "rect";
+                })[0]
+                .width(width);
+              vc_this.currentDrawingShape
+                .getChildren((element) => {
+                  return element.getAttr("name") === currentTool.name + "rect";
+                })[0]
+                .height(height);
+            }
+            break;
+          case "poly":
+            //隐藏label
+            vc_this.currentDrawingShape
+              .getChildren((element) => {
+                return element.getAttr("name") === currentTool.name + "label";
+              })[0]
+              .hide();
+            var x = circle.x();
+            var y = circle.y();
+            //更改拖拽点的位置
+            shapePoints[xChange] = x;
+            shapePoints[yChange] = y;
+            break;
+          default:
+            break;
+        }
+      });
+      circle.on("dragend", (e) => {
+        console.log(e,2)
+        switch (currentTool.type) {
+          case "rect":
+            //修改标签位置
+            var rect = vc_this.currentDrawingShape.getChildren((node) => {
+              return node.getAttr("name") === currentTool.name + "rect";
+            })[0];
+            var label = vc_this.currentDrawingShape.getChildren((node) => {
+              return node.getAttr("name") === currentTool.name + "label";
+            })[0];
+            label.setAttrs({
+              x:
+                (rect.getClientRect().x / vc_this.scale - vc_this.layer.getAttr("x")) /
+                vc_this.layer.scaleX(),
+              y:
+                (rect.getClientRect().y / vc_this.scale - vc_this.layer.getAttr("y")) /
+                vc_this.layer.scaleX(),
+              visible: true,
+            });
+            //使所有顶点在顶层显示
+            vc_this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+            circle.draggable(false);
+            break;
+          case "poly":
+            //修改标签位置
+            var poly = vc_this.currentDrawingShape.getChildren((node) => {
+              return node.getAttr("name") === currentTool.name + "poly";
+            })[0];
+            var label = vc_this.currentDrawingShape.getChildren((node) => {
+              return node.getAttr("name") === currentTool.name + "label";
+            })[0];
+            label.setAttrs({
+              x: poly.points()[0],
+              y: poly.points()[1],
+              visible: true,
+            });
+            //使所有顶点在顶层显示
+            vc_this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+            circle.draggable(false);
+            break;
+          default:
+            break;
+        }
+        vc_this.$message({
+          message: "修改成功!",
+          type: "success",
+          center: true,
+          duration: 1000,
+        });
+
+        e.cancelBubble = true;
+      });
+      return circle;
+    },
+    drawLabel(currentTool, x, y, group, labelText) {
+      var label = new Konva.Label({
+        x: x,
+        y: y,
+        name: currentTool.name + "label",
+        visible: true,
+        opacity: 1,
+      });
+      var tag = new Konva.Tag({
+        fill: currentTool.color,
+      });
+      var text = new Konva.Text({
+        text: labelText,
+        fontFamily: "Calibri",
+        fontSize: 16 / this.scale / this.layer.scaleX(),
+        padding: 1 / this.scale / this.layer.scaleX(),
+        fill: "#fff",
+      });
+      label.add(tag);
+      label.add(text);
+      group.add(label);
+      return label;
+    },
+    /**
+     * 线
+     * @param //points 坐标数组
+     */
+    drawLine(currentTool, points, group) {
+      var line = new Konva.Line({
+        name: currentTool.name + "line",
+        points: points,
+        stroke: currentTool.lineColor,
+        strokeWidth: 1,
+        visible: true,
+        draggable: false,
+        closed: true,
+        strokeScaleEnabled: false,
+        opacity: 1, //透明度
+      });
+      group.add(line);
+      return line;
+    },
+    /**
+         *多边形
+          @param currentTool
+         * @param points 多边形绘画的各个顶点,类型数组
+         */
+    drawPolygon(currentTool, points, group) {
+      var poly = new Konva.Line({
+        name: currentTool.name + "poly",
+        points: points,
+        /*  fill: currentTool.color, */
+        stroke: currentTool.color,
+        strokeWidth: 1,
+        draggable: false,
+        opacity: 0.5,
+        lineCap: "round",
+        lineJoin: "round",
+        closed: true,
+        strokeScaleEnabled: false,
+      });
+      this.currentDrawingShape = poly;
+      group.add(poly);
+      var vc_this = this;
+      poly.getParent().on("mouseleave", (e) => {
+        vc_this.stage.container().style.cursor = "crosshair";
+      });
+      poly.getParent().on("mousedown", (e) => {
+        if (e.evt.button == 0) {
+          //绘画结束
+          if (!vc_this.drawing) {
+            vc_this.stage.container().style.cursor = "move";
+            //设置现在绘画节点的对象为该多边形和顶点的组
+            vc_this.currentDrawingShape = poly.getParent();
+            // 如果要让顶点和多边形一起拖拽,必须设置,多边形不能被拖拽
+            poly.setAttr("draggable", false);
+            poly.getParent().setAttr("draggable", true);
+            //使所有顶点在顶层显示
+            vc_this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+            //添加删除撤销对象
+            this.currentDel = vc_this.currentDrawingShape;
+            this.currentCancel = vc_this.currentDrawingShape;
+            vc_this.layer.draw();
+          } else {
+            vc_this.stage.container().style.cursor = "crosshair";
+            poly.getParent().setAttr("draggable", false);
+          }
+        }
+      });
+      poly.getParent().on("dragend", (e) => {
+        if (currentTool.name === vc_this.toolObject[1].name) {
+          var updatePoints = [];
+          var polyPoints = poly.points();
+          for (var i = 0; i < polyPoints.length / 2; i++) {
+            updatePoints.push(polyPoints[i * 2] + poly.getParent().x());
+            updatePoints.push(polyPoints[i * 2 + 1] + poly.getParent().y());
+          }
+          poly.getParent().destroy();
+          vc_this.currentDrawingShape = vc_this.drawGroup(
+            updatePoints,
+            vc_this.toolObject[1]
+          );
+          //使所有顶点在顶层显示
+          vc_this.stage.find("Circle").forEach((element) => {
+            element.moveToTop();
+          });
+          //添加删除撤销对象
+          this.currentDel = vc_this.currentDrawingShape;
+          this.currentCancel = vc_this.currentDrawingShape;
+          vc_this.layer.draw();
+          /*   vc_this.setMaskData(); */
+        }
+        vc_this.$message({
+          message: "修改成功!",
+          type: "success",
+          center: true,
+          duration: 1000,
+        });
+        vc_this.stage.container().style.cursor = "crosshair";
+        //设置组不能拖动
+        vc_this.currentDrawingShape.setAttr("draggable", false);
+      });
+      return poly;
+    },
+    /**
+     *矩形
+     * @param (currentTool, x, y, group)
+     */
+    drawRect(currentTool, x, y, group) {
+      var rect = new Konva.Rect({
+        name: currentTool.name + "rect",
+        x: x,
+        y: y,
+        width: 0,
+        height: 0,
+        opacity: 0.5,
+        /*   fill: currentTool.color, */
+        stroke: currentTool.color,
+        strokeScaleEnabled: false,
+        strokeWidth: 1,
+      });
+      this.currentDrawingShape = rect;
+      group.add(rect);
+      var vc_this = this;
+      rect.getParent().on("mouseleave", () => {
+        vc_this.stage.container().style.cursor = "crosshair";
+      });
+      rect.getParent().on("mousedown", (e) => {
+        if (e.evt.button == 0) {
+          //如果不是正在绘画图形时
+          if (!vc_this.drawing) {
+            vc_this.stage.container().style.cursor = "move";
+            //设置现在绘画节点的对象为该多边形和顶点的组
+            vc_this.currentDrawingShape = rect.getParent();
+            // 如果要让顶点和多边形一起拖拽,必须设置,多边形不能被拖拽
+            rect.setAttr("draggable", false);
+            rect.getParent().setAttr("draggable", true);
+            //使所有顶点在顶层显示
+            vc_this.stage.find("Circle").forEach((element) => {
+              element.moveToTop();
+            });
+            //添加删除撤销对象
+            this.currentDel = vc_this.currentDrawingShape;
+            this.currentCancel = vc_this.currentDrawingShape;
+            vc_this.layer.draw();
+          } else {
+            vc_this.stage.container().style.cursor = "crosshair";
+            rect.getParent().setAttr("draggable", false);
+          }
+        }
+      });
+      rect.getParent().on("dragend", (e) => {
+        if (currentTool.name === vc_this.toolObject[0].name) {
+          var updatePoints = [];
+          var rectPoints = rect
+            .getParent()
+            .getChildren((element) => {
+              return element.getAttr("name") === currentTool.name + "line";
+            })[0]
+            .points();
+          for (var i = 0; i < rectPoints.length / 2; i++) {
+            updatePoints.push(rectPoints[i * 2] + rect.getParent().x());
+            updatePoints.push(rectPoints[i * 2 + 1] + rect.getParent().y());
+          }
+          rect.getParent().destroy();
+          vc_this.currentDrawingShape = vc_this.drawGroup(
+            updatePoints,
+            vc_this.toolObject[0]
+          );
+          //添加删除撤销对象
+          this.currentDel = vc_this.currentDrawingShape;
+          this.currentCancel = vc_this.currentDrawingShape;
+          vc_this.layer.draw();
+          /*   vc_this.setMaskData(); */
+        }
+        //使所有顶点在顶层显示
+        vc_this.stage.find("Circle").forEach((element) => {
+          element.moveToTop();
+        });
+        vc_this.$message({
+          message: "修改成功!",
+          type: "success",
+          center: true,
+          duration: 1000,
+        });
+        vc_this.stage.container().style.cursor = "crosshair";
+        //设置组不能拖动
+        vc_this.currentDrawingShape.setAttr("draggable", false);
+      });
+      return rect;
+    },
+    /**
+     *多边形组
+     * @param points 多边形绘画的各个顶点,类型数组
+     */
+    drawGroup(points, currentTool) {
+      //拖拽组
+      var group = new Konva.Group({
+        name: currentTool.name + "Group",
+        draggable: false,
+      });
+      switch (currentTool.type) {
+        case "poly":
+          for (var i = 0; i < points.length / 2; i++) {
+            var p = {
+              x: points[i * 2],
+              y: points[i * 2 + 1],
+            };
+            if (i == 0) {
+              //添加标签
+              this.drawLabel(currentTool, p.x, p.y, group, this.label);
+            }
+            //添加多边形的点
+            this.drawCircle(currentTool, p.x, p.y, group, points);
+          }
+          //绘画多边形
+          var poly = this.drawPolygon(currentTool, points, group);
+          //添加多边形的边
+          var polyline = this.drawLine(currentTool, points, group);
+          poly.moveToBottom();
+          polyline.moveToBottom();
+          this.layer.draw();
+          //使所有顶点在顶层显示
+          this.stage.find("Circle").forEach((element) => {
+            element.moveToTop();
+          });
+          break;
+        case "rect":
+          //添加矩形的点
+          for (var i = 0; i < points.length / 2; i++) {
+            var p = {
+              x: points[i * 2],
+              y: points[i * 2 + 1],
+            };
+            //添加矩形的点
+            this.drawCircle(currentTool, p.x, p.y, group, points);
+          }
+          //修改顶点的名字
+          group
+            .getChildren((node) => {
+              return node.getClassName() === "Circle";
+            })[0]
+            .name("rectTopLeft");
+          group
+            .getChildren((node) => {
+              return node.getClassName() === "Circle";
+            })[1]
+            .name("rectTopRight");
+          group
+            .getChildren((node) => {
+              return node.getClassName() === "Circle";
+            })[2]
+            .name("rectBottomRight");
+          group
+            .getChildren((node) => {
+              return node.getClassName() === "Circle";
+            })[3]
+            .name("rectBottomLeft");
+          //绘制矩形
+          var rect = this.drawRect(currentTool, points[0], points[1], group);
+          this.currentDrawingShape.setAttrs({
+            width: points[4] - points[0],
+            height: points[5] - points[1],
+          });
+          //添加矩形的边
+          this.drawLine(currentTool, points, group);
+          //添加标签
+          this.drawLabel(
+            currentTool,
+            rect.getClientRect().x,
+            rect.getClientRect().y,
+            group,
+            this.label
+          );
+          //使所有顶点在顶层显示
+          this.stage.find("Circle").forEach((element) => {
+            element.moveToTop();
+          });
+          break;
+        default:
+          break;
+      }
+      this.layer.add(group);
+      this.layer.draw();
+      return group;
+    },
+  },
+  mounted() {
+    this.initKonvaStage();
+    this.$nextTick(() => {
+      window.addEventListener("resize", this.resizeStage);
+    });
+    //禁止浏览器右击菜单
+    document.oncontextmenu = function (e) {
+      return false;
+    };
+  },
+  destroyed() {
+    window.removeEventListener("resize", this.resizeStage);
+    this.stage.destroy();
+  },
+};
+</script>
+
+<style scoped>
+#map {
+  background: #ddd;
+  width: 100%;
+  aspect-ratio: 16/9;
+}
+</style>

+ 440 - 0
ruoyi-ui/src/views/shipinggaoj/shebecanshuhuabu/index - 副本.vue

@@ -0,0 +1,440 @@
+<template>
+  <div>
+
+  </div>
+</template>
+<script>
+// import mqttHandle from "../../../utils/mqttHandler.js"
+import mqtt from 'mqtt';
+import { MqttClient } from 'mqtt'
+// 状态变量
+ // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
+ var client = MqttClient||null
+export default {
+  data() {
+    return {
+      imgUrl: "../../../assets/images/pic_ssyl_lt.png",
+      isDrawing: false, // 是否正在绘制
+      ratio: 1,
+      imgWidth: 3020,
+      imgHeight: 1080,
+      wrapWidth: 600,
+      wrapHeight: 300,
+      canvasWidth: 600,
+      canvasHeight: 300,
+      drawingPoints: [],
+      drawedPoints: [],
+      imgCanvas: null,
+      imgCtx: null,
+      drawCanvas: null,
+      drawCtx: null,
+      saveCanvas: null,
+      saveCtx: null,
+      submitData: [
+        // {"polygon":{"x1":0,"y1":0,"x2":1920,"y2":0,"x3":1920,"y3":1080,"x4":0,"y4":1080}},
+        // {
+        //   polygon: {
+        //     x1: 700,
+        //     y1: 273,
+        //     x2: 975,
+        //     y2: 278,
+        //     x3: 1107,
+        //     y3: 368,
+        //     x4: 718,
+        //     y4: 354,
+        //   },
+        // },
+        // {
+        //   polygon: {
+        //     x1: 49,
+        //     y1: 32,
+        //     x2: 183,
+        //     y2: 35,
+        //     x3: 181,
+        //     y3: 100,
+        //     x4: 55,
+        //     y4: 97,
+        //   },
+        // },
+        // {
+        //   polygon: {
+        //     x1: 433,
+        //     y1: 250,
+        //     x2: 706,
+        //     y2: 253,
+        //     x3: 707,
+        //     y3: 392,
+        //     x4: 435,
+        //     y4: 393,
+        //   },
+        // },
+        // {
+        //   polygon: {
+        //     x1: 45,
+        //     y1: 539,
+        //     x2: 193,
+        //     y2: 538,
+        //     x3: 192,
+        //     y3: 622,
+        //     x4: 41,
+        //     y4: 623,
+        //     x5: 42,
+        //     y5: 623,
+        //   },
+        // },
+      ],
+      connectionStatus:'',
+      isConnected:false,
+      connecting:false,
+      messages:[{ type: 'sent' , content: '', timestamp: '' }],
+      messageToSend:[],
+      mqttConfig:{
+      	url: 'ws://13.229.167.76:1884/mqtt',
+      	topic: 'detection/rect'
+      },
+      mqttThemeName:{
+      	url: 'ws://13.229.167.76:1884/mqtt',
+      	topic: 'detection/rect'
+      },
+      // [
+      //   {"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354}}
+      // ]
+    };
+  },
+  created() {
+
+    // console.log(JSON.parse(this.$route.query.src))
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.initCanvas();
+      this.getImage();
+    });
+    // this.toggleConnection()
+    // this.mqttzz()
+    // setTimeout(() => {
+    // }, 500);
+  },
+  methods: {
+    // 创mqtt最终版
+    mqttzz(){
+      // 创建一个连接到MQTT broker的客户端实例
+         // 连接成功后,订阅一个主题
+         client.on('connect', function () {
+           client.subscribe('detection/rect', function (err) {
+             if (!err) {
+               console.log('成功订阅 detection/rect 主题!')
+             }
+           })
+         })
+
+         // 监听订阅主题上的消息
+         client.on('message', function (topic, message) {
+           // 处理接收到的消息
+           console.log('收到主题 ' + topic + ' 的消息: ' + message.toString())
+         })
+    },
+    initCanvas() {
+      // 初始化canvas画布
+
+      let canvasWrap = document.getElementsByClassName("canvas-wrap");
+      this.wrapWidth = canvasWrap[0].clientWidth;
+      this.wrapHeight = canvasWrap[0].clientHeight;
+
+      this.imgCanvas = document.getElementById("imgCanvas");
+      this.imgCtx = this.imgCanvas.getContext("2d");
+
+      // 绘制canvas
+      this.drawCanvas = document.getElementById("drawCanvas");
+      this.drawCtx = this.drawCanvas.getContext("2d");
+
+      // 保存绘制区域 saveCanvas
+      this.saveCanvas = document.getElementById("saveCanvas");
+      this.saveCtx = this.saveCanvas.getContext("2d");
+      // this.initImgCanvas()
+    },
+    initImgCanvas() {
+      // 计算宽高比
+      let ww = this.wrapWidth; // 画布宽度
+      let wh = this.wrapHeight; // 画布高度
+      let iw = this.imgWidth; // 图片宽度
+      let ih = this.imgHeight; // 图片高度
+
+      if (iw / ih < ww / wh) {
+        // 以高为主
+        this.ratio = ih / wh;
+        this.canvasHeight = wh;
+        this.canvasWidth = (wh * iw) / ih;
+      } else {
+        // 以宽为主
+        this.ratio = iw / ww;
+        this.canvasWidth = ww;
+        this.canvasHeight = (ww * ih) / iw;
+      }
+      // 初始化画布大小
+      this.imgCanvas.width = this.canvasWidth;
+      this.imgCanvas.height = this.canvasHeight;
+      this.drawCanvas.width = this.canvasWidth;
+      this.drawCanvas.height = this.canvasHeight;
+      this.saveCanvas.width = this.canvasWidth;
+      this.saveCanvas.height = this.canvasHeight;
+
+      // 图片加载绘制
+      let img = document.createElement("img");
+      img.src = this.imgUrl;
+      console.log(this.imgUrl)
+      img.onload = () => {
+        console.log("图片已加载");
+        this.imgCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);
+        this.renderDatas(); // 渲染原有数据
+      };
+    },
+    startDraw() {
+      // 绘制区域
+      if (this.isDrawing) return;
+      this.isDrawing = true;
+      // 绘制逻辑
+      this.drawCanvas.addEventListener("click", this.drawImageClickFn);
+      this.drawCanvas.addEventListener("dblclick", this.drawImageDblClickFn);
+      this.drawCanvas.addEventListener("mousemove", this.drawImageMoveFn);
+    },
+    clearAll() {
+      // 清空所有绘制区域
+      this.saveCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+      this.drawedPoints = [];
+    },
+    getImage() {
+      // 这里请求接口 ...
+      this.imgUrl = "https://img1.baidu.com/it/u=3898911181,4093953224&fm=253&fmt=auto&app=138&f=JPEG?w=600&h=400";
+      // this.imgWidth = 1920;
+      // this.imgHeight = 1080;
+      // this.imgUrl =JSON.parse(this.$route.query.src)
+      this.imgWidth = 660;
+      this.imgHeight = 380;
+      this.imgUrl && this.initImgCanvas();
+    },
+    drawImageClickFn(e) {
+      let drawCtx = this.drawCtx;
+      if (e.offsetX || e.layerX) {
+        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+        let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
+        if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
+          this.drawingPoints.push([pointX, pointY]);
+        }
+      }
+    },
+    drawImageMoveFn(e) {
+      let drawCtx = this.drawCtx;
+      if (e.offsetX || e.layerX) {
+        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+        // 绘制
+        drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+
+        // 绘制点
+        drawCtx.fillStyle = "blue";
+        this.drawingPoints.forEach((item, i) => {
+          drawCtx.beginPath();
+          drawCtx.arc(...item, 6, 0, 180);
+          drawCtx.fill(); //填充
+        });
+
+        // 绘制动态区域
+        drawCtx.save();
+        drawCtx.beginPath();
+        this.drawingPoints.forEach((item, i) => {
+          drawCtx.lineTo(...item);
+        });
+        drawCtx.lineTo(pointX, pointY);
+        drawCtx.lineWidth = "3";
+        drawCtx.strokeStyle = "blue";
+        drawCtx.fillStyle = "rgba(255, 0, 0, 0.3)";
+        drawCtx.stroke();
+        drawCtx.fill(); //填充
+        drawCtx.restore();
+      }
+    },
+    drawImageDblClickFn(e) {
+      let drawCtx = this.drawCtx;
+      let saveCtx = this.saveCtx;
+      if (e.offsetX || e.layerX) {
+        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
+        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
+        let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
+        if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
+          this.drawingPoints.push([pointX, pointY]);
+        }
+      }
+      // 清空绘制图层
+      drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
+      // 绘制区域至保存图层
+      this.drawSaveArea(this.drawingPoints);
+
+      this.drawedPoints.push(this.drawingPoints);
+      this.drawingPoints = [];
+      this.isDrawing = false;
+
+      // 绘制结束逻辑
+      this.drawCanvas.removeEventListener("click", this.drawImageClickFn);
+      this.drawCanvas.removeEventListener("dblclick", this.drawImageDblClickFn);
+      this.drawCanvas.removeEventListener("mousemove", this.drawImageMoveFn);
+    },
+    drawSaveArea(points) {
+      // console.log(points, "points");
+      if (points.length === 0) return;
+      this.saveCtx.save();
+      this.saveCtx.beginPath();
+      points.forEach((item, i) => {
+        this.saveCtx.lineTo(...item);
+      });
+      this.saveCtx.closePath();
+      this.saveCtx.lineWidth = "2";
+      this.saveCtx.fillStyle = "rgba(255,0, 255, 0.3)";
+      this.saveCtx.strokeStyle = "red";
+      this.saveCtx.stroke();
+      this.saveCtx.fill(); //填充
+      this.saveCtx.restore();
+    },
+
+    savePoints() {
+      // 将画布坐标数据转换成提交数据
+      let objectPoints = [];
+      // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
+      objectPoints = this.drawedPoints.map((area) => {
+        let polygon = {};
+        area.forEach((point, i) => {
+          polygon[`x${i + 1}`] = Math.round(point[0] * this.ratio);
+          polygon[`y${i + 1}`] = Math.round(point[1] * this.ratio);
+        });
+        // console.log(polygon)
+        return {
+          polygon: polygon,
+        };
+      });
+      this.submitData = objectPoints;
+      console.log("最终提交数据", objectPoints);
+      this.messageToSend = this.submitData
+      // this.sendMessage()
+      // this.$router.go(-1)
+    },
+    toggleConnection(){
+      if (this.isConnected) {
+        // 断开连接
+        client.end()
+        this.isConnected= false
+        this.connectionStatus = 'Disconnected'
+        return
+      }
+
+      // 建立连接
+      this.connecting = true
+      try {
+        client= mqtt.connect(this.mqttConfig.url, {
+          clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
+          keepalive: 60,
+          clean: true,
+          connectTimeout: 4000,
+          reconnectPeriod: 1000
+        })
+        client.on('connect', () => {
+          this.isConnected = true
+          this.connectionStatus= 'Connected'
+          this.connecting = false
+          console.log(3)
+          // 订阅主题
+          client.subscribe(this.mqttConfig.topic, (err) => {
+            if (err) {
+              console.error('Subscribe error:', err)
+            }else{
+               console.log('成功订阅 detection/rect 主题!')
+            }
+
+          })
+        })
+        client.on('message', (topic, message) => {
+          // 接受信息
+          console.log(topic,message)
+          this.messages.unshift({
+            type: 'received',
+            content: message.toString(),
+            timestamp: new Date().toLocaleTimeString()
+          })
+        })
+        client.on('error', (err) => {
+          console.error('MQTT Error:', err)
+          this.connectionStatus= 'Error'
+          this.connecting = false
+        })
+      } catch (error) {
+        console.error('Connection error:', error)
+        this.connectionStatus= 'Error'
+        this.connecting = false
+      }
+    },
+    sendMessage(){
+      if (!client || !this.messageToSend) return
+      this.messageToSend = JSON.stringify(this.messageToSend)
+      console.log(this.messageToSend)
+      client.publish(this.mqttConfig.topic, this.messageToSend)
+      this.messages.unshift({
+        type: 'sent',
+        content: this.messageToSend,
+        timestamp: new Date().toLocaleTimeString()
+      })
+      this.messageToSend = []
+    },
+    renderDatas() {
+      // 将提交数据数据转换成画布坐标
+      this.drawedPoints = this.submitData.map((item) => {
+        let polygon = item.polygon;
+        let points = [];
+        for (let i = 1; i < Object.keys(polygon).length / 2 + 1; i++) {
+          if (!isNaN(polygon[`x${i}`]) && !isNaN(polygon[`y${i}`])) {
+            points.push([
+              polygon[`x${i}`] / this.ratio,
+              polygon[`y${i}`] / this.ratio,
+            ]);
+          }
+        }
+        this.drawSaveArea(points);
+        return points;
+      });
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+.tool-box {
+  width: 98%;
+  height: 40px;
+  padding: 5px 30px;
+  margin: 20px auto 0;
+  box-sizing: border-box;
+  text-align: right;
+}
+.canvas-wrap {
+  // width: 80vw;
+  // height: 45vw;
+  width:88%;
+  height: 33.75vw;
+  margin: 0px auto;
+  background-color: #000; //#fff;
+  border: 3px;
+  border-color: #333;
+  position: relative;
+}
+#imgCanvas,
+#drawCanvas,
+#saveCanvas {
+  background: rgba(255, 0, 255, 0);
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+}
+#drawCanvas {
+  z-index: 2;
+}
+</style>
+

+ 1345 - 0
ruoyi-ui/src/views/shipinggaoj/shishi/index - 副本.vue

@@ -0,0 +1,1345 @@
+<template>
+  <div class="app-container" style="padding-top: 20px;height: 120vh;"  >
+    <div class="ntgs">
+    <el-row :gutter="10" class="mb8">
+     <div class="iuer" style="margin-bottom:10px;">
+       <!-- <div style="display: flex;align-items: center; " class="ingaqe">
+            <el-select v-model="queryParams.name" placeholder="请选监控名称" clearable>
+              <el-option
+                v-for="dict in postList"
+                :key="dict.indexCode"
+                :label="dict.name"
+                :value="dict.name"
+              />
+            </el-select>
+			<div class="ksfpofg" @click="handleQuery">
+						  搜索
+						  </div>
+       </div> -->
+	   <!-- <div class="ite">
+	      <div class="ksfpo" @click="osge"  v-hasPermi="['system:camera:openDz']">
+			  <img src="../../../assets/images/icon_ssjk_kman_open.png" alt="" style="width:10px;height: 10px;">
+			  开门</div>
+		  <div class="ksfpo ksfpok" @click="osgef" v-hasPermi="['system:camera:closeDz']">
+		  			  <img src="../../../assets/images/icon_ssjk_kman_close.png" alt="" style="width:10px;height: 10px;">
+		  			  关门</div>
+	   </div> -->
+<!--  -->
+     </div>
+      <!-- <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['investigate:table:add']"
+        >新增</el-button>
+      </el-col>
+
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['investigate:table:remove']"
+        >删除</el-button>
+      </el-col> -->
+     <!-- <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['investigate:table:export']"
+        >导出</el-button>
+      </el-col> -->
+      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
+    </el-row>
+	<div>
+		<el-row :gutter="20">
+          <!-- postList -->
+					<el-col :span='5'>
+						<!-- <div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 100vh;overflow:auto" class="infinite-list">
+              <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">通道列表</p>
+              <div style=" height: 36px;;line-height: 36px;margin-top: 10px;"v-for="(item,index) in 20"   >
+                              <div @click="ishg(item)" style="display: flex;align-items: center;justify-content: space-between;">
+                                <div style="font-size: 16px;
+              color: #333333;"> 通道{{ index >8 ? index + 1 : '0'  + (index + 1)}}</div>
+                                <img src="../../../assets/images/icon_htgl_zd.png" alt="" style="width: 10px;height: 12px;">
+                              </div>
+                          </div>
+            </div> -->
+					</el-col>
+        <!-- v-if="isshoe" -->
+        <el-col :span='24' style="padding-left: 30px; background-color: #fff;border-radius: 10px;padding: 20px; height: 100vh;" >
+          <div style="display: flex;align-items: center;justify-content: space-between;">
+            <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">实时检测</p>
+            <div>
+             <!-- <el-button type="danger" plain>删除</el-button>
+              <el-button type="warning" plain>置顶</el-button> -->
+              <el-button type="success" plain @click="cnde">关闭</el-button>
+            </div>
+          </div>
+          <div class="video-container">
+              <!-- <h3>实时YOLO检测</h3> -->
+
+              <!-- http://192.168.101.22:5000/video_feed form.reportAddress -->
+              <img :src="'http://10.90.90.83:5000/video_feed'" width="100%" height="460" id="yolo-stream">
+          </div>
+          <div class="controls">
+              <button @click="refreshStream">刷新视频</button>
+          </div>
+
+          <!-- <div style="width: 100%; height: 480px;">
+            <div v-if="isfse" id="divPlugin" style="width: 100%; height: 480px;" ></div>
+          </div> -->
+          <!-- <img src="../../../assets/images/pic_ssyl_lt.png" alt="" style="width: 100%; margin-top: 20px;"> -->
+          <!-- 344 -->
+          <!-- <video id="video" controls autoplay muted width="100%" height="480px"style="margin-top: 20px;"></video> -->
+        						<!-- <video
+        						      class="videosmall"
+        						      ref="videosmallone"
+        						      preload="auto"
+        						      muted
+        						      autoplay
+        							  width="95%"
+        						      type="rtmp/flv"
+        						    >
+        						      <source src="" />
+        						    </video>
+        					</el-col>
+
+			<!-- <el-col :span="24">
+				<div class="ihgswq wrapper"  ref="wrapper" style=" overflow: hidden;">
+						  <div class="fijge content nhgwesvq" ref="content" style="width:1610px;">
+									<div class='shotw '   v-for="(item,index) in postList" :key="index" @click="isfgw(item)" >
+											  <img src="../../../assets/images/fengm.png" alt="">
+												<img src="../../../assets/images/icon_spjk_play.png" alt="" class="iges">
+											  <p style="font-size: 14px;">{{item.name}}</p>
+									</div>
+						  </div>
+				</div>
+			</el-col> -->
+      </el-col>
+		</el-row>
+
+
+	  <!-- <pagination
+	     v-show="total>0"
+	     :total="total"
+	     :page.sync="queryParams.pageNo"
+	     :limit.sync="queryParams.pageSize"
+	     @pagination="getList"
+	   /> -->
+	</div>
+
+
+	</div>
+
+    <!-- 添加或修改岗位对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+
+    </el-dialog>
+
+    <el-dialog :title="titles" :visible.sync="opens" width="1000px" append-to-body>
+    </el-dialog>
+
+	<el-dialog title="页面二维码" :visible.sync="opent" width="200px" style="padding: 0;" class="nhgrls" append-to-body>
+	  <div v-show="opent" style="display: flex;justify-content: center;align-items: center;">
+		  <!-- <span>{{'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg}}</span> -->
+			   <!-- <vue-qr   :text="'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg" :size="200"></vue-qr> -->
+	  </div>
+	</el-dialog>
+  </div>
+</template>
+
+<script>
+  import { listWarnManage, getWarnManage, delWarnManage, addWarnManage, updateWarnManage } from "@/api/manage/warnManage"
+// import { listPost, getPost, delPost, addPost, updatePost,updateFs,updateGx } from "@/api/kaoch/renyuan";
+// import { listReservat,camera,cameraIndexCode, listReservatd, getReservat, delReservat, addReservat, updateReservat,setPass,delReservathx,openDz,closeDz } from "@/api/tonggi/houtai";
+// import vueQr from "vue-qr";
+// import videojs from 'video.js'
+// import 'video.js/dist/video-js.css'
+// import {videoPlayer} from 'vue-video-player'
+// import 'videojs-flash'
+// import flvjs from 'flv.js/dist/flv.min.js'
+// import flvjs from "flv.js";
+import Bscroll from "better-scroll";
+export default {
+  name: "Post",
+  dicts: ['sys_normal_disable','sys_yes_no','youke','tjzh','youkes','lafafen','fange','jluly'],
+  // components: {
+  //     vueQr,
+	 //  videoPlayer
+  //   },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+	  opent:false,
+	  bg:null,
+    titles:'',
+	editableTabsValue:'6',
+    opens:false,
+	  imageUrl:'@/assets/logo/logo.png',
+	  printObj: {
+	           id: "nhgrew", // 这里是要打印元素的ID
+	           popTitle: "", // 打印的标题
+	         },
+	  pickerOptions:{
+	            disabledDate (time) {
+	              //disabledDate 文档上:设置禁用状态,参数为当前日期,要求返回 Boolean
+	              // return time.getTime() > Date.now()//选当前时间之前的时间
+	              return time.getTime() < Date.now()  - 8.64e7;//选当前时间之后的时间
+	            }
+	        },
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+	  checkedScoreDataDetails: [],
+	  scoreDataDetailsList:[],
+	  tabPosition:'left',
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 岗位表格数据
+      postList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize:500,
+		name:null,
+        postCode: undefined,
+        postName: undefined,
+        status: undefined,
+        reservatType:undefined
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {
+        receptionId: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+
+
+      },
+      ruless:{
+        visitName: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitPhone: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitNum: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitDate: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitTime: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+
+      },
+      forms:{},
+			tableMaxHeight:'200',
+      kje:0,
+      ksjegsg:[],
+	   Scroll: null,
+	   videoShow: false,
+	flvPlayer:null,
+	player: null,
+	name:null,
+	isshiwa:false,
+	isjfwe:{},
+	isshoe:false,
+   webRtcServer: null,
+   camera_ip: '127.0.0.1:8000',
+   g_iWndIndex:0,
+   iRtspPort:'',//预览中的ip
+   szDeviceIdentify:'',//ip_port,
+   isfse:false
+    };
+  },
+  created() {
+    this.isfse = false
+    // this.getList();
+  window.onresize = () => {
+  	      this.changeTableMaxHeight()
+  	    }
+  	    this.changeTableMaxHeight()
+  },
+  mounted() {
+    // this.refreshStream()
+     // this.webRtcServer = new WebRtcStreamer('video', location.protocol + '//' + this.camera_ip)
+     //      //需要查看的rtsp地址,根据自己的摄像头传入对应的rtsp地址即可。注意:视频编码格式必须是H264的,否则无法正常显示,编码格式可在摄像头的后台更改
+     //      this.webRtcServer.connect('rtsp://admin:zxy123456@192.168.101.64:554/h264/ch1/main/av_stream')
+  	window.onresize = () => {
+  	          this.changeTableMaxHeight()
+  	        }
+  	        this.changeTableMaxHeight()
+
+		this.$nextTick(() => {
+		        this.initScroll()
+		    })
+  },
+   beforeDestroy() {
+      // this.destoryVideo()
+      // if(WebVideoCtrl){
+      //   console.log(this.szDeviceIdentify)
+      // 	WebVideoCtrl.I_Logout(this.szDeviceIdentify)
+      //   WebVideoCtrl.I_StopAllPlay()
+      // 	WebVideoCtrl.I_DestroyPlugin()
+      //   WebVideoCtrl.I_Resize()
+      // }
+    },
+  methods: {
+    refreshStream() {
+                const video = document.getElementById('yolo-stream');
+                video.src = 'http://10.90.90.83:5000/video_feed?' + new Date().getTime();
+            },
+    // 通道点击
+    ishg(val){
+      this.isfse = false
+      this.clickStartRealPlay('192.168.101.64', '80',1, 0, 1);
+      // this.getVideo()
+
+    },
+    cnde(){
+      this.$router.go(-1)
+    },
+
+
+	  init(val) { //这个val 就是一个地址,例如: http://192.168.2.201:85/live/9311272c49b845baa2b2810ad9bf3f68.flv 这是个服务器返回给我的一个监控视频流地址
+	        setTimeout(() => { //使用定时器是因为,在mounted声明周期里调用,可能会出现DOM没加载出来的原因
+	          var videoElement = this.$refs.videosmallone; // 获取到html中的video标签
+			  this.isshiwa = true
+	          if (flvjs.isSupported()) {
+	          //因为我这个是复用组件,进来先判断 player是否存在,如果存在,销毁掉它,不然会占用TCP名额
+	            if (this.player !== null) {
+	              this.player.pause();
+	              this.player.unload();
+	              this.player.detachMediaElement();
+	              this.player.destroy();
+	              this.player = null;
+	            }
+	            this.player = flvjs.createPlayer( //创建直播流,加载到DOM中去
+	              {
+	                type: "mp4",
+	                url: val, //你的url地址
+	                isLive: true, //数据源是否为直播流
+	                hasAudio: false, //数据源是否包含有音频
+	                hasVideo: true, //数据源是否包含有视频
+	                enableStashBuffer: true, //是否启用缓存区
+	              },
+	              {
+	                enableWorker: false, //不启用分离线程
+	                enableStashBuffer: false, //关闭IO隐藏缓冲区
+	                autoCleanupSourceBuffer: true, //自动清除缓存
+	                lazyLoad: false,
+	              }
+	            );
+				this.isshoe = true
+	            this.player.attachMediaElement(videoElement); //放到dom中去
+
+	            //!!!!!!这里需要注意,有的时候load加载完成不一定可以播放,要是播放不成功,用settimeout 给下面的this.player.play() 延时几百毫秒再播放
+	            // setTimeout(this.player.play(), 48000);
+				setTimeout(() =>{
+					//到时间时只执行一次就停止
+					this.player.load();//准备完成
+					this.player.play()
+					console.log('播放')
+				},900)
+
+
+	          }
+	        }, 500);
+	      },
+
+	  createVideo() {
+	        if (flvjs.isSupported()) {
+				console.log(1)
+	          var videoElement = document.getElementById('myFlvVideo')
+			  console.log(videoElement,flvjs)
+	          this.flvPlayer = flvjs.createPlayer(
+	            {
+	              type: 'application/x-mpegURL',
+	              isLive: true,
+	              hasAudio: false,
+	              url:'https://stream1.freetv.fun/86d463c0006da643e45e26b34875df87059dcba13e69d0a5471b185793c122a2.m3u8'
+	            },
+	            {
+	              cors: true, // 是否跨域
+	              enableWorker: false, // 是否多线程工作
+	              enableStashBuffer: false, // 是否启用缓存
+	              stashInitialSize: 400, // 缓存大小(kb)  默认384kb
+	              autoCleanupSourceBuffer: true // 是否自动清理缓存
+	            }
+	          )
+	          this.flvPlayer.attachMediaElement(videoElement)
+	          this.flvPlayer.load()
+	          this.flvPlayer.play()
+			  console.log(1244)
+	          // 报错重连
+	          this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
+	            console.log('errorType:', errType)
+	            console.log('errorDetail:', errDetail)
+	            if (this.flvPlayer) {
+	              this.destoryVideo()
+	              this.createVideo()
+	            }
+	          })
+	        }
+
+			console.log(this.flvPlayer.play())
+	      },
+	      destoryVideo() {
+	        this.player.pause()
+	        this.player.unload()
+	        this.player.detachMediaElement()
+	        this.player.destroy()
+	        this.player = null
+	      },
+
+	  initScroll() {
+	    	  // 给内层盒子设置宽度,不设置宽度的话无法滚动
+	    	  // let width = this.goods.length * 60
+	    	  // // 如果有外边距,可以这样写。需要去掉最后一个元素的外边距,在后面减一下
+	    	  // let width = this.goodslength * (60 + 10) - 10
+			  let width = 6 * (200 + 10) - 10
+	        // this.$refs.content.style.width = width + 'px'
+	        this.$nextTick(()=>{
+	          if(!this.Scroll) {
+	            this.Scroll = new Bscroll(this.$refs.wrapper,{
+	              click: true,      // 配置允许点击事件
+	              scrollX: true,    // 开启横向滚动
+	              eventPassthrough: 'vertical',  // 当设置 eventPassthrough 为 'vertical' 的时候,scrollY 无效
+				  mouseWheel: true,
+				  scrollbar: { // 滚动条, 要加相对位置
+				              fade: true
+				            }
+	            })
+	          } else {
+	            this.Scroll.refresh()     // 重新计算 better-scroll,当 DOM 结构发生变化的时确保滚动效果正常
+	          }
+	        })
+	      },
+
+    /** 查询岗位列表 */
+    getList() {
+	  // this.queryParams
+    // this.loading = true
+    getWarnManage(this.$route.query.id).then(response => {
+      this.form = response.data
+      this.init(this.form.videoAddress)
+      // this.getVideo()
+      // WebVideoCtrl.I_ShowPlugin()
+      // this.loading = false
+      // this.open = true
+      // this.title = "修改告警管理"
+    })
+  //     camera(this.queryParams).then(response => {
+  //       this.postList = response.data.data.list;
+		// if(response.data.data != null){
+		// if(response.data.data.list.length != 0){
+		// 	let ne = response.data.data.list[0]
+		// 	response.data.data.list.filter(rtu=>{
+		// 		if(rtu.name == '后门道闸'){
+		// 			console.log(3,rtu)
+		// 			ne = rtu
+		// 			return
+		// 		}
+		// 	})
+		// 	this.isfgw(ne)
+		// 	this.isjfwe =ne
+
+		// }
+		// }
+  //       // this.postList=[{'nsje':null,'visitPhone':null,'isReception':'Y'}]
+  //       this.total = response.data.data.total;
+  //       this.loading = false;
+  //     });
+    },
+    getListh() {
+      this.loading = true;
+      listReservatd().then(response => {
+        // this.postList = response.rows;
+        this.ksjegsg= response.data
+        // this.total = response.total;
+        this.loading = false;
+      });
+    },
+	isfgw(val){
+		this.isjfwe = val
+		let nhge={cameraIndexCode:val.indexCode}
+		this.isshiwa = false
+		this.isshoe= false
+	   cameraIndexCode(nhge.cameraIndexCode).then(response => {
+		   console.log(response.data.data.url)
+		   this.isshoe= true
+		  this.init(response.data.data.url)
+		   this.isshiwa = true
+	  // this.postList = response.rows;
+	  // this.total = response.total;
+	  });
+		console.log(val,4)
+	},
+	osge(){
+		console.log(this.isjfwe,45)
+		if(this.isjfwe.name == '后门道闸'){
+			this.isjfwe.name ='后门抓拍一体机1'
+		}
+		let nge={equipmentName:this.isjfwe.name}
+		openDz(nge).then(response => {
+
+		});
+	},
+	osgef(){
+		if(this.isjfwe.name == '后门道闸'){
+			this.isjfwe.name ='后门抓拍一体机1'
+		}
+		let nge={equipmentName:this.isjfwe.name}
+		closeDz(nge).then(response => {
+		  // this.postList = response.rows;
+		});
+	},
+
+    ilw(row,val){
+      this.kje = val
+      // console.log(row)
+      if(row.value == 0){
+          this.queryParams.reservatType = undefined
+      }else{
+        this.queryParams.reservatType = row.value
+      }
+    console.log(this.kje)
+      this.queryParams.pageNum  = 1
+      this.getList()
+    },
+  nhgwel(item){
+    this.form.receptionId = item.receptionId
+    this.form.receptionName = item.receptionName
+    this.form.receptionPhone = item.phonenumber
+
+  },
+    getPass(row) {
+      const _this = this
+      this.$confirm('是否审核通过', "提醒", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return setPass({
+        visitType: 3,
+        reservatId: row.reservatId,
+        // xmStatus:row.xmStatus
+      })
+      }).then(() => {
+    	   _this.getList();
+        _this.msgSuccess("提交成功");
+      })
+    },
+    infoBtn(row) {
+    	const _this = this
+    	this.$confirm('是否拒绝', "提醒", {
+    	  confirmButtonText: "确定",
+    	  cancelButtonText: "取消",
+    	  type: "warning"
+    	}).then(function() {
+    	  return setPass({
+    	  visitType: 2,
+    	   reservatId: row.reservatId,
+    	  // xmStatus:row.xmStatus
+    	})
+    	}).then(() => {
+    	  _this.getList();
+    	  _this.msgSuccess("提交成功");
+    	})
+
+    },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+	  this.opens = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+		receptionId:undefined,
+        receptionPhone:undefined,
+        // postSort: 0,
+        // status: "0",
+        receptionName: undefined
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.reservatId)
+      this.single = selection.length!=1
+      this.multiple = !selection.length
+    },
+    nhgeo(row){
+      this.reset();
+     this.open = true;
+     this.title = "分配接待人员";
+     this.form.reservatId = row.reservatId;
+     this.form.reservatConfigTimeId=row.reservatConfigTimeId;
+     this.form.visitDate=row.visitDate
+    },
+    handleDeleteh(row){
+      this.$router.push({
+        path: '/bjqs',
+      		query: {
+      			'id':row.reservatId,
+      			'name':null,
+      			'names':null,
+      			'isxz':1
+      		}
+      })
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.forms = {
+        reservatType:'1'
+      }
+      this.opens = true;
+      this.titles = "添加预约人员";
+	  // this.scoreDataDetailsList = []
+	  // this.$router.push({
+	  //   path: '/system/bjq',
+	  // })
+	  // this.$router.push({
+	  //   path: '/bjqs',
+	  // 		query: {
+	  // 			'id':null,
+	  // 			'name':null,
+	  // 			'names':null,
+	  // 			'isxz':1
+	  // 		}
+	  // })
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+           const recordId = row.recordId || this.ids
+           getReservat(recordId).then(response => {
+             this.forms = response.data;
+             this.opens = true;
+             this.title = "修改访问记录";
+           });
+    },
+    /** 提交按钮 */
+    submitForm: function() {
+      this.$refs["form"].validate(valid => {
+              if (valid) {
+                // if (this.form.reservatId != null) {
+                  updateReservat(this.form).then(response => {
+                    this.$modal.msgSuccess("操作成功");
+                    this.open = false;
+                    this.getList();
+                  });
+                // } else {
+                //   addReservat(this.form).then(response => {
+                //     this.$modal.msgSuccess("新增成功");
+                //     this.open = false;
+                //     this.getList();
+                //   });
+                // }
+              }
+            });
+    },
+    submitForms: function() {
+      this.$refs["forms"].validate(valid => {
+              if (valid) {
+                // if (this.form.reservatId != null) {
+                  // updateReservat(this.forms).then(response => {
+                  //   this.$modal.msgSuccess("操作成功");
+                  //   this.open = false;
+                  //   this.getList();
+                  // });
+                // } else {
+                  this.forms.visitTime = this.forms.visitTime + '-' + this.forms.visitTime
+                  addReservat(this.forms).then(response => {
+                    this.$modal.msgSuccess("新增成功");
+                    this.opens = false;
+                    this.getList();
+                  });
+                // }
+              }
+            });
+    },
+
+	nglqw(val){
+		this.opent = true
+		this.bg = val.investigateTableId
+	},
+
+
+	iszheg(event){
+	 console.log(event);
+
+
+	 // 校验身份证:
+	 console.log(reg.test(this.form.idCard),23741)
+	 		if ( reg.test(this.form.idCard)|| _IDre15.test(this.form.idCard)) {
+	 			// this.idea();
+	 			this.go(this.form.idCard);
+	 			// callback()
+	 		} else {
+	   if(ncjsle.test(this.form.idCard) || nhyeli.test(this.form.idCard)){
+	      console.log(3)
+	   }else{
+	     if(gnse.test(this.form.idCard)  ){
+	         console.log(4)
+	     }else{
+	       if(tw.test(this.form.idCard) || twe.test(this.form.idCard)){
+	         console.log(5)
+	       }else{
+	         this.$message.error('证件格式不正确');
+	       }
+	     }
+
+	   }
+	 		}
+	},
+	erw(row){
+		this.$router.push({
+		  path: '/reny/ewm',
+		  query:{
+			   'tenantId':row.investigateTableId
+			  }
+		})
+	},
+
+	hussar_17Click(val) {
+	        const _this = this
+	        var url =process.env.VUE_APP_BASE_API + 'pages/index/index?id=' + val.investigateTableId;
+			 console.log(url,this.$refs.canvas,6)
+			this.opent = true
+	        QRCode.toCanvas(
+	                      canvas,
+	                      url,//生成二维码的数据
+	                      {width: 100, height:100, margin: 1.5},//margin调整二维码的白边大小
+	                      function (error) {
+	                        if (error) {
+	                          console.log(error);
+	                        }
+	                      }
+	                    );
+
+	        // console.log(qrcode,987)
+	      },
+	/** 成绩_子添加按钮操作 */
+	handleAddScoreDataDetails() {
+
+	  let obj = {};
+	  obj.duty = "";
+	  obj.idCard = "";
+	  obj.phonenumber = "";
+	  obj.userName = "";
+	  this.scoreDataDetailsList.push(obj);
+	  console.log(this.scoreDataDetailsList)
+	},
+	/** 成绩_子删除按钮操作 */
+	handleDeleteScoreDataDetails() {
+	  if (this.checkedScoreDataDetails.length == 0) {
+	    this.$modal.msgError("请先选择要删除的数据");
+	  } else {
+	    const scoreDataDetailsList = this.scoreDataDetailsList;
+	    const checkedScoreDataDetails = this.checkedScoreDataDetails;
+	    this.scoreDataDetailsList = scoreDataDetailsList.filter(function(item) {
+	      return checkedScoreDataDetails.indexOf(item.index) == -1
+	    });
+	  }
+	},
+	/** 复选框选中数据 */
+	handleScoreDataDetailsSelectionChange(selection) {
+	  this.checkedScoreDataDetails = selection.map(item => item.index)
+	},
+	/** 成绩_子序号 */
+	rowScoreDataDetailsIndex({ row, rowIndex }) {
+	  row.index = rowIndex + 1;
+	},
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const postIds = row.recordId || this.ids;
+      delReservat(postIds).then(response => {
+       this.$modal.msgSuccess("操作成功");
+        this.getList();
+      });
+
+      // this.$modal.confirm('是否确认删除数据项?').then(function() {
+      //   return delPost(postIds);
+      // }).then(() => {
+      //   this.getList();
+      //   this.$modal.msgSuccess("删除成功");
+      // }).catch(() => {});
+    },
+    handleDeletehx(row) {
+      const postIds = row.reservatId || this.ids;
+      let nhg={}
+      nhg.reservatId = postIds
+      delReservathx(nhg).then(response => {
+       this.$modal.msgSuccess("操作成功");
+        this.getList();
+      });
+
+      // this.$modal.confirm('是否确认删除数据项?').then(function() {
+      //   return delPost(postIds);
+      // }).then(() => {
+      //   this.getList();
+      //   this.$modal.msgSuccess("删除成功");
+      // }).catch(() => {});
+    },
+	// 发送短信
+	handleUpdatefas(row){
+		updateFs(row).then(response => {
+		 this.$modal.msgSuccess("发送成功");
+		  // this.getList();
+		});
+	},
+	handleDeletegx(row){
+		updateGx(row).then(response => {
+		  this.$modal.msgSuccess("发送成功");
+		  // this.getList();
+		});
+	},
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('system/reservat/export', {
+        ...this.queryParams
+      }, `预约人员.xlsx`)
+    },
+		// 获取屏幕高度
+		showFilterForm () {
+		      this.filterActive = !this.filterActive
+		      this.changeTableMaxHeight()
+		    },
+
+		    changeTableMaxHeight () {
+		      let height = document.body.offsetHeight // 网页可视区域高度
+		      // if (this.filterActive) {
+		      //   this.tableMaxHeight = height - 320
+		      // } else {
+		        this.tableMaxHeight = height - 350
+		      // }
+		      console.log(height)
+		    },
+    // 播放摄像头
+    getVideo() {
+    	var that=this;
+       this.isfse  = true
+    	this.initVideoPlay('192.168.101.64', '80', 'admin', 'zxy123456','divPlugin')
+    },
+    // 有插件
+    initVideoPlay(ip, port, username, password,id) {
+    	var that = this;
+    	var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
+    	var g_oLocalConfig = null; //本地配置
+    	// let ip = this.szIP //硬盘录像机ip
+    	// let port = this.szPort //默认为80端口
+    	// let username = this.szUsername //账号:
+    	// let password = this.szPassword // 密码
+    	var iRtspPort = ''
+    	// 1.初始化插件参数及插入插件
+    	WebVideoCtrl.I_InitPlugin({
+    		bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
+    		iWndowType: 1,
+    		bDebugMode: true,
+    		cbSelWnd: function(xmlDoc) {
+    			g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
+    			const szInfo = "当前选择的窗口编号:" + g_iWndIndex;
+    			this.g_iWndIndex = g_iWndIndex;
+    			console.log(szInfo, "szInfo");
+    		},
+    		cbDoubleClickWnd: function(iWndIndex, bFullScreen) {
+    			let szInfo = "当前放大的窗口编号:" + iWndIndex;
+    			if (!bFullScreen) {
+    				szInfo = "当前还原的窗口编号:" + iWndIndex;
+    			}
+    			// console.log(szInfo, "szInfo");
+    		},
+    		cbEvent: function(iEventType, iParam1, iParam2) {
+    			if (2 == iEventType) {
+    				// 回放正常结束
+    				console.log("窗口" + iParam1 + "回放结束!");
+    			} else if (-1 == iEventType) {
+    				console.log("设备" + iParam1 + "网络错误!");
+    			} else if (3001 == iEventType) {
+    				clickStopRecord(g_szRecordType, iParam1);
+    			}
+    		},
+    		//2.登录摄像头
+    		cbInitPluginComplete: function() {
+    			const oLiveView = {
+    				iProtocol: 1, // protocol 1:http, 2:https
+    				szIP: ip, // protocol ip
+    				szPort: port, // protocol port
+    				szUsername: username, // device username
+    				szPassword: password, // device password
+    				iStreamType: 1, // stream 1:main stream  2:sub-stream  3:third stream  4:transcode stream
+    				iChannelID: 1, // channel no
+    				bZeroChannel: false, // zero channel
+    			};
+    			// var swidth=Number((that.width*Number(that.scale))).toFixed(2)
+    			// var sheight=Number((that.height*Number(that.scale))).toFixed(2)
+    			// that.swidth=swidth
+    			// that.sheight=sheight
+    			WebVideoCtrl.I_InsertOBJECTPlugin(id).then(
+    				() => {
+    					// setTimeout(function(){
+    					// 	WebVideoCtrl.I_Resize(swidth,sheight)
+    					// },300)
+    					WebVideoCtrl.I_Login(
+    						oLiveView.szIP,
+    						oLiveView.iProtocol,
+    						oLiveView.szPort,
+    						oLiveView.szUsername,
+    						oLiveView.szPassword, {
+    							timeout: 3000,
+    							async: false,
+    							success: function(xmlDoc) {
+    								console.log(" 登录成功!");
+    								let a = ip
+    								let b = port
+    								setTimeout(function() {
+    									//延迟方法
+    									setTimeout(function() {
+    										//调用预览摄像头这里可以循环创建
+    										that.clickStartRealPlay(a, b,1, 0, 1);
+    										// that.clickStartRealPlay(a, b, 1, 1,2);
+    										// that.clickStartRealPlay(a, b, 1, 2,3);
+    										// clickStartRealPlay(a,b, 1, 3, 4);
+    										// clickStartRealPlay(a,b, 1, 4, 5);
+    										// clickStartRealPlay(a,b, 1, 5, 6);
+    										// clickStartRealPlay(a,b, 1, 6, 7);
+    										// clickStartRealPlay(a,b, 1, 7, 8);
+    									}, 1000);
+
+
+    									setTimeout(function() {
+    										// 获取通道 (如果多个摄像头需要获取多个通道需要调用)
+    										// getChannelInfo(a);
+    										//获取端口 (在这里获取RTSP 端口号 预览时传入)
+    										getDevicePort(a);
+    									}, 10)
+
+    								}, 10);
+    							},
+    							error: function(oError) {
+    								console.log(" 登录失败!", oError);
+    							},
+    						}
+    					);
+    					// 检查插件是否最新
+    					WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {
+    						if (bFlag) {
+    							alert(
+    								"检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!"
+    							);
+
+    						}
+    					});
+    				},
+    				() => {
+    					alert(
+    						"插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!"
+    					);
+
+    				}
+    			);
+
+    		},
+    	});
+    	// 3.获取通道
+    	function getChannelInfo(a) {
+    		var szDeviceIdentify = a,
+    			oSel = null; //通道列表
+    		if (null == szDeviceIdentify) {
+    			return;
+    		}
+
+    		// 模拟通道 有
+    		WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("VideoInputChannel");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text();
+    					if ("" == name) {
+    						name = "Camera " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+
+    					// console.log(id + "通道id是")
+    					// console.log(name + "通道name是")
+    				});
+    				console.log(szDeviceIdentify + " 获取模拟通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取模拟通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    		// 数字通道
+    		WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text(),
+    						online = $(this).find("online").eq(0).text();
+    					if ("false" == online) { // 过滤禁用的数字通道
+    						return true;
+    					}
+    					if ("" == name) {
+    						name = "IPCamera " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+    				});
+    				console.log(szDeviceIdentify + " 获取数字通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取数字通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    		// 零通道
+    		WebVideoCtrl.I_GetZeroChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("ZeroVideoChannel");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text();
+    					if ("" == name) {
+    						name = "Zero Channel " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+    					if ("true" == $(this).find("enabled").eq(0).text()) { // 过滤禁用的零通道
+
+    					}
+    				});
+    				console.log(szDeviceIdentify + " 获取零通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取零通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    	};
+
+    	//4.获取端口
+    	function getDevicePort(a) {
+    		var szDeviceIdentify = a;
+
+    		if (null == szDeviceIdentify) {
+    			return;
+    		}
+    		WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then((oPort) => {
+    			// console.log(oPort.iDevicePort + "iDevicePort的值是")
+    			// console.log(oPort.iRtspPort + "iRtspPort的值是")
+    			console.log(szDeviceIdentify + " 获取端口成功!");
+    			iRtspPort = oPort.iRtspPort
+    			that.iRtspPort = iRtspPort
+    		}, (oError) => {
+    			var szInfo = "获取端口失败!";
+    			console.log(szDeviceIdentify + szInfo, oError.errorCode, oError.errorMsg);
+    		});
+    	};
+    },
+    // 5.开始预览
+    clickStartRealPlay(szIP, szPort, iStreamType, iWndIndex, iChannelID) {
+    	var oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex),
+    		szDeviceIdentify = szIP + "_" + szPort, //ip
+    		iChannelID = iChannelID,
+    		bZeroChannel = false,
+    		iPort = this.iRtspPort,
+    		szInfo = "";
+    	iStreamType = iStreamType;
+    	if (null == szDeviceIdentify) {
+    		return null;
+    	}
+    	this.szDeviceIdentify = szDeviceIdentify;
+    	var startRealPlay = function() {
+    		WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
+    			iStreamType: iStreamType,
+    			iChannelID: iChannelID,
+    			bZeroChannel: bZeroChannel,
+    			iWndIndex: iWndIndex, //要播放的窗口
+    			iPort: iPort, //如果多个摄像头需要必填 (RTSP 端口号)
+    			success: function() {
+    				szInfo = "开始预览窗口" + iWndIndex + "成功!";
+    				console.log(szDeviceIdentify + " " + szInfo);
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 开始预览窗口" + iWndIndex + "失败!", oError
+    					.errorCode, oError.errorMsg);
+    			}
+    		});
+    	};
+
+    	if (oWndInfo != null) { // 已经在播放了,先停止
+    		WebVideoCtrl.I_Stop({
+    			success: function() {
+    				startRealPlay();
+    			}
+    		});
+    	} else {
+    		startRealPlay();
+    	}
+    },
+  }
+};
+</script>
+
+<style lang="scss">
+	.isjses{
+		.el-tabs--left .el-tabs__nav-wrap.is-left::after{
+			width:6px;
+		}
+		.el-tabs--left .el-tabs__active-bar.is-left,{
+			width:6px;
+		}
+	}
+	.ingaqe{
+		.el-input--medium{
+			width:100%;
+		}
+	}
+	.nhgrls{
+		.el-dialog__body{
+			padding: 0;
+		}
+	}
+  .hyr{
+    span{
+      text-decoration:underline;
+    }
+  }
+</style>
+<style scoped lang="scss">
+	.nghwgq{
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		margin-top: 90px;
+		div{
+			color:#aaa;
+		}
+	}
+	.ihgswq{
+		// width:100%;
+		// overflow-x: hidden;
+		// margin-top: 30px;
+	}
+	.fijge{
+		// width: 110%;
+		display: flex;
+		display: -webkit-flex;
+		justify-content: space-between;
+		.shotw{
+			position: relative;
+			// width:32%;
+			width: 238px;
+			height: 140px;
+			margin-left: 0;
+			margin-right: 20px;
+			margin-bottom: 15px;
+			img{
+				height: 100%;
+				cursor:pointer;
+			}
+		  p{
+			  // bottom:-10px;
+			  margin: 0;
+			  font-weight: bold;
+			  font-size: 16px;
+			   padding: 5px  10px;
+			   cursor:pointer;
+		  }
+		  .iges{
+			position: absolute;
+			top:50%;
+			left:50%;
+			width:30px;
+			height: 30px;
+			transform: translate(-50%,-50%);
+			cursor:pointer;
+		  }
+		}
+	}
+	.nhgwesvq{
+		width:1610px !important;
+	}
+	.shotw{
+		position: relative;
+		margin-left: -20px;
+		margin-right: -20px;
+		img{
+			width:100%;
+			height: 80vh;
+		}
+	  p{
+	     position: absolute;
+		 bottom: 0;
+		 left:0;
+		 background-color: rgba(0, 0, 0, .5);
+		 width: 100%;
+		 padding: 13px  5px;
+		 color:#fff;
+		 font-weight: bold;
+		 font-size: 18px;
+	  }
+	  .p{
+		  top:0px;
+		  height: 60px;
+		  margin: 0;
+		  padding-left: 20px;
+	  }
+	}
+
+
+	.ksfpo{
+		background-color: #3464EB;
+		padding: 6px 12px;
+		border-radius: 4px ;
+		color:#fff;
+		cursor:pointer;
+	}
+	.ksfpok{
+		background-color: #FFFFFF;
+		padding: 5px 11px;
+		border-radius: 4px;
+		color:#3464EB;
+		border: 1px solid #3464EB;
+		margin-left: 10px;
+		cursor:pointer;
+	}
+	.ksfpofg{
+		background-color: #75DB75;
+		padding: 5px 11px;
+		border-radius: 4px;
+		color:#FFFFFF;
+		border: 1px solid #75DB75;
+		margin-left: 10px;
+		cursor:pointer;
+	}
+  .iuer{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .ite{
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      p{
+        cursor:pointer;
+        margin: 0;
+        font-size: 15px;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color:#666666;
+        padding: 4px 12px;
+        background: #Fff;
+        border-radius: 4px;
+        margin-right: 20px;
+		position: relative;
+      }
+      .actt{
+        background: #fff;
+        // border-bottom: 3px solid #5974E0;
+        // border-radius: 0;
+		// border-bottom-right-radius: 4px;
+        color: #5974E0;
+      }
+	  .actt{
+		    &::after {
+		          content: "";
+		          width: 40%;
+		          height: 5px;
+				  border-radius: 3px;
+		          transform: translate(-50%);
+		          background-color: #5974E0;
+		          position: absolute;
+		          left: 50%;
+		          bottom:-3px;
+		        }
+
+	  }
+
+    }
+  }
+  .lqw{
+    padding: 0 10px;
+    margin: 0;
+    margin-bottom: 20px;
+  }
+.nhgel{
+  height: 170px;
+  background-color: #313b61;
+  width: 100%;
+  position: absolute;
+  top:0;
+  left:0;
+  z-index: 0;
+}
+	.app-container{
+		background-color: #f3f4f6;
+		padding-top: 10px;
+		height: 180vh;
+
+	}
+	.ntgs{
+	position: relative;
+		// background-color: #fff;
+		padding: 5px;
+		// border-radius: 5px;
+		padding-top: 10px;
+	     padding: 10px 20px;
+		.pagination-container{
+			height: 50px;
+		}
+	}
+	.nghfs{
+	position: relative;
+		background-color: #fff;
+		padding-top: 18px !important;
+		padding: 5px;
+		// border-radius: 5px;
+		// margin-bottom: 20px;
+	}
+	.ksf{
+		img{
+			width:100%;
+			height: 100%;
+		}
+	}
+   .ingwfaq{
+	   font-weight: bold;
+	   font-size: 16px;
+   }
+</style>

+ 1601 - 0
ruoyi-ui/src/views/shipinggaoj/shishi/index.vue

@@ -0,0 +1,1601 @@
+<template>
+  <div class="app-container" style="height: 100vh;"  v-loading="loading"
+    element-loading-text="拼命加载中"
+    element-loading-spinner="el-icon-loading"
+    element-loading-background="rgba(0, 0, 0, 0.8)">
+    <div class="ntgs" style="padding: 0;">
+    <el-row :gutter="10" class="mb8">
+     <div class="iuer" style="margin-bottom:10px;">
+     </div>
+    </el-row>
+
+	<div>
+		<el-row :gutter="20">
+          <!-- postList -->
+					<el-col :span='4'>
+						<div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 95vh;">
+              <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">盒子管理</p>
+                <div class=" infinite-list" style="overflow:auto;height:  93vh" >
+                  <div class="head-container">
+                    <el-input
+                      v-model="equipmentName"
+                      placeholder="请输入设备名称"
+                      clearable
+                      size="small"
+                      @blur="nsdfse"
+                      prefix-icon="el-icon-search"
+                      style="margin-bottom: 20px"
+                    />
+                  </div>
+                  <div class="head-container">
+                    <el-tree
+                      :data="deptOptions"
+                      :props="defaultProps"
+                      :expand-on-click-node="false"
+                      :filter-node-method="filterNode"
+                      ref="tree"
+                      default-expand-all
+                      highlight-current
+                      @node-click="ishg"
+                    />
+                  </div>
+                </div>
+              <!-- <div :class="ishge == index ? 'anche' : ''" style=" height: 36px;;line-height: 36px;margin-top: 10px;padding: 0 10px;"v-for="(item,index) in channelNumberList" :key="index">
+                              <div @click="ishg(item,index)" style="display: flex;align-items: center;justify-content: space-between;">
+                                <el-tooltip class="item" effect="dark" :content="item.channelNum == null?'暂无数据' : item.channelNum" placement="top-start">
+                                <div style="font-size: 16px;
+              color: #333333; overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"> {{item.channelNum == null?'暂无数据' : item.channelNum}}</div>
+              </el-tooltip>
+                                <img src="../../../assets/images/icon_htgl_zd.png" alt="" style="width: 10px;height: 12px;">
+                              </div>
+                          </div> -->
+            </div>
+					</el-col>
+        <!-- v-if="isshoe" -->
+        <el-col :span='20' style="padding-left: 30px; background-color: #fff;border-radius: 10px;padding: 20px; height: 95vh;" >
+          <div style="display: flex;align-items: center;justify-content: space-between;margin-bottom: 18px;">
+            <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">实时检测
+            </p>
+          </div>
+          <div class="dflext mb10">
+            <div style="flex: 1;"></div>
+          </div>
+           <div style="display: flex; flex-wrap: wrap;">
+            <!-- <div   class="video-container" style="text-align: center; width: 100%; " >
+                 <img :src="'http://127.0.0.1:5000/video_feed'"  width="640px" height="420px" id="yolo-stream">
+             </div> -->
+             <div :class="isahsge == 0?'actw' :''" @click="refreshStream('yolo-stream',0)" class="video-container" style="text-align: center; width: 50%; height: 240px; background-color: #CEE8E0; border: 1px solid #75a295;" >
+                 <img :src="'http://192.168.1.240:5000/video_feed'"  width="100%" height="240px" id="yolo-stream">
+             </div>
+             <div :class="isahsge == 1?'actw' :''" @click="refreshStream('yolo-stream1',1)" class="video-container" style="text-align: center; width: 50%; height: 240px; background-color: #CEE8E0; border: 1px solid #75a295;" >
+                 <img :src="'http://192.168.1.240:5000/video_feed'"  width="100%" height="240px" id="yolo-stream1">
+             </div>
+             <div :class="isahsge == 2?'actw' :''" @click="refreshStream('yolo-stream2',2)" class="video-container" style="text-align: center; width: 50%; height: 240px; background-color: #CEE8E0; border: 1px solid #75a295;" >
+                 <img :src="'http://192.168.1.240:5000/video_feed'"  width="100%" height="240px" id="yolo-stream2">
+             </div>
+             <div :class="isahsge == 3?'actw' :''" @click="refreshStream('yolo-stream3',3)" class="video-container" style="text-align: center; width: 50%; height: 240px; background-color: #CEE8E0; border: 1px solid #75a295;" >
+                 <img :src="'http://192.168.1.240:5000/video_feed'"  width="100%" height="240px" id="yolo-stream3">
+             </div>
+           </div>
+
+         <div class="controls">
+             <!-- <button @click="refreshStream">刷新</button> -->
+             <!-- <button @click="unse">打开目录</button> -->
+         </div>
+          <!-- 344 -->
+          <!-- <video id="video" controls autoplay muted width="100%" height="480px"style="margin-top: 20px;"></video> -->
+        						<!-- <video
+        						      class="videosmall"
+        						      ref="videosmallone"
+        						      preload="auto"
+        						      muted
+        						      autoplay
+        							  width="95%"
+        						      type="rtmp/flv"
+        						    >
+        						      <source src="" />
+        						    </video> -->
+        					</el-col>
+
+
+			<!-- <el-col :span="24">
+				<div class="ihgswq wrapper"  ref="wrapper" style=" overflow: hidden;">
+						  <div class="fijge content nhgwesvq" ref="content" style="width:1610px;">
+									<div class='shotw '   v-for="(item,index) in postList" :key="index" @click="isfgw(item)" >
+											  <img src="../../../assets/images/fengm.png" alt="">
+												<img src="../../../assets/images/icon_spjk_play.png" alt="" class="iges">
+											  <p style="font-size: 14px;">{{item.name}}</p>
+									</div>
+						  </div>
+				</div>
+			</el-col> -->
+		</el-row>
+
+
+	  <!-- <pagination
+	     v-show="total>0"
+	     :total="total"
+	     :page.sync="queryParams.pageNo"
+	     :limit.sync="queryParams.pageSize"
+	     @pagination="getList"
+	   /> -->
+	</div>
+
+
+	</div>
+
+    <!-- 添加或修改岗位对话框 -->
+    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
+
+    </el-dialog>
+
+    <el-dialog :title="titles" :visible.sync="opens" width="1000px" append-to-body>
+    </el-dialog>
+
+	<el-dialog title="页面二维码" :visible.sync="opent" width="200px" style="padding: 0;" class="nhgrls" append-to-body>
+	  <div v-show="opent" style="display: flex;justify-content: center;align-items: center;">
+		  <!-- <span>{{'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg}}</span> -->
+			   <!-- <vue-qr   :text="'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg" :size="200"></vue-qr> -->
+	  </div>
+	</el-dialog>
+  </div>
+</template>
+
+<script>
+  import { listChannelNumber, listChannelNumbernopa,getChannelNumber, delChannelNumber, addChannelNumber, updateChannelNumber,deptTreec } from "@/api/system/channelNumber"
+  import { listWarnManage, getWarnManage, delWarnManage, addWarnManage, updateWarnManage } from "@/api/manage/warnManage"
+import { listParameterSet, getParameterSet, delParameterSet, addParameterSet, updateParameterSet } from "@/api/manage/parameterSet"
+import { qighs } from "@/api/manage/equipmentManage"
+import { listEquipmentManageNoPage,  } from "@/api/manage/equipmentManage"
+// import { listReservat,camera,cameraIndexCode, listReservatd, getReservat, delReservat, addReservat, updateReservat,setPass,delReservathx,openDz,closeDz } from "@/api/tonggi/houtai";
+// import vueQr from "vue-qr";
+// import videojs from 'video.js'
+// import 'video.js/dist/video-js.css'
+// import {videoPlayer} from 'vue-video-player'
+// import 'videojs-flash'
+// import flvjs from 'flv.js/dist/flv.min.js'
+// import flvjs from "flv.js";
+import mqtt from 'mqtt';
+import { MqttClient } from 'mqtt'
+import axios from 'axios'
+// 状态变量
+ // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
+ var client = MqttClient||null
+import Bscroll from "better-scroll";
+import { treeselect,listDept  } from "@/api/system/dept";
+export default {
+  name: "Post",
+  dicts: ['sys_normal_disable','sys_yes_no','youke','tjzh','youkes','lafafen','fange','jluly'],
+  // components: {
+  //     vueQr,
+	 //  videoPlayer
+  //   },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+	  opent:false,
+	  bg:null,
+    titles:'',
+    equipmentName:null,
+	editableTabsValue:'6',
+    opens:false,
+    // 通道管理表格数据
+    channelNumberList: [],
+	  imageUrl:'@/assets/logo/logo.png',
+	  printObj: {
+	           id: "nhgrew", // 这里是要打印元素的ID
+	           popTitle: "", // 打印的标题
+	         },
+	  pickerOptions:{
+	            disabledDate (time) {
+	              //disabledDate 文档上:设置禁用状态,参数为当前日期,要求返回 Boolean
+	              // return time.getTime() > Date.now()//选当前时间之前的时间
+	              return time.getTime() < Date.now()  - 8.64e7;//选当前时间之后的时间
+	            }
+	        },
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+	  checkedScoreDataDetails: [],
+	  scoreDataDetailsList:[],
+	  tabPosition:'left',
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 岗位表格数据
+      postList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize:500,
+		    name:null,
+        postCode: undefined,
+        postName: undefined,
+        status: undefined,
+        reservatType:undefined
+      },
+      // 表单参数
+      form: {},
+      // 部门树选项
+      deptOptions: undefined,
+      // 表单校验
+      rules: {
+        receptionId: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+      },
+      ruless:{
+        visitName: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitPhone: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitNum: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitDate: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+        visitTime: [
+          { required: true, message: "不能为空", trigger: "blur" }
+        ],
+
+      },
+      forms:{
+        parameterId: null,
+                channelId: null,
+                equipmentId: null,
+                equipmentNum: null,
+                equipmentName: null,
+                channelNum: null,
+                channelRange: null,
+                leaveTime: 10,
+                playTime: 10,
+                leaveRate: 0.5,
+                playRate: 0.5,
+                delFlag: null,
+                createBy: null,
+                createTime: null,
+                updateBy: null,
+                updateTime: null,
+                remark: null
+      },
+			tableMaxHeight:'200',
+      kje:0,
+      ksjegsg:[],
+	   Scroll: null,
+	   videoShow: false,
+	flvPlayer:null,
+	player: null,
+	name:null,
+	isshiwa:false,
+	isjfwe:{},
+	isshoe:false,
+   webRtcServer: null,
+   camera_ip: '127.0.0.1:8000',
+   g_iWndIndex:0,
+   iRtspPort:'',//预览中的ip
+   szDeviceIdentify:'',//ip_port,
+   isfse:false,
+
+   g_bEnableDraw:false,
+    // 所有绘制的图形
+    shapes: [],
+    // 禁用
+    isdisflag:false,
+    connectionStatus:'',
+    isConnected:false,
+    connecting:false,
+    messages:[{ type: 'sent' , content: '', timestamp: '' }],
+    messageToSend:[],
+    mqttConfig:{
+    	url: 'ws://13.229.167.76:1884/mqtt',
+    	topic: 'detection/rect'
+    },
+    mqttThemeName:{
+    	url: 'ws://13.229.167.76:1884/mqtt',
+    	topic: 'detection/rect'
+    },
+    ishge:0,
+    isurwe:'',
+    shiweis:null,
+    isahsge:0,
+    defaultProps: {
+      children: "children",
+      label: "equipmentName",
+      value:'equipmentId'
+    },
+
+    };
+  },
+  created() {
+    this.isfse = false
+    // this.getList();
+    // this.getListtd()
+    this.getTreeselect()
+  window.onresize = () => {
+  	      this.changeTableMaxHeight()
+  	    }
+  	    this.changeTableMaxHeight()
+
+  },
+  mounted() {
+    // this.fullScreen()
+  // this.toggleConnection()
+     // this.webRtcServer = new WebRtcStreamer('video', location.protocol + '//' + this.camera_ip)
+     //      //需要查看的rtsp地址,根据自己的摄像头传入对应的rtsp地址即可。注意:视频编码格式必须是H264的,否则无法正常显示,编码格式可在摄像头的后台更改
+     //      this.webRtcServer.connect('rtsp://admin:zxy123456@192.168.101.64:554/h264/ch1/main/av_stream')
+  	window.onresize = () => {
+  	          this.changeTableMaxHeight()
+  	        }
+  	        this.changeTableMaxHeight()
+
+		this.$nextTick(() => {
+		        this.initScroll()
+		    })
+  },
+
+   beforeDestroy() {
+
+    },
+  methods: {
+    // 筛选节点
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.label.indexOf(value) !== -1;
+    },
+    nsdfse(){
+      this.getTreeselect()
+    },
+    /** 查询部门下拉树结构 */
+    getTreeselect() {
+      // this.queryParams
+      let sngse={'equipmentName':this.equipmentName}
+      console.log(sngse)
+      listEquipmentManageNoPage(sngse).then(response => {
+        this.deptOptions = response.rows
+        this.deptOptions.filter(rou=>{
+          rou.children.filter(rout=>{
+            rout.equipmentName  = rout.channelNum
+            rout.equipmentId  = rout.channelId
+          })
+        })
+        this.loading = false
+      })
+    },
+    // 节点单击事件
+    handleNodeClick(data) {
+      // this.queryParams.deptId = data.deptId;
+      // this.ghwe.deptName = data.deptName
+      // this.ghwe.deptId = data.deptId
+      // this.handleQuery();
+      const video = document.getElementById(this.shiweis);
+      video.src = 'http://192.168.1.240:5000/video_feed?' + new Date().getTime();
+    },
+    fullScreen () {
+          // vedios.forEach(item => {
+            var vlc = document.getElementById('rt')
+            vlc.video.aspectRatio = '16:9' // 设置比例
+            vlc.playlist.playItem(item.path) // 重新加载
+          // })
+        },
+    unse(){
+      // document.getElementById('openDataDir').addEventListener('click', async function() {
+          const status = document.getElementById('status');
+          status.textContent = '正在打开...';
+          status.className = 'mt-4 text-center text-blue-500';
+          status.classList.remove('hidden');
+          // let sgse = JSON.stringify({ directory: '/home/boman/uploadPath/deviceManage/videoRecored/' })
+          axios({
+                  method:"post",
+                  url:"http://192.168.9.92:5000/open-directory",
+                  headers:{
+                    'Content-Type':'application/json;charset=utf-8'
+                  },
+                  data:JSON.stringify({ directory: '/home/boman/uploadPath/deviceManage/videoRecored/' })
+              }).then(function (resp) {
+                  alert(resp.data);
+              })
+            // status.textContent = '已成功打开目录';
+            // status.className = 'mt-4 text-center text-green-500';
+          // })
+    },
+    refreshStream(row,index) {
+      this.shiweis = row
+      this.isahsge = index
+      // const video = document.getElementById(row);
+      // video.src = 'http://127.0.0.1:5000/video_feed/video_feed?' + new Date().getTime();
+            },
+    /** 查询通道管理列表 */
+    getListtd() {
+      this.loading = true
+      let queryParams = {}
+      listChannelNumbernopa().then(response => {
+        this.channelNumberList = response.rows
+        if(this.channelNumberList.length != 0){
+          if(this.channelNumberList[0].isChannel == 'Y'){
+            // console.log(4)
+            this.form = this.channelNumberList[0].parameterSet
+            this.form.channelId = this.channelNumberList[0].channelId
+            this.form.isChannel = this.channelNumberList[0].isChannel
+            this.form.equipmentNum = this.channelNumberList[0].equipmentNum
+            this.form.equipmentId = this.channelNumberList[0].equipmentId
+            this.form.equipmentName = this.channelNumberList[0].equipmentName
+            this.form.channelNum = this.channelNumberList[0].channelNum
+            let snghs = this.channelNumberList[0].videoAddress.split('@')
+            let snghst = snghs[1].split(':')
+            let snsgduan = snghst[1].split('/')
+            getChannelNumber(this.channelNumberList[0].channelId).then(response => {
+              this.shapes = JSON.parse(response.data.parameterSet.channelRange)
+            })
+             console.log(snghs,snghst,snsgduan)
+            let sgse={'ip':this.channelNumberList[0].equipmentIp,
+            'account':this.channelNumberList[0].account,
+            'password':this.channelNumberList[0].password,
+            'port':this.channelNumberList[0].port
+            }
+
+          }else{
+            this.form = {parameterId: null,
+                  channelId: this.channelNumberList[0].channelId,
+                  equipmentId: this.channelNumberList[0].equipmentId,
+                  equipmentNum: this.channelNumberList[0].equipmentNum,
+                  equipmentName: this.channelNumberList[0].equipmentName,
+                  channelNum: this.channelNumberList[0].channelNum,
+                  channelRange: null,
+                  isChannel:this.channelNumberList[0].isChannel,
+                  leaveTime: 10,
+                  playTime: 10,
+                  leaveRate: 0.5,
+                  playRate: 0.5,
+                  delFlag: null,
+                  createBy: null,
+                  createTime: null,
+                  updateBy: null,
+                  updateTime: null,
+                  remark: null}
+                  let snghs = this.channelNumberList[0].videoAddress.split('@')
+                  let snghst = snghs[1].split(':')
+                  let snsgduan = snghst[1].split('/')
+                   console.log(snghs,snghst,snsgduan)
+                  let sgse={'ip':this.channelNumberList[0].equipmentIp,
+                  'account':this.channelNumberList[0].account,
+                  'password':this.channelNumberList[0].password,
+                  'port':this.channelNumberList[0].port
+                  }
+          }
+        }
+
+
+
+           this.loading = false
+        // getWarnManage(this.$route.query.id).then(response => {
+          // this.form = response.data
+        this.loading = false
+      })
+    },
+    clickEnableDraw() {
+        WebVideoCtrl.I_SetDrawStatus(true).then(() => {
+            this.g_bEnableDraw = true;
+            // showOPInfo("启用绘制成功!");
+        }, (oError) => {
+            // showOPInfo("启用绘制失败!", oError.errorCode, oError.errorMsg);
+        });
+    },
+    getdrawFn(){
+      this.isdisflag=!this.isdisflag;
+      if(this.isdisflag){
+        this.clickDisableDraw()
+      }else{
+        this.clickEnableDraw()
+      }
+    },
+    // 禁用多边形绘制
+    clickDisableDraw() {
+        WebVideoCtrl.I_SetDrawStatus(false).then(() => {
+            this.g_bEnableDraw = false;
+            // showOPInfo("禁用绘制成功!");
+            this.clickAddSnapPolygon()
+        }, (oError) => {
+            // showOPInfo("禁用绘制失败!", oError.errorCode, oError.errorMsg);
+        });
+    },
+    clickGetSnapPolygon() {
+      var that=this;
+        WebVideoCtrl.I_GetSnapPolygonInfo(this.g_iWndIndex).then((szXml) => {
+            console.log('获取图形:', szXml);
+            that.getpoint(szXml)
+        });
+    },
+    //获取x,y轴
+    getpoint(xmlString){
+      var that=this;
+        const parser = new DOMParser();
+            const xmlDoc = parser.parseFromString(xmlString, "text/xml");
+            // 获取所有 SnapPolygon 节点
+            const polygonNodes = xmlDoc.querySelectorAll("SnapPolygon");
+             var newArr=[];
+             var arr1=JSON.parse(JSON.stringify(this.shapes))
+            // 提取每个多边形的 id 和坐标点
+            this.polygons = Array.from(polygonNodes).map((polygonNode) => {
+              const id = polygonNode.querySelector("id").textContent;
+              const pointNodes = polygonNode.querySelectorAll("point");
+              const points = Array.from(pointNodes).map((pointNode) => ({
+                x: pointNode.querySelector("x").textContent,
+                y: pointNode.querySelector("y").textContent,
+                name:'区域' + id
+              }));
+              var newobj={
+                id:id,
+                points:points
+              }
+              newArr.push(newobj)
+              // return { id, points };
+            });
+           this.shapes = arr1.map(item1 => {
+             const matchedItem = newArr.find(item2 => item2.id == item1.id);
+             return {
+               id: item1.id,
+               points: matchedItem ? matchedItem.points : item1.points,
+             };
+           });
+           console.log(this.shapes)
+        // this.shapes=JSON.parse(JSON.stringify(newArr))
+        this.messageToSend = this.shapes
+        this.form.channelRange = JSON.stringify(this.shapes)
+        this.sendMessage()
+        console.log(this.shapes)
+    },
+    toggleConnection(){
+      if (this.isConnected) {
+        // 断开连接
+        client.end()
+        this.isConnected= false
+        this.connectionStatus = 'Disconnected'
+        return
+      }
+
+      // 建立连接
+      this.connecting = true
+      try {
+        client= mqtt.connect(this.mqttConfig.url, {
+          clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
+          keepalive: 60,
+          clean: true,
+          connectTimeout: 4000,
+          reconnectPeriod: 1000
+        })
+        client.on('connect', () => {
+          this.isConnected = true
+          this.connectionStatus= 'Connected'
+          this.connecting = false
+          console.log(3)
+          // 订阅主题
+          client.subscribe(this.mqttConfig.topic, (err) => {
+            if (err) {
+              console.error('Subscribe error:', err)
+            }else{
+               console.log('成功订阅 detection/rect 主题!')
+            }
+
+          })
+        })
+        client.on('message', (topic, message) => {
+          // 接受信息
+          console.log(topic,message)
+          this.messages.unshift({
+            type: 'received',
+            content: message.toString(),
+            timestamp: new Date().toLocaleTimeString()
+          })
+        })
+        client.on('error', (err) => {
+          console.error('MQTT Error:', err)
+          this.connectionStatus= 'Error'
+          this.connecting = false
+        })
+      } catch (error) {
+        console.error('Connection error:', error)
+        this.connectionStatus= 'Error'
+        this.connecting = false
+      }
+    },
+    sendMessage(){
+      if (!client || !this.messageToSend) return
+      this.messageToSend = JSON.stringify(this.messageToSend)
+      console.log(this.messageToSend)
+      client.publish(this.mqttConfig.topic, this.messageToSend)
+      this.messages.unshift({
+        type: 'sent',
+        content: this.messageToSend,
+        timestamp: new Date().toLocaleTimeString()
+      })
+      this.messageToSend = []
+    },
+    // 添加图形,最多不超过16个图形
+    clickAddSnapPolygon() {
+      var that=this;
+        if (!this.g_bEnableDraw) {
+            return;
+        }
+        var shapes=JSON.parse(JSON.stringify(this.shapes))
+        let szId = 1; // 默认从 1 开始
+        if(shapes&&shapes.length>0){
+          const ids  = shapes.map(item => item.id).sort((a, b) => a - b);
+          for (const id of ids) {
+            if (id > szId) {
+              // 如果当前 id > szId,说明 szId 未被使用
+              break;
+            }
+            szId = Number(id) + 1; // 否则,继续检查下一个
+          }
+        }
+        if (!/^[1-9]\d*$/.test(szId)) {
+            alert("图形ID只能为正整数!");
+            return
+        }
+        if (Number(szId) > 32) {
+            alert("图形ID范围1-32!");
+            return
+        }
+        console.log(szId)
+        // var szName = encodeString($("#snapName").val());
+        var szName = '';
+        var szInfo={
+
+        }
+        var szInfo = "<?xml version='1.0' encoding='utf-8'?>";
+        szInfo += "<SnapPolygonList>";
+        szInfo += "<SnapPolygon>";
+        szInfo += "<id>" + szId + "</id>";          // [1, 32]
+        szInfo += "<polygonType>0</polygonType>"; //如果想绘制多边形,polygonType指需要改为1
+        szInfo += "<PointNumMax>17</PointNumMax>";  // [MinClosed, 17]
+        szInfo += "<MinClosed>4</MinClosed>";       // [4, 17]
+        szInfo += "<tips>#" + szId + "#" + szName + "</tips>";
+        szInfo += "<isClosed>false</isClosed>";
+        szInfo += "<color><r>0</r><g>255</g><b>0</b></color>";
+        szInfo += "<pointList/>";
+        szInfo += "</SnapPolygon>";
+        szInfo += "</SnapPolygonList>";
+
+        WebVideoCtrl.I_SetSnapPolygonInfo(this.g_iWndIndex, szInfo).then(() => {
+            // showOPInfo("添加图形成功!");
+            var obj={
+              id:szId,
+              points:[],
+              'name':'区域' + szId
+            }
+            if(this.shapes&&this.shapes.length){
+              this.shapes.splice(Number(szId)-1,0,obj)
+            }else{
+              this.shapes.push(obj)
+            }
+            console.log(this.shapes)
+        });
+        WebVideoCtrl.I_SetSnapDrawMode(this.g_iWndIndex, 2);
+    },
+    //删除图形
+    clickDelSnapPolygon(szId,idx) {
+        if (!this.g_bEnableDraw) {
+            return;
+        }
+
+        var aShapes = [];
+        aShapes.push({
+            polygonType: 0,
+            id: szId
+        });
+        this.shapes.splice(idx,1)
+        WebVideoCtrl.I_ClearSnapInfo(this.g_iWndIndex, aShapes);
+    },
+    // 清空图形
+    clickDelAllSnapPolygon() {
+        if (!this.g_bEnableDraw) {
+            return;
+        }
+        WebVideoCtrl.I_ClearSnapInfo(this.g_iWndIndex).then(() => {
+            // showOPInfo("清空图形成功!");
+             this.shapes=[];
+        }, (oError) => {
+            // showOPInfo("清空图形失败!", oError.errorCode, oError.errorMsg);
+        });
+    },
+
+
+
+    // 通道点击
+    ishg(val,row){
+      this.isfse = false
+      this.ishge = row
+       getChannelNumber(val.channelId).then(response => {
+         // const video = document.getElementById(this.shiweis);
+         // video.src = 'http://192.168.101.64:5000/video_feed/video_feed?' + new Date().getTime();
+         if(response.data.isChannel == 'Y'){
+           this.form = response.data.parameterSet
+           this.shapes = JSON.parse(this.form.channelRange)
+           this.form.channelId = response.data.channelId
+           this.form.isChannel = response.data.isChannel
+           this.form.equipmentNum = response.data.equipmentNum
+           this.form.equipmentId = response.data.equipmentId
+           this.form.equipmentName = response.data.equipmentName
+           this.form.channelNum = response.data.channelNum
+           let snghs = response.data.videoAddress.split('@')
+           let snghst = snghs[1].split(':')
+           let snsgduan = snghst[1].split('/')
+            console.log(snghs,snghst,snsgduan)
+           let sgse={'ip':response.data.equipmentIp,
+           'account':response.data.account,
+           'password':response.data.password,
+           'port':response.data.port
+           }
+
+         }else{
+           this.form = {parameterId: null,
+                 channelId: response.data.channelId,
+                 equipmentId: response.data.equipmentId,
+                 equipmentNum: response.data.equipmentNum,
+                 equipmentName: response.data.equipmentName,
+                 channelNum: response.data.channelNum,
+                 channelRange: null,
+                 isChannel:response.data.isChannel,
+                 leaveTime: 10,
+                 playTime: 10,
+                 leaveRate: 0.5,
+                 playRate: 0.5,
+                 delFlag: null,
+                 createBy: null,
+                 createTime: null,
+                 updateBy: null,
+                 updateTime: null,
+                 remark: null}
+                 let snghs = response.data.videoAddress.split('@')
+                 let snghst = snghs[1].split(':')
+                 let snsgduan = snghst[1].split('/')
+                  console.log(snghs,snghst,snsgduan)
+                 let sgse={'ip':response.data.equipmentIp,
+                 'account':response.data.account,
+                 'password':response.data.password,
+                 'port':response.data.port
+                 }
+         }
+         // this.isurwe = response.data.photoAddress
+       })
+
+      // this.clickStartRealPlay('192.168.101.64', '80',1, 0, 1);
+
+    },
+
+
+	  init(val) { //这个val 就是一个地址,例如: http://192.168.2.201:85/live/9311272c49b845baa2b2810ad9bf3f68.flv 这是个服务器返回给我的一个监控视频流地址
+	        setTimeout(() => { //使用定时器是因为,在mounted声明周期里调用,可能会出现DOM没加载出来的原因
+	          var videoElement = this.$refs.videosmallone; // 获取到html中的video标签
+			  this.isshiwa = true
+	          if (flvjs.isSupported()) {
+	          //因为我这个是复用组件,进来先判断 player是否存在,如果存在,销毁掉它,不然会占用TCP名额
+	            if (this.player !== null) {
+	              this.player.pause();
+	              this.player.unload();
+	              this.player.detachMediaElement();
+	              this.player.destroy();
+	              this.player = null;
+	            }
+	            this.player = flvjs.createPlayer( //创建直播流,加载到DOM中去
+	              {
+	                type: "flv",
+	                url: val, //你的url地址
+	                isLive: true, //数据源是否为直播流
+	                hasAudio: false, //数据源是否包含有音频
+	                hasVideo: true, //数据源是否包含有视频
+	                enableStashBuffer: true, //是否启用缓存区
+	              },
+	              {
+	                enableWorker: false, //不启用分离线程
+	                enableStashBuffer: false, //关闭IO隐藏缓冲区
+	                autoCleanupSourceBuffer: true, //自动清除缓存
+	                lazyLoad: false,
+	              }
+	            );
+				this.isshoe = true
+	            this.player.attachMediaElement(videoElement); //放到dom中去
+
+	            //!!!!!!这里需要注意,有的时候load加载完成不一定可以播放,要是播放不成功,用settimeout 给下面的this.player.play() 延时几百毫秒再播放
+	            // setTimeout(this.player.play(), 48000);
+				setTimeout(() =>{
+					//到时间时只执行一次就停止
+					this.player.load();//准备完成
+					this.player.play()
+					console.log('播放')
+				},900)
+	          }
+	        }, 500);
+	      },
+
+	  createVideo() {
+	        if (flvjs.isSupported()) {
+				console.log(1)
+	          var videoElement = document.getElementById('myFlvVideo')
+			  console.log(videoElement,flvjs)
+	          this.flvPlayer = flvjs.createPlayer(
+	            {
+	              type: 'application/x-mpegURL',
+	              isLive: true,
+	              hasAudio: false,
+	              url:'https://stream1.freetv.fun/86d463c0006da643e45e26b34875df87059dcba13e69d0a5471b185793c122a2.m3u8'
+	            },
+	            {
+	              cors: true, // 是否跨域
+	              enableWorker: false, // 是否多线程工作
+	              enableStashBuffer: false, // 是否启用缓存
+	              stashInitialSize: 400, // 缓存大小(kb)  默认384kb
+	              autoCleanupSourceBuffer: true // 是否自动清理缓存
+	            }
+	          )
+	          this.flvPlayer.attachMediaElement(videoElement)
+	          this.flvPlayer.load()
+	          this.flvPlayer.play()
+			  console.log(1244)
+	          // 报错重连
+	          this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
+	            console.log('errorType:', errType)
+	            console.log('errorDetail:', errDetail)
+	            if (this.flvPlayer) {
+	              this.destoryVideo()
+	              this.createVideo()
+	            }
+	          })
+	        }
+
+			console.log(this.flvPlayer.play())
+	      },
+	      destoryVideo() {
+	        this.player.pause()
+	        this.player.unload()
+	        this.player.detachMediaElement()
+	        this.player.destroy()
+	        this.player = null
+	      },
+
+	  initScroll() {
+	    	  // 给内层盒子设置宽度,不设置宽度的话无法滚动
+	    	  // let width = this.goods.length * 60
+	    	  // // 如果有外边距,可以这样写。需要去掉最后一个元素的外边距,在后面减一下
+	    	  // let width = this.goodslength * (60 + 10) - 10
+			  let width = 6 * (200 + 10) - 10
+	        // this.$refs.content.style.width = width + 'px'
+	        this.$nextTick(()=>{
+	          if(!this.Scroll) {
+	            this.Scroll = new Bscroll(this.$refs.wrapper,{
+	              click: true,      // 配置允许点击事件
+	              scrollX: true,    // 开启横向滚动
+	              eventPassthrough: 'vertical',  // 当设置 eventPassthrough 为 'vertical' 的时候,scrollY 无效
+				  mouseWheel: true,
+				  scrollbar: { // 滚动条, 要加相对位置
+				              fade: true
+				            }
+	            })
+	          } else {
+	            this.Scroll.refresh()     // 重新计算 better-scroll,当 DOM 结构发生变化的时确保滚动效果正常
+	          }
+	        })
+	      },
+    // 取消按钮
+    cancel() {
+      this.open = false;
+	  this.opens = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {
+		receptionId:undefined,
+        receptionPhone:undefined,
+        // postSort: 0,
+        // status: "0",
+        receptionName: undefined
+      };
+      this.resetForm("form");
+    },
+
+	iszheg(event){
+	 console.log(event);
+
+
+	 // 校验身份证:
+	 console.log(reg.test(this.form.idCard),23741)
+	 		if ( reg.test(this.form.idCard)|| _IDre15.test(this.form.idCard)) {
+	 			// this.idea();
+	 			this.go(this.form.idCard);
+	 			// callback()
+	 		} else {
+	   if(ncjsle.test(this.form.idCard) || nhyeli.test(this.form.idCard)){
+	      console.log(3)
+	   }else{
+	     if(gnse.test(this.form.idCard)  ){
+	         console.log(4)
+	     }else{
+	       if(tw.test(this.form.idCard) || twe.test(this.form.idCard)){
+	         console.log(5)
+	       }else{
+	         this.$message.error('证件格式不正确');
+	       }
+	     }
+
+	   }
+	 		}
+	},
+	erw(row){
+		this.$router.push({
+		  path: '/reny/ewm',
+		  query:{
+			   'tenantId':row.investigateTableId
+			  }
+		})
+	},
+
+	hussar_17Click(val) {
+	        const _this = this
+	        var url =process.env.VUE_APP_BASE_API + 'pages/index/index?id=' + val.investigateTableId;
+			 console.log(url,this.$refs.canvas,6)
+			this.opent = true
+	        QRCode.toCanvas(
+	                      canvas,
+	                      url,//生成二维码的数据
+	                      {width: 100, height:100, margin: 1.5},//margin调整二维码的白边大小
+	                      function (error) {
+	                        if (error) {
+	                          console.log(error);
+	                        }
+	                      }
+	                    );
+
+	        // console.log(qrcode,987)
+	      },
+	/** 成绩_子添加按钮操作 */
+	handleAddScoreDataDetails() {
+
+	  let obj = {};
+	  obj.duty = "";
+	  obj.idCard = "";
+	  obj.phonenumber = "";
+	  obj.userName = "";
+	  this.scoreDataDetailsList.push(obj);
+	  console.log(this.scoreDataDetailsList)
+	},
+	/** 成绩_子删除按钮操作 */
+	handleDeleteScoreDataDetails() {
+	  if (this.checkedScoreDataDetails.length == 0) {
+	    this.$modal.msgError("请先选择要删除的数据");
+	  } else {
+	    const scoreDataDetailsList = this.scoreDataDetailsList;
+	    const checkedScoreDataDetails = this.checkedScoreDataDetails;
+	    this.scoreDataDetailsList = scoreDataDetailsList.filter(function(item) {
+	      return checkedScoreDataDetails.indexOf(item.index) == -1
+	    });
+	  }
+	},
+	/** 复选框选中数据 */
+	handleScoreDataDetailsSelectionChange(selection) {
+	  this.checkedScoreDataDetails = selection.map(item => item.index)
+	},
+	/** 成绩_子序号 */
+	rowScoreDataDetailsIndex({ row, rowIndex }) {
+	  row.index = rowIndex + 1;
+	},
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const postIds = row.recordId || this.ids;
+      delReservat(postIds).then(response => {
+       this.$modal.msgSuccess("操作成功");
+        this.getList();
+      });
+
+      // this.$modal.confirm('是否确认删除数据项?').then(function() {
+      //   return delPost(postIds);
+      // }).then(() => {
+      //   this.getList();
+      //   this.$modal.msgSuccess("删除成功");
+      // }).catch(() => {});
+    },
+    handleDeletehx(row) {
+      const postIds = row.reservatId || this.ids;
+      let nhg={}
+      nhg.reservatId = postIds
+      delReservathx(nhg).then(response => {
+       this.$modal.msgSuccess("操作成功");
+        this.getList();
+      });
+
+      // this.$modal.confirm('是否确认删除数据项?').then(function() {
+      //   return delPost(postIds);
+      // }).then(() => {
+      //   this.getList();
+      //   this.$modal.msgSuccess("删除成功");
+      // }).catch(() => {});
+    },
+	// 发送短信
+	handleUpdatefas(row){
+		updateFs(row).then(response => {
+		 this.$modal.msgSuccess("发送成功");
+		  // this.getList();
+		});
+	},
+	handleDeletegx(row){
+		updateGx(row).then(response => {
+		  this.$modal.msgSuccess("发送成功");
+		  // this.getList();
+		});
+	},
+    /** 导出按钮操作 */
+    handleExport() {
+      this.download('system/reservat/export', {
+        ...this.queryParams
+      }, `预约人员.xlsx`)
+    },
+		// 获取屏幕高度
+		showFilterForm () {
+		      this.filterActive = !this.filterActive
+		      this.changeTableMaxHeight()
+		    },
+		    changeTableMaxHeight () {
+		      let height = document.body.offsetHeight // 网页可视区域高度
+		      // if (this.filterActive) {
+		      //   this.tableMaxHeight = height - 320
+		      // } else {
+		        this.tableMaxHeight = height - 350
+		      // }
+		      console.log(height)
+		    },
+    // 播放摄像头
+    getVideo(row) {
+    	var that=this;
+       this.isfse  = true
+       console.log(row)
+    	this.initVideoPlay(row.ip, row.port, row.account, row.password,'divPlugin')
+    },
+    // 有插件
+    initVideoPlay(ip, port, username, password,id) {
+    	var that = this;
+    	var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
+    	var g_oLocalConfig = null; //本地配置
+    	// let ip = this.szIP //硬盘录像机ip
+    	// let port = this.szPort //默认为80端口
+    	// let username = this.szUsername //账号:
+    	// let password = this.szPassword // 密码
+    	var iRtspPort = ''
+    	// 1.初始化插件参数及插入插件
+    	WebVideoCtrl.I_InitPlugin({
+    		bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
+    		iWndowType: 1,
+    		bDebugMode: true,
+    		cbSelWnd: function(xmlDoc) {
+    			g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
+    			const szInfo = "当前选择的窗口编号:" + g_iWndIndex;
+    			this.g_iWndIndex = g_iWndIndex;
+    			console.log(szInfo, "szInfo");
+    		},
+    		cbDoubleClickWnd: function(iWndIndex, bFullScreen) {
+    			let szInfo = "当前放大的窗口编号:" + iWndIndex;
+    			if (!bFullScreen) {
+    				szInfo = "当前还原的窗口编号:" + iWndIndex;
+    			}
+    			// console.log(szInfo, "szInfo");
+    		},
+    		cbEvent: function(iEventType, iParam1, iParam2) {
+    			if (2 == iEventType) {
+    				// 回放正常结束
+    				console.log("窗口" + iParam1 + "回放结束!");
+    			} else if (-1 == iEventType) {
+    				console.log("设备" + iParam1 + "网络错误!");
+    			} else if (3001 == iEventType) {
+    				clickStopRecord(g_szRecordType, iParam1);
+    			}
+    		},
+    		//2.登录摄像头
+    		cbInitPluginComplete: function() {
+    			const oLiveView = {
+    				iProtocol: 1, // protocol 1:http, 2:https
+    				szIP: ip, // protocol ip
+    				szPort: port, // protocol port
+    				szUsername: username, // device username
+    				szPassword: password, // device password
+    				iStreamType: 1, // stream 1:main stream  2:sub-stream  3:third stream  4:transcode stream
+    				iChannelID: 1, // channel no
+    				bZeroChannel: false, // zero channel
+    			};
+    			// var swidth=Number((that.width*Number(that.scale))).toFixed(2)
+    			// var sheight=Number((that.height*Number(that.scale))).toFixed(2)
+    			// that.swidth=swidth
+    			// that.sheight=sheight
+    			WebVideoCtrl.I_InsertOBJECTPlugin(id).then(
+    				() => {
+    					// setTimeout(function(){
+    					// 	WebVideoCtrl.I_Resize(swidth,sheight)
+    					// },300)
+    					WebVideoCtrl.I_Login(
+    						oLiveView.szIP,
+    						oLiveView.iProtocol,
+    						oLiveView.szPort,
+    						oLiveView.szUsername,
+    						oLiveView.szPassword, {
+    							timeout: 3000,
+    							async: false,
+    							success: function(xmlDoc) {
+    								console.log(" 登录成功!");
+    								let a = ip
+    								let b = port
+    								setTimeout(function() {
+    									//延迟方法
+    									setTimeout(function() {
+    										//调用预览摄像头这里可以循环创建
+    										that.clickStartRealPlay(a, b,1, 0, 1);
+    										// that.clickStartRealPlay(a, b, 1, 1,2);
+    										// that.clickStartRealPlay(a, b, 1, 2,3);
+    										// clickStartRealPlay(a,b, 1, 3, 4);
+    										// clickStartRealPlay(a,b, 1, 4, 5);
+    										// clickStartRealPlay(a,b, 1, 5, 6);
+    										// clickStartRealPlay(a,b, 1, 6, 7);
+    										// clickStartRealPlay(a,b, 1, 7, 8);
+    									}, 1000);
+
+
+    									setTimeout(function() {
+    										// 获取通道 (如果多个摄像头需要获取多个通道需要调用)
+    										// getChannelInfo(a);
+    										//获取端口 (在这里获取RTSP 端口号 预览时传入)
+    										getDevicePort(a);
+    									}, 10)
+
+    								}, 10);
+    							},
+    							error: function(oError) {
+    								console.log(" 登录失败!", oError);
+    							},
+    						}
+    					);
+    					// 检查插件是否最新
+    					WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {
+    						if (bFlag) {
+    							alert(
+    								"检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!"
+    							);
+
+    						}
+    					});
+    				},
+    				() => {
+    					alert(
+    						"插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!"
+    					);
+
+    				}
+    			);
+
+    		},
+    	});
+    	// 3.获取通道
+    	function getChannelInfo(a) {
+    		var szDeviceIdentify = a,
+    			oSel = null; //通道列表
+    		if (null == szDeviceIdentify) {
+    			return;
+    		}
+    		// 模拟通道 有
+    		WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("VideoInputChannel");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text();
+    					if ("" == name) {
+    						name = "Camera " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+
+    					// console.log(id + "通道id是")
+    					// console.log(name + "通道name是")
+    				});
+    				console.log(szDeviceIdentify + " 获取模拟通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取模拟通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    		// 数字通道
+    		WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text(),
+    						online = $(this).find("online").eq(0).text();
+    					if ("false" == online) { // 过滤禁用的数字通道
+    						return true;
+    					}
+    					if ("" == name) {
+    						name = "IPCamera " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+    				});
+    				console.log(szDeviceIdentify + " 获取数字通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取数字通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    		// 零通道
+    		WebVideoCtrl.I_GetZeroChannelInfo(szDeviceIdentify, {
+    			success: function(xmlDoc) {
+    				var oChannels = $(xmlDoc).find("ZeroVideoChannel");
+
+    				$.each(oChannels, function(i) {
+    					var id = $(this).find("id").eq(0).text(),
+    						name = $(this).find("name").eq(0).text();
+    					if ("" == name) {
+    						name = "Zero Channel " + (i < 9 ? "0" + (i + 1) : (i + 1));
+    					}
+    					if ("true" == $(this).find("enabled").eq(0).text()) { // 过滤禁用的零通道
+
+    					}
+    				});
+    				console.log(szDeviceIdentify + " 获取零通道成功!");
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 获取零通道失败!", oError.errorCode, oError.errorMsg);
+    			}
+    		});
+    	};
+
+    	//4.获取端口
+    	function getDevicePort(a) {
+    		var szDeviceIdentify = a;
+
+    		if (null == szDeviceIdentify) {
+    			return;
+    		}
+    		WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then((oPort) => {
+    			// console.log(oPort.iDevicePort + "iDevicePort的值是")
+    			// console.log(oPort.iRtspPort + "iRtspPort的值是")
+    			console.log(szDeviceIdentify + " 获取端口成功!");
+    			iRtspPort = oPort.iRtspPort
+    			that.iRtspPort = iRtspPort
+    		}, (oError) => {
+    			var szInfo = "获取端口失败!";
+    			console.log(szDeviceIdentify + szInfo, oError.errorCode, oError.errorMsg);
+    		});
+    	};
+    },
+    // 5.开始预览
+    clickStartRealPlay(szIP, szPort, iStreamType, iWndIndex, iChannelID) {
+      var that=this;
+    	var oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex),
+    		szDeviceIdentify = szIP + "_" + szPort, //ip
+    		iChannelID = iChannelID,
+    		bZeroChannel = false,
+    		iPort = this.iRtspPort,
+    		szInfo = "";
+    	iStreamType = iStreamType;
+    	if (null == szDeviceIdentify) {
+    		return null;
+    	}
+    	this.szDeviceIdentify = szDeviceIdentify;
+    	var startRealPlay = function() {
+    		WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
+    			iStreamType: iStreamType,
+    			iChannelID: iChannelID,
+    			bZeroChannel: bZeroChannel,
+    			iWndIndex: iWndIndex, //要播放的窗口
+    			iPort: iPort, //如果多个摄像头需要必填 (RTSP 端口号)
+    			success: function() {
+    				szInfo = "开始预览窗口" + iWndIndex + "成功!";
+    				console.log(szDeviceIdentify + " " + szInfo);
+    			},
+    			error: function(oError) {
+    				console.log(szDeviceIdentify + " 开始预览窗口" + iWndIndex + "失败!", oError
+    					.errorCode, oError.errorMsg);
+    			}
+    		});
+    	};
+
+    	if (oWndInfo != null) { // 已经在播放了,先停止
+    		WebVideoCtrl.I_Stop({
+    			success: function() {
+    				startRealPlay();
+    			}
+    		});
+    	} else {
+    		startRealPlay();
+    	}
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          console.log(this.form)
+          // return
+          if (this.form.isChannel != 'N') {
+            updateParameterSet(this.form).then(response => {
+              this.$modal.msgSuccess("修改成功")
+              this.open = false
+              // this.$router.go(-1)
+            })
+          } else {
+            addParameterSet(this.form).then(response => {
+              this.$modal.msgSuccess("新增成功")
+              this.open = false
+              // this.$router.go(-1)
+            })
+          }
+        }
+      })
+    },
+  }
+};
+</script>
+
+<style lang="scss">
+  .snhseinu{
+    .el-input--medium .el-input__inner{
+      border: none;
+    }
+  }
+	.isjses{
+		.el-tabs--left .el-tabs__nav-wrap.is-left::after{
+			width:6px;
+		}
+		.el-tabs--left .el-tabs__active-bar.is-left,{
+			width:6px;
+		}
+	}
+	.ingaqe{
+		.el-input--medium{
+			width:100%;
+		}
+	}
+	.nhgrls{
+		.el-dialog__body{
+			padding: 0;
+		}
+	}
+  .hyr{
+    span{
+      text-decoration:underline;
+    }
+  }
+</style>
+<style scoped lang="scss">
+	.nghwgq{
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		margin-top: 90px;
+		div{
+			color:#aaa;
+		}
+	}
+	.ihgswq{
+		// width:100%;
+		// overflow-x: hidden;
+		// margin-top: 30px;
+	}
+	.fijge{
+		// width: 110%;
+		display: flex;
+		display: -webkit-flex;
+		justify-content: space-between;
+		.shotw{
+			position: relative;
+			// width:32%;
+			width: 238px;
+			height: 140px;
+			margin-left: 0;
+			margin-right: 20px;
+			margin-bottom: 15px;
+			img{
+				height: 100%;
+				cursor:pointer;
+			}
+		  p{
+			  // bottom:-10px;
+			  margin: 0;
+			  font-weight: bold;
+			  font-size: 16px;
+			   padding: 5px  10px;
+			   cursor:pointer;
+		  }
+		  .iges{
+			position: absolute;
+			top:50%;
+			left:50%;
+			width:30px;
+			height: 30px;
+			transform: translate(-50%,-50%);
+			cursor:pointer;
+		  }
+		}
+	}
+	.nhgwesvq{
+		width:1610px !important;
+	}
+	.shotw{
+		position: relative;
+		margin-left: -20px;
+		margin-right: -20px;
+		img{
+			width:100%;
+			height: 80vh;
+		}
+	  p{
+	     position: absolute;
+		 bottom: 0;
+		 left:0;
+		 background-color: rgba(0, 0, 0, .5);
+		 width: 100%;
+		 padding: 13px  5px;
+		 color:#fff;
+		 font-weight: bold;
+		 font-size: 18px;
+	  }
+	  .p{
+		  top:0px;
+		  height: 60px;
+		  margin: 0;
+		  padding-left: 20px;
+	  }
+	}
+
+
+	.ksfpo{
+		background-color: #3464EB;
+		padding: 6px 12px;
+		border-radius: 4px ;
+		color:#fff;
+		cursor:pointer;
+	}
+	.ksfpok{
+		background-color: #FFFFFF;
+		padding: 5px 11px;
+		border-radius: 4px;
+		color:#3464EB;
+		border: 1px solid #3464EB;
+		margin-left: 10px;
+		cursor:pointer;
+	}
+	.ksfpofg{
+		background-color: #75DB75;
+		padding: 5px 11px;
+		border-radius: 4px;
+		color:#FFFFFF;
+		border: 1px solid #75DB75;
+		margin-left: 10px;
+		cursor:pointer;
+	}
+  .iuer{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .ite{
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      p{
+        cursor:pointer;
+        margin: 0;
+        font-size: 15px;
+        font-family: PingFang SC;
+        font-weight: 500;
+        color:#666666;
+        padding: 4px 12px;
+        background: #Fff;
+        border-radius: 4px;
+        margin-right: 20px;
+		position: relative;
+      }
+      .actt{
+        background: #fff;
+        // border-bottom: 3px solid #5974E0;
+        // border-radius: 0;
+		// border-bottom-right-radius: 4px;
+        color: #5974E0;
+      }
+	  .actt{
+		    &::after {
+		          content: "";
+		          width: 40%;
+		          height: 5px;
+				  border-radius: 3px;
+		          transform: translate(-50%);
+		          background-color: #5974E0;
+		          position: absolute;
+		          left: 50%;
+		          bottom:-3px;
+		        }
+
+	  }
+
+    }
+  }
+  .lqw{
+    padding: 0 10px;
+    margin: 0;
+    margin-bottom: 20px;
+  }
+.nhgel{
+  height: 170px;
+  background-color: #313b61;
+  width: 100%;
+  position: absolute;
+  top:0;
+  left:0;
+  z-index: 0;
+}
+	.app-container{
+		background-color: #f3f4f6;
+		padding-top: 10px;
+		height: 180vh;
+
+	}
+	.ntgs{
+	position: relative;
+		// background-color: #fff;
+		padding: 5px;
+		// border-radius: 5px;
+		padding-top: 10px;
+	     padding: 10px 20px;
+		.pagination-container{
+			height: 50px;
+		}
+	}
+	.nghfs{
+	position: relative;
+		background-color: #fff;
+		padding-top: 18px !important;
+		padding: 5px;
+		// border-radius: 5px;
+		// margin-bottom: 20px;
+	}
+	.ksf{
+		img{
+			width:100%;
+			height: 100%;
+		}
+	}
+   .ingwfaq{
+	   font-weight: bold;
+	   font-size: 16px;
+   }
+.dflex{display: flex;}
+.dflext{display: flex;align-items: flex-start;}
+.drawings-list{width: 100%;flex: 0 0 auto;padding-left: 10px;line-height:36px ;
+  .delimg{width: 15px;height: 15px;margin-left: 5px;}
+  .txt{font-size: 12px;padding-left: 5px;flex: 1;}
+  .tflex{display: flex;align-items: center;}
+}
+.disbtn{display: flex;align-items: center;flex: 0 0 auto;min-height: 34px;cursor: pointer;
+  img{width: 14px;height: 14px;margin-right: 10px;}
+  font-weight: 500;
+  font-size: 14px;
+  color: #444444;
+}
+.anche{
+  background: #E7F1EE !important;
+  border-radius: 4px  !important;
+  font-weight: 400;
+  div{
+    color: #03BF8A !important;
+  }
+}
+.actw{
+  border-color: #f8b500 !important;
+}
+</style>

+ 8 - 0
ruoyi-ui/src/views/shishijianc.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>