<template>
  <!-- 三维画布 -->
  <div style="width:100%;height:calc(100vh - 90px);position:relative;top: 0;left: 0;">
    <div id="THREE_div" ref="draw" class="draw" />
    <div v-if="loadSuccess" class="loadingBox">
      <div class="progress">
        <div class="progress-bar progress-bar-danger progress-bar-striped active" :style="{ width: progress }">
          <div class="progress-value">{{ progress }}</div>
        </div>
      </div>
      <div class="loadingBox1">变电站三维模型加载中... 请稍候！</div>
    </div>
    <el-button v-show="!isroam" class="THREE-button" :style="{ right: isRightList ? '630px' : '290px' }"
      @click.stop="rangingClick">{{ !isranging
        ? '开始' : '结束' }}测距</el-button>
    <el-button v-show="!isroam" :style="{ right: isRightList ? '490px' : '150px' }" @click="reset"
      class="THREE-button">恢复初始态</el-button>
    <el-button class="THREE-button" :style="{ right: isRightList ? '350px' : '10px' }" @click.stop="roamClick">{{
      !isroam
        ? '开始' : '结束' }}漫游</el-button>
    <div v-show="isRightList" class="THREE-right-list" @click.stop>
      <div class="THREE-right-list-title">
        <span>
          <span v-show="selType == '01'">摄像机列表</span>
          <span v-show="selType == '02'">点位列表</span>
          <span v-show="selType == '05'">设备列表</span></span>
        <img src="@/assets/3d/u523.png" style="cursor: pointer;margin:0" alt="" @click.stop="isRightList = false">
      </div>
      <div class="THREE-right-list-main">
        <el-input class="screenHomepage" v-if="selType != '04'" placeholder="请输入内容" v-model="search" clearable
          @clear="searchNmae" @change="searchNmae" @input="searchNmae">
          <template #suffix>
            <img src="@/assets/3d/spjk_ss.png" style="cursor:pointer ;">
          </template>
        </el-input>

        <div v-if="selType == '01'" class="THREE-right-list-main-tab">
          <div :class="isOnLine == '01' ? 'THREE-right-list-main-tab-hov' : ''" @click.stop="rightTabClik('01')">全部
          </div>
          <div :class="isOnLine == '02' ? 'THREE-right-list-main-tab-hov' : ''" @click.stop="rightTabClik('02')">在线
          </div>
          <div :class="isOnLine == '03' ? 'THREE-right-list-main-tab-hov' : ''" @click.stop="rightTabClik('03')">离线
          </div>
        </div>
      </div>
      <ul v-show="selType != '04'" :style="{ height: selType == '01' ? 'calc(100vh - 260px)' : 'calc(100vh - 220px)' }">
        <li v-for="(i, index) in searchdata" :class="dataIndex == index ? 'THREE-right-list-main-li-hov' : ''"
          @click.stop="listClick(i, index), information = false">
          <span v-show="selType == '03'" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
            {{ i.name }}
          </span>
          <span v-if="selType == '05'" style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
            {{ i.name }} {{ i.objinfo.componentId == null ? '(主设备)' : '(部件)' }}
          </span>
          <span v-show="selType != '03' && selType != '05'" style="display:flex;">
            <span v-show="selType == '01'">
              <span v-if="i.type == 'Camera'">
                <span v-if="i.objinfo != undefined">
                  <img v-show="i.objinfo.online == 1" src="@/assets/3d/zx.png" alt="">
                  <img v-show="i.objinfo.online == 0" src="@/assets/3d/lx.png" alt="">
                  <img v-show="i.objinfo.online == null" src="@/assets/3d/lx.png" alt="">
                </span>
                <span v-if="i.objinfo == undefined">
                  {{ i.objinfo }}
                  <img src="@/assets/3d/lx.png" alt="">
                </span>
              </span>
              <span v-if="i.type == 'Camera1'">
                <span v-if="i.objinfo != undefined">
                  <img v-show="i.objinfo.online == 1" src="@/assets/3d/zx1.png" alt="">
                  <img v-show="i.objinfo.online == 0" src="@/assets/3d/lx1.png" alt="">
                  <img v-show="i.objinfo.online == null" src="@/assets/3d/lx1.png" alt="">
                </span>
                <span v-if="i.objinfo == undefined">
                  <img src="@/assets/3d/lx1.png" alt="">
                </span>
              </span>
            </span>
            <span
              style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis; display:inline-block;width:135px;">{{
                i.objname }}</span>
          </span>
          <div v-show="selType == '01'" class="THREE-right-list-main-icon">
            <img v-show="i.objinfo != undefined" src="@/assets/3d/xq.png" title="摄像机信息" alt="摄像机信息"
              @click.stop="informationClick(i), listClick(i, index)">
            <img v-show="i.objinfo == undefined" src="@/assets/3d/xq_dis.png" title="摄像机信息" alt="摄像机信息">
            <img v-if="i.objinfo == undefined || i.objinfo.channelList == undefined || i.objinfo.online == 0"
              src="@/assets/3d/sc_dis.png" title="实时视频" alt="实时视频">
            <img v-if="i.objinfo != undefined && i.objinfo.channelList != undefined && i.objinfo.online == 1"
              src="@/assets/3d/ks.png" title="实时视频-1" alt="实时视频-1" @click.stop="realTimeVideo(i, 0)">
            <img
              v-if="i.objinfo != undefined && i.objinfo.channelList != undefined && i.objinfo.channelList.length == 2"
              src="@/assets/3d/ks.png" title="实时视频-2" alt="实时视频-2" @click.stop="realTimeVideo(i, 1)">
            <img v-show="i.type == 'Camera' && !i.start" src="@/assets/3d/ange.png" title="摄像机范围" alt="摄像机范围"
              @click.stop="listange(i)">
            <img v-show="i.type == 'Camera' && i.start" src="@/assets/3d/ange1.png" title="摄像机范围" alt="摄像机范围"
              @click.stop="listange(i)">
          </div>
          <div v-show="selType == '02'" class="three-right-list-main-icon">
            <img v-show="i.objinfo != undefined" src="@/assets/3d/xq.png" title="巡视点位信息" alt="巡视点位信息"
              @click.stop="informationClick(i), listClick(i, index)">
            <img v-if="!i.objinfo && !i.objinfo.patroldeviceJson" src="@/assets/3d/sc_dis.png" title="实时视频" alt="实时视频">
            <img v-else src="@/assets/3d/ks.png" title="实时视频-1" alt="实时视频-1" @click.stop="getDeviceVideo(i, 0)">
            <img v-show="i.objinfo == undefined" @click.stop src="@/assets/3d/xq_dis.png" title="巡视点位信息" alt="巡视点位信息">
            <img src="@/assets/sytlechange/u157.svg" alt="" title="历史记录"
              @click.stop="historicalRecords(i), listClick(i, index)">
          </div>
          <div v-show="selType == '05'" class="THREE-right-list-main-icon">
            <img src="@/assets/3d/xq.png" @click.stop="informationClick(i), listClick(i, index)" title="部件信息"
              alt="部件信息">
          </div>
        </li>
      </ul>
      <el-input v-show="selType == '04'" class="screenHomepage" v-model="filterText" placeholder="请输入内容"
        style="width:90.4%;margin-left:15px;" clearable>
        <template #suffix>
          <img src="@/assets/3d/spjk_ss.png" style="cursor:pointer ;">
        </template>
      </el-input>
      <el-tree ref="treeRef" v-show="selType == '04'" :expand-on-click-node="false" default-expand-all node-key="id"
        :data="searchdata" :props="defaultProps" @node-click="handleNodeClick" :filter-node-method="filterNode"
        style="margin-top:10px;">
        <template #default="{ node, data }">
          <div v-show="node.level == 1" style="display:flex;justify-content:space-between;width:100%">
            <span>{{ data.objname }}</span>
            <span class="THREE-right-list-main-icon" style="display:flex;margin-right:10px">
              <img v-show="data.objinfo != undefined" src="@/assets/3d/xq.png" title="无人车信息" alt="无人车信息"
                @click.stop="informationClick(data), handleNodeClick(data, node)">
              <img v-show="data.objinfo == undefined" @click.stop src="@/assets/3d/xq_dis.png" title="无人车信息"
                alt="无人车信息">
              <img v-if="data.objinfo == undefined || data.objinfo.channelList == undefined || data.objinfo.online == 0"
                src="@/assets/3d/sc_dis.png" title="实时视频" alt="实时视频">
              <img v-if="data.objinfo != undefined && data.objinfo.channelList != undefined" src="@/assets/3d/ks.png"
                title="实时视频-1" alt="实时视频-1" @click.stop="realTimeVideo(data, 0)">
              <img
                v-if="data.objinfo != undefined && data.objinfo.channelList != undefined && data.objinfo.channelList.length == 2"
                src="@/assets/3d/ks.png" title="实时视频-2" alt="实时视频-2" @click.stop="realTimeVideo(data, 1)">
            </span>
          </div>
          <div v-show="node.level == 2" style="display:flex;justify-content:space-between;width:100%">
            <span>{{ data.name }}</span>
            <span class="THREE-right-list-main-icon" style="display:flex;margin-right:10px">
              <img src="@/assets/3d/manyou.png" title="漫游" alt="漫游" @click.stop="unmannedRoam(data, node)"></span>
          </div>
        </template>
      </el-tree>
    </div>
    <div v-show="isSelType" id="context-operate" @click.stop>
      <div :class="selType == '05' ? 'context-operate-hov' : ''" @click="selTypeChange('05')">
        <span v-show="selType == '05'"><img src="@/assets/navigation/swxs_sz_sb1.png" alt=""></span>
        <span v-show="selType != '05'"><img src="@/assets/navigation/swxs_sz_sb.png" alt=""></span>
        <span>设备</span>
      </div>
      <div :class="selType == '01' ? 'context-operate-hov' : ''" @click="selTypeChange('01')">
        <span v-show="selType == '01'"><img src="@/assets/navigation/swxs_sz_sxt1.png" alt=""></span>
        <span v-show="selType != '01'"><img src="@/assets/navigation/swxs_sz_sxt.png" alt=""></span>
        <span>摄像机</span>
      </div>
      <div :class="selType == '02' ? 'context-operate-hov' : ''" @click="selTypeChange('02')">
        <span v-show="selType == '02'"><img src="@/assets/navigation/swxs_sz_sj1.png" alt=""></span>
        <span v-show="selType != '02'"><img src="@/assets/navigation/swxs_sz_sj.png" alt=""></span>
        <span>点位</span>
      </div>

    </div>
    <!-- 详细信息弹窗 -->
    <div class="detailed-information" v-if="information">
      <div id="detailed-information" v-drag class="examination">
        <div class="examination-title">{{ objRow.name }}</div>
        <div class="examination-close" @click.stop="information = false"><img src="@/assets/3d/u523.png" /></div>
        <div class="examination-contont" v-if="selType == '01'">
          <div class="examination-contont-text">设备编码：{{ objRow.userData.objinfo.patroldeviceCode }}</div>
          <div class="examination-contont-text">设备名称：{{ objRow.userData.objinfo.patroldeviceName }}</div>
          <div class="examination-contont-text">设备类型：{{ objRow.userData.objinfo.typeName }}</div>
          <div class="examination-contont-text">视频类型：
            <span v-if="objRow.userData.objinfo.videoMode == 1">可见光</span>
            <span v-if="objRow.userData.objinfo.videoMode == 2">红外</span>
            <span v-if="objRow.userData.objinfo.videoMode == 3">可见光与红外</span>
          </div>
          <div class="examination-contont-text">使用类型：
            <span v-if="objRow.userData.objinfo.useMode == 10">枪机</span>
            <span v-if="objRow.userData.objinfo.useMode == 11">球机</span>
            <span v-if="objRow.userData.objinfo.useMode == 12">云台</span>
          </div>
          <div class="examination-contont-text">设备型号：{{ objRow.userData.objinfo.deviceModel }}</div>
          <div class="examination-contont-text">生产厂家：{{ objRow.userData.objinfo.manufacturer }}</div>
          <div class="examination-contont-text">安装位置：{{ objRow.userData.objinfo.place }}</div>
        </div>
        <div class="examination-contont" v-if="selType == '02'">
          <div class="examination-contont-text">点位名称：{{ objRow.userData.objinfo.deviceName }}</div>
          <div class="examination-contont-text">所属主设备：{{ objRow.userData.objinfo.mainDeviceName }}</div>
          <div class="examination-contont-text">所属部件：{{ objRow.userData.objinfo.componentName }}</div>
          <div class="examination-contont-text">关联摄像机/预置位：
            <!-- {{ objRow.userData.objinfo.patroldeviceJson.device_code }}/ {{ objRow.userData.objinfo.patroldeviceJson.device_pos }} -->
          </div>
          <div class="examination-contont-text">识别类型：
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 1">表计读取</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 2">位置状态识别</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 3">设备外观查看</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 4">红外测温</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 5">声音检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 6">闪烁检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 13">局放特高频检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 12">局放地电压检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 11">局放超声波检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 101">环境温度检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 102">环境湿度检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 103">氧气浓度检测</span>
            <span v-if="objRow.userData.objinfo.recognitionTypeList == 104">SF6浓度检测</span>
          </div>
          <div class="examination-contont-text">表计类型：{{ objRow.userData.objinfo.meterType }}</div>
          <div class="examination-contont-text">分析类型：{{ objRow.userData.objinfo.manufacturer }}
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'isolator'">刀闸状态</span>
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'switch'">开关/压板状态</span>
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'meter'">仪表读数</span>
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'infrared'">红外温度</span>
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'sound'">声音</span>
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'light'">指示灯</span>
            <span
              v-if="objRow.userData.objinfo.pictureAnalysisTypeList && objRow.userData.objinfo.pictureAnalysisTypeList.PictureAnalysisType == 'qrcode'">实物ID</span>
          </div>
        </div>
        <div class="examination-contont" v-if="selType == '04'">
          <div class="examination-contont-text">设备编码：{{ objRow.userData.objinfo.patroldeviceCode }}</div>
          <div class="examination-contont-text">设备名称：{{ objRow.userData.objinfo.patroldeviceName }}</div>
          <div class="examination-contont-text">是否轮转：{{ objRow.userData.objinfo.istransport }}
            <span v-if="objRow.userData.objinfo.istransport == '0'">轮转</span>
            <span v-if="objRow.userData.objinfo.istransport == '1'">不论转</span>
          </div>
          <div class="examination-contont-text">设备型号：{{ objRow.userData.objinfo.deviceModel }}</div>
          <div class="examination-contont-text">生产厂家： {{ objRow.userData.objinfo.manufacturer }}</div>
          <div class="examination-contont-text">生产国家：{{ objRow.userData.objinfo.productionCountry }}</div>
          <div class="examination-contont-text">安装位置：{{ objRow.userData.objinfo.place }}
          </div>
        </div>
        <div class="examination-contont " v-if="selType == '05'">
          <div v-if="objRow.userData.objinfo.componentName != undefined" class="examination-contont-text">部件名称：{{
            objRow.userData.objinfo.componentName }}</div>
          <div v-if="objRow.userData.objinfo.componentName == undefined" class="examination-contont-text">设备名称：{{
            objRow.userData.objinfo.mainDeviceName }}</div>
          <div class="examination-contont-text">所属区域：{{ objRow.userData.objinfo.areaName }}</div>
          <div class="examination-contont-text">所属间隔：{{ objRow.userData.objinfo.bayName }}</div>
          <div v-if="associationTitle == '关联部件'" class="examination-contont-text">所属主设备： {{
            objRow.userData.objinfo.mainDeviceName }}</div>
        </div>
      </div>
    </div>
    <!-- 告警详情 -->
    <Eldialog v-if="giveAlarmDia" title="告警详情" :zIndex="2000" :width="'700px'" @before-close="giveAlarmDia = false">
      <template v-slot:PopFrameContent>
        <div class="examine">
          <img src="@/assets/giveanalarm/hecha.png" style="position: absolute;left: 0px;" v-if="AlarmMapOne.flag">
          <div class="examination-contont">
            <div style="display: flex;  justify-content: center;width:100%;margin-top:20px;margin-bottom:10px;">
              <el-button class="searchButton1" @click.stop="previousPage" :disabled="Index + 1 == 1">
                <svg t="1686723317756" style="  transform: rotate(180deg);margin-right:5px" class="icon"
                  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2537"
                  xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="14">
                  <path
                    d="M989.866667 482.133333L597.333333 110.933333c-17.066667-17.066667-42.666667-17.066667-59.733333 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l315.733333 298.666666H64c-25.6 0-42.666667 17.066667-42.666667 42.666667s17.066667 42.666667 42.666667 42.666667H853.333333l-315.733333 298.666666c-17.066667 17.066667-17.066667 42.666667 0 59.733334 8.533333 8.533333 21.333333 12.8 29.866667 12.8 8.533333 0 21.333333-4.266667 29.866666-12.8l392.533334-371.2c8.533333-8.533333 12.8-21.333333 12.8-29.866667s-4.266667-21.333333-12.8-29.866667z"
                    fill="currentColor" p-id="2538"></path>
                </svg>
                上一个</el-button>
              <el-button class="searchButton1"
                style="color:#009bff;font-size:14px;border:1px solid #009bff;padding:3px 5px;height:32px;">共{{
                  Length }}页,当前为第{{ Index + 1 }}页</el-button>

              <el-button class="searchButton1" @click.stop="nextPage" :disabled="Index + 1 == Length">
                下一个
                <svg t="1686723317756" style="margin-left:5px" class="icon" viewBox="0 0 1024 1024" version="1.1"
                  xmlns="http://www.w3.org/2000/svg" p-id="2537" xmlns:xlink="http://www.w3.org/1999/xlink" width="14"
                  height="14">
                  <path
                    d="M989.866667 482.133333L597.333333 110.933333c-17.066667-17.066667-42.666667-17.066667-59.733333 0-17.066667 17.066667-17.066667 42.666667 0 59.733334l315.733333 298.666666H64c-25.6 0-42.666667 17.066667-42.666667 42.666667s17.066667 42.666667 42.666667 42.666667H853.333333l-315.733333 298.666666c-17.066667 17.066667-17.066667 42.666667 0 59.733334 8.533333 8.533333 21.333333 12.8 29.866667 12.8 8.533333 0 21.333333-4.266667 29.866666-12.8l392.533334-371.2c8.533333-8.533333 12.8-21.333333 12.8-29.866667s-4.266667-21.333333-12.8-29.866667z"
                    fill="currentColor" p-id="2538"></path>
                </svg>

              </el-button>

              <!-- <el-button
              style="color:#009bff;font-size:14px;border:1px solid #009bff;padding:3px 5px;height:32px;background-color: rgba(8, 80, 58, 0.5)"
              @click.stop="nextPage" :disabled="Index + 1 == Length">
              下一个<img src="/src/assets/giveanalarm/jiantouright.png"></el-button> -->
            </div>
            <div class="examination-contont-title" style="margin-top:10px;"><span
                style="border-left:4px solid #FFBD00;display: inline-block;height: 10px;margin-right: 5px;"></span>告警信息
            </div>
            <div class="examine-contont-body">
              <div class="examine-contont-body-left">
                <div class="examine-contont-body-left-test">点位名称：{{ AlarmMapOne.deviceName }}</div>
                <div class="examine-contont-body-left-test">设备名称：{{ AlarmMapOne.mainDeviceName }}</div>
                <div class="examine-contont-body-left-test">部件名称：{{ AlarmMapOne.componentName }}</div>
                <div class="examine-contont-body-left-test">告警来源：
                  <span v-if="AlarmMapOne.taskAlarmType == 1">巡视任务</span>
                  <span v-if="AlarmMapOne.taskAlarmType == 2">静默任务</span>
                  <span v-if="AlarmMapOne.taskAlarmType == 3">巡视设备</span>
                </div>
                <div class="examine-contont-body-left-test">告警等级：
                  <span v-if="AlarmMapOne.alarmLevel == 1" style="color: #0099FF;">预警</span>
                  <span v-if="AlarmMapOne.alarmLevel == 2" style="color: #FFFF00;">一般</span>
                  <span v-if="AlarmMapOne.alarmLevel == 3" style="color: #FF9900;">严重</span>
                  <span v-if="AlarmMapOne.alarmLevel == 4" style="color: #FF3300;">危急</span>
                </div>
                <div class="examine-contont-body-left-test" style="display: flex;">
                  <div style="width:155px;">告警描述：</div>
                  <div>{{ AlarmMapOne.content }}</div>
                </div>
                <div class="examine-contont-body-left-test">告警时间：{{ AlarmMapOne.alarmDate }}</div>
              </div>
              <div class="examine-contont-body-right">
                <!-- @click="pictureDetails" -->
                <div class="examine-contont-body-right-image" style="">
                  <img v-if="AlarmMapOne.defectFilePath" src="@/assets/3d/xsri_fd.png" alt="">
                  <el-image style="position: absolute;width:100%;height:100%; opacity: 0;"
                    :src="url + '/previewimage?type=alarm&filename=' + encodeURI(AlarmMapOne.defectFilePath)"
                    :zoom-rate="1.2"
                    :preview-src-list="[url + '/previewimage?type=alarm&filename=' + encodeURI(AlarmMapOne.defectFilePath)]"
                    :preview-teleported="true" fit="cover" />
                </div>
                <img class="examine-contont-body-right-img"
                  :src="url + '/previewimage?type=alarm&filename=' + encodeURI(AlarmMapOne.defectFilePath)" alt="">
              </div>
            </div>
            <div class="examination-contont-title" style="margin-top: 20px;"><span
                style="border-left:4px solid #FFBD00;display: inline-block;height: 10px;margin-right: 5px;"></span>核查确认
            </div>
            <div class="examine-contont-body-left-test" style="display: flex; align-items: center;">
              <div style="width:85px;text-align: right;margin-right: 5px;">是否属实</div>
              <el-radio-group v-model="AlarmMapOne.checkResult" style="margin-left:8px;">
                <el-radio label="1">是</el-radio>
                <el-radio label="2">否</el-radio>
              </el-radio-group>
            </div>
            <div class="examine-contont-body-left-test" style="display: flex;align-items: start;">
              <div style="width:85px;text-align: right;margin-right: 5px;">反馈意见</div>
              <div style="width: 90%;margin-left:8px;"><el-input v-model="AlarmMapOne.checkComment" :rows="2"
                  type="textarea" placeholder=" " /></div>
            </div>
          </div>
          <div class="flex w-full items-center justify-center mt-[20px]">
            <el-button @click.stop="giveAlarmDia = false, AlarmMap.length = 0"
              class="THREE-button1 mr-[30px]">取消</el-button>
            <el-button @click.stop="determination" class="THREE-button1">确定</el-button>
          </div>
        </div>
      </template>
    </Eldialog>
    <!-- 历史点位信息 -->
    <Eldialog v-if="history" title="历史巡视记录" :zIndex="2000" :width="'1540px'" @before-close="history = false">
      <template v-slot:PopFrameContent>
        <div>
          <el-date-picker v-model="timeSlot" type="daterange" range-separator="至" start-placeholder="开始时间"
            end-placeholder="结束时间" style="margin-right: 10px;" value-format="YYYY-MM-DD" />
          <el-button class="searchButton" @click="historicalRecords(deviceIdone)">搜索</el-button>
          <el-button class="searchButton" @click="hisreset()">重置</el-button>
        </div>
        <el-table v-loading="hisloading" :data="historydata" style="width: 100%;height: calc(70vh);
                overflow: auto;;margin: 15px 0px;" row-key="id" default-expand-all :row-class-name="tableRowClassName"
          :header-cell-style="{ background: '#002b6a', color: '#B5D7FF', height: '50px' }">
          <el-table-column type="index" align="center" label="序号" width="60px" />
          <el-table-column prop="mainDeviceName" label="设备名称" />
          <el-table-column prop="componentName" label="部件名称" />
          <el-table-column prop="deviceName" label="点位名称" />
          <el-table-column prop="meterType" label="表计类型" align="center">
            <template #default="scope">
              <span
                v-if="currency(MeterTypeList, scope.row.meterType) != undefined && currency(MeterTypeList, scope.row.meterType) != ''">{{
                  currency(MeterTypeList, scope.row.meterType) }}</span>
              <span v-else>--</span>
            </template>
          </el-table-column>
          <el-table-column prop="time" label="巡视时间" width="110px" align="center" />
          <el-table-column prop="flag" label="状态" width="100px" align="center">
            <template #default="scope">
              <span v-if="scope.row.flag == '0'">未巡视</span>
              <span v-if="scope.row.flag == '1'">已巡视</span>
              <span v-if="scope.row.flag == '2'">已完成</span>
              <span v-if="scope.row.flag == '3'">设备检修中</span>
              <span v-if="scope.row.flag == '4'">巡视失败</span>
              <span v-if="scope.row.flag == '5'">已修正</span>
              <span v-if="scope.row.flag == '6'">采集失败</span>
            </template>
          </el-table-column>
          <el-table-column prop="materialId" label="实物id" align="center">
          </el-table-column>
          <el-table-column prop="desc" label="识别类型" width="140px">
            <template #default="scope">
              <span v-if="scope.row.recognitionType">{{ currency(recognitionType,
                scope.row.recognitionType,)
              }}</span>
              <span v-else>--</span>
            </template>
          </el-table-column>
          <el-table-column label="识别值" width="100px">
            <template #default="scope">
              <span
                v-if="scope.row.valueType == 'meter' || scope.row.valueType == 'partial' || scope.row.valueType == 'partial' || scope.row.valueType == 'infrared'">
                <span v-if="scope.row.analysisResult == '异常'" style="color: red;font-size: 16px;font-weight: bold;">
                  {{ scope.row.value }} {{ scope.row.unit }}
                </span>
                <span v-else>
                  {{ scope.row.value }} {{ scope.row.unit }}
                </span>
              </span>
              <span v-else>
                <span v-if="scope.row.desc != null && scope.row.desc != '' && scope.row.valueType != 'sound'">
                  {{ scope.row.desc }}
                </span>
                <span v-else>--</span>
              </span>
            </template>
          </el-table-column>
          <el-table-column prop="analysisResult" label="巡视结论" align="center" width="80px">
            <template #default="scope">
              <span v-if="scope.row.analysisResult == '正常' && scope.row.flag != '7'"
                style="color: rgb(0, 249, 162)">正常</span>
              <span v-if="scope.row.analysisResult == '异常' && scope.row.flag != '7'"
                style="color: rgb(255, 51, 0);font-size: 16px;font-weight: bold;">异常</span>
              <span v-if="scope.row.analysisResult == '设备检修' && scope.row.flag != '7'"
                style="color: rgb(0, 153, 255)">设备检修</span>
              <span v-if="scope.row.analysisResult == '失败' && scope.row.flag != '7'"
                style="color: rgb(255, 189, 0)">失败</span>
              <span v-if="scope.row.analysisResult == '成功' && scope.row.flag != '7'"
                style="color: rgb(0, 249, 162)">成功</span>
              <span v-if="scope.row.flag == '7'" style="color: rgb(255, 51, 0);">表计读数异常</span>
              <span
                v-if="(scope.row.analysisResult == '' && scope.row.flag != '7') || (scope.row.analysisResult == null && scope.row.flag != '7')">--</span>
            </template>
          </el-table-column>
          <el-table-column prop="reviseValue" label="修正值" align="center">
            <template #default="scope">
              <span v-if="scope.row.reviseValid == null">--</span>
              <span v-else> {{ scope.row.reviseValue }} {{ scope.row.unit }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="reviseValid" label="修正结论" align="center">
            <template #default="scope">
              <span v-if="scope.row.reviseValid == 0">正常</span>
              <span v-if="scope.row.reviseValid == 1">异常</span>
              <span v-if="scope.row.reviseValid == null">--</span>
            </template>
          </el-table-column>
        </el-table>
        <Page :total="histotal" v-model:size="historParams.size" v-model:current="historParams.current"
          @pagination="historicalRecords(deviceIdone)">
        </Page>
      </template>
    </Eldialog>
    <div id="contextimg">
      <img src="@/assets/3d/luminescence.svg" alt="">
    </div>
    <div id="contextmenu">
      <ul v-if="selType == '01'">
        <li @click.stop="CameraInformation">摄像机信息</li>
        <li
          v-if="!isVideo || dataSel == undefined || dataSel.userData == undefined || dataSel.userData.objinfo == undefined || dataSel.userData.objinfo.channelList == undefined || dataSel.userData.objinfo.online == 0"
          style="color: #ffffff41;">实时视频</li>
        <li
          v-if="isVideo && dataSel.userData != undefined && dataSel.userData.objinfo != undefined && dataSel.userData.objinfo.channelList != undefined && dataSel.userData.objinfo.online == 1"
          @click.stop="realTimeVideo(1, 0)">实时视频-1</li>
        <li
          v-if="isVideo && dataSel.userData != undefined && dataSel.userData.objinfo != undefined && dataSel.userData.objinfo.channelList != undefined && dataSel.userData.objinfo.channelList.length == 2 && dataSel.userData.objinfo.online == 1"
          @click.stop="realTimeVideo(1, 1)">实时视频-2</li>
      </ul>
      <ul v-show="selType == '02'">
        <li @click.stop="CameraInformation">巡视点位信息</li>
      </ul>
      <ul v-show="selType == '04'">
        <li @click.stop="CameraInformation">无人车信息</li>
        <li
          v-if="!isVideo || dataSel == undefined || dataSel.userData == undefined || dataSel.userData.objinfo == undefined || dataSel.userData.objinfo.channelList == undefined || dataSel.userData.objinfo.online == 0"
          style="color: #ffffff41;">实时视频</li>
        <li
          v-if="isVideo && dataSel.userData != undefined && dataSel.userData.objinfo != undefined && dataSel.userData.objinfo.channelList != undefined && dataSel.userData.objinfo.online == 1"
          @click.stop="realTimeVideo(1, 0)">实时视频-1</li>
        <li
          v-if="isVideo && dataSel.userData != undefined && dataSel.userData.objinfo != undefined && dataSel.userData.objinfo.channelList != undefined && dataSel.userData.objinfo.channelList.length == 2 && dataSel.userData.objinfo.online == 1"
          @click.stop="realTimeVideo(1, 1)">实时视频-2</li>
      </ul>
      <ul v-show="selType == '05'">
        <li :class="isdevice ? 'contextmenu-disabled' : ''" @click.stop="CameraInformation">设备/部件详情</li>
      </ul>
    </div>
    <!-- 视频弹窗 -->
    <div v-drag class="videoPopup" v-if="videoShow">
      <img src="@/assets/3d/u523.png" style="cursor:pointer;position:absolute;right:20px;top:10px;z-index:2024"
        @click="videoShow = false" />
      <JessibucaPlayer ref="recordVideoPlayer" :_uid="101" :devicechannelInfo="devicechannelInfo" :visible.sync="true"
        :videoUrl="videoUrl" :videofmp4="videofmp4" :hasAudio="false" fluent autoplay live @closeVideo="closeVideo">
      </JessibucaPlayer>
    </div>

  </div>
</template>
<script setup>
import { getdata, getArea } from '@/api/monitordevice'
import { getDeviceByType } from "@/api/device";
import JessibucaPlayer from '@/components/jessibuca/index1.vue' // 视频
import { useUserStore } from '@/store/modules/user'
import axios from 'axios'
import { getSubstationById, getHistoryDevice } from '@/api/substation'
import { setAlarmLogStatus } from "@/api/alarmInfo";//告警信息获取
import { getNotCheckAlarmCount } from '@/api/home';
import { onMounted, ref, reactive, onBeforeUnmount, nextTick, watch } from 'vue'
import * as THREE from 'three'
import TWEEN from 'tween'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' // 控制器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' // 控制器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' // 控制器
import { ElMessage } from 'element-plus'
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer"
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass"
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass"
// 伽玛校正后处理Shader
import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader'
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass"
// SMAA抗锯齿通道
import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass'
import jt from '@/assets/3d/jt.png'
import gaojing from '@/assets/3d/gaojing.png'
import gaojing1 from '@/assets/3d/gaojing1.png'
import gaojing2 from '@/assets/3d/gaojing2.png'
import { PathPointList } from '@/utils/PathPointList.js'
import { PathGeometry } from '@/utils/PathGeometry.js'
import position from '../3DModelSet/index.json'
import Eldialog from '@/components/seccmsdialog/eldialog.vue'
import Page from '@/components/Pagination/page.vue'
const userStore = useUserStore()
const taskName = ref()
const tableData = ref([])
const info = ref({
  size: 10,
  current: 1,
  type: '',
  areaId: ''
})
const PatrolEquipmentType = ref([]) // 设备类型
const total = ref()
const loading = ref(false)
const url = userStore.webApiBaseUrl;
let renderer = reactive(null) // 渲染器
const draw = ref() // 场景div
let scene = reactive(null) // 场景
const progress = ref(0) // 场景 - 加载进度条
const loadSuccess = ref(true) // 场景 - 加载进度条 显示
const clientWidth = ref()
const clientHeight = ref()
let defaultCamera = reactive(null) // 相机
let activeCamera = reactive(null)
let controls = reactive(null) // 相机控制器

const selModel = ref() // 选中的模型
let _animate = null // 动画
let _animate1 = null // 动画
let _animate2 = null // 动画
let mixer = null // 运行动画
let mixerData = [] // 运行动画
let gridHelper = null // 网格地面
let axesHelper = null // 坐标系
let luminescence = [] // 发光数据
let state = {
  wireframe: false, // 显示线框
  grid: false, // 显示坐标轴

  addLights: true,
  exposure: 2.0,
  textureEncoding: 'sRGB',
  ambientIntensity: 1,
  ambientColor: 0xcccccc,
  directIntensity: 0.8 * Math.PI,
  directColor: 0xcccccc,
  bgColor1: '#008157',
  bgColor2: '#040F11'
}

let lights = []
let content = null
const videoShow = ref(false)

let composer = null
let outlinePass = null

let spritedata = []



// 测距
let lineId = 0
let drawingLine = false
let markers = {} // {1:[],2:[]}
let textDoms = {}
let pointsDom = {}
const srangingRaycaster = new THREE.Raycaster()
let srangingIntersects
const srangingMouse = new THREE.Vector2()

// 初始化
onMounted(() => {
  getTypeTwo()
  setupWebSocket()
  initRenderer()

  //取消选中并且取消右键操作
  document.body.onselectstart = document.body.oncontextmenu = function () {
    return false
  }
})
//获取告警信息
const giveAnAlarm = ref([])
const PoliceId = ref([])
function Information(val) {
  const params = {
    stationId: userStore.stationId,
  }
  getNotCheckAlarmCount(params).then(resany => {
    giveAnAlarm.value = resany.data.notCheck

    if (selType.value == '05') {
      for (var i = 0; i <= searchdata.value.length; i++) {
        if (searchdata.value[i] != undefined) {
          for (var j = 0; j <= resany.data.notCheck.length; j++) {
            if (resany.data.notCheck[j] != undefined) {
              if (resany.data.notCheck[j].componentId) {
                if (searchdata.value[i].objinfo.componentId == resany.data.notCheck[j].componentId) {
                  PoliceId.value.push(searchdata.value[i].id)
                }
              } else if (resany.data.notCheck[j].mainDeviceId) {
                if (searchdata.value[i].objinfo.mainDeviceId == resany.data.notCheck[j].mainDeviceId) {
                  PoliceId.value.push(searchdata.value[i].id)
                }
              }
            }
          }
        }
      }
    }

    if (val == '01') {
      var newArr = [...new Set(PoliceId.value)];
      newArr.forEach((element) => {
        let model = scene.getObjectByProperty('uuid', element)
        // const box = new THREE.BoxHelper(model, '#fff000')
        // box.userData.uuid = model.uuid
        // scene.add(box)
        // 发光
        luminescence.push(model)
        outlineObj()
        // 贴图
        addSprite(model)
      })
    } else if (val == '03') {
      const policeId = ref([])
      for (var k = 0; k <= searchdata.value.length; k++) {
        if (searchdata.value[k] != undefined) {
          policeId.value.push(searchdata.value[k].id)
          var newArr = [...new Set(policeId.value)];
          newArr.forEach(element => {
            let model = scene.getObjectByProperty('uuid', element)
            luminescence.length = 0
            // outlineObj()// 发光
            cancal(model)

          })
        }

      }
      var newArr = [...new Set(PoliceId.value)];
      newArr.forEach((element) => {
        let model = scene.getObjectByProperty('uuid', element)
        // const box = new THREE.BoxHelper(model, '#fff000')
        // box.userData.uuid = model.uuid
        // scene.add(box)
        // 发光
        luminescence.push(model)
        outlineObj()
        // 贴图
        addSprite(model)
      })
    }


  })

}
const recognitionType = ref([])
function getTypeTwo() {
    getDeviceByType({ dictcode: 'recognition_type' }).then((res) => {
        recognitionType.value = res.data
    })
}
// 页面退出
onBeforeUnmount(() => {
  window.removeEventListener('resize', resize)
  window.removeEventListener('click', portClick)

  renderer.domElement.removeEventListener('click', rangingModelClick)
  window.removeEventListener('contextmenu', portDBClick)
  window.removeEventListener('wheel', handleMouseWheel)
  window.removeEventListener('mousemove', onDocumentMouseMove)
  //取消选中并且取消右键操作
  document.body.onselectstart = document.body.oncontextmenu = null
  cancelAnimationFrame(_animate)
  removeObj(scene)
  renderer && renderer.dispose()
  renderer.forceContextLoss()
  renderer.domElement = null
  renderer.content = null
  renderer = null
  THREE.Cache.clear()
  if (ws1 != null) {
    ws1.close()
  }
  let rangingText = document.getElementsByClassName('rangingText')
  let rangingDian = document.getElementsByClassName('rangingDian')
  if (rangingText.length != 0) {
    for (let i = 0; i < rangingText.length; i++) {
      rangingText[i].remove()
      i--
    }
  }
  if (rangingDian.length != 0) {
    for (let i = 0; i < rangingDian.length; i++) {
      rangingDian[i].remove()
      i--
    }
  }
})
// 初始化渲染器
function initRenderer() {
  // 初始化场景
  clientWidth.value = draw.value.clientWidth
  clientHeight.value = draw.value.clientHeight
  // 初始化场景
  scene = new THREE.Scene()
  // 初始化相机
  defaultCamera = new THREE.PerspectiveCamera(60, clientWidth.value / clientHeight.value, 0.01, 1000)
  activeCamera = defaultCamera
  scene.add(defaultCamera)
  // 实例化渲染器
  renderer = window.renderer = new THREE.WebGLRenderer()
  // renderer.physicallyCorrectLights = true
  renderer.useLegacyLights = true
  renderer.gammaOutput = true
  renderer.gammaFactor = 2.2
  renderer.setClearColor(0x131a25, 0)

  // 设置设备像素比
  renderer.setPixelRatio(window.devicePixelRatio)
  // 设置渲染区域尺寸
  renderer.setSize(draw.value.clientWidth, draw.value.clientHeight)
  // 初始化相机控制器
  controls = new OrbitControls(defaultCamera, renderer.domElement)
  controls.enableRotate = true //禁止旋转
  controls.enablePan = true //禁止平移
  controls.enableZoom = true //禁止缩放
  controls.autoRotate = false // 是否自动旋转
  controls.autoRotateSpeed = -1 // 旋转速度
  controls.screenSpacePanning = true
  // controls.enableDamping = true // 开启控制器的阻尼效果
  // AxesHelper：辅助观察的坐标系
  // const axesHelper = new THREE.AxesHelper(150)
  // scene.add(axesHelper)
  draw.value.appendChild(renderer.domElement)
  // 运行动画
  animate()
  // 添加事件
  addmeth()
  // 加载场景模型
  initgltfLoader()
}
// 运行动画
function animate() {
  if (resizeRendererToDisplaySize(renderer)) {
    defaultCamera.aspect = clientWidth.value / clientHeight.value;
    defaultCamera.updateProjectionMatrix();
  }
  TWEEN.update()
  controls && controls.update()
  composer ? composer.render() : renderer.render(scene, activeCamera)
  if (spritedata.length != 0) {
    if (isroam.value == false) {
      for (let i = 0; i < spritedata.length; i++) {
        spritedata[i].material.rotation -= 0.02
      }
    }
  }

  _animate = requestAnimationFrame(animate) // 循环调用函数
}
// 添加事件
function addmeth() {
  window.addEventListener('resize', resize, false)
  window.addEventListener('click', portClick, false)
  renderer.domElement.addEventListener('click', rangingModelClick, false)
  window.addEventListener('contextmenu', portDBClick, false)
  window.addEventListener('wheel', handleMouseWheel, false)
  window.addEventListener('mousemove', onDocumentMouseMove, false);
  //esc删除绘制
  window.addEventListener('keydown', function (event) {
    if (event.key === 'Escape') {
      //清除没画完的线
      if (drawingLine) {
        [...textDoms[lineId], ...pointsDom[lineId]].forEach(item => item.remove())
        markers[lineId].forEach(item => scene.remove(item))
        markers[lineId] = null
        textDoms[lineId] = null
        pointsDom[lineId] = null
        drawingLine = false
      }
    }
  })
}
// 加载场景模型 gltf
function initgltfLoader() {
  const manager = new THREE.LoadingManager()
  manager.setURLModifier((url, path) => {
    return (path || '') + url
  })
  const gltfLoader = new GLTFLoader(manager)
  const dracoLoader = new DRACOLoader()
  dracoLoader.setDecoderPath('./static/js/')
  dracoLoader.setDecoderConfig({ type: 'js' })
  gltfLoader.setDRACOLoader(dracoLoader)
  gltfLoader.load('./static/3DModel/scene.glb', (gltf) => {
    const model = gltf.scene || gltf.scenes[0]
    const clips = gltf.animations || []
    setContent(model, clips)
    // 加载JSON 数据
    initData()
    loadSuccess.value = false
  }, (xhr) => {
    const percentage = Math.floor(xhr.loaded / xhr.total * 100)
    progress.value = percentage + '%'
  })
}
// 模型属性设置
function setContent(object, clips) {
  clear()
  object.updateMatrixWorld()
  const box = new THREE.Box3().setFromObject(object)
  const size = box.getSize(new THREE.Vector3()).length()
  const center = box.getCenter(new THREE.Vector3())
  // 相机控制器重置
  controls.reset()

  object.position.x += (object.position.x - center.x)
  object.position.y = 17
  object.position.z += (object.position.z - center.z)

  controls.maxDistance = size * 10
  defaultCamera.near = size / 100
  defaultCamera.far = size * 100

  // 更新相机
  defaultCamera.updateProjectionMatrix()
  // 相机视角设置

  defaultCamera.position.copy(center)
  defaultCamera.position.x = 0.1653268513339453
  defaultCamera.position.y = 108.83794927572215
  defaultCamera.position.z = 71.85528617360808
  defaultCamera.lookAt(center)
  content = object
  controls.saveState()
  // 添加模型
  scene.add(object)

  state.addLights = true
  content.traverse((node) => {
    if (node.isLight) {
      state.addLights = false
    }
  })
  // 添加光照
  updateLights()
  updateTextureEncoding()
  updateDisplay()

}
// 重置
function reset() {
  defaultCamera.position.set(0.1653268513339453, 108.83794927572215, 71.85528617360808)
  controls.target.set(0, 0, 0)
  controls.update()
  clearDiv()
  isranging.value = false
  renderer.domElement.style.cursor = 'unset'

  information.value = false
  let rangingText = document.getElementsByClassName('rangingText')
  let rangingDian = document.getElementsByClassName('rangingDian')
  if (rangingText.length != 0) {
    for (let i = 0; i < rangingText.length; i++) {
      rangingText[i].remove()
      i--
    }
  }
  if (rangingDian.length != 0) {
    for (let i = 0; i < rangingDian.length; i++) {
      rangingDian[i].remove()
      i--
    }
  }

  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].name == '线' || scene.children[i].name == '球') {
      scene.children[i].traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.geometry.dispose()
          obj.material.dispose()
        }
      })
      scene.remove(scene.children[i])
      i--
    }
  }
}
function updateDisplay() {
  traverseMaterials(content, (material) => {
    material.wireframe = state.wireframe
  })
  if (state.grid !== Boolean(gridHelper)) {
    if (state.grid) {
      gridHelper = new THREE.GridHelper()
      axesHelper = new THREE.AxesHelper(100)
      axesHelper.renderOrder = 999
      axesHelper.onBeforeRender = (renderer) => renderer.clearDepth()
      scene.add(gridHelper)
      scene.add(axesHelper)
    } else {
      scene.remove(gridHelper)
      scene.remove(axesHelper)
      gridHelper = null
      axesHelper = null
    }
  }
}
function updateTextureEncoding() {
  const encoding = state.textureEncoding === 'sRGB'
    ? THREE.sRGBEncoding
    : THREE.LinearEncoding
  traverseMaterials(content, (material) => {
    if (material.map) material.map.encoding = encoding
    if (material.emissiveMap) material.emissiveMap.encoding = encoding
    if (material.map || material.emissiveMap) material.needsUpdate = true
  })
}
// 添加光照
function updateLights() {
  if (state.addLights && !lights.length) {
    addLights()
  } else if (!state.addLights && lights.length) {
    removeLights()
  }
  renderer.toneMappingExposure = state.exposure

  if (lights.length === 2) {
    lights[0].intensity = state.ambientIntensity
    lights[0].color.setHex(state.ambientColor)
    lights[1].intensity = state.directIntensity
    lights[1].color.setHex(state.directColor)
  }
}
// 添加光照
function addLights() {
  const light1 = new THREE.AmbientLight(state.ambientColor, state.ambientIntensity)
  light1.name = 'ambient_light'
  defaultCamera.add(light1)

  const light2 = new THREE.DirectionalLight(state.directColor, state.directIntensity)
  light2.position.set(0.5, 0, 0.866)
  light2.name = 'main_light'
  defaultCamera.add(light2)

  lights.push(light1, light2)
}
// 删除光照
function removeLights() {
  lights.forEach((light) => light.parent.remove(light))
  lights.length = 0
}

// 单击模型事件
const AlarmMap = ref([])
const AlarmMapOne = ref()
const Index = ref(0)
const Length = ref()
function portClick(event) {
  // 测距
  if (isranging.value == true) return
  // 保持原事件
  // event.preventDefault()
  // 清除右侧选中
  dataIndex.value = null
  if (isroam.value == true) return
  treeRef.value.setCurrentKey(null)
  // 清除右键弹框
  const contextmenu = document.getElementById('contextmenu')
  contextmenu.style.display = 'none'
  const contextimg = document.getElementById('contextimg')
  contextimg.style.display = 'none'
  // 建立射线
  const vector = new THREE.Vector3()
  vector.set((event.layerX / clientWidth.value) * 2 - 1, -(event.layerY / clientHeight.value) * 2 + 1)
  const raycaster = new THREE.Raycaster()
  // // 建立一个空物体
  raycaster.setFromCamera(vector, activeCamera)
  raycaster.params.Line.threshold = 0.01
  const intersections = raycaster.intersectObjects(scene.children)
  let selectedObject = null

  // 清除所有选中框
  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].type == 'BoxHelper') {
      scene.children[i].traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.geometry.dispose()
          obj.material.dispose()
        }
      })
      scene.remove(scene.children[i])
      i--
    }
  }
  if (intersections.length > 0) { // 判断参数[boxMesh]中模型对象是否与射线相交
    intersections.forEach(function (e) {
      var obj = e.object
      if (obj instanceof THREE.Sprite && obj.type == 'Sprite') {
        if (obj.name === "sprite3") {
          for (var i = 0; i <= giveAnAlarm.value.length; i++) {
            if (giveAnAlarm.value[i] != undefined && obj.userData.objinfo != undefined) {
              if (giveAnAlarm.value[i].componentId) {
                if (giveAnAlarm.value[i].componentId == obj.userData.objinfo.componentId) {
                  AlarmMap.value.push(giveAnAlarm.value[i])
                } else if (giveAnAlarm.value[i].mainDeviceId && giveAnAlarm.value[i].mainDeviceId == undefined) {
                  if (giveAnAlarm.value[i].mainDeviceId == obj.userData.objinfo.mainDeviceId) {
                    AlarmMap.value.push(giveAnAlarm.value[i])
                  }
                }
              }
            }
          }
          for (var i = 0; i < AlarmMap.value.length - 1; i++) {
            for (var j = i + 1; j < AlarmMap.value.length; j++) {
              if (AlarmMap.value[i].id == AlarmMap.value[j].id) {
                AlarmMap.value.splice(j, 1);
                j--;
              }
            }
          }
          for (var i = 0; i < AlarmMap.value.length; i++) {
            AlarmMap.value[i].flag = false
            AlarmMap.value[i].checkResult = '1'
          }
          Length.value = AlarmMap.value.length
          AlarmMapOne.value = AlarmMap.value[Index.value]
          Index.value = 0
          giveAlarmDia.value = true
          return
        }
      }
    })
  }
  if (intersections.length > 0) {
    for (var i = 0; i < intersections.length; i++) {
      // 遍历线相交模型
      if (intersections[i].object instanceof THREE.Mesh) {
        // 取第一个（距离最近）的相交Mesh类型模型
        // 如果要排除地面等参照模型，也可在此处添加判断条件
        if (intersections[i].object.name.indexOf('不动') != -1) continue
        if (intersections[i].object.parent.userData.type == 'Projection') continue
        selModel.value = intersections[i]
        selectedObject = intersections[i].object
        break
      }
    }
  }
  if (selectedObject) {
    // 清除右键弹出框
    let model = BoxHelper(selectedObject)
    dataSel.value = model
    if (model) {
      //清除右侧摄像机选中
      if (selType.value == '04') {
        treeRef.value.setCurrentKey(model.uuid)
      } else {
        data.value.forEach((element, index) => {
          if (element.id == model.uuid) {
            dataIndex.value = index
          }
        })
      }
      let isModel = true
      for (let i = 0; i < scene.children.length; i++) {
        if (scene.children[i].type == 'BoxHelper') {
          if (model.uuid == element.userData.uuid) {
            scene.children[i].traverse(function (obj) {
              if (obj.type === 'Mesh') {
                obj.geometry.dispose()
                obj.material.dispose()
              }
            })
            scene.remove(scene.children[i])
            i--
          }
        }
      }
      if (isModel) {
        const box = new THREE.BoxHelper(model, '#fff000')  //object 模型
        box.userData.uuid = model.uuid
        scene.add(box)
      }
    }
  }
}
// 右击模型事件
function portDBClick(event) {
  // 建立射线
  const layerX = event.x
  const layerY = event.y - 75
  // 建立射线
  const vector = new THREE.Vector3()
  vector.set((event.layerX / clientWidth.value) * 2 - 1, -(event.layerY / clientHeight.value) * 2 + 1)
  const raycaster = new THREE.Raycaster()
  // // 建立一个空物体
  raycaster.setFromCamera(vector, activeCamera)
  raycaster.params.Line.threshold = 0.01
  const intersections = raycaster.intersectObjects(scene.children)
  let selectedObject = null
  if (intersections.length > 0) {
    for (var i = 0; i < intersections.length; i++) {
      // 遍历线相交模型
      if (intersections[i].object.userData.type == 'PatrolLine') continue
      if (intersections[i].object instanceof THREE.Mesh) {
        if (intersections[i].object.name.indexOf('不动') != -1) break
        selModel.value = intersections[i]
        selectedObject = intersections[i].object
        break
      }
    }
  }
  if (selectedObject) {
    let model = BoxHelper(selectedObject)
    if (selType.value == '05') {
      model = BoxHelper(selectedObject)
      if (model.userData.type == 'UV' || model.userData.type == 'Camera' || model.userData.type == 'Camera1') return
    }
    if (selType.value == '01') if (model.userData.type == 'EquipmentComponentSettings' || model.userData.type == 'UV') return
    if (selType.value == '04') if (model.userData.type == 'EquipmentComponentSettings' || model.userData.type == 'Camera' || model.userData.type == 'Camera1') return
    dataSel.value = model
    if (model.userData.type == 'Camera' || model.userData.type == 'Camera1' || model.userData.type == 'UV') {
      model.userData.objinfo == undefined || model.userData.objinfo == null ? isVideo.value = false : isVideo.value = true
    }
    model.userData.type == 'Camera' || model.userData.type == 'UV' ? isCameraMenu.value = true : isCameraMenu.value = false
    model.userData.type == 'EquipmentComponentSettings' ? isdevice.value = false : isdevice.value = true
    scene.children.forEach(element => {
      if (element.type == 'BoxHelper') {
        if (model.userData.type == 'EquipmentComponentSettings' || model.userData.type == 'Camera' || model.userData.type == 'Camera1' || model.userData.type == 'UV') {
          if (element.userData.uuid == model.uuid) {
            if (model.userData.objinfo != null || model.userData.objinfo != undefined) {
              const contextmenu = document.getElementById('contextmenu')
              const contextimg = document.getElementById('contextimg')
              contextmenu.style.display = 'block'
              contextimg.style.display = 'block'
              if (layerY + 200 > window.innerHeight) {
                contextmenu.style.top = Number(window.innerHeight - contextmenu.offsetHeight - 75) + 'px'
              } else {
                contextmenu.style.top = layerY - 30 + 'px'
              }
              if (layerX + 180 > window.innerWidth) {
                contextmenu.style.left = window.innerWidth - 250 + 'px'
              } else {
                contextmenu.style.left = layerX + 20 + 'px'
              }
              contextmenu.style.display = 'block'
              contextimg.style.display = 'block'
              contextimg.style.left = layerX - 20 + 'px'
              contextimg.style.top = layerY - 30 + 'px'
            }
          } else {
            const contextmenu = document.getElementById('contextmenu')
            const contextimg = document.getElementById('contextimg')
            contextmenu.style.display = 'none'
            contextimg.style.display = 'none'
          }
        }
      }
    })
  }
}
//右键详细信息
function CameraInformation(e) {
  information.value = true
  objRow.value = dataSel.value
  nextTick(() => {
    const detailedInformation = document.getElementById('detailed-information')
    detailedInformation.style.left = e.layerX - 60 + 'px'
    detailedInformation.style.top = e.layerY - 40 + 'px'
  })
  const contextmenu = document.getElementById('contextmenu')
  contextmenu.style.display = 'none'
  const contextimg = document.getElementById('contextimg')
  contextimg.style.display = 'none'
}
function onDocumentMouseMove(event) {
  if (isranging.value == true) {
    srangingMouse.x = (event.clientX / renderer.domElement.offsetWidth) * 2 - 1
    srangingMouse.y = -((event.clientY - 90) / renderer.domElement.offsetHeight) * 2 + 1
    if (drawingLine) {
      srangingRaycaster.setFromCamera(srangingMouse, defaultCamera)
      srangingIntersects = srangingRaycaster.intersectObjects(scene.children)
      if (srangingIntersects.length === 0) return
      let line = markers[lineId][2]
      line.computeLineDistances()
      updateLinePoint(line, srangingIntersects[0].point, 3)

    }
  } else {
    event.preventDefault()
    // 建立射线
    const vector = new THREE.Vector3()
    vector.set((event.layerX / clientWidth.value) * 2 - 1, -(event.layerY / clientHeight.value) * 2 + 1)
    const raycaster = new THREE.Raycaster()
    // // 建立一个空物体
    raycaster.setFromCamera(vector, defaultCamera)
    raycaster.params.Line.threshold = 0.01
    const intersections = raycaster.intersectObjects(scene.children)

    if (intersections.length > 0) { // 判断参数[boxMesh]中模型对象是否与射线相交
      intersections.forEach(function (e) {
        var obj = e.object
        if (obj instanceof THREE.Sprite && obj.type == 'Sprite') {
          document.body.style.cursor = 'pointer'
        }
      })
    } else {
      document.body.style.cursor = 'default'
    }
  }
}
// 报警发光
function outlineObj() {
  composer = new EffectComposer(renderer)
  // 创建一个渲染器通道，场景和相机作为参数
  const renderPass = new RenderPass(scene, defaultCamera)
  // 将上面创建的渲染器通道添加到composer中
  composer.addPass(renderPass)
  // 定义一个二维向量,尺寸和场景的canvas画布保持一致
  // 将二维向量、屏幕和相机作为参数创建OutlinePass对象
  outlinePass = new OutlinePass(new THREE.Vector2(clientWidth.value, clientHeight.value), scene, defaultCamera)
  outlinePass.selectedObjects = luminescence
  outlinePass.renderToScreen = true
  //模型描边颜色，默认白色         
  outlinePass.visibleEdgeColor.set('red')
  //高亮发光描边厚度
  outlinePass.edgeThickness = 5
  //高亮描边发光强度
  outlinePass.edgeStrength = 2
  //模型闪烁频率控制，默认0不闪烁
  outlinePass.pulsePeriod = 2
  outlinePass.edgeGlow = 5 // 发光
  // 添加到后处理对象composer中
  composer.addPass(outlinePass)
  // 创建伽马校正后处理通道
  // THREEjs并没有直接提供伽马校正的后处理通道，提供了一个伽马校正的Shader对象GammaCorrectionShader，
  // 这时候可以把Shader对象作为ShaderPass的参数创建一个通道。
  // 创建伽马校正后处理通道
  const gammaPass = new ShaderPass(GammaCorrectionShader)
  composer.addPass(gammaPass)

  // // 使用后处理 模型会有锯齿
  // // 创建SMAAPass抗锯齿通道
  // // 获取.setPixelRatio()设置的设备像素比
  const pixelRatio = renderer.getPixelRatio()
  const smaaPass = new SMAAPass(clientWidth.value * pixelRatio, clientHeight.value * pixelRatio)
  composer.addPass(smaaPass)
}
function addSprite(selectedObjects) {
  const box = new THREE.Box3().setFromObject(selectedObjects)
  const center = box.getCenter(new THREE.Vector3())
  // 贴图

  let sprite = new THREE.Sprite(new THREE.SpriteMaterial({
    map: new THREE.TextureLoader().load(gaojing),
    transparent: true
  }))
  const sprite1 = new THREE.Sprite(new THREE.SpriteMaterial({
    map: new THREE.TextureLoader().load(gaojing1),
    transparent: true
  }))
  const sprite2 = new THREE.Sprite(new THREE.SpriteMaterial({
    map: new THREE.TextureLoader().load(gaojing2),
    transparent: true
  }))
  sprite.scale.set(4, 4, 4)
  sprite.position.set(center.x, center.y + 6, center.z)
  sprite.userData.id = selectedObjects.uuid
  sprite.name = 'sprite1'
  scene.add(sprite)
  sprite1.scale.set(3, 3, 3)
  sprite1.position.set(center.x, center.y + 6, center.z)
  sprite1.userData.id = selectedObjects.uuid
  sprite1.name = 'sprite2'
  scene.add(sprite1)
  sprite2.scale.set(1.5, 1.5, 1.5)
  sprite2.position.set(center.x, center.y + 6, center.z)
  sprite2.userData.id = selectedObjects.uuid
  sprite2.name = 'sprite3'
  sprite2.userData.objinfo = selectedObjects.userData.objinfo
  scene.add(sprite2)
  spritedata.push(sprite)
}
// 取消报警
function cancal(model) {
  outlineObj()
  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].type == 'Sprite') {
      if (scene.children[i].userData.id == model.uuid) {
        scene.children[i].traverse(function (obj) {
          if (obj.type === 'Mesh') {
            obj.geometry.dispose()
            obj.material.dispose()
          }
        })
        scene.remove(scene.children[i])
        i--
      }

    }
  }
}
function BoxHelper(selectedObject) {
  if (selectedObject.type == 'Mesh') {
    if (selectedObject.parent.name == 'Scene' && selectedObject.parent.type == 'Group' || selectedObject.parent.type == 'Scene') {
      return selectedObject
    }
    return BoxHelper(selectedObject.parent)
  } else if (selectedObject.type == 'Object3D') {
    if (selectedObject.parent.name == 'Scene' && selectedObject.parent.type == 'Group' || selectedObject.parent.type == 'Scene') {
      return selectedObject
    } else {
      return BoxHelper(selectedObject.parent)
    }
  } else if (selectedObject.type == 'Group') {
    if (selectedObject.userData.type == 'Camera' || selectedObject.userData.type == 'Camera1' || selectedObject.userData.type == 'UV') {
      return selectedObject
    } else if (selectedObject.parent.name == 'Scene' && selectedObject.parent.type == 'Group' || selectedObject.parent.type == 'Scene') {
      return selectedObject
    } else {
      return BoxHelper(selectedObject.parent)
    }
  }
}
function clear() {
  if (!content) return
  scene.remove(content)
  content.traverse((node) => {
    if (!node.isMesh) return
    node.geometry.dispose()

  })
  traverseMaterials(content, (material) => {
    MAP_NAMES.forEach((map) => {
      if (material[map]) material[map].dispose()
    })
  })
}
function removeObj(obj) {
  let arr = obj.children.filter(x => x)
  arr.forEach(item => {
    if (item.children.length) {
      removeObj(item)
    } else {
      item.clear()
    }
  })
  obj.clear()
  arr = null
}
function traverseMaterials(object, callback) {
  object.traverse((node) => {
    if (!node.isMesh) return
    const materials = Array.isArray(node.material)
      ? node.material
      : [node.material]
    materials.forEach(callback)
  })
}

// 监听尺寸变化
function resize() {
  // 重置渲染器输出画布canvas尺寸
  clientWidth.value = draw.value.clientWidth
  clientHeight.value = window.innerHeight - 75
  const k = draw.value.clientWidth / (window.innerHeight - 75) // 窗口宽高比
  defaultCamera.aspect = k
  defaultCamera.updateProjectionMatrix()
  renderer.setSize(draw.value.clientWidth, window.innerHeight - 75)
}
function handleMouseWheel(event) {
  if (event.target.localName == 'canvas') {
    // 设置相机缩放比数值越大缩放越明显
    const factor = 2
    // 从鼠标位置转化为webgl屏幕坐标位置
    const glScreenX = (event.clientX / controls.domElement.width) * 2 - 1
    const glScreenY = -(event.clientY / controls.domElement.height) * 2 + 1
    const vector = new THREE.Vector3(glScreenX, glScreenY, 0)
    // 从屏幕向量转为3d空间向量
    vector.unproject(controls.object)
    // 相机偏移量
    vector.sub(controls.object.position).setLength(factor)
    if (event.deltaY < 0) {
      controls.object.position.add(vector)
      controls.target.add(vector)
    } else {
      controls.object.position.sub(vector)
      controls.target.sub(vector)
    }
    controls.update()
  }
}








const isRightList = ref(true)
const dataJson = ref() // Json数据
const dataIndex = ref() // 列表选中
const dataSel = ref() // 列表选中数据
const selType = ref('05') // 选中类型
const data = ref([]) // 右侧列表数据

const search = ref('') // 右侧搜索框
const searchdata = ref([])
const isOnLine = ref('01') // 右侧摄像头显示 在线/离线

const objRow = ref({}) //获取详细信息
const information = ref(false) // 详细信息弹框
const defaultProps = ref({
  children: 'children',
  label: 'objname'
})
const isSelType = ref(true)
const treeRef = ref()

const treeLine = ref()
const filterText = ref('') //无人车搜索


const isCameraMenu = ref(false) // 右键是否显示删除摄像机
const isdevice = ref(true) // 是否是设备
const isVideo = ref(false) // 是否显示视频


const giveAlarmDia = ref(false) // 告警弹框
watch(filterText, (val) => {
  treeRef.value.filter(val)
})
function filterNode(value, data) {
  if (!value) return true
  if (data.objname == null) {
    return data.name.indexOf(value) !== -1;
  } else {
    return data.objname.indexOf(value) !== -1;
  }
}
// 加载JSON数据
function initData() {
  const params = {
    stationId: userStore.stationId
  }
  getSubstationById(params).then((item) => {
    if (item.code == 0) {
      if (item.data.custom2) {
        dataJson.value = JSON.parse(item.data.custom2)
        if (dataJson.value.Camera != '') {
          let is = false
          if (selType.value == '01') {
            data.value.forEach(element => {
              element.start = false
            })
            data.value = dataJson.value.Camera
            searchdata.value = JSON.parse(JSON.stringify(data.value))
            is = true
          }
          loadModel('Camera', dataJson.value.Camera, is)
        }
        if (dataJson.value.UV != '') {
          let is = false
          if (selType.value == '04') {
            data.value = dataJson.value.UV
            searchdata.value = JSON.parse(JSON.stringify(data.value))
            for (let i = 0; i < searchdata.value.length; i++) {
              if (data.value[i].line) data.value[i].children = JSON.parse(data.value[i].line)
              if (searchdata.value[i].line) searchdata.value[i].children = JSON.parse(searchdata.value[i].line)
            }
            is = true
          }
          loadModel('UV', dataJson.value.UV, is)
        }
        if (dataJson.value.DevicePoint != '') {
          let is = false
          if (selType.value == '02') {
            data.value = dataJson.value.DevicePoint
            searchdata.value = JSON.parse(JSON.stringify(data.value))
            is = true
          }
          loadModel('DevicePoint', dataJson.value.DevicePoint, is)
        }
        if (dataJson.value.EquipmentComponentSettings != '') {
          if (selType.value == '05') {
            data.value = dataJson.value.EquipmentComponentSettings
            searchdata.value = JSON.parse(JSON.stringify(data.value))
            Information('01')
            scene.children[1].traverse(function (obj) {
              data.value.forEach(element => {
                if (obj.userData.name == element.equipmentname) {
                  obj.userData.type = 'EquipmentComponentSettings'
                  obj.uuid = element.id
                  obj.userData.objinfo = element.objinfo
                  obj.userData.x = element.x
                  obj.userData.y = element.y
                  obj.userData.z = element.z
                }
              })
            })
          }
        }
      }
    }
  })
}
const backups = ref([])
function rightTabClik(str) {
  isOnLine.value = str
  if (str == '02') {
    searchdata.value = data.value.filter(item => item.objinfo != undefined && item.objinfo.channelList != undefined && item.objinfo.online == 1)
    backups.value = data.value.filter(item => item.objinfo != undefined && item.objinfo.channelList != undefined && item.objinfo.online == 1)
  } else if (str == '03') {
    searchdata.value = data.value.filter(item => item.objinfo == undefined || item.objinfo.online != 1)
    backups.value = data.value.filter(item => item.objinfo == undefined || item.objinfo.online != 1)
  } else {
    searchdata.value = data.value
  }
}

function searchNmae() {
  if (selType.value == '05') {
    searchdata.value = data.value.filter(item => item.name.indexOf(search.value) !== -1)
  } else {
    if (selType.value == '01') {
      if (isOnLine.value == '02' || isOnLine.value == '03') {
        searchdata.value = backups.value.filter(item => item.objname.indexOf(search.value) !== -1)
      } else {
        searchdata.value = data.value.filter(item => item.objname.indexOf(search.value) !== -1)
      }

    } else {
      searchdata.value = data.value.filter(item => item.objname.indexOf(search.value) !== -1)
    }
  }


}
const isranging = ref(false)
const isroam = ref(false)
let texture = ''
let mesh = ''
let meshs = ''
let curve = ''
// 单点漫游
function unmannedRoam(row, node) {
  mixer = null
  texture = ''
  curve = ''
  loopTime = 0
  treeLine.value = node.parent.data
  dataSel.value = scene.getObjectByProperty('uuid', node.parent.data.id)
  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].userData.type == 'PatrolLine') {
      scene.children[i].traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.material.visible = false
        }
      })
    }
  }
  let point = []
  let dataPoint = JSON.parse(row.points)
  for (let a = 0; a < dataPoint.length; a++) {
    point.push(new THREE.Vector3(
      dataPoint[a].x,
      dataPoint[a].y + 0.1,
      dataPoint[a].z
    ))
  }
  curve = new THREE.CatmullRomCurve3(point, false)
  curve.curveType = 'catmullrom'
  curve.closed = false // 是否自动闭合
  curve.tension = 0
  let up = new THREE.Vector3(0, 1, 0)
  // 创建路线点列表
  let pathPointLists = new PathPointList()
  pathPointLists.set(curve.points, 0.5, 5000, up, false)
  let geometry = new PathGeometry()
  geometry.update(pathPointLists, {
    width: 1,
    arrow: false
  })
  texture = new THREE.TextureLoader().load(jt, function (texture) {
    texture.wrapS = texture.wrapT = THREE.RepeatWrapping
    texture.anisotropy = renderer.capabilities.getMaxAnisotropy()
  })

  // 创建材质
  let material = new THREE.MeshPhongMaterial({
    color: 0xFFFFFF,
    depthWrite: true,
    transparent: true,
    opacity: 1,
    side: THREE.DoubleSide,
    map: texture,
  })
  mesh = new THREE.Mesh(geometry, material)
  mesh.userData.type = 'PatrolLine'
  scene.add(mesh)
  // 获取无人车动画
  for (let i = 0; i < mixerData.length; i++) {
    if (mixerData[i].scene.uuid == dataSel.value.uuid) {
      mixer = new THREE.AnimationMixer(dataSel.value)
      for (var a = 0; a < mixerData[i].animations.length; a++) {
        mixer.clipAction(mixerData[i].animations[a]).play()
      }
    }
  }
  isroam.value = true
  isRightList.value = false

  registerRenderFunc('walk', (delta) => {
    if (isroam.value == true) {
      updateNPCPosition()
      // 更新相机
      updateCameraBehindNPC()
    }
  })
  isSelType.value = false
  cancelAnimationFrame(_animate)
  render1()
}
let loopTime = 0 // loopTime: 循环一圈的时间
let renderFunc = {}
const clock = new THREE.Clock()  // 计时工具
let cameraTween;  // 相机的补间动画
let step = 0; // NPC当前的步数索引
function render1() {
  _animate1 = requestAnimationFrame(render1)
  if (isroam.value == true) {
    try {
      // 预约下一帧的渲染动作
      // 让渲染器渲染一帧相机捕捉到的场景
      renderer.render(scene, defaultCamera);
      // 更新控制器
      controls.update();
      if (mixer) {
        mixer.update(3 / 100)
      }
      if (texture) {
        texture.offset.x -= 0.02
        texture.repeat.x = 0.4
      }
      // 更新补间动画
      if (TWEEN && cameraTween) TWEEN.update();
      // 获取时间差
      const delta = clock.getDelta();
      // 执行registerRenderFunc方式注册进来的渲染操作
      const funcNames = Object.keys(renderFunc);
      if (funcNames && funcNames.length > 0) {
        funcNames.forEach((funcName) => {
          try {
            // 不太放心，try-catch一下，保证出现意外也能继续执行后面的内容
            renderFunc[funcName](delta);
          } catch (e) {

          }
        });
      }
    } catch (e) {

    }
  }
}

/**
 * 更新NPC的位置
 */
function updateNPCPosition() {
  // 分段数，数越大，前进时取的点之间的距离越小，移动速度越慢
  const segment = 2000;
  // 从路径曲线上面取点
  const stepPoints = curve.getSpacedPoints(segment);
  // 每次前进一小段
  step += 1;
  // NPC下个位置的索引
  const npcIndex = step % segment;
  // NPC眼睛看向的点的索引
  const eyeIndex = (step + 50) % segment;
  if (eyeIndex == 0) {
    isroam.value = false
    disposeWalking()
    isRightList.value = true
    isSelType.value = true
    if (mesh) {
      dataSel.value.position.x = treeLine.value.coordinate.x
      dataSel.value.position.y = treeLine.value.coordinate.y
      dataSel.value.position.z = treeLine.value.coordinate.z
      dataSel.value.rotation.x = treeLine.value.rotation.x
      dataSel.value.rotation.y = treeLine.value.rotation.y
      dataSel.value.rotation.z = treeLine.value.rotation.z
      scene.remove(mesh)
      mesh = ''
    }
    dataSel.value = null
    reset()
    animate()
    cancelAnimationFrame(_animate1)

    return
  }
  // NPC下一个位置
  const npcPoint = stepPoints[npcIndex];
  // NPC眼睛看向的位置
  const eyePoint = stepPoints[eyeIndex];
  if (dataSel.value == null) return
  // 更新NPC模型的位置
  dataSel.value.position.copy(npcPoint);
  // 更新NPC模型看向的位置，保证模型的“朝向”
  dataSel.value.lookAt(eyePoint.x, eyePoint.y, eyePoint.z);
}
/**
 * 更新相机的位置等状态，让用户的视角移动到NPC身后
 * @param moveSmooth 是否平滑移动
 * @param callback 动作完成后执行的回调函数
 */
function updateCameraBehindNPC(moveSmooth, callback) {
  // 相机的相对偏移向量, y = 1.0 让相机接近平视前方的效果， z = -5, 在NPC后5距离的位置。
  const relativeCameraOffset = new THREE.Vector3(0, 3, -5);
  // 转换为相对NPC世界矩阵的坐标
  if (dataSel.value == null) return
  const targetCameraPosition = relativeCameraOffset.applyMatrix4(dataSel.value.matrixWorld);
  if (moveSmooth) {
    // 平滑移动时，使用TWEEN补间动画。
    flyTo(targetCameraPosition, 1000, callback, () => {
      // 更新控制器的目标为NPC的位置
      const walkerPosition = dataSel.value.position.clone();
      controls.target = new THREE.Vector3(walkerPosition.x, walkerPosition.y, walkerPosition.z);
    });
  } else {
    // 在曲线上分段前进的过程中，每段的间距非常非常小，已经接近丝滑，此时不需要使用TWEEN了
    defaultCamera.position.set(targetCameraPosition.x, targetCameraPosition.y, targetCameraPosition.z);
    // 更新控制器的目标为NPC的位置
    const walkerPosition = dataSel.value.position.clone();
    controls.target = new THREE.Vector3(walkerPosition.x, walkerPosition.y + 2, walkerPosition.z);
    // 执行回调函数
    callback && callback();
  }
}
/**
 * 平滑飞入
 * @param position 目标位置
 * @param duration 持续时间，默认500ms。
 * @param callback 回调函数
 * @param onUpdate 更新回调
 */
function flyTo(position, duration, callback, onUpdate) {
  // 未指定持续时间的，默认500毫秒
  if (duration === undefined || duration === null) {
    duration = 500;
  }
  // 取相机当前位置，从当前位置，平滑移动到目标位置
  const curCameraPosition = defaultCamera.position.clone();
  // 创建补间动画TWEEN对象
  cameraTween = new TWEEN.Tween(curCameraPosition).to(position, duration).easing(TWEEN.Easing.Quadratic.Out);
  // 设定更新过程中执行的动作
  cameraTween.onUpdate((obj) => {
    // 持续duration毫秒的移动过程中， obj为“此时”坐标移动到的位置，通过不断地将相机的位置设定到坐标“此时”变化到的位置，来形成一个平滑的移动效果。
    defaultCamera.position.set(obj.x, obj.y, obj.z);
    // 如果指定了onUpdate方法，再执行下指定的onUpdate
    onUpdate && onUpdate(obj);
  });
  // 设定完成后执行的动作
  cameraTween.onComplete(() => {
    callback && callback();
  });
  // 开始补间动画（注意配合每帧渲染时的TWEEN.update()更新动画）
  cameraTween.start();
}
/**
 * 注册渲染中执行的方法
 * @param name 设定函数名称
 * @param func 函数方法体
 */
function registerRenderFunc(name, func) {
  renderFunc[name] = func;
}

/**
 * 销毁漫游相关的各种资源和动画
 * （可以根据具体情况进行优化）
 */
function disposeWalking() {
  step = 0
  // 销毁渲染帧时的附加处理
  logoutRenderFunc('walk');
  logoutRenderFunc('walk-way');
}
/**
 * 注销渲染中执行的方法
 * @param name 要注销的函数名称
 */
function logoutRenderFunc(name) {
  const old = renderFunc[name];
  if (old) {
    delete renderFunc[name];
  }
}
// 全景开始漫游
function roamClick() {
  if (_animate) cancelAnimationFrame(_animate)
  if (_animate1) cancelAnimationFrame(_animate1)
  if (_animate2) cancelAnimationFrame(_animate2)
  if (isroam.value == false) {
    texture = ''
    curve = ''
    isroam.value = true
    isRightList.value = false
    isSelType.value = false
    information.value = false
    giveAlarmDia.value = false
    videoShow.value = false
    loopTime = 0
    //创建样条曲线，作为运动轨迹
    curve = new THREE.CatmullRomCurve3([
      new THREE.Vector3(-16.3, 17.2, 52),
      new THREE.Vector3(-16.3, 17.2, -32),
      new THREE.Vector3(11, 17.2, -32),
      new THREE.Vector3(11, 17.2, 52),
    ], false)
    curve.curveType = 'catmullrom'
    curve.closed = false
    curve.tension = 0
    // 创建路线点列表
    var pathPointLists = new PathPointList()
    pathPointLists.set(curve.points, 0.5, 10, new THREE.Vector3(0, 1, 0), false)
    var geometry = new PathGeometry()
    geometry.update(pathPointLists, {
      width: 2,
      arrow: false
    })
    texture = new THREE.TextureLoader().load(jt, function (texture) {
      texture.wrapS = texture.wrapT = THREE.RepeatWrapping
      texture.anisotropy = renderer.capabilities.getMaxAnisotropy()
    })

    // 创建材质
    var material = new THREE.MeshPhongMaterial({
      color: 0xFFFFFF,
      depthWrite: true,
      transparent: true,
      opacity: 1,
      side: THREE.DoubleSide,
      map: texture,
    })
    meshs = new THREE.Mesh(geometry, material)
    scene.add(meshs)
    render2()
  } else {
    disposeWalking()
    isroam.value = false
    isRightList.value = true
    isSelType.value = true
    if (mesh) {
      dataSel.value.position.x = treeLine.value.coordinate.x
      dataSel.value.position.y = treeLine.value.coordinate.y
      dataSel.value.position.z = treeLine.value.coordinate.z
      dataSel.value.rotation.x = treeLine.value.rotation.x
      dataSel.value.rotation.y = treeLine.value.rotation.y
      dataSel.value.rotation.z = treeLine.value.rotation.z
      scene.remove(mesh)
      mesh = ''
    }
    if (meshs) {
      scene.remove(meshs)
      meshs = ''
    }
    dataSel.value = null
    reset()
    animate()
  }
}

function render2() {
  if (isroam.value == true) {
    if (loopTime <= 1 - 0.0004 * 80) {
      const point = curve.getPointAt(loopTime) //获取样条曲线指定点坐标，作为相机的位置
      defaultCamera.position.set(point.x, point.y + 3, point.z)

      const pointBox = curve.getPointAt(loopTime + 0.0004 * 80) //获取样条曲线指定点坐标
      defaultCamera.lookAt(pointBox.x, pointBox.y + 3, pointBox.z)
      loopTime += 0.0004
    } else {
      loopTime = 0
      isroam.value = true
      roamClick()
    }
    if (texture) {
      texture.offset.x -= 0.03
      texture.repeat.x = 0.4
    }
    renderer.render(scene, defaultCamera)
    _animate2 = requestAnimationFrame(render2)
  }
}
// 开始测距
function rangingClick() {
  isranging.value = !isranging.value
  if (isranging.value) {
    renderer.domElement.style.cursor = 'crosshair'
  } else {
    renderer.domElement.style.cursor = 'unset'
  }
}

function rangingModelClick(event) {
  if (isranging.value && event.button === 0) {
    srangingMouse.x = (event.clientX / renderer.domElement.offsetWidth) * 2 - 1
    srangingMouse.y = -((event.clientY - 90) / (renderer.domElement.offsetHeight)) * 2 + 1;
    srangingRaycaster.setFromCamera(srangingMouse, defaultCamera)
    srangingIntersects = srangingRaycaster.intersectObjects(scene.children)
    if (srangingIntersects.length === 0) return
    if (!drawingLine) {
      //加入距离文字
      let text1 = document.createElement('span')
      text1.className = 'rangingText'
      text1.style.position = 'absolute'
      text1.style.top = '0'
      text1.style.color = 'red'
      text1.style.pointerEvents = 'none'
      document.body.appendChild(text1)
      textDoms[lineId] = [text1]

      //加入2d的点
      let point2d1 = document.createElement('div')
      point2d1.className = 'rangingDian'
      point2d1.style.position = 'absolute'
      point2d1.style.width = '10px'
      point2d1.style.height = '10px'
      point2d1.style.borderRadius = '50%'
      point2d1.style.pointerEvents = 'none'
      point2d1.style.cursor = 'pointer'
      point2d1.style.transform = 'translate(-50%,-50%)'
      point2d1.style.top = '0'
      point2d1.style.background = 'orange'
      let point2d2 = point2d1.cloneNode()
      document.body.appendChild(point2d1)
      document.body.appendChild(point2d2)
      pointsDom[lineId] = [point2d1, point2d2]




      //加入3d中的两圆球
      let marker1 = new THREE.Mesh(
        new THREE.SphereGeometry(0.1, 10, 20),
        new THREE.MeshBasicMaterial({
          color: 0x0000ff,
        })
      );
      let marker2 = marker1.clone()
      markers[lineId] = [marker1, marker2]
      marker1.name = '球'
      marker2.name = '球'
      scene.add(marker1, marker2)

      //构建虚线
      const geometry = new THREE.BufferGeometry().setFromPoints(
        [srangingIntersects[0].point, srangingIntersects[0].point.clone()]
      )
      let line = new THREE.LineSegments(
        geometry,
        new THREE.LineDashedMaterial({
          color: 0xff0000,
          transparent: true,
          depthTest: false,
          dashSize: 1,//短划线的大小
          gapSize: 0.1//短划线之间的距离
        })
      )
      //这行代码很关键,让屏幕外区域的点,正确显示
      line.frustumCulled = false
      markers[lineId].push(line)
      line.name = '线'
      scene.add(line)

      marker1.lineId = marker2.lineId = line.lineId = lineId
      drawingLine = true


      let cacheId = lineId
      line.onBeforeRender = function () {
        //实时渲染text和2d的点
        const positions = line.geometry.attributes.position.array
        const v0 = new THREE.Vector3(
          positions[0],
          positions[1],
          positions[2]
        )
        const v1 = new THREE.Vector3(
          positions[3],
          positions[4],
          positions[5]
        )
        const distance = v0.distanceTo(v1)
        let [text1] = textDoms[cacheId]
        text1.innerHTML = distance.toFixed(2) + 'm'

        let point1 = new THREE.Vector3().lerpVectors(v0, v1, 0)
        let point2 = new THREE.Vector3().lerpVectors(v0, v1, 1)
        point1 = WorldtoScreenPosition(point1)
        point2 = WorldtoScreenPosition(point2)
        text1.style.left = point1.x + "px"
        text1.style.top = point1.y + 95 + "px"

        let [point2d1, point2d2] = pointsDom[cacheId]
        point1 = WorldtoScreenPosition(v0)
        point2 = WorldtoScreenPosition(v1)
        point2d1.style.left = point1.x + "px"
        point2d1.style.top = point1.y + 90 + "px"
        point2d2.style.left = point2.x + "px"
        point2d2.style.top = point2.y + 90 + "px"


        //实时渲染3d的两球
        let [marker1, marker2] = markers[cacheId]
        marker1.position.set(v0)
        marker2.position.set(v1)
      }
    } else {
      let line = markers[lineId][2]
      //保存旧的material
      line.oldMaterial = line.material
      //虚线变实线
      line.material = new THREE.LineBasicMaterial({
        color: 0xff5555,
        transparent: true,
        depthTest: false
      })

      updateLinePoint(line, srangingIntersects[0].point, 3)

      //让2d中的两点可拖动
      let [point2d1, point2d2] = pointsDom[lineId]
      point2d1.style.pointerEvents = 'unset'
      point2d2.style.pointerEvents = 'unset'
      //监听两点的拖拽
      draggablePoint(point2d1, lineId)
      draggablePoint(point2d2, lineId)


      lineId++
      drawingLine = false
    }

  }
}
function draggablePoint(el, id) {
  let timeId = null
  let index = pointsDom[id].findIndex(item => item === el)
  let line = markers[id][2]
  el.addEventListener('mousedown', (e) => {
    timeId = setTimeout(() => {
      changeMaterial(line)
      //变虚线
      timeId = null
      //长按监听移动
      document.addEventListener('mousemove', handlePointMove)
    }, 100);
    document.addEventListener('mouseup', handlePointUp)
  })
  function handlePointMove(event) {
    //打出射线
    srangingMouse.x = (event.clientX / renderer.domElement.offsetWidth) * 2 - 1
    srangingMouse.y = -((event.clientY - 75) / (renderer.domElement.offsetHeight)) * 2 + 1;
    srangingRaycaster.setFromCamera(srangingMouse, defaultCamera)
    srangingIntersects = srangingRaycaster.intersectObjects(scene.children)
    //排除含有lineId的物体
    srangingIntersects = srangingIntersects.filter(item => !('lineId' in item.object))
    if (srangingIntersects.length === 0) return
    //变更线段两端点的位置
    let arrayStart = index && 3
    updateLinePoint(line, srangingIntersects[0].point, arrayStart)
  }


  function handlePointUp() {
    if (timeId) {
      clearTimeout(timeId)
      timeId = null
    } else {
      changeMaterial(line)
    }
    document.removeEventListener('mouseup', handlePointUp)
    document.removeEventListener('mousemove', handlePointMove)
  }

}

function changeMaterial(object3d) {
  let temp = object3d.oldMaterial
  object3d.oldMaterial = object3d.material
  object3d.material = temp
}

function updateLinePoint(line, point, arrayIndex) {
  const positions = line.geometry.attributes.position.array
  positions[arrayIndex] = point.x
  positions[arrayIndex + 1] = point.y
  positions[arrayIndex + 2] = point.z
  line.geometry.attributes.position.needsUpdate = true
}
//------------------------------------------------------------

function resizeRendererToDisplaySize(renderer) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}


function WorldtoScreenPosition(pos) {
  const canvas = renderer.domElement;
  const worldVector = new THREE.Vector3(pos.x, pos.y, pos.z)
  const standardVector = worldVector.project(defaultCamera)
  const widthHalf = canvas.width / 2
  const heightHalf = canvas.height / 2
  return {
    x: Math.round(standardVector.x * widthHalf + widthHalf),
    y: Math.round(-standardVector.y * heightHalf + heightHalf),
    z: 1
  }
}


// 切换显示
function selTypeChange(str) {
  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].userData.type == 'Camera' || scene.children[i].userData.type == 'Camera1' || scene.children[i].userData.type == 'UV' || scene.children[i].userData.type == 'PatrolLine') {
      scene.children[i].traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.material.visible = false
        }
      })
    }
  }
  data.value = []
  if (dataJson.value) {
    if (str == '01') {
      if (dataJson.value.Camera) data.value = dataJson.value.Camera
      searchdata.value = JSON.parse(JSON.stringify(data.value))
      for (let i = 0; i < scene.children.length; i++) {
        if (scene.children[i].userData.type == 'Camera' || scene.children[i].userData.type == 'Camera1') {
          scene.children[i].traverse(function (obj) {
            if (obj.type === 'Mesh') {
              obj.material.visible = true
            }
          })
        }
      }
    } else if (str == '02') {
      if (dataJson.value.DevicePoint) data.value = dataJson.value.DevicePoint
      searchdata.value = JSON.parse(JSON.stringify(data.value))
      for (let i = 0; i < scene.children.length; i++) {
        if (scene.children[i].userData.type == 'DevicePoint') {
          scene.children[i].traverse(function (obj) {
            if (obj.type === 'Mesh') {
              obj.material.visible = true
            }
          })
        }
      }
    } else if (str == '04') {
      if (dataJson.value.UV) data.value = dataJson.value.UV
      searchdata.value = JSON.parse(JSON.stringify(data.value))
      for (let i = 0; i < searchdata.value.length; i++) {
        if (searchdata.value[i].line) searchdata.value[i].children = JSON.parse(searchdata.value[i].line)
      }
      for (let i = 0; i < scene.children.length; i++) {
        if (scene.children[i].userData.type == 'UV') {
          scene.children[i].traverse(function (obj) {
            if (obj.type === 'Mesh') {
              obj.material.visible = true
            }
          })
        }
      }
    } else if (str == '05') {
      if (dataJson.value.EquipmentComponentSettings) data.value = dataJson.value.EquipmentComponentSettings
      searchdata.value = JSON.parse(JSON.stringify(data.value))
      if (dataJson.value.EquipmentComponentSettings != '') {
        data.value = dataJson.value.EquipmentComponentSettings
        searchdata.value = JSON.parse(JSON.stringify(data.value))
        scene.children[1].traverse(function (obj) {
          data.value.forEach(element => {
            if (obj.userData.name == element.equipmentname) {
              obj.userData.type = 'EquipmentComponentSettings'
              obj.uuid = element.id
              obj.userData.objinfo = element.objinfo
              obj.userData.x = element.x
              obj.userData.y = element.y
              obj.userData.z = element.z
            }
          })
        })
      }
    }
  }
  isRightList.value = true
  selType.value = str
  reset()
}
// 无人车菜单点击
function handleNodeClick(row, node) {
  if (node.level == 1) {
    for (let i = 0; i < scene.children.length; i++) {
      if (scene.children[i].userData.type == 'PatrolLine') {
        scene.children[i].traverse(function (obj) {
          if (obj.type === 'Mesh') {
            obj.material.visible = false
          }
        })
      }
    }
    let model = scene.getObjectByProperty('uuid', row.id)
    dataSel.value = model
    for (let i = 0; i < scene.children.length; i++) {
      if (scene.children[i].type == 'BoxHelper') {
        scene.children[i].traverse(function (obj) {
          if (obj.type === 'Mesh') {
            obj.geometry.dispose()
            obj.material.dispose()
          }
        })
        scene.remove(scene.children[i])
        i--
      }
    }
    model.traverse(function (obj) {
      if (obj.type === 'Mesh') {
        obj.material.visible = true
      }
    })
    const box = new THREE.BoxHelper(model, '#fff000')
    box.userData.uuid = model.uuid
    scene.add(box)
    controls.enabled = true
    var pos = new THREE.Vector3(Number(model.userData.x1), Number(model.userData.y1), Number(model.userData.z1))
    var pos2 = new THREE.Vector3(Number(model.position.x), Number(model.position.y), Number(model.position.z))
    animateCamera(defaultCamera.position, pos, controls.target, pos2)
  }
}
// 列表点击 - 视角切换
function listClick(row, index) {
  dataIndex.value = index
  let model = scene.getObjectByProperty('uuid', row.id)
  if (selType.value == '05') {
    for (let i = 0; i < scene.children.length; i++) {
      if (scene.children[i].type == 'BoxHelper') {
        scene.children[i].traverse(function (obj) {
          if (obj.type === 'Mesh') {
            obj.geometry.dispose()
            obj.material.dispose()
          }
        })
        scene.remove(scene.children[i])
        i--
      }
    }
    // 框选
    const BoxHelper = new THREE.BoxHelper(model, '#fff000')
    BoxHelper.userData.uuid = model.uuid
    scene.add(BoxHelper)

    const box = new THREE.Box3().setFromObject(model)
    const center = box.getCenter(new THREE.Vector3())
    let arr = true
    position.forEach(element => {
      if (element.name == model.userData.name) {
        arr = false
        var pos = new THREE.Vector3(element.x1, element.y1, element.z1)
        var pos2 = new THREE.Vector3(element.x, element.y, element.z)
        animateCamera(defaultCamera.position, pos, controls.target, pos2)
      }
    })
    if (arr == true) {
      var pos = new THREE.Vector3(center.x + 8, center.y, center.z)
      var pos2 = new THREE.Vector3(center.x, center.y, center.z)
      animateCamera(defaultCamera.position, pos, controls.target, pos2)
    }
    return
  }
  dataSel.value = model
  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].type == 'BoxHelper') {
      scene.children[i].traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.geometry.dispose()
          obj.material.dispose()
        }
      })
      scene.remove(scene.children[i])
      i--
    }
  }
  model.traverse(function (obj) {
    if (obj.type === 'Mesh') {
      obj.material.visible = true
    }
  })
  const box = new THREE.BoxHelper(model, '#fff000')
  box.userData.uuid = model.uuid
  scene.add(box)
  controls.enabled = true
  var pos = new THREE.Vector3(Number(model.userData.x1), Number(model.userData.y1), Number(model.userData.z1))
  var pos2 = new THREE.Vector3(Number(model.position.x), Number(model.position.y), Number(model.position.z))
  animateCamera(defaultCamera.position, pos, controls.target, pos2)
}

function listange(row) {
  let model = scene.getObjectByProperty('uuid', row.id)
  let isAdd = true
  scene.children.forEach((item) => {
    if (item.userData.type == 'Projection') {
      if (row.id == item.userData.uuid) {
        item.rotation.x = model.rotation.x
        item.rotation.y = model.rotation.y
        item.rotation.z = model.rotation.z
        item.traverse(function (obj) {
          if (obj.type === 'Mesh') {
            if (row.start) {
              let num = 30
              let timer = setInterval(() => {
                num--
                item.scale.set(num, num, num)
                if (num == 1) {
                  obj.material.visible = false
                  clearInterval(timer)
                }
              }, 1)
            } else {
              let num = 1
              obj.material.visible = true
              let timer = setInterval(() => {
                num++
                item.scale.set(num, num, num)
                if (num == 30) {
                  clearInterval(timer)
                }
              }, 1)
            }
          }
        })
        isAdd = false
      }
    }
  })

  if (isAdd) {
    let gltfLoader = new GLTFLoader() //obj加载器
    // 引入默认纹理
    gltfLoader.load('./static/3DModel/range.glb', (gltf1) => {
      let model1 = gltf1.scene
      model1.position.set(Number(model.position.x), Number(model.position.y), Number(model.position.z))
      model1.rotation.x = model.rotation.x
      model1.rotation.y = model.rotation.y
      model1.rotation.z = model.rotation.z
      model1.userData.type = 'Projection'
      model1.userData.uuid = row.id
      model1.userData.select = true
      scene.add(model1)
      let num = 1
      let timer = setInterval(() => {
        num = num + 1
        model1.scale.set(num, num, num)
        if (num == 30) clearInterval(timer)
      }, 1)
    })
  }
  row.start = !row.start
}

const deviceId = ref('')
const channelId = ref('')
const videofmp4 = ref('')
// 播放视频
function getVideoUrl(row, index) {
  if (index == 'camera') {
    deviceId.value = row.patroldevice_code
    channelId.value = row.patroldevice_channelcode
  } else {
    deviceId.value = row.channelList[index].deviceid
    channelId.value = row.channelList[index].channelid
    if (row.channelList[index].deviceid == undefined) {
      deviceId.value = row.channelList[index].deviceId
      channelId.value = row.channelList[index].channelId
    }
  }

  axios.get(userStore.webApiMonitorUrl + '/api/play/start/' + deviceId.value + '/' + channelId.value, {}).then((res) => {
    if (res.data.data != undefined) {
      videoUrl.value = res.data.data.ws_flv
      videofmp4.value = res.data.data.fmp4
      if (index == 'camera') {
        presetPosition(130, row.patroldevice_pos)
      }

    }
  }).catch(function (error) {
  })
}
function presetPosition(cmdCode, presetPos) { // 预置位操作 ---设置、删除、调用

  axios.get(userStore.webApiBaseUrl + '/basedata/substation-patroldevice/isWorkingOfPatrolDevice?stationcode=' + userStore.stationCode + "&devicecode=" + deviceId.value, {}).then((resize) => {
    if (res.data.data == "0") {
      console.log("预置位")
      axios.post(userStore.webApiMonitorUrl + '/api/ptz/front_end_command/' + deviceId.value + '/' + channelId.value + '?cmdCode=' + cmdCode + '&parameter1=0&parameter2=' + presetPos + '&combindCode2=0', {}).then((res) => { })
    }
  })
}
//摄像机-摄像机-视频播放
const videoChannelList = ref([])
function realTimeVideo(row, index) {
  const contextmenu = document.getElementById('contextmenu')
  contextmenu.style.display = 'none'
  const contextimg = document.getElementById('contextimg')
  contextimg.style.display = 'none'
  // if (isVideo.value == true) {
  if (row == 1) {
    if (index == 0) {
      videoChannelList.value = dataSel.value.userData.objinfo.channelList[0]
      getVideoUrl(dataSel.value.userData.objinfo, index)
    } else if (index == 1) {
      videoChannelList.value = dataSel.value.userData.objinfo.channelList[1]
      getVideoUrl(dataSel.value.userData.objinfo, index)
    }
    videoShow.value = true
    return
  }
  if (index == 0) {
    getVideoUrl(row.objinfo, index)
    videoChannelList.value = scene.getObjectByProperty('uuid', row.id).userData.objinfo.channelList[0]
    videoShow.value = true
  } else if (index == 1) {
    getVideoUrl(row.objinfo, index)
    videoChannelList.value = scene.getObjectByProperty('uuid', row.id).userData.objinfo.channelList[1]
    videoShow.value = true
  } else if (index == 3) {
    ElMessage({
      message: '此摄像机暂无实时视频',
      type: 'warning',
    })
    return false
  }
  // }
}
function getDeviceVideo(row) {
  let camera = JSON.parse(row.objinfo.patroldeviceJson)
  console.log(camera)
  getVideoUrl(camera[0], 'camera')
  videoShow.value = true
}
//列表点击-查看详细信息
function informationClick(row) {
  information.value = true
  objRow.value = scene.getObjectByProperty('uuid', row.id)
  nextTick(() => {
    const detailedInformation = document.getElementById('detailed-information')
    detailedInformation.style.right = '26%'
    detailedInformation.style.bottom = '15%'
    detailedInformation.style.left = 'auto'
    detailedInformation.style.top = 'auto'
  })
  clearDiv()
}
//点位历史记录
const history = ref(false)
const histotal = ref(0)
const historParams = ref({
  size: 10,
  current: 1,
  deviceId: '',
  startDate: '',
  endDate: ''
})
const historydata = ref([])
const hisloading = ref(false)
const timeSlot = ref([])
const deviceIdone = ref('')
function historicalRecords(row) {
  getType()
  deviceIdone.value = row
  historParams.value.deviceId = row.objinfo.deviceId
  console.log(timeSlot.value)
  if (timeSlot.value.length > 0) {
    historParams.value.startDate = timeSlot.value[0]
    historParams.value.endDate = timeSlot.value[1]
  } else {
    historParams.value.startDate = ''
    historParams.value.endDate = ''
  }
  hisloading.value = true
  history.value = true
  getHistoryDevice(historParams.value).then(res => {
    if (res.code == 0) {
      historydata.value = res.data.records
      historParams.value.size = res.data.size
      historParams.value.current = res.data.current
      histotal.value = res.data.total
      hisloading.value = false
      // history.value = false
    }
  })
}
function hisreset() {
  timeSlot.value.length = 0
  historicalRecords(deviceIdone.value)
}
const tableRowClassName = ({
  row,
  rowIndex,
}) => {
  if (rowIndex % 2 === 0) {
    return 'warning-row'
  } else if (rowIndex % 2 === 1) {
    return 'success-row'
  }
  return ''
}
function currency(list, itemcode) {
  let dictname = ''
  list.forEach((element) => {
    if (element.itemcode == itemcode) {
      dictname = element.dictname
    }
  })
  return dictname
}
const MeterTypeList = ref([])
function getType() {
  const paramstypes = {
    dictcode: 'MeterType'
  }
  getDeviceByType(paramstypes).then((res) => {
    MeterTypeList.value = res.data
  })
}
// 视角切换
function animateCamera(current1, target1, current2, target2) {
  // current1 相机当前的位置
  // target1 相机的目标位置
  // current2 当前的controls的target
  // target2 新的controls的target
  var tween = new TWEEN.Tween({
    x1: current1.x, // 相机当前位置x
    y1: current1.y, // 相机当前位置y
    z1: current1.z, // 相机当前位置z
    x2: current2.x, // 控制当前的中心点x
    y2: current2.y, // 控制当前的中心点y
    z2: current2.z // 控制当前的中心点z
  })
  tween.to({
    x1: target1.x, // 新的相机位置x
    y1: target1.y, // 新的相机位置y
    z1: target1.z, // 新的相机位置z
    x2: target2.x, // 新的控制中心点位置x
    y2: target2.y, // 新的控制中心点位置x
    z2: target2.z // 新的控制中心点位置x
  }, 1000)
  tween.onUpdate(function () {
    defaultCamera.position.x = this.x1
    defaultCamera.position.y = this.y1
    defaultCamera.position.z = this.z1
    controls.target.x = this.x2
    controls.target.y = this.y2
    controls.target.z = this.z2
    controls.update()
  })
  tween.easing(TWEEN.Easing.Cubic.InOut)
  tween.start()
}
// 开始加载模型
function loadModel(name, data, is) {
  for (let i = 0; i < data.length; i++) {
    for (let a = 0; a < scene.children.length; a++) {
      if (data[i].id == scene.children[a].uuid) {
        return
      }
    }
    let gltfLoader = new GLTFLoader() //obj加载器
    let modeltype = name
    if (name == 'Camera') if (data[i].type == 'Camera1') modeltype = 'Camera1'
    gltfLoader.load('./static/3DModel/' + modeltype + '.glb', (gltf1) => {
      let model = gltf1.scene
      model.position.set(data[i].coordinate.x, data[i].coordinate.y, data[i].coordinate.z)
      if (data[i].rotation) {
        model.rotation.x = data[i].rotation.x
        model.rotation.y = data[i].rotation.y
        model.rotation.z = data[i].rotation.z
      }
      model.uuid = data[i].id
      model.name = data[i].objname
      model.userData.type = modeltype
      model.userData.x1 = data[i].coordinate.x1
      model.userData.y1 = data[i].coordinate.y1
      model.userData.z1 = data[i].coordinate.z1
      model.userData.normal = data[i].coordinate.normal
      model.userData.objinfo = data[i].objinfo
      if (modeltype == 'UV') {
        if (model.userData.line) {
          model.userData.line = JSON.parse(data[i].line)
        }
      }
      model.traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.material.visible = is
        }
      })
      mixerData.push(gltf1)
      scene.add(model)
    })
  }
}
// 清除模型选中和右键选择框
function clearDiv() {
  for (let i = 0; i < scene.children.length; i++) {
    if (scene.children[i].type == 'BoxHelper' || scene.children[i].userData.type == 'Projection') {
      scene.children[i].traverse(function (obj) {
        if (obj.type === 'Mesh') {
          obj.geometry.dispose()
          obj.material.dispose()
        }
      })
      scene.remove(scene.children[i])
      i--
    }
  }
  dataSel.value = ''
  selModel.value = ''
  dataIndex.value = null
}












// 摄像机关联查询
function getData() {
  const params = {
    stationId: userStore.stationId,
    patrolDeviceName: taskName.value,
    areaId: info.value.areaId,
    type: info.value.type,
    size: info.value.size,
    current: info.value.current
  }
  PatrolEquipmentType.value = ''
  getDeviceByType({ dictcode: 'PatrolEquipmentType' }).then((res) => {
    PatrolEquipmentType.value = res.data
  })
  // getArea({ stationCode: userStore.stationCode }).then((res) => {
  //   areaIdType.value = res.data
  // })
  loading.value = true
  getdata(params).then((res) => {
    loading.value = false
    tableData.value = res.data.records
    info.value.size = res.data.size
    info.value.current = res.data.current
    total.value = res.data.total
  })
}
//控制告警详情弹窗

const multipleSelection = ref()
//视频配置
const isswitch = ref(false)
const devicechannelInfo = ref({})
const videoUrl = ref('')
function closeVideo(index) { // 关闭视频

}
// var source = new EventSource(userStore.webApiBaseUrl + '/sse/connect/taskresult_' + userStore.stationCode + "_" + userStore.userId,)
const ws1 = new WebSocket(userStore.wsApiBaseUrl + '/websocket/taskresult_' + userStore.stationCode + "_" + userStore.userId);
function setupWebSocket() {

  ws1.onopen = () => {

  };
  ws1.onerror = (error) => {
  };
  ws1.onmessage = (e) => {
    if (e.data != 0) {
      getData()
    }
  }
  ws1.onclose = () => {

  };

}

//监听
watch(() => userStore.giveanalarmInfo, (newValue, oldValue) => {
  Information('03')
  giveAnAlarm.value.push(JSON.parse(newValue))
  Length.value = Length.value + 1
},
  { deep: true })


watch(() => userStore.trendsInfo, (newValue, oldValue) => {
  Information('02')
  const valueData = JSON.parse(newValue)
  for (var i = 0; i < AlarmMap.value.length; i++) {
    AlarmMap.value[i].flag = false
    if (AlarmMap.value[i].id == valueData.id) {
      AlarmMap.value[i].flag = true
    }
  }
},
  { deep: true })
//核查
function determination() {
  AlarmMapOne.value.checkFlag = 1
  AlarmMapOne.value.deviceId = AlarmMapOne.value.deviceid
  setAlarmLogStatus(AlarmMapOne.value).then(res => {
    if (res.code == 0) {
      ElMessage({
        type: 'success',
        message: '审核成功',
      })
      // if (AlarmMap.value.length > 1) {
      const allComponentId = ref([])
      const allMainDeviceId = ref([])
      const AlarmMapId = ref()
      const alarmId = ref()
      const policeId = ref([])
      AlarmMapId.value = AlarmMap.value.splice(Index.value, 1)
      Length.value = AlarmMap.value.length
      if (Index.value == AlarmMap.value.length) {
        Index.value = Index.value - 1
        AlarmMapOne.value = AlarmMap.value[Index.value]
        // AlarmMap.value[Index.value].flag = false
      } else {
        AlarmMapOne.value = AlarmMap.value[Index.value]
      }

      alarmId.value = AlarmMapId.value[0]

      for (var i = 0; i < AlarmMap.value.length; i++) {
        if (AlarmMap.value[i].componentId) {
          allComponentId.value.push(AlarmMap.value[i].componentId)
        } else if (AlarmMap.value[i].mainDeviceId) {
          allMainDeviceId.value.push(AlarmMap.value[i].mainDeviceId)
        }
      }
      var ComponentIds = [...new Set(allComponentId.value)];
      var MainDeviceIds = [...new Set(allMainDeviceId.value)];
      if (ComponentIds.indexOf(alarmId.value.componentId) == -1 && ComponentIds.length != 0 || MainDeviceIds.indexOf(alarmId.value.mainDeviceId) == -1 && MainDeviceIds.length != 0) {
        for (var k = 0; k <= searchdata.value.length; k++) {
          if (searchdata.value[k] != undefined && alarmId.value != undefined) {
            if (alarmId.value.componentId) {
              if (searchdata.value[k].objinfo.componentId == alarmId.value.componentId) {
                policeId.value.push(searchdata.value[k].id)
              }
            } else if (alarmId.value.componentId) {
              if (searchdata.value[k].objinfo.mainDeviceId == alarmId.value.mainDeviceId) {
                policeId.value.push(searchdata.value[k].id)
              }
            }
            if (policeId.value.length != 0) {
              var newArr = [...new Set(policeId.value)];
              newArr.forEach(element => {
                let model = scene.getObjectByProperty('uuid', element)
                for (var j = 0; j < luminescence.length; j++) {
                  if (luminescence[j].uuid == model.uuid) {
                    luminescence.splice(j, 1);
                    // outlineObj()// 发光
                    cancal(model)
                    return
                  }
                }
              })
            }
          }
        }
      } else if (ComponentIds.length == 0 && MainDeviceIds.length == 0) {
        for (var k = 0; k <= searchdata.value.length; k++) {
          if (searchdata.value[k] != undefined) {
            policeId.value.push(searchdata.value[k].id)
            var newArr = [...new Set(policeId.value)];
            newArr.forEach(element => {
              let model = scene.getObjectByProperty('uuid', element)
              luminescence.length = 0
              // outlineObj()// 发光
              cancal(model)

            })
          }

        }

      }
      if (AlarmMap.value.length == 0) {
        giveAlarmDia.value = false
        AlarmMap.length = 0
      }
      // Information()
    }

  })
}
//上一页
function previousPage() {
  Index.value = Index.value - 1
  AlarmMapOne.value = AlarmMap.value[Index.value]
}
//下一页
function nextPage() {
  Index.value = Index.value + 1
  AlarmMapOne.value = AlarmMap.value[Index.value]
}
</script>

<style lang="scss" scoped>
#THREE_div {
  width: 100%;
  height: 100%;
}

//进度条
.loadingBox {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #001b4a;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2001;
}

.loadingBox1 {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 98;
  color: #ffffff;
  font-size: 20px;
  margin-top: 60px;
}

.progress {
  height: 17px;
  background: #131a25;
  padding: 3px;
  overflow: visible;
  border-radius: 20px;
  border-top: 1px solid #000;
  border-bottom: 1px solid #7992a8;
  width: 300px;

  .progress-bar {
    border-radius: 20px;
    position: relative;
    animation: animate-positive 2s;
    float: left;
    width: 0;
    height: 100%;
    font-size: 12px;
    line-height: 20px;
    color: #fff;
    text-align: center;
    background-color: #009bff;
    -webkit-transition: width .6s ease;
    -o-transition: width .6s ease;
    transition: width .6s ease;

  }

  .active {
    animation: reverse stripes 0.40s linear infinite, animate-positive 2s;
  }

  .progress-value {
    display: none;
    padding: 3px 7px;
    font-size: 13px;
    color: #fff;
    border-radius: 4px;
    background: #191919;
    border: 1px solid #000;
    position: absolute;
    top: -40px;
    right: -10px;
  }

  .progress-value:after {
    content: "";
    border-top: 10px solid #191919;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    position: absolute;
    bottom: -6px;
    left: 26%;
  }
}

.progress-bar-striped {
  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
  background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
  -webkit-background-size: 40px 40px;
  background-size: 40px 40px;
}

@-webkit-keyframes stripes {
  from {
    background-position: 40px 0
  }

  to {
    background-position: 0 0
  }
}

@-o-keyframes stripes {
  from {
    background-position: 40px 0
  }

  to {
    background-position: 0 0
  }
}

@keyframes stripes {
  from {
    background-position: 40px 0
  }

  to {
    background-position: 0 0
  }
}

@-webkit-keyframes animate-positive {
  0% {
    width: 0;
  }
}

@keyframes animate-positive {
  0% {
    width: 0;
  }
}

.context-operate-hov {
  color: #00ffff !important;
  box-shadow: 0 0 4px #00ffff;
  border: 1px solid #00ffff !important;
}

#context-operate {
  position: absolute;
  left: 50%;
  bottom: 30px;
  transform: translateX(-50%);
  z-index: 1001;
  display: flex;

  div {
    width: 62px;
    height: 62px;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    color: #ffffff;
    background: #1b2028;
    border-radius: 5px;
    margin: 0 10px;
    padding: 6px 0;
    border: 1px solid #ffffff;
    cursor: pointer;
    color: #ffffff;

    span {
      width: 100%;
      text-align: center;
      display: block;
      font-size: 14px;

      img {
        width: 20px;
        height: 20px;
        display: inline-block;
        ;
      }
    }
  }
}

.THREE-right-list {
  position: absolute;
  right: 13px;
  top: 8px;
  z-index: 1001;
  width: 320px;
  height: calc(100% - 18px);
  background: url('@/assets/navigation/sanwei.png') no-repeat;
  background-size: 100% 100%;
  background-color: #001b4a;

  .THREE-right-list-title {
    width: 100%;
    height: 50px;
    line-height: 50px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: #fff;
    font-size: 16px;
    font-weight: 700;
    padding: 10px 15px 0;
    margin-bottom: 10px;

    img {
      display: inline-block !important;
      margin-right: 20px;
      vertical-align: text-bottom;
    }
  }

  .THREE-right-list-main {
    width: 100%;
    padding: 10px 15px 0;

    .THREE-right-list-main-tab {
      width: 100%;
      display: flex;
      justify-content: space-between;
      margin: 10px 0;

      div {
        width: 30%;
        height: 30px;
        text-align: center;
        line-height: 30px;
        background: transparent;
        color: rgba(255, 255, 255, 0.498039215686275);
        border: 1px solid #225b7e;
        border-radius: 3px;
        cursor: pointer;
        font-size: 14px;
      }
    }

    .THREE-right-list-main-tab-hov {
      color: #009bff !important;
      border: 1px solid #009bff !important;
      background: rgba(0, 155, 255, 0.2) !important;
    }

    :deep(.el-input__wrapper) {
      height: 36px;
      line-height: 36px;
      // // box-shadow: none !important;
      border: 0px solid #046344;
      background-color: #ffffff00 !important;
    }

    :deep(input) {
      color: #fff !important;
    }

  }

  ul {
    width: 100%;
    margin-top: 10px;
    overflow: auto;
  }

  .THREE-right-list-main-li-hov {
    background: url('@/assets/3d/right_list_hov.png') no-repeat;
    color: #009bff !important;
    cursor: pointer;
  }

  li {
    width: 100%;
    height: 36px;
    line-height: 36px;
    padding: 0 20px;
    color: #fff;
    display: flex;
    font-size: 14px;
    justify-content: space-between;


    img {
      display: inline-block;
      vertical-align: text-bottom;
      margin-right: 6px;
    }

    &:hover {
      color: #009bff;
      // background: url('@/assets/3d/right_list_hov.png') no-repeat;
      background-size: 100% 100%;
    }
  }
}

.THREE-right-list-main-icon {
  img {
    width: 14px;
    height: 14px;
    margin: 0 5px;
    cursor: pointer;
  }
}

.THREE-button {
  position: absolute;
  top: 15px;
  width: 130px;
  height: 36px;
  background: url('@/assets/3d/an_d.png') no-repeat;
  background-size: 100% 100%;
  color: #009bff;
  border: none;
  z-index: 1001;

  :deep(.el-button.is-disabled, .el-button.is-disabled:focus, .el-button.is-disabled:hover) {
    color: #009bff !important;
    background: url('@/assets/3d/an_d.png') no-repeat !important;
    background-size: 100% 100% !important;
    border: none !important;
  }

  &:focus {
    color: #009bff;
    background: url('@/assets/3d/an_d.png') no-repeat;
    background-size: 100% 100%;
  }

  &:hover {
    border: none !important;
    background: url('@/assets/3d/an_d1.png') no-repeat;
    background-size: 100% 100%;
    color: #009bff;
  }
}

//按钮样式
.THREE-button1 {
  width: 110px;
  height: 34px;
  background: url('@/assets/3d/xsri_an.png') no-repeat;
  background-size: 100% 100%;
  color: #009bff;
  border: none;

  :deep(.el-button.is-disabled, .el-button.is-disabled:focus, .el-button.is-disabled:hover) {
    color: #009bff !important;
    background: url('@/assets/3d/xsri_an.png') no-repeat !important;
    background-size: 100% 100% !important;
    border: none !important;
  }

  &:focus {
    color: #009bff;
    background: url('@/assets/3d/xsri_an.png') no-repeat;
    background-size: 100% 100%;
  }

  &:hover {
    border: none !important;
    background: url('@/assets/3d/xsri_an1.png') no-repeat;
    background-size: 100% 100%;
    color: #009bff;
  }
}

//详细信息弹窗
.detailed-information {

  .examination {
    width: 406px;
    height: 330px;
    position: fixed;
    background: url(@/assets/3d/sxjxq.png) no-repeat;
    background-size: 100% 100%;
    padding: 0 25px 15px;


    .examination-title {
      margin-top: 20px;
      width: 100%;
      height: 40px;
      text-align: center;
      line-height: 40px;
      font-weight: 700;
      font-style: normal;
      font-size: 16px;
      color: #009bff;
      background: url(@/assets/3d/u714.png) no-repeat;
      background-size: 100% 100%;
    }

    .examination-close {
      position: absolute;
      top: 30px;
      right: 20px;
      cursor: pointer;
    }

    .examination-contont {
      color: #fff;
      font-size: 14px;

      .examination-contont-text {
        margin-top: 11px;
      }
    }
  }
}

.examine {
  .examination-title {
    width: 100%;
    height: 40px;
    text-align: center;
    line-height: 40px;
    font-weight: 700;
    font-style: normal;
    font-size: 18px;
    color: #FFFFFF;
    background-size: 100% 100%;
  }

  .examination-contont {
    color: #fff;
    font-size: 14px;

    .examination-contont-title {
      width: 100%;
      font-weight: 700;
      font-style: normal;
      font-size: 14px;
      color: #009bff;
    }

    .examine-contont-body-left-test {
      font-weight: 400;
      font-style: normal;
      font-size: 14px;
      color: #FFFFFF;
      margin-top: 10px;
      padding: 0 10px;
    }

    .examine-contont-body {
      width: 100%;
      height: 245px;
      display: flex;
      align-items: center;

      .examine-contont-body-left {
        width: 60%;
        // border: 1px solid red;

        .examine-contont-body-left-test {
          font-weight: 400;
          font-style: normal;
          font-size: 14px;
          color: #FFFFFF;
          margin-top: 10px;
        }
      }

      .examine-contont-body-right {
        width: 40%;
        position: relative;
        margin-top: -50px;

        .examine-contont-body-right-image {
          width: 26px;
          height: 26px;
          position: absolute;
          background-color: #0000007f;
          right: 8px;
          top: 8px;
          border-radius: 5px;
          display: flex;
          align-items: center;
          justify-content: center;
          cursor: pointer;
        }

        .examine-contont-body-right-img {
          width: 100%;
          height: 140px;
          object-fit: contain;
        }
      }
    }
  }
}

/* 用来设置当前页面element全局table 选中某行时的背景色*/
:deep(.el-table__body tr.current-row>td) {
  background-color: rgba(255, 255, 255, 0.2) !important;
}

:deep(.el-table__header-wrapper) {
  border-left: #009bff 3px solid;
  border-right: #009bff 3px solid;
}

:deep(.el-table__body-wrapper) {
  color: #fff;
}

:deep(.el-table) {
  --el-table-row-hover-bg-color: transparent !important;
  --el-table-border-color: transparent !important;
  --el-table-bg-color: transparent !important;
}

:deep(.el-table__empty-text) {
  color: #fff !important;
}

:deep(.el-input__inner) {
  color: #fff !important;
}

:deep(.el-date-editor .el-range-input) {
  color: #fff !important;
}

:deep(.is-background .el-pager li.is-active) {
  background: #009BFF !important;
  border: 1px solid #009BFF;
  color: #ffffff;
  font-weight: normal;
}

:deep(.el-tree) {
  background-color: transparent !important;
}

:deep(.el-tree-node.is-current>.el-tree-node__content) {
  width: 100%;
  height: 40px;
  color: #009bff !important;
  background: url('@/assets/3d/right_list_hov.png') no-repeat !important;
  background-size: 100% 100%;
}

:deep(.el-tree-node__content) {
  width: 100% !important;
  height: 40px !important;
  margin: auto !important;
  color: #ffffff !important;
  background-color: transparent !important;
}

//视频大小
.videoPopup {
  position: fixed;
  top: 150px;
  z-index: 100;
  width: 420px;
  // margin: auto;
  height: 236px;
  cursor: pointer;
  // margin: auto;
}

:deep(.el-textarea) {
  --el-input-bg-color: #ffffff00 !important;
  --el-input-border-color: #009bff2f !important;
  --el-input-text-color: #fff !important;
  --el-input-focus-border-color: #009bff2f !important;
}

:deep(.el-radio) {
  --el-radio-text-color: #ffffff !important;
}


#contextimg {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1001;
  display: none;
  color: #009bff;

  img {
    color: #009bff;
    width: 40px;
    height: 40px;
  }
}

#contextmenu {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1001;
  width: 180px;
  display: none;
  border-radius: 3px;
  background: url('@/assets/3d/wrccz.png') no-repeat;
  background-size: 100% 100%;
  padding: 10px 0;

  li {
    width: 100%;
    height: 32px;
    line-height: 32px;
    text-align: center;
    cursor: pointer;
    font-size: 14px;
    color: #ffffff;

    &:hover {
      color: #009bff;
      background: url('@/assets/3d/menu_hov.png') no-repeat;
      background-size: 100% 100%;
    }
  }
}

.searchButton1 {
  border: #009bff solid 1px !important;
  background-color: transparent !important;
  color: #fff !important;
  margin-left: 10px;
}

:deep(.el-button.is-disabled) {
  background-color: transparent !important;
  color: #fff !important;
  border-color: #009bff !important;
}

:deep(.el-input-number__decrease) {
  background-color: transparent !important;
}

:deep(.el-input-number__increase) {
  background-color: transparent !important;
}

:deep(.el-input-number.is-controls-right .el-input-number__increase) {
  border: transparent !important;
}

:deep(.el-input-number.is-controls-right .el-input-number__decrease) {
  border: transparent !important;
}

:deep(.el-input-number .el-icon) {
  color: #009bff91 !important;
}

:deep(.el-input-number .el-icon:hover) {
  color: #009bff !important;
}

:deep(.el-input__inner) {
  color: #fff !important;
}

:deep(.is-checked .el-radio__inner) {
  border-color: #009bff !important;
  background: #009bff !important;
}

:deep(.el-radio__inner) {
  border-color: #009bff !important;
  background: transparent !important;
}

:deep(.is-checked .el-radio__inner::after) {
  width: 6px;
  height: 6px;
  border-radius: var(--el-radio-input-border-radius);
  background-color: rgb(15, 51, 42);
}

:deep(.el-radio__input.is-checked + .el-radio__label) {
  color: #009bff !important;
}
</style>
