<template>
  <div class="page">
    <!-- 查询 -->
    <map-search
      v-if="getUserInfo"
      :sys-user-info="sysUserInfo"
      :type.sync="type"
      :show-resource-layers="false"
      :show-incidents="true"
      @search="onMapSearch"
      @clickEmployee="onClickEmployee"
      @clickRail="onClickRail"
      @clickStation="onClickStation"
      @clickPoi="onClickPoi"
      @clickCompany="clickCompany"
      @getStationsByType="onGetStationsByType"
      @clearMap="clearMap"
      @hideAllLayers="onHideAllLayers"
      ref="mapsearch"
    ></map-search>
    <!-- 地图 -->
    <a-map
      ref="map"
      class="map"
      :load-options="loadOptions"
      :map-options="mapOptions"
      :markers="markers"
      :cluster="cluster"
      :info-window-data="info"
      :layers="layers"
      :plugin="plugin"
      :move-marker="moveMarker"
      :move-along="moveAlong"
      :speed-ratio="speedRatio"
      @complete="onMapComplete"
      @clickMap="onClickMap"
      @clickMarker="onClickMarker"
      @emitMap="mapFn"
      @placeSearch="onPlaceSearch"
      @circleEditorChange="onCircleEditorChange"
      @polygonEditorChange="onPolygonEditorChange"
      @rectangleEditorChange="onRectangleEditorChange"
      @move="onMove"
      @draw="onDraw"
      @clickCluster="clickCluster"
    >
      <!-- 安保员弹框 -->
      <a-info-window :info-window-options="infoWindow.employee" :class-name="['info-window', 'info-window-employee']">
        <div class="infoWin security">
          <div class="header">
            <div class="photo">{{ info.nameSlice }}</div>
            {{ info.name }}({{ info.dutyStatusText }})
          </div>
          <div
            class="security-content marginBottom11"
            v-if="platform === '2' && info?.resourceTypes?.includes('ProprietorManaged') && !isCompany"
          >
            所属内保单位：
            <el-tooltip effect="dark" :content="info.proprietorCompanyName" placement="top">
              <span class="blue active" @click="clickCompany(info, 'employee', 'Proprietor')">{{
                info.proprietorCompanyNameSlice
              }}</span>
            </el-tooltip>
          </div>
          <div class="security-content marginBottom11">
            所属公司：
            <el-tooltip effect="dark" :content="info.companyName" placement="top">
              <span
                v-if="employeeTypeName === '保安员' && info.institutional !== '0104'"
                class="blue active"
                @click="clickCompany(info, 'employee')"
                >{{ info.companyNameSlice }}</span
              >
              <span v-if="employeeTypeName !== '保安员' || info.institutional === '0104'">{{
                info.companyNameSlice + (info.institutional === "0104" ? "/自招" : "")
              }}</span>
            </el-tooltip>
          </div>
          <div class="security-content marginBottom11" v-if="info.occupationType !== '保卫管理员'">
            所属{{ stationTypeName }}：
            <el-tooltip effect="dark" :content="info.securityStationName" placement="top">
              <span class="blue active" @click="clickStation(info, 'employee')">{{ info.securityStationNameSlice }}</span>
            </el-tooltip>
          </div>
          <div class="security-content marginBottom11">
            证件号码：{{ isIdCardNo ? info.idCardNo : "***************" }}
            <span class="hide-show" @click.stop="isIdCardNo = !isIdCardNo" v-if="isIdCardNo">隐藏</span>
            <span class="hide-show" @click.stop="isIdCardNo = !isIdCardNo" v-if="!isIdCardNo">显示</span>
          </div>
          <div class="security-content marginBottom11">
            联系方式：{{ isContact ? info.contact : "***********" }}
            <span class="hide-show" @click.stop="isContact = !isContact" v-if="isContact">隐藏</span>
            <span class="hide-show" @click.stop="isContact = !isContact" v-if="!isContact">显示</span>
          </div>

          <div
            v-if="employeeTypeName === '保安员' || info.occupationType === '保卫管理员'"
            class="security-content marginBottom11"
          >
            实名认证：{{ info.authenticatedStatusText }}
          </div>
          <div
            v-if="employeeTypeName === '保安员' || info.occupationType === '保卫管理员'"
            class="security-content marginBottom11"
          >
            持证情况：{{ info.certificateSituation }}
          </div>
          <!-- 人员类型 -->
          <div class="security-content marginBottom11" style="border-bottom: 1px solid #bdcfde">
            人员类型：{{ info.occupationType }}
          </div>
          <div class="security-content marginBottom11">指挥调度</div>
          <div class="security-content marginBottom11">
            <div
              class="info-window-btn"
              :class="{
                activeBtn: index === commandIndex,
                disabledBtn: info.dutyStatusText !== '在岗' && index !== 3,
              }"
              v-for="(item, index) in commandList.filter((command) => {
                if (command.value === 'ptt') {
                  return command.dispatchClient === 'wildfire';
                } else {
                  return true;
                }
              })"
              :key="index"
              @click="commandCk(index, item)"
            >
              {{ item.label }}
            </div>
          </div>
          <div class="security-content marginBottom11" style="border-top: 1px solid #bdcfde">轨迹服务</div>
          <div class="security-content marginBottom11">
            <div
              class="info-window-btn"
              v-for="(item, index) in trackList"
              :key="index"
              :class="{
                activeBtn: index === trackIndex,
                disabledBtn: info.dutyStatusText !== '在岗',
              }"
              @click="trackCk(index)"
            >
              {{ item.label }}
            </div>
          </div>
        </div>
      </a-info-window>
      <!-- 驻勤点弹框 -->
      <a-info-window :info-window-options="infoWindow.station" :class-name="['info-window', 'info-window-station']">
        <div class="infoWin">
          <div class="header-new">
            <img class="header-img" src="@/assets/images/mapSearch/驻勤点备份.png" alt="" />

            <div class="header-details">
              {{ info.name }}
              <div class="header-btn">
                <div class="btn" @click="railFun(info, 'station')">周边调度</div>
                <div class="btn" @click="openElectronic(info)">电子围栏</div>
              </div>
            </div>
          </div>
          <div v-if="info.returnWin === 'employee'">
            <span class="href-to" @click="onClickEmployee(info.returnDetail)">
              &lt;返回{{ resourceType === "Security" ? "保安员" : "社会力量" }}信息
            </span>
          </div>
          <div v-if="info.returnWin === 'companyStations'">
            <span class="href-to" @click="clickCompanyStations(info, 'back')"> &lt;返回驻勤点列表 </span>
          </div>
          <div class="content-new" v-if="!info?.resourceTypes?.includes('ProprietorManaged')">
            <div class="content-new-label">公司名称：</div>
            <el-tooltip effect="dark" :content="info.companyName" placement="top">
              <div v-if="resourceType === 'Security'" class="content-new-value active" @click="clickCompany(info, 'station')">
                {{ info.companyNameSlice }}
              </div>
              <div v-if="resourceType === 'Population'">
                {{ info.companyNameSlice }}
              </div>
            </el-tooltip>
          </div>
          <div class="content-new">
            <div class="content-new-label">负责人员：</div>
            <div class="content-new-value">{{ info.principalName }}</div>
          </div>
          <div class="content-new">
            <div class="content-new-label">联系方式：</div>
            <div class="content-new-value">
              {{ isPhone ? info.principalContact : "***********" }}
              <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="isPhone">隐藏</span>
              <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="!isPhone">显示</span>
            </div>
          </div>
          <div class="content-new" v-if="resourceType === 'Security'">
            <div class="content-new-label">服务对象名称：</div>
            <div class="content-new-value">{{ info.serviceScope }}</div>
          </div>
          <!-- 区别驻勤点、社区警务 -->
          <div class="content-new">
            <div class="content-new-label">{{ stationTypeName }}监管机构：</div>
            <el-tooltip effect="dark" :content="info.superviseDepartName" placement="top">
              <div class="content-new-value">
                {{ info.superviseDepartNameSlice }}
              </div>
            </el-tooltip>
          </div>
          <div class="content-new">
            <div class="content-new-label">{{ stationTypeName }}地址：</div>
            <el-tooltip effect="dark" :content="info.address" placement="top">
              <div class="content-new-value">{{ info.addressSlice }}</div>
            </el-tooltip>
          </div>
          <div class="content-new">
            <div class="content-new-label">{{ stationTypeName }}人数：</div>
            <div class="content-new-value active" @click="clickStationEmployees(info, 'station')">
              {{ resourceType === "Security" ? info.countOfSecurityMan : info.countOfCommunityUser }}
            </div>
          </div>
          <div class="content-new" v-if="resourceType === 'Security'">
            <div class="content-new-label">驻勤点类型：</div>
            <div class="content-new-value">
              {{ info.stationTypes && info.stationTypes.length > 0 ? info.stationTypes[0].name : "" }}
            </div>
          </div>
        </div>
      </a-info-window>
      <!-- 公司弹框 -->
      <a-info-window :info-window-options="infoWindow.company" :class-name="['info-window', 'info-window-company']">
        <div class="infoWin">
          <div class="header-new">
            <img
              class="header-img"
              :src="
                this.platform === '2' && info?.resourceTypes?.includes('Proprietor')
                  ? require('@/assets/images/mapSearch/内保单位.png')
                  : require('@/assets/images/mapSearch/搜地址.png')
              "
              alt=""
            />{{ info.name }}
          </div>
          <div v-if="info.returnWin === 'station'" class="back" @click="onClickStation(info.returnDetail, 'station')">
            &lt; 返回驻勤点信息
          </div>
          <div v-if="info.returnWin === 'employee'">
            <span class="href-to" @click="onClickEmployee(info.returnDetail)"> &lt; 返回保安员信息 </span>
          </div>

          <div class="content-new">
            <div class="content-new-label">
              {{ this.platform === "2" && info?.resourceTypes?.includes("Proprietor") ? "负责人员" : "法定代表人" }}：
            </div>
            <div class="content-new-value">{{ info.legal }}</div>
          </div>
          <div class="content-new">
            <div class="content-new-label">联系方式：</div>
            <div class="content-new-value">
              {{ isPhone ? info.legalContact : "***********" }}
              <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="isPhone">隐藏</span>
              <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="!isPhone">显示</span>
            </div>
          </div>
          <div class="content-new">
            <div class="content-new-label">
              {{ this.platform === "2" && info?.resourceTypes?.includes("Proprietor") ? "内保单位地址" : "注册地址" }}：
            </div>
            <el-tooltip effect="dark" :content="info.registerAddress" placement="top">
              <div class="content-new-value">
                {{ info.registerAddressSlice }}
              </div>
            </el-tooltip>
          </div>
          <div class="content-new" v-if="this.platform === '2' && info?.resourceTypes?.includes('Proprietor')">
            <div class="content-new-label">内保单位监督机构：</div>
            <div class="content-new-value">{{ info.superviseDepartName }}</div>
          </div>
          <div class="content-new" v-if="this.platform === '2' && info?.resourceTypes?.includes('Proprietor')">
            <div class="content-new-label">驻勤点个数：</div>
            <div class="content-new-value active" @click="clickCompanyStations(info, 'company')">
              {{ info.countOfActivityStation }}
            </div>
          </div>
          <div class="content-new" v-if="this.platform === '1'">
            <div class="content-new-label">保安员数：</div>
            <div class="content-new-value">{{ info.countOfSecurityMan }}</div>
          </div>
          <div class="content-new" v-if="this.platform === '2' && info?.resourceTypes?.includes('Proprietor')">
            <div class="content-new-label">内保单位类型：</div>
            <div class="content-new-value">
              {{ info.institutionalName }}
            </div>
          </div>
          <div class="content-new" v-if="this.platform === '2' && info?.resourceTypes?.includes('Proprietor')">
            <div class="content-new-label">保卫管理员人数：</div>
            <div class="content-new-value">
              {{ info.countOfMan }}
            </div>
          </div>
        </div>
      </a-info-window>
      <!-- 驻勤点安保员弹框 -->
      <a-info-window
        :info-window-options="infoWindow.stationEmployees"
        :class-name="['info-window', 'info-window-stationEmployees']"
      >
        <div class="infoWin">
          <div class="header-new">
            <img class="header-img" src="@/assets/images/mapSearch/驻勤点备份.png" alt="" />{{ info.name }}
          </div>
          <div v-if="info.returnWin === 'station'" class="back-station" @click="onClickStation(info.returnDetail)">
            &lt; 返回{{ resourceType === "Security" ? "保安员" : "社会力量" }}信息
          </div>

          <div class="info-window-stationEmployees-people">
            <div v-for="item in info.stationEmployees" :key="item.id" style="border-bottom: 1px solid #bdcfde; margin-top: 16px">
              <div class="circle-style">{{ item.name }}</div>

              <div class="circle-detail">
                <div class="detail-item">{{ item.name }} <span v-if="item.stationResponsible">（负责人）</span></div>
                <div class="detail-item">
                  <div class="detail-item-label">联系方式：</div>
                  <div class="detail-item-value">
                    {{ item.isPhone ? item.contact : "***********" }}
                  </div>
                  <span class="hide-show" @click="setItemPhoneVisible(item)">
                    {{ item.isPhone ? "隐藏" : "显示" }}
                  </span>
                </div>
                <div class="detail-item">
                  <div class="detail-item-label">在岗情况：</div>
                  <div class="detail-item-value">{{ item.dutyStatusText }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </a-info-window>
      <!-- 内保单位驻勤点弹框 -->
      <a-info-window
        :info-window-options="infoWindow.companyStations"
        :class-name="['info-window', 'info-window-companyStations']"
      >
        <div class="infoWin">
          <div class="header-new">
            <img class="header-img" src="@/assets/images/mapSearch/内保单位.png" alt="" />{{ info.companyName }}
          </div>
          <div class="back-station" @click="clickCompany(info, 'companyStations')">&lt; 返回内保单位信息</div>
          <div class="info-window-companyStations-station">
            <div v-for="item in info.companyStations" :key="item.id" style="border-bottom: 1px solid #bdcfde; margin-top: 16px">
              <div style="float: left">
                <img style="width: 45px; height: 45px" src="@/assets/images/mapSearch/驻勤点备份.png" alt="" />
              </div>

              <div class="circle-detail" style="cursor: pointer" @click="clickStation(item, 'companyStations')">
                <div class="detail-item">{{ item.name }}</div>
                <div class="detail-item">
                  <div class="detail-item-label">负责人员：</div>
                  <div class="detail-item-value">{{ item.principalName }}</div>
                </div>
                <div class="detail-item">
                  <div class="detail-item-label">联系方式：</div>
                  <div class="detail-item-value">
                    {{ item.isPhone ? item.principalContact : "***********" }}
                  </div>
                  <span class="hide-show" @click="setItemPhoneVisible(item)">
                    {{ item.isPhone ? "隐藏" : "显示" }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </a-info-window>
      <!-- 地点弹框 -->
      <a-info-window :info-window-options="infoWindow.location" :class-name="['info-window', 'info-window-location']">
        <div class="address-header">{{ info.name }}</div>
        <div class="address-item">
          <div class="address-label">联系地址：</div>
          <div class="address-value">{{ info.address }}</div>
        </div>
        <div class="address-item">
          <div class="address-label">联系电话：</div>
          <div class="address-value">
            {{ isPhone ? info.tel : "***********" }}
            <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="isPhone">隐藏</span>
            <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="!isPhone">显示</span>
          </div>
        </div>
        <div class="address-btn">
          <div class="btn" @click="railFun(info, 'location')">周边搜索</div>
        </div>
      </a-info-window>
      <!-- 周边调度弹框 -->
      <a-info-window :info-window-options="infoWindow.rail" :class-name="['info-window', 'info-window-rail']">
        <div class="infoWin">
          <div class="rail-item">
            <div class="rail-label">事件类别：</div>
            <div class="rail-value">{{ info.name }}</div>
          </div>
          <div class="rail-item">
            <div class="rail-label">报警人员：</div>
            <div class="rail-value">{{ info.empName }}</div>
          </div>
          <div class="rail-footer">
            <div class="footer-label">周边搜索范围</div>
            <el-select v-model="value" placeholder="请选择" class="footer-select" size="mini" @change="drawCircle(info)">
              <el-option v-for="item in distanceList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
            </el-select>
            <div class="btn" @click="railCk">周边调度</div>
          </div>
        </div>
      </a-info-window>
      <a-info-window :info-window-options="infoWindow.railTwo" :class-name="['info-window', 'info-window-railTwo']">
        <div class="infoWin">
          <div v-if="info.type === 'station'">
            <span class="back-to" @click="showInfoByRowClick(rail, 'station')"> &lt; 返回</span>
          </div>
          <div v-if="info.type === 'location'">
            <span class="back-to" @click="showInfoByRowClick(rail, 'location')"> &lt; 返回</span>
          </div>
          <div v-if="info.type === 'employee'">
            <span class="back-to" @click="showInfoByRowClick(rail, 'employee')"> &lt; 返回</span>
          </div>
          <div class="rail-footer noborder-Top">
            <div class="footer-label">周边搜索范围</div>
            <el-select v-model="value" placeholder="请选择" class="footer-select" size="mini" @change="drawCircle(info)">
              <el-option v-for="item in distanceList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
            </el-select>
            <div class="btn" @click="railCk">周边调度</div>
          </div>
        </div>
      </a-info-window>
      <!-- 多人调度窗口 -->
      <a-info-window
        :info-window-options="infoWindow.railSecurity"
        :class-name="['info-window', 'info-window-railSecurity']"
        @close="onDispatchWindowClose"
      >
        <div>
          <el-button type="primary" plain size="mini"> 全部 </el-button>
        </div>
        <div class="scroll">
          <div
            class="scroll-item"
            v-for="(item, index) in stationEmployeesList"
            :class="['scroll-item-' + item.dutyStatus]"
            :key="index"
            @click="selectCk(index, item)"
          >
            <div class="scroll-photo">{{ item.nameSlice }}</div>
            <div class="scroll-detail">
              <div>
                <div class="detail-item">{{ item.name }}</div>
                <div class="detail-item">
                  <div class="label">所属公司:</div>
                  <div class="value">{{ item.companyName }}</div>
                </div>
                <div class="detail-item">
                  <div class="label">所属{{ item?.rts.includes("Security") ? "驻勤点" : "社会力量" }}:</div>
                  <div class="value">{{ item.securityStationName }}</div>
                </div>
                <div class="detail-item">
                  <div class="label">联系方式:</div>
                  <div class="value">
                    {{ isPhone ? item.contact : "***********" }}
                    <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="isPhone">隐藏</span>
                    <span class="hide-show" @click.stop="isPhone = !isPhone" v-if="!isPhone">显示</span>
                  </div>
                </div>
                <div class="detail-item">
                  <div class="label">证件号码:</div>
                  <div class="value">
                    {{ isIdCardNo ? item.idCardNo : "***************" }}
                    <span class="hide-show" @click.stop="isIdCardNo = !isIdCardNo" v-if="isIdCardNo">隐藏</span>
                    <span class="hide-show" @click.stop="isIdCardNo = !isIdCardNo" v-if="!isIdCardNo">显示</span>
                  </div>
                </div>
              </div>
              <div class="no-select" v-if="!item.active"></div>
              <img src="@/assets/images/mapSearch/勾选.png" alt="" class="gx" v-if="item.active" />
            </div>
          </div>
        </div>
        <div class="scroll-footer">
          <div class="footer-total">
            一共选中<span>{{ allMembers.filter((x) => x.active).length }}</span
            >人
          </div>
          <div class="footer-btn">
            <div class="btn" @click="openGroupFormDialog">文字调度</div>
            <div class="btn" @click="openGroupCall('audio')">语音调度</div>
            <div class="btn" @click="openGroupCall('video')">视频调度</div>
            <div class="btn" @click="openGroupCall('videoLocalMute')">视频上拉</div>
            <div class="btn" @click="openPPTCall">对接</div>
          </div>
        </div>
      </a-info-window>
      <!-- SOS -->
      <a-info-window
        :info-window-options="infoWindow.SOS"
        :class-name="['info-window', 'info-window-sos']"
        @click="openCallBySOS"
      >
        <div class="content">
          <span class="name">{{ info.name }}</span>
          <span class="ellipse" :title="info.content">{{ info.content }}</span>
        </div>
      </a-info-window>
    </a-map>
    <!-- 工具栏 -->
    <map-toolbar
      :show-list="mapToolList"
      @changeLayer="changeLayer"
      @fence="setFence"
      @video="setVideo"
      @preview="setPreview"
      @broadcast="setBroadcast"
      @circle="setCircle"
      @square="setSquare"
      @polygon="setPolygon"
      @traffic="setTraffic"
      @star="setStar"
      @measure="setMeasure"
      @chair="setChair"
      @history="setHistory"
      @clearMap="clearMap"
      @hideAllLayers="onHideAllLayers"
      @hideAllList="hideAllList"
    ></map-toolbar>
    <trajectory-dialog
      v-if="isTrajectoryDialog"
      ref="trajectory"
      :info="info"
      :map="map"
      @cancel="trajectoryCancel"
      @setTrack="onSetTrack"
      @refresh="onRefresh"
      @startMove="onStartMove"
      @stopMove="onStopMove"
      @pauseMove="onPauseMove"
      @backStep="onBackStep"
      @nextStep="onNextStep"
    ></trajectory-dialog>
    <electronic-fence-dialog
      ref="electronicFence"
      v-if="isElectronicFenceDialog"
      @cancel="electronicFenceCancel"
      @addElectronic="addElectronic"
      @electronicFenceEdit="electronicFenceEditFn"
      :info="info"
      @del="delElectronic"
    ></electronic-fence-dialog>
    <electronic-fence-edit-dialog
      ref="electronicFenceEdit"
      v-show="isElectronicFenceEditDialog"
      :info="info"
      :electronic-fence-info="electronicFenceInfo"
      @openPeopleNum="openPeopleNumFn"
      @cancel="electronicFenceEditCancel"
      :map="map"
      @clearMap="clearMap"
      @back="showElectronic"
    >
    </electronic-fence-edit-dialog>
    <electronic-fence-people
      v-if="isElectronicFencePeople"
      :list="electronicFencePeopleList"
      :station-name="info.name"
      @cancel="electronicFencePeopleCancel"
    >
    </electronic-fence-people>
    <el-dialog width="680px" custom-class="group-form" :visible.sync="groupFormDialogVisible" title="文字调度">
      <el-row class="memberList">
        <el-col v-for="(item, index) in form.memberList" :key="index" :span="3" class="member-item">
          <el-avatar :size="50" :src="item.avatar" @error="handleImgError">
            <div class="avatar">{{ item.nameSlice }}</div>
          </el-avatar>
          <span class="nick">{{ item.name }}</span>
        </el-col>
      </el-row>
      <div class="content">
        <div class="notice">注意：请确保所有人员都已经完成基础信息初始化，否则该人员无法成功加入群组</div>
        <div class="dispatch-content">
          <h2>文字调度</h2>
          <el-form :model="form" :rules="rules" ref="ruleForm" label-width="100px">
            <el-form-item label="调度事由" prop="name">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="调度任务内容" prop="schedulingContent">
              <el-input type="textarea" v-model="form.schedulingContent"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button @click="cancelDispatch('ruleForm')">取消调度</el-button>
              <el-button type="primary" @click="startDispatch('ruleForm')">开始调度</el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>
    </el-dialog>
    <!-- 图片预览 -->
    <image-previewer></image-previewer>
    <transition name="slide-fade">
      <!-- 调度窗口 -->
      <div v-show="railDispatchShow" class="rail-dispatch" v-drag>
        <div class="header">
          <div>
            <el-button type="primary" size="mini" @click="clickAllDuty()">全部</el-button>
            <el-button type="primary" size="mini" @click="clickOnDuty()">在岗</el-button>
            <el-button type="primary" size="mini" @click="clickNoDuty()">离岗</el-button>
            <el-checkbox
              v-if="showDutyCheckbox"
              v-model="dutyCheckAll"
              :indeterminate="isIndeterminate"
              style="padding-left: 300px"
              @change="onCheckDuty"
              >全选</el-checkbox
            >
          </div>

          <i class="el-icon-close" @click="onRailDispatchClose"></i>
        </div>
        <div class="scroll">
          <div
            v-for="(item, index) in stationEmployeesListFilter"
            class="scroll-item"
            :class="['scroll-item-' + item.dutyStatus]"
            :key="item.id"
            @click="selectCk(index, item)"
          >
            <div class="scroll-photo">
              <div class="scroll-photo-name">{{ item.nameSlice }}</div>
              <div class="scroll-photo-checkbox">
                <!--                <el-checkbox v-model="item.active" @change="changesStationEmployeesActive(index)"></el-checkbox>-->
                <div class="no-select" v-if="!item.active"></div>
                <img src="@/assets/images/mapSearch/勾选.png" alt="" class="gx" v-if="item.active" />
                <!-- <div class="no-select" v-if="!item.active"></div>
                <div class="gx" v-if="item.active"></div> -->
                <!-- <img
                  src="@/assets/images/mapSearch/勾选.png"
                  alt=""
                  class="gx"
                  v-if="item.active"
                /> -->
              </div>
            </div>
            <div class="scroll-detail">
              <div class="detail-box">
                <div class="detail-item">{{ item.name }}({{ item.dutyStatusText }})</div>
                <div class="detail-item">
                  <div class="label">所属公司:</div>
                  <el-tooltip effect="dark" :content="item.companyName" placement="top">
                    <div class="value">{{ item.companyNameSlice }}</div>
                  </el-tooltip>
                </div>
                <div class="detail-item">
                  <div class="label">所属{{ item.rts.includes("Security") ? "驻勤点" : "社会力量" }}:</div>
                  <el-tooltip effect="dark" :content="item.securityStationName" placement="top">
                    <div class="value">{{ item.securityStationNameSlice }}</div>
                  </el-tooltip>
                </div>
                <div class="detail-item">
                  <div class="label">联系方式:</div>
                  <div class="value">
                    {{ item.isPhone ? item.contact : "***********" }}
                    <span class="hide-show" @click.stop="changeStationIsPhone(index)" v-if="item.isPhone">隐藏</span>
                    <span class="hide-show" @click.stop="changeStationIsPhone(index)" v-if="!item.isPhone">显示</span>
                  </div>
                </div>
                <div class="detail-item">
                  <div class="label">证件号码:</div>
                  <div class="value">
                    {{ item.isIdCardNo ? item.idCardNo : "***************" }}
                    <span class="hide-show" @click.stop="changeStationIsIdCardNo(index)" v-if="item.isIdCardNo">隐藏</span>
                    <span class="hide-show" @click.stop="changeStationIsIdCardNo(index)" v-if="!item.isIdCardNo">显示</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="scroll-footer">
          <div class="footer-total">
            一共选中
            <span>{{ allMembers.filter((x) => x.active).length }}</span>
            人
          </div>
          <div class="footer-btn">
            <div class="btn" @click="openGroupFormDialog">文字调度</div>
            <div class="btn" @click="openGroupCall('audio')">语音调度</div>
            <div class="btn" @click="openGroupCall('video')">视频调度</div>
            <div class="btn" @click="openGroupCall('videoLocalMute')">视频上拉</div>
            <div v-if="dispatchClient === 'wildfire'" class="btn" @click="openPPTCall">对讲</div>
          </div>
        </div>
      </div>
    </transition>
    <!-- 野火IM -->
    <wf-client v-if="dispatchClient === 'wildfire'" :visible.sync="conversationVisible" :single="isSingle"></wf-client>
    <!-- TIM即时通信 -->
    <current-conversation
      v-if="conversationVisible && dispatchClient === 'tencent'"
      :is-complete="isComplete"
      :default-message.sync="defaultMessage"
      @close="onCloseConversation"
    ></current-conversation>
    <!-- 野火音视频 -->
    <div
      v-if="!sharedMiscState.isElectron && voipProxy.callId && dispatchClient === 'wildfire'"
      class="voip-div-container"
      v-draggable
      v-bind:class="{
        single: voipProxy.type === 'single',
        multi: voipProxy.type === 'multi',
        conference: voipProxy.type === 'conference',
      }"
    >
      <Single v-if="voipProxy.type === 'single'" ref="handle-id" />
      <Multi v-if="voipProxy.type === 'multi'" ref="handle-id" />
      <Conference
        v-if="voipProxy.type === 'conference'"
        ref="handle-id"
        :member-list.sync="memberList"
        :all-members="allMembers"
        :is-single="isSingle"
        :call-type="callType"
        @participantJoined="participantJoined"
        @participantLeft="participantLeft"
        @hangup="onHangup"
      />
    </div>
    <!-- TRTC音视频 -->
    <call-layer
      v-if="dispatchClient === 'tencent'"
      ref="callLayer"
      :member-list.sync="memberList"
      :all-members.sync="allMembers"
      :type="callType"
      :yardman-type="yardmanType"
      :audio="stream.audio"
      :video="stream.video"
      @kickOut="onKickOut"
    ></call-layer>
    <!-- 野火对讲弹框 -->
    <el-dialog :visible.sync="pttVisible" custom-class="ptt-dialog" title="对讲" width="476px" :show-close="false">
      <ptt-client ref="pttClient" :conversationInfo="conversationInfo.currentConversationInfo" @close="closePTT"></ptt-client>
    </el-dialog>
  </div>
</template>

<script>
import { AMap, AInfoWindow } from "@/components/AMap";
import mapSearch from "@/components/mapSearch/index.vue";
import mapToolbar from "@/components/mapToolbar/index.vue";
import { getCompanyDetail } from "@/api/company-controller";
import { getEmployees, getEmployeeDetail } from "@/api/employee-controller";
import electronicFenceDialog from "./components/electronicFence.vue";
import electronicFenceEditDialog from "./components/electronicFenceEdit.vue";
import electronicFencePeople from "./components/electronicFencePeople.vue";
import { mapState, mapGetters } from "vuex";
import { getAllStationTypes, getStationDetail, getStations } from "@/api/security-station-controller";
import trajectoryDialog from "./components/trajectory.vue";
import tim from "@/tim";
import imagePreviewer from "@/components/timApp/message/image-previewer.vue";
import { deleteRail } from "@/api/security-station-rails-controller";
import _webSocket from "@/utils/websocket";
import { textSlice } from "@/api/common";
import { handleDebounce } from "@/utils";
import _ from "lodash";
import { getCurrentUser } from "@/api/tenant-user-controller";
import wfClient from "@/ui/main/HomePage.vue";
import appServerApi from "@/api/appServerApi";
import { removeItem, setItem } from "@/ui/util/storageHelper";
import wfc from "@/wfc/client/wfc";
import store from "@/store.js";
import im from "@/utils/im";
import { createJoinAndInviteConference } from "@/utils/wfc";
import Single from "@/ui/voip/Single.vue";
import Multi from "@/ui/voip/Multi.vue";
import Conference from "@/ui/voip/conference/Conference.vue";
import avenginekit from "@/wfc/av/internal/engine.min";
import avenginekitproxy from "@/wfc/av/engine/avenginekitproxy";
import { isElectron } from "@/platform";
import { Draggable } from "draggable-vue-directive";
import EventType from "@/wfc/client/wfcEvent";
import ConnectionStatus from "@/wfc/client/connectionStatus";
import pttClient from "@/ui/ptt/pttClient.vue";
import currentConversation from "@/components/timApp/conversation/current-conversation.vue";
import CallLayer from "@/components/timApp/trtc/calling-index.vue";

var avenginkitSetuped = false;

export default {
  name: "dispatch",
  components: {
    AMap,
    AInfoWindow,
    mapSearch,
    mapToolbar,
    trajectoryDialog,
    electronicFenceDialog,
    electronicFenceEditDialog,
    electronicFencePeople,
    imagePreviewer,
    wfClient,
    Conference,
    Multi,
    Single,
    pttClient,
    currentConversation,
    CallLayer,
  },
  data() {
    return {
      platform: localStorage.getItem("platform") || "1",
      deskTypes: localStorage.getItem("platform") === "1" ? ["Normal"] : ["Proprietor"],
      isCompany: false,
      supportConference: avenginekit.startConference !== undefined,
      voipProxy: avenginekitproxy,
      mapToolList: ["tile", "media", "draw", "tools", "more", "history"],
      mapToolDisableList: [],
      isElectronicFencePeople: false,
      electronicFencePeopleList: [],
      isElectronicFenceEditDialog: false,
      map: null,
      AMap: null,
      isComplete: false,
      conversationVisible: false,
      isTrajectoryDialog: false,
      isElectronicFenceDialog: false,
      railDispatchShow: false,
      value: 0,
      distanceList: [
        { label: "请选择", value: 0 },
        { label: "100米", value: 100 },
        { label: "300米", value: 300 },
        { label: "500米", value: 500 },
      ],
      loadOptions: {
        version: "2.0",
      },
      mapOptions: {
        viewMode: "3D", //是否为3D地图模式
        pitchEnable: true,
        rotateEnable: true,
      },
      markers: [],
      infoWindow: {
        employee: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        station: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        company: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        location: {
          anchor: "bottom-center",
          offset: [0, -60],
          position: undefined,
          autoMove: false,
        },
        stationEmployees: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        companyStations: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        rail: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        railTwo: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        railSecurity: {
          anchor: "bottom-center",
          offset: [0, -56],
          position: undefined,
          autoMove: false,
        },
        track: {
          anchor: "bottom-center",
          offset: [0, 0],
          position: undefined,
          autoMove: false,
        },
        SOS: {
          isCustom: true,
          anchor: "bottom-center",
          offset: [0, -46],
          position: undefined,
          autoMove: false,
          info: {
            name: "",
            content: "",
          },
        },
      },
      info: {
        resourceTypes: [],
      },
      layers: [{ type: "default" }],
      plugin: ["AMap.MouseTool", "AMap.PlaceSearch"],
      moveMarker: {
        icon: require("@/assets/images/mapSearch/在岗_保安员.png"),
        anchor: "bottom-center",
      },
      moveAlong: {
        autoRotation: false,
      },
      type: 1,
      infoType: "",
      stationTypes: [],
      isIdCardNo: false,
      isContact: false,
      commandList: [
        { label: "文字", value: "character" },
        { label: "语音", value: "audio" },
        { label: "视频调度", value: "video" },
        { label: "周边调度", value: "rail" },
        { label: "视频上拉", value: "videoLocalMute" },
        { label: "对讲", value: "ptt", dispatchClient: this.dispatchClient },
      ], //指挥调度
      commandIndex: undefined,
      trackList: [
        { label: "轨迹查询", value: "" },
        // { label: "轨迹上拉", value: "" },
      ], //轨迹服务
      trackIndex: undefined,
      companyDetail: false,
      isPhone: false,
      rail: {},
      employee: {},
      stationEmployeesListType: "all", // all,on,off
      stationEmployeesList: [],
      stationEmployeesListFilter: [],
      totalNum: 0,
      previous: 0,
      nextPage: 4,
      // tim创建群聊表单
      groupFormDialogVisible: false,
      memberList: [],
      allMembers: [],
      stream: {
        audio: true,
        video: true,
      },
      //调度类型：1视频调度 2 视频上拉：除了视频上拉传2，其他音频调度与视频调度都传1
      yardmanType: "1",
      callType: "video",
      form: {
        groupID: "",
        name: "",
        schedulingContent: "",
        type: this.TIM.TYPES.GRP_WORK,
        introduction: "",
        notification: "",
        joinOption: "FreeAccess",
        memberList: [],
      },
      rules: {
        name: [{ required: true, message: "请输入调度事由", trigger: "blur" }],
        schedulingContent: [{ required: true, message: "请输入调度事由", trigger: "blur" }],
      },
      isImgError: false,
      stationForRail: {},
      electronicFenceInfo: {},
      delElectronicIndex: null,
      circleFigure: null,
      circleEditorObject: null,
      rectangleFigure: null,
      rectangleEditor: null,
      polygonFigure: null,
      polygonEditor: null,
      // sect.slice(0, 2)
      movePath: [],
      moveStatus: "",
      speedRatio: 1,
      ws: null,
      showStationEmployees: false,
      levelNameList: [
        //警情上报强提醒，弱提醒
        {
          label: "特别重大",
          level: "Greats",
          bgColor: "#A80000",
          index: 0,
        },
        {
          label: "重大",
          level: "Great",
          bgColor: "#F48200",
          index: 1,
        },
        {
          label: "较大",
          level: "More",
          bgColor: "#F7BE00",
          index: 2,
        },
        {
          label: "一般",
          level: "Comon",
          bgColor: "#00B40C",
          index: 3,
        },
      ],
      TRTCActionMap: {},
      showDutyCheckbox: false, //点击在岗时候显示
      isIndeterminate: false,
      dutyCheckAll: false,
      cluster: {},
      stationTypeNameMap: {
        Security: "驻勤点",
        Population: "社区警务",
      },
      employeeTypeNameMap: {
        Proprietor: "保卫管理员",
        Security: "保安员",
        Population: "社会力量",
      },
      sharedMiscState: store.state.misc,
      conversationInfo: store.state.conversation,
      pttVisible: false,
      isSingle: false,
    };
  },
  computed: {
    ...mapState({
      currentConversation: (state) => state.conversation.currentConversation,
      currentMessageList: (state) => state.conversation.currentMessageList,
      dispatching: (state) => state.video.dispatching,
      appLoadingMask: (state) => state.appLoadingMask,
      roomId: (state) => state.trtc.roomId,
    }),
    ...mapGetters(["toAccount", "currentConversationType", "sysUserInfo", "dispatchClient"]),
    getUserInfo() {
      return this.sysUserInfo && Object.keys(this.sysUserInfo).length > 0;
    },
    profile() {
      return this.currentConversation.type === this.TIM.TYPES.CONV_C2C
        ? this.currentConversation.userProfile
        : this.currentConversation.groupProfile;
    },
    defaultMessage: {
      get() {
        return this.currentConversation.type === this.TIM.TYPES.CONV_C2C ? "" : this.form.schedulingContent;
      },
      set(value) {
        this.form.schedulingContent = value;
      },
    },
    stationTypeName() {
      const { resourceTypes } = this.info;
      if (resourceTypes) {
        if (resourceTypes.includes("Security")) {
          return this.stationTypeNameMap["Security"];
        } else {
          return this.stationTypeNameMap["Population"];
        }
      } else {
        return "";
      }
    },
    employeeTypeName() {
      const { resourceTypes } = this.info;
      if (resourceTypes) {
        if (resourceTypes.includes("Security")) {
          return this.employeeTypeNameMap["Security"];
        } else if (resourceTypes.includes("Proprietor")) {
          return this.employeeTypeNameMap["Proprietor"];
        } else {
          return this.employeeTypeNameMap["Population"];
        }
      } else {
        return "";
      }
    },
    resourceType() {
      if (Object.prototype.hasOwnProperty.call(this.info, "resourceTypes")) {
        if (this.info.resourceTypes.length === 2) {
          return "Security";
        } else {
          return this.info.resourceTypes[0];
        }
      } else {
        return "";
      }
    },
  },
  directives: {
    Draggable,
  },
  watch: {
    stationEmployeesListType(val) {
      switch (val) {
        case "all":
          this.stationEmployeesListFilter = this.stationEmployeesList;
          break;
        case "on":
          this.stationEmployeesListFilter = this.stationEmployeesList.filter((x) => x.dutyStatus === "SignIn");
          break;
        case "off":
          this.stationEmployeesListFilter = this.stationEmployeesList.filter((x) => x.dutyStatus !== "SignIn");
          break;
      }
    },
  },
  methods: {
    async loginWithAuthCode() {
      this.loginStatus = 3;
      appServerApi
        .loginWithAuthCode(1891929349, 66666)
        .then((res) => {
          const { userId, token, portrait } = res;
          this.firstTimeConnect = wfc.connect(userId, token);
          setItem("wfcUserId", userId);
          setItem("wfcToken", token);
          setItem("userPortrait", portrait);
        })
        .catch((err) => {
          this.authCode = "";
          this.loginStatus = 0;
          this.$notify({
            title: "登录失败",
            text: err.message,
            type: "error",
          });
        });
    },
    onKickOut(id) {
      // allMembers将移除的人active设为false
      this.allMembers.forEach((member) => {
        if (member.tencentUserId === id) {
          member.active = false;
        }
      });
    },
    handleDebounce(func, wait) {
      handleDebounce(func, wait);
    },
    /**
     * @周边调度画圆
     */
    drawCircle(info) {
      console.log("drawCircle", info);
      const coordinates = [info.longitude, info.latitude];
      this.$refs.map.drawCircle(coordinates, this.value);
    },
    /**
     * @隐藏所有弹框
     */
    onHideAllLayers() {
      this.railDispatchShow = false;
      this.isTrajectoryDialog = false;
      this.isElectronicFenceDialog = false;
      this.isElectronicFenceEditDialog = false;
    },
    /**
     * @mapsearch页面隐藏列表
     */
    hideAllList() {
      this.$refs.mapsearch.hideAllList();
    },
    /**
     * @编辑某条电子围栏
     * @param data
     */
    electronicFenceEditFn({ data }) {
      console.log("编辑某条电子围栏", data);
      // this.map.clearMap();
      this.isElectronicFenceEditDialog = true;
      this.isElectronicFenceDialog = false;
      this.electronicFenceInfo = JSON.parse(JSON.stringify(data));
      this.electronicFenceInfo.time = [this.electronicFenceInfo.beginTime, this.electronicFenceInfo.endTime];
      // 显示可编辑围栏区域
      // this.showMapEditor(data);
    },
    /**
     * @是否有人在编辑范围内
     * @param target
     */
    setContain(target) {
      console.log("setContain", this.markers);
      console.log("setContain", this.cluster.dataOptions);
      const isContain = this.cluster.dataOptions.filter((x) => {
        if (target.contains(x.lnglat)) {
          return x;
        }
      });
      console.log(isContain);
      this.stationEmployeesList = [];
      getEmployees({
        pageIndex: 1,
        pageSize: 1000,
        ids: isContain.map((x) => x.id),
        searchModel: "SelectedEmployees",
        deskTypes: this.isCompany ? ["Normal", "Proprietor"] : this.deskTypes,
      }).then((res) => {
        this.setEmployeesInContain(res);
      });
    },
    setEmployeesInContain(isContain) {
      this.stationEmployeesList = [...isContain]
        .map((extData) => {
          console.log(extData);
          const { idCardNo, contact, name, companyName, securityStationName } = extData;
          return {
            ...extData,
            isPhone: false,
            isIdCardNo: false,
            active: false,
            nameSlice: name.slice(-2),
            companyNameSlice: textSlice(companyName),
            securityStationNameSlice: textSlice(securityStationName),
            idCardNoHide: this.parseStringToStar(idCardNo),
            contactHide: this.parseStringToStar(contact),
          };
        })
        .filter((x) => x !== undefined);
      this.stationEmployeesListFilter = this.stationEmployeesList;
      this.totalNum = 0;
      console.log(this.stationEmployeesList);
      if (this.stationEmployeesList.length > 0) {
        this.stationEmployeesList.forEach((item) => {
          item.active = false;
        });
        this.allMembers = this.stationEmployeesList.filter(({ dutyStatus }) => dutyStatus === "SignIn");
        this.stationEmployeesListType = "all";
        this.dutyCheckAll = false;
        this.railDispatchShow = true;
      }
    },
    showMapEditor({ shapeType, shapedLocation }) {
      switch (shapeType) {
        case "Circle": // 圆
          this.showCircleEditor(shapedLocation);
          break;
        case "Polygon":
          this.showPolygonEditor(shapedLocation);
          break;
        case "Crib":
          this.showCribEditor(shapedLocation);
          break;
      }
    },
    showCircleEditor(shapedLocation) {
      console.log(shapedLocation);
      let that = this;
      const { geos } = shapedLocation;
      const center = [Number(geos[0].lon), Number(geos[0].lat)];
      const { radius } = shapedLocation;
      this.$refs.map
        .setCircleEditor({
          center,
          radius,
        })
        .then(({ figure, editor }) => {
          that.circleFigure = figure;
          that.circleEditorObject = editor;
          that.circleEditorObject.open();
        });
    },
    onCircleEditorChange(event) {
      console.log("on circle Editor Change", event);
      const { target } = event;
      const center = target.getCenter().toArray();
      const radius = target.getRadius();
      console.log(center, radius);
      this.$refs.electronicFenceEdit.setForm({
        shapeType: "Circle",
        shapedLocation: {
          radius,
          geos: [
            {
              lon: center[0],
              lat: center[1],
            },
          ],
        },
      });
      this.setContain(target);
    },
    showPolygonEditor(shapedLocation) {
      let that = this;
      let list = shapedLocation.geos.map((item) => [item.lon, item.lat]);
      this.$refs.map.setPolygonEditor(list).then(({ figure, editor }) => {
        that.polygonFigure = figure;
        that.polygonEditor = editor;
        that.polygonEditor.open();
      });
    },
    onPolygonEditorChange(event) {
      console.log(event);
      const { target } = event;
      // const center = target.getCenter().toArray();
      // const radius = target.getRadius();
      const path = target.getPath();
      console.log(path);
      let coordinate = [];
      path.forEach((e) => {
        coordinate.push({ lon: e.lng, lat: e.lat });
      });
      this.$refs.electronicFenceEdit.setForm({
        shapeType: "Polygon",
        shapedLocation: {
          radius: "",
          geos: coordinate,
        },
      });
      this.setContain(target);
    },
    onRectangleEditorChange(event) {
      const { target } = event;
      let attr = target.getOptions();
      let bounds = attr.bounds;
      let coordinate = [
        { lat: bounds.northEast.lat, lon: bounds.northEast.lng },
        { lat: bounds.southWest.lat, lon: bounds.southWest.lng },
      ];
      this.$refs.electronicFenceEdit.setForm({
        shapeType: "Crib",
        shapedLocation: {
          radius: "",
          geos: coordinate,
        },
      });
      this.setContain(target);
    },
    showCribEditor(shapedLocation) {
      let that = this;
      let southWest = [shapedLocation.geos[1].lon, shapedLocation.geos[1].lat];
      let northEast = [shapedLocation.geos[0].lon, shapedLocation.geos[0].lat];
      this.$refs.map
        .setRectangleEditor({
          northEast,
          southWest,
        })
        .then(({ figure, editor }) => {
          that.rectangleFigure = figure;
          that.rectangleEditor = editor;
          that.rectangleEditor.open();
        });
    },
    openPeopleNumFn(id) {
      this.isElectronicFencePeople = true;
      getEmployees({
        pageIndex: 1,
        pageSize: 5000,
        securityStationIds: [id + ""],
        searchModel: "SecurityStation",
        deskTypes: this.isCompany ? ["Normal", "Proprietor"] : this.deskTypes,
      }).then((res) => {
        this.electronicFencePeopleList = res;
      });
    },
    electronicFencePeopleCancel() {
      this.isElectronicFencePeople = false;
    },
    //查看返回时显示电子围栏查询
    showElectronic() {
      this.isElectronicFenceDialog = true;
      this.isElectronicFenceEditDialog = false;
      this.isElectronicFencePeople = false;
    },
    addElectronic() {
      this.isElectronicFenceEditDialog = true;
      this.isElectronicFenceDialog = false;
      this.electronicFenceInfo = JSON.parse(JSON.stringify(this.info));
      this.electronicFenceInfo = {};
    },
    delElectronic(data) {
      console.log(data);
      let params = {
        id: data.data.id,
      };
      deleteRail(params)
        .then((res) => {
          console.log("deleteRail", res);
          this.$refs["electronicFence"].getRails();
          this.$message({
            message: "删除成功",
            type: "success",
          });
        })
        .catch((err) => {
          console.log(err);
        });
    },
    electronicFenceEditCancel() {
      this.isElectronicFenceEditDialog = false;
      this.cleanDrawFigure();
    },
    cleanDrawFigure() {
      if (this.circleEditorObject) {
        this.map.remove(this.circleFigure);
        this.circleEditorObject.close();
      }
      if (this.rectangleEditor) {
        this.map.remove(this.rectangleFigure);
        this.rectangleEditor.close();
      }
      if (this.polygonEditor) {
        this.map.remove(this.polygonFigure);
        this.polygonEditor.close();
      }
    },
    mapFn(obj, AMap) {
      this.map = obj;
      this.AMap = AMap;
    },
    openElectronic() {
      this.isElectronicFenceDialog = true;
      this.infoWindow.station.position = null;
    },
    electronicFenceCancel() {
      this.isElectronicFenceDialog = false;
    },
    selectCk(index, item) {
      if (item.dutyStatusText === "离岗") return false;
      this.seMemberList(index, item);
      // console.log(this.memberList);
      console.log(
        "yyyy",
        this.allMembers.filter((x) => !x.active)
      );
    },
    seMemberList(index, item) {
      this.totalNum = 0;
      // item.active = !item.active;
      // this.memberList = this.stationEmployeesList.filter((x) => x.active);
      this.memberList = [];
      this.stationEmployeesList.forEach((employee) => {
        if (employee.id === item.id) {
          employee.active = !employee.active;
          const member = this.allMembers.find((x) => x.id === item.id);
          if (member) {
            member.active = employee.active;
          }
        }
        if (employee.active) {
          this.memberList.push(employee);
        }
      });
      let checkedCount = this.memberList.length;
      this.dutyCheckAll = checkedCount === this.stationEmployeesListFilter.length;
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.stationEmployeesListFilter.length;
      this.allMembers.forEach((member) => {
        if (item.id === member.id) {
          member.active = item.active;
        }
      });
      this.totalNum = this.memberList.length;
    },
    parseStringToStar(str) {
      return str.length > 2 ? str.substr(0, 2) + new Array(str.length - 2).join("*") + str.substr(-2) : str;
    },
    lookCompany(type) {
      if (type === "detail") {
        this.companyDetail = false;
      } else {
        this.companyDetail = true;
      }
    },
    //地址周边搜索
    railFun(info, type) {
      console.log("railInfo", info);
      let iconUrl;
      if (type === "location") {
        const coordinates = info.location.split(",");
        info["longitude"] = coordinates[0];
        info["latitude"] = coordinates[1];
        info["type"] = "location";
      }
      if (type === "station") {
        iconUrl = require("@/assets/images/mapSearch/驻勤点.png");
        if (info.resourceTypes.length === 1 && info.resourceTypes[0] === "Population") {
          iconUrl = {
            image: require("@/assets/images/mapSearch/社区警务.png"),
            imageSize: [56, 56],
          };
        } else {
          iconUrl = {
            image: info.stationTypes[0].mapIcon,
            imageSize: [56, 56],
          };
        }
      }
      this.markers = [
        {
          position: [Number(info.longitude), Number(info.latitude)],
          anchor: "bottom-center",
          icon: iconUrl,
          extData: info,
        },
      ];

      this.rail = info;
      if (type === "station" || type === "location" || type === "employee") {
        this.showInfoByRowClick(info, "railTwo");
      } else {
        this.showInfoByRowClick(info, "rail");
      }
    },
    commandCk: _.debounce(function (index, item) {
      console.log(this);
      if (this.dispatching) return;
      this.commandIndex = index;
      if (item.value === "rail") {
        // 周边调度
        // 搜保安员列表点击后触发
        // 聚焦并弹框
        let iconUrl;
        if (this.employee.dutyStatusText === "在岗") {
          iconUrl = require("@/assets/images/mapSearch/在岗_保安员.png");
        } else {
          iconUrl = require("@/assets/images/mapSearch/离岗_保安员.png");
        }
        this.markers = [
          {
            position: [Number(this.employee.longitude), Number(this.employee.latitude)],
            anchor: "bottom-center",
            icon: iconUrl,
            extData: this.employee,
          },
        ];
        this.rail = this.employee;
        this.showInfoByRowClick(this.employee, "railTwo");
      } else if (item.value === "character") {
        this.character(this.info);
      } else if (item.value === "video") {
        this.memberList = [];
        // 1V1 视频调度
        this.startVideoCall();
      } else if (item.value === "audio") {
        this.memberList = [];
        // 1V1 语音
        this.startAudioCall();
      } else if (item.value === "videoLocalMute") {
        // 视频上拉
        this.videoLocalMute();
      } else if (item.value === "ptt") {
        // 对讲
        this.memberList = [this.info];
        this.openPPTCall();
      }
    }, 500),
    oneCall() {
      return new Promise((resolve) => {
        this.memberList = [this.info];
        this.allMembers = [];
        this.memberList.forEach((member) => {
          member.state = "CONNECTING";
          member.action = "";
        });
        this.callType = "video";
        this.yardmanType = "1";
        this.stream.video = true;
        this.stream.audio = true;
        resolve();
      });
    },
    oneTel() {
      return new Promise((resolve) => {
        this.memberList = [this.info];
        this.allMembers = [];
        this.memberList.forEach((member) => {
          member.state = "CONNECTING";
          member.action = "";
        });
        this.stream.video = false;
        this.stream.audio = true;
        this.yardmanType = "1";
        this.callType = "audio";
        resolve();
      });
    },
    oneMuteVideoCall() {
      return new Promise((resolve) => {
        this.memberList = [this.info];
        this.allMembers = [];
        this.memberList.forEach((member) => {
          member.state = "CONNECTING";
          member.action = "";
          // member.id = member.employeeId
        });
        this.stream.video = false;
        this.stream.audio = true;
        this.yardmanType = "2";
        this.callType = "video";
        resolve();
      });
    },
    // * 单人音频
    startAudioCall() {
      this.oneTel().then(() => {
        if (this.dispatchClient === "tencent") {
          this.$bus.$emit("video-call");
        } else {
          const users = [...this.memberList].map((x) => {
            return {
              uid: x.tencentUserId,
              displayName: x.name,
            };
          });
          // createJoinAndInviteConference(createOpts, false, false, false, users, "");
          const createOpts = {
            title: "指挥调度",
            audience: true,
            allowTurnOnMic: true,
            advance: false,
          };
          console.log(users);
          this.isSingle = true;
          const audioOnly = true;
          const muteVideo = true;
          // type:audio语音，video视频，videoup视频上拉；
          const extraType = "audio";
          this.callType = "audio";
          const extra = `{"type": "${extraType}","initiator": "${this.sysUserInfo.name}","organization": "${this.sysUserInfo.deviceName}"}`;
          createJoinAndInviteConference(createOpts, audioOnly, false, muteVideo, users, "指挥调度", extra);
        }
      });
    },
    // * 单人视频
    startVideoCall() {
      this.oneCall().then(() => {
        if (this.dispatchClient === "tencent") {
          this.$bus.$emit("video-call");
        } else {
          const users = [...this.memberList].map((x) => {
            return {
              uid: x.tencentUserId,
              displayName: x.name,
            };
          });
          const createOpts = {
            title: "指挥调度",
            audience: true,
            allowTurnOnMic: true,
            advance: false,
          };
          console.log(users);
          this.isSingle = true;
          const audioOnly = false;
          const muteVideo = false;
          // type:audio语音，video视频，videoup视频上拉；
          const extraType = "video";
          this.callType = "video";
          const extra = `{"type": "${extraType}","initiator": "${this.sysUserInfo.name}","organization": "${this.sysUserInfo.deviceName}"}`;
          createJoinAndInviteConference(createOpts, audioOnly, false, muteVideo, users, "指挥调度", extra);
        }
      });
    },
    // * 视频上拉
    videoLocalMute() {
      this.oneMuteVideoCall().then(() => {
        if (this.dispatchClient === "tencent") {
          this.$bus.$emit("video-call");
        } else {
          this.videoLocalMuteCall();
        }
      });
    },
    videoLocalMuteCall() {
      this.memberList = [this.info];
      const createOpts = {
        title: "指挥调度",
        audience: true,
        allowTurnOnMic: true,
        advance: false,
      };
      const users = [...this.memberList].map((x) => {
        return {
          uid: x.tencentUserId,
          displayName: x.name,
        };
      });
      // type:audio语音，video视频，videoup视频上拉；
      this.isSingle = true;
      this.audioOnly = true;
      const extraType = "videoup";
      this.callType = "videoup";
      const extra = `{"type": "${extraType}","initiator": "${this.sysUserInfo.name}","organization": "${this.sysUserInfo.deviceName}"}`;
      // createJoinAndInviteConference(createOpts, audioOnly, false, muteVideo, users, "指挥调度", extra);
      createJoinAndInviteConference(createOpts, false, false, true, users, "指挥调度", extra);
    },
    videoCall() {
      console.log(this.info);

      this.startVideoDispatch();
    },
    trackCk(index) {
      this.trackIndex = index;

      console.log("employee", this.infoWindow.employee);
      if (index === 0) {
        //轨迹查询
        this.isTrajectoryDialog = true;
        // this.onHideAllLayers();
        this.railDispatchShow = false;
        this.isElectronicFenceDialog = false;
        this.isElectronicFenceEditDialog = false;
        this.hideAllList();
        this.infoWindow.employee.position = null;
        // getEmployeesTrack(this.info).then(res=>{
        //   console.log
        // })
      }
    },
    trajectoryCancel() {
      this.isTrajectoryDialog = false;
      this.onHideAllLayers();
      this.infoWindow.employee.position = null;
      this.$refs.map.stopMove();
      this.clearMap();
    },
    onSetTrack(path) {
      console.log("onSetTrack", path);
      this.$refs.map.setMoveAnimation(path);
      // this.$refs.map.moveStart()
    },
    onMove(e) {
      const { index } = e;
      this.$refs.trajectory.setCurrentRow(index);
    },
    onRefresh(speedRatio) {
      this.$refs.map.stopMove();
      this.$refs.map.moveStart(speedRatio);
    },
    onStartMove(speedRatio) {
      this.speedRatio = speedRatio;
      if (this.moveStatus === "pause") {
        this.$refs.map.resumeMove();
      } else {
        this.$refs.map.moveStart();
      }
      this.moveStatus = "moving";
    },
    onPauseMove() {
      this.$refs.map.pauseMove();
      this.moveStatus = "pause";
    },
    onStopMove() {
      this.$refs.map.stopMove();
      this.moveStatus = "stop";
    },
    onBackStep() {
      this.$refs.map.backStep();
    },
    onNextStep() {
      this.$refs.map.nextStep();
    },
    onMapComplete() {
      // if (process.env.VUE_APP_ENV === "development") {
      //   this.appLoadingMask.close();
      // }
      let userInfoJson;
      if (Object.keys(this.sysUserInfo).length > 0) {
        userInfoJson = this.sysUserInfo;
        this.setCenterByCurrent(userInfoJson);
      } else {
        getCurrentUser().then((response) => {
          this.setCenterByCurrent(response);
        });
      }
    },
    /**
     * @地图视窗移动到指定中心点
     * @param userInfoJson
     */
    async setCenterByCurrent(userInfoJson) {
      if (userInfoJson) {
        const { orgLongitude, orgLatitude } = userInfoJson;
        if (orgLongitude && orgLatitude) {
          this.$refs.map.setCenter([Number(orgLongitude), Number(orgLatitude)]);
          this.appLoadingMask.close();
        } else {
          const company = await getCompanyDetail(userInfoJson.organizationId);
          if (company) {
            const { longitude, latitude } = company;
            if (longitude && latitude) {
              this.$refs.map.setCenter([Number(longitude), Number(latitude)]);
              this.appLoadingMask.close();
            }
          }
        }
      }

      // 判断是否在调度范围内
      // this.$refs.map.locationInContain(longitude, latitude);
    },
    onClickMap(e) {
      console.log("onClickMap", e);
    },
    // 点聚合图标事件
    clickCluster({ cluster, clusterData, lnglat }, map) {
      const { p } = cluster;
      if (clusterData.length > 1) {
        map.setZoomAndCenter(map.getZoom() + 1, lnglat);
      } else {
        if (p.type === "employee") {
          // onClickEmployee
          this.onClickEmployee(p);
        } else if (p.type === "station") {
          // onClickStation
          this.onClickStation(p);
        } else if (p.type === "company") {
          // clickCompany
          console.log("clickCluster", p);
          this.clickCompany(p, "company");
        }
      }
    },
    onClickMarker(e) {
      const { target } = e;
      console.log("onClickMarker", target.getPosition());
      console.log("onClickMarker", target.getExtData());
      this.info = { ...this.info, ...target.getExtData() };
      console.log("onClickMarker info", this.info);
      this.infoWindow[this.info.type].position = target.getPosition();
      if (this.info.type === "employee") {
        getEmployeeDetail(this.info.id)
          .then((employeeDetail) => {
            this.$set(this.info, "authenticatedStatusText", employeeDetail.authenticatedStatusText);
            this.$set(this.info, "certificateSituation", employeeDetail.certificateSituation);
          })
          .catch((err) => {
            console.log(err);
          });

        this.employee = this.info;
      } else if (this.info.type === "SOS") {
        // this.infoWindow.SOS.position = undefined;
      }
      this.onHideAllLayers();
      this.hideAllList();
      this.updateMarkerIcon(this.info);
    },
    updateMarkerIcon(data) {
      const { type, id } = data;
      if (!type) return;
      if (type === "location") {
        this.markers.forEach((marker) => {
          if (marker.extData.id === id) {
            marker.icon = require("@/assets/images/map/icons/mark_r.png");
            this.showInfoByRowClick(data, "location");
          } else {
            marker.icon = require("@/assets/images/map/icons/mark_b.png");
          }
        });
      }
    },
    //显示弹窗
    showInfoByRowClick(data, type) {
      this.info = { ...{}, ...data };
      console.log("showInfoByRowClick", type, this.info);
      if (type === "location") {
        //查地址
        console.log("===data.location==", data.location);
        const coordinates = data.location.split(",");
        const coordinatess = [Number(coordinates[0]), Number(coordinates[1])];
        this.infoWindow[type].position = coordinatess;

        console.log(this.infoWindow);
        this.$refs.map.setZoomAndCenter(12, coordinatess);
      } else if (type === "employee" || type === "station") {
        //查保安员或者驻勤点或者公司
        const coordinates = [data.longitude, data.latitude + 0.038];
        this.infoWindow[type].position = [Number(data.longitude), Number(data.latitude)];
        this.$refs.map.setZoomAndCenter(12, coordinates);
      } else if (type === "company") {
        const coordinates = [data.longitude, data.latitude];
        this.infoWindow[type].position = coordinates;
        this.$refs.map.setZoomAndCenter(12, coordinates);
      } else if (type === "stationEmployees") {
        //查驻勤点保安员
        const coordinates = [data.longitude, data.latitude];
        this.infoWindow[type].position = [Number(data.longitude), Number(data.latitude)];
        this.$refs.map.setZoomAndCenter(12, coordinates);
      } else if (type === "companyStations") {
        //查内保单位驻勤点
        const coordinates = [data.longitude, data.latitude];
        this.infoWindow[type].position = [Number(data.longitude), Number(data.latitude)];
        this.$refs.map.setZoomAndCenter(12, coordinates);
        this.info.type = type;
        this.markers = [
          {
            position: coordinates,
            anchor: "bottom-center",
            icon: require("@/assets/images/mapSearch/内保单位公司.png"),
            extData: {
              ...data,
              type,
            },
          },
        ];
      } else if (type === "rail") {
        const coordinates = [data.longitude, data.latitude];
        this.infoWindow[type].position = [Number(data.longitude), Number(data.latitude)];
        this.$refs.map.setZoomAndCenter(12, coordinates);
        this.value = 0;
      } else if (type === "railTwo") {
        const coordinates = [data.longitude, data.latitude];
        this.infoWindow[type].position = [Number(data.longitude), Number(data.latitude)];
        this.$refs.map.setZoomAndCenter(12, coordinates);
        this.value = 0;
      } else if (type === "railSecurity") {
        const coordinates = [data.longitude, data.latitude];
        this.infoWindow[type].position = [Number(data.longitude), Number(data.latitude)];
        this.$refs.map.setZoomAndCenter(12, coordinates);
      }
    },
    /**
     * 渲染聚合图标样式
     * @param context
     */
    renderClusterMarker(context) {
      const div = document.createElement("div");
      const bgColor = "#0E71FF";
      const fontColor = "white";
      div.style.backgroundColor = bgColor;
      const size = 80;
      div.style.width = div.style.height = size + "px";
      div.style.borderRadius = size / 2 + "px";
      div.innerHTML = context.count;
      div.style.lineHeight = size + "px";
      div.style.color = fontColor;
      div.style.fontSize = "22px";
      div.style.textAlign = "center";
      context.marker.setContent(div);
      context.marker.setAnchor("center");
    },
    /**
     * 聚合下单个人员图标渲染
     * @param marker
     * @param data
     */
    renderEmployeeMarker({ marker, data }) {
      const [item] = data;
      let iconUrl;
      const { dutyStatus, rts } = item;
      console.log("dutyStatus", dutyStatus);
      console.log("rts", rts);
      if (dutyStatus === "SignIn") {
        if (rts.includes("Security")) {
          iconUrl = require("@/assets/images/mapSearch/在岗_保安员.png");
        } else if (rts.includes("Proprietor")) {
          iconUrl = require("@/assets/images/mapSearch/保卫管理员.png");
        } else {
          iconUrl = require("@/assets/images/mapSearch/社会力量.png");
        }
        console.log("employeeCluster", item);
      } else {
        iconUrl = require("@/assets/images/mapSearch/离岗_保安员.png");
      }
      marker.setIcon(iconUrl);
      marker.setAnchor("bottom-center");
    },
    /**
     * 聚合下单驻勤点图标渲染
     * @param marker
     * @param data
     * @param Icon
     */
    renderStationMarker({ marker, data }, { Icon }) {
      const [{ rts, stationTypes }] = data;
      let mapIconUrl;
      if (stationTypes && stationTypes.length > 0) {
        //有驻勤点类型
        const stationType = this.stationTypes.find((t) => t.code === stationTypes[0]);
        if (stationType && stationType.mapIcon) {
          mapIconUrl = stationType.mapIcon;
        } else {
          mapIconUrl = require("@/assets/images/mapSearch/驻勤点.png");
        }
        // const { mapIcon } = this.stationTypes.find((t) => t.code === stationTypes[0]);

        if (rts.length === 1 && rts[0] === "Population") {
          mapIconUrl = require("@/assets/images/mapSearch/社区警务.png");
        }
      } else {
        //没有驻勤点类型
        mapIconUrl = require("@/assets/images/mapSearch/社区警务.png");
      }

      const icon = new Icon({
        image: mapIconUrl,
        imageSize: [56, 56],
      });
      marker.setIcon(icon); // imageSize: [56, 56],
      marker.setAnchor("bottom-center");
    },
    renderProprietorMarker({ marker }, { Pixel }) {
      // marker.setAnchor("bottom-center");
      marker.setIcon(require("@/assets/images/mapSearch/内保单位公司.png"));
      marker.setOffset(new Pixel(-28, -56));
    },
    /**
     * 搜索后地图撒点
     * @param type 搜索类型
     * @param data 点位数据
     */
    onMapSearch({ type, data }) {
      // this.cluster = {};
      if (type === 4) {
        //搜索地址
        console.log("on search place", data);
        this.markers = data
          .map((poi, index) => {
            const { location } = poi;
            if (location && location.length > 0) {
              const coordinates = location.split(",");
              console.log(coordinates);
              return {
                position: [Number(coordinates[0]), Number(coordinates[1])],
                anchor: "bottom-center",
                icon: require("@/assets/images/map/icons/mark_b.png"),
                label: {
                  content: index + 1,
                  direction: "center",
                  offset: [0, 0],
                },
                extData: poi,
              };
            }
          })
          .filter((x) => x !== undefined);
        console.log("markers", this.markers);
      } else {
        //搜索人员
        this.markers = [];
        let points = [];
        data.forEach((point) => {
          const { longitude, latitude } = point;
          if (longitude && latitude) {
            points.push({
              lnglat: [Number(point.longitude), Number(point.latitude)],
              extData: point,
              ...point,
            });
          }
        });
        if (points.length > 0) {
          // const count = this.markers.length;
          this.cluster = {
            dataOptions: [...points],
            MarkerClusterOptions: {
              maxZoom: 18,
              gridSize: 10, // 聚合计算时网格的像素大小，默认60
              clusterByZoomChange: true,
              renderClusterMarker: (context) => this.renderClusterMarker(context),
              renderMarker: ({ marker, data }) => {
                if (type === 1) {
                  // 人员
                  this.renderEmployeeMarker({ marker, data });
                } else if (type === 2) {
                  // 驻勤点
                  this.renderStationMarker({ marker, data }, this.AMap);
                } else if (type === 3) {
                  // 内保单位
                  this.renderProprietorMarker({ marker }, this.AMap);
                }
              },
            },
          };
        }
      }
    },
    //地址搜索
    onPlaceSearch(data) {
      // console.log("onPlaceSearch", data);
      if (!data) return;
      this.markers = data
        .map((poi, index) => {
          const { location } = poi;
          if (location && location.length > 0) {
            console.log(location);
            const coordinates = location.split(",");
            poi["type"] = "location";
            poi["addressSlice"] = textSlice(poi.address); //多出部分省略号显示
            return {
              position: [Number(coordinates[0]), Number(coordinates[1])],
              anchor: "bottom-center",
              icon: require("@/assets/images/map/icons/mark_b.png"),
              label: {
                content: index + 1,
                direction: "center",
                offset: [0, 0],
              },
              extData: poi,
            };
          }
        })
        .filter((x) => x !== undefined);
      console.log("markers", this.markers);
    },
    changeStationIsPhone(index) {
      let list = [...this.stationEmployeesList];
      list[index].isPhone = !list[index].isPhone;
      this.stationEmployeesList = [...list];
    },
    changeStationIsIdCardNo(index) {
      let list = [...this.stationEmployeesList];
      list[index].isIdCardNo = !list[index].isIdCardNo;
      this.stationEmployeesList = [...list];
    },
    //周边调度选择保安员计算人数
    changesStationEmployeesActive(index) {
      let that = this;
      let list = JSON.parse(JSON.stringify(that.stationEmployeesList));
      list[index].active = !list[index].active;
      this.$nextTick(() => {
        that.stationEmployeesList = [];
        that.stationEmployeesList = list;
        this.memberList = this.stationEmployeesList.filter((item) => item.active);
        this.totalNum = this.memberList.length;
      });
    },
    //周边调度查询保安员并撒点
    railCk() {
      if (this.value === 0) {
        this.$message({
          message: "请选择范围",
          type: "warning",
        });
      }
      getEmployees({
        pageIndex: 1,
        pageSize: 1000,
        // securityStationId: this.rail.id,
        longitude: this.rail.longitude,
        latitude: this.rail.latitude,
        distance: this.value,
        searchModel: "Geo",
        deskTypes: this.isCompany ? ["Normal", "Proprietor"] : this.deskTypes,
      })
        .then((stationEmployees) => {
          console.log("stationEmployees:", stationEmployees);
          this.stationEmployeesList = [];
          this.markers = [];
          stationEmployees.forEach((item) => {
            item.active = false;
            item["nameSlice"] = item.name.slice(-2);
            item["idCardNoHide"] = this.parseStringToStar(item.idCardNo);
            item["contactHide"] = this.parseStringToStar(item.contact);
            item["companyNameSlice"] = textSlice(item.companyName);
            item["securityStationNameSlice"] = textSlice(item.securityStationName);
            item["type"] = "employee";
            item["isPhone"] = false;
            item["isIdCardNo"] = false;
            let iconUrl;
            if (item.dutyStatusText === "在岗") {
              if (item.rts.includes("Security")) {
                iconUrl = require("@/assets/images/mapSearch/在岗_保安员.png");
              } else if (item.rts.includes("Proprietor")) {
                iconUrl = require("@/assets/images/mapSearch/保卫管理员.png");
              } else {
                iconUrl = require("@/assets/images/mapSearch/社会力量.png");
              }
            } else {
              iconUrl = require("@/assets/images/mapSearch/离岗_保安员.png");
            }
            this.markers.push({
              position: [Number(item.longitude), Number(item.latitude)],
              anchor: "bottom-center",
              icon: iconUrl,
              extData: item,
            });
          });
          this.stationEmployeesList = stationEmployees;
          this.stationEmployeesListFilter = this.stationEmployeesList;
          this.allMembers = this.stationEmployeesList.filter(({ dutyStatus }) => dutyStatus === "SignIn");
          this.totalNum = 0;
          this.stationEmployeesList.forEach((item) => {
            item.active = false;
          });
          this.stationEmployeesListFilter = this.stationEmployeesList;
          this.stationEmployeesListType = "all";
          this.dutyCheckAll = false;
          this.railDispatchShow = true;
        })

        .catch((err) => {
          console.log(err);
        });
    },
    onClickRail(rail) {
      this.rail = rail;
      // latitude
      // longitude
      console.log("===========", rail);
      rail["type"] = "rail";
      this.markers = [
        {
          position: [Number(rail.longitude), Number(rail.latitude)],
          anchor: "bottom-center",
          extData: rail,
          icon: {
            image: require("@/assets/images/mapSearch/警情打点.png"),
            imageSize: [56, 56],
          },
        },
      ];
      this.showInfoByRowClick(rail, "rail");
    },
    // 搜保安员列表点击后触发
    onClickEmployee(employee) {
      // 聚焦并弹框
      getEmployeeDetail(employee.id)
        .then((employeeDetail) => {
          console.log("onClickEmployee", employeeDetail);
          this.employee = employeeDetail;
          let iconUrl;
          if (employeeDetail.dutyStatusText === "在岗") {
            if (employeeDetail.resourceTypes.includes("Security")) {
              iconUrl = require("@/assets/images/mapSearch/在岗_保安员.png");
            } else if (employeeDetail.resourceTypes.includes("Proprietor")) {
              iconUrl = require("@/assets/images/mapSearch/保卫管理员.png");
            } else {
              iconUrl = require("@/assets/images/mapSearch/社会力量.png");
            }
          } else {
            iconUrl = require("@/assets/images/mapSearch/离岗_保安员.png");
          }
          employeeDetail["nameSlice"] = employeeDetail.name.slice(-2);
          employeeDetail["idCardNoHide"] = this.parseStringToStar(employeeDetail.idCardNo);
          employeeDetail["contactHide"] = this.parseStringToStar(employeeDetail.contact);
          employeeDetail["type"] = "employee";
          employeeDetail["companyNameSlice"] = textSlice(employeeDetail.companyName); //多出部分省略号显示
          employeeDetail["proprietorCompanyNameSlice"] = textSlice(employeeDetail.proprietorCompanyName); //多出部分省略号显示
          employeeDetail["securityStationNameSlice"] = textSlice(employeeDetail.securityStationName); //多出部分省略号显示
          this.cluster.dataOptions = [];
          this.markers = [
            {
              position: [Number(employeeDetail.longitude), Number(employeeDetail.latitude)],
              anchor: "bottom-center",
              icon: iconUrl,
              extData: employeeDetail,
            },
          ];
          this.showInfoByRowClick(employeeDetail, "employee");
        })
        .catch((err) => {
          console.log(err);
        });
    },
    // 搜驻勤点后触发
    async onClickStation(station, type) {
      // 聚焦并弹框
      console.log("onClickStation", station);
      if (type === "employee") {
        this.onClickEmployee(this.employee);
      } else {
        let StationDetail = await getStationDetail(station.id);
        StationDetail["type"] = "station";
        StationDetail["returnWin"] = station.returnWin;
        StationDetail["returnDetail"] = station.returnDetail;
        StationDetail["companyNameSlice"] = textSlice(StationDetail.companyName); //多出部分省略号显示
        StationDetail["securityStationNameSlice"] = textSlice(StationDetail.name); //多出部分省略号显示
        StationDetail["superviseDepartNameSlice"] = textSlice(StationDetail.superviseDepartName); //多出部分省略号显示
        StationDetail["addressSlice"] = textSlice(StationDetail.address); //多出部分省略号显示
        console.log("station:", StationDetail);
        let mapIconUrl;
        if (StationDetail.stationTypes && StationDetail.stationTypes.length > 0) {
          //有驻勤点类型
          mapIconUrl = StationDetail.stationTypes[0].mapIcon;
          if (StationDetail.resourceTypes.length === 1 && StationDetail.resourceTypes[0] === "Population") {
            mapIconUrl = require("@/assets/images/mapSearch/社区警务.png");
          }
        } else {
          //没有驻勤点类型，说明是社区警务
          mapIconUrl = require("@/assets/images/mapSearch/社区警务.png");
        }
        this.info = StationDetail;
        this.cluster.dataOptions = [];
        this.markers = [
          {
            position: [Number(StationDetail.longitude), Number(StationDetail.latitude)],
            anchor: "bottom-center",
            // icon: require("@/assets/images/mapSearch/驻勤点.png"),
            icon: {
              image: mapIconUrl,
              imageSize: [56, 56],
            },
            extData: StationDetail,
          },
        ];
        this.showInfoByRowClick(StationDetail, "station");
      }
    },
    // 搜地点列表点击后触发
    onClickPoi(poi) {
      console.log("on click poi point: ", poi);
      // 聚焦并弹框
      let tempMarker;
      this.markers.forEach((marker) => {
        if (marker.extData.id === poi.id) {
          marker.icon = require("@/assets/images/map/icons/mark_r.png");
          this.showInfoByRowClick(poi, "location");
          tempMarker = marker;
        } else {
          // marker.icon = require("@/assets/images/map/icons/mark_b.png");
        }
      });
      this.markers = [];
      this.markers.push(tempMarker);
    },
    // 跳转公司
    async clickCompany(info, infoType, isProprietor) {
      console.log("company", info);
      let companyId = infoType === "company" ? info.id : info.organizationId;
      if (isProprietor === "Proprietor") {
        companyId = info.proprietorCompanyId;
      }
      if (infoType === "companyStations") {
        if (info.proprietorCompanyId) {
          companyId = info.proprietorCompanyId;
        }
      }
      const company = await getCompanyDetail(companyId);
      console.log("companyDetail", company);
      let companyIcon = require("@/assets/images/mapSearch/公司.png");
      if (company.resourceTypes.includes("Proprietor")) {
        companyIcon = require("@/assets/images/mapSearch/内保单位公司.png");
      }
      company["returnWin"] = infoType;
      company["returnDetail"] = info;
      company["type"] = "company";
      company["registerAddressSlice"] = textSlice(company.registerAddress);
      this.cluster.dataOptions = [];
      this.markers = [
        {
          position: [Number(company.longitude), Number(company.latitude)],
          anchor: "bottom-center",
          icon: companyIcon,
          extData: company,
        },
      ];
      console.log(this.markers);
      this.showInfoByRowClick(company, "company");
    },
    // 跳转驻勤点
    clickStation(info, infoType) {
      let stationId = "";
      if (infoType === "companyStations") {
        stationId = info.id;
      } else {
        stationId = info.securityStationId;
      }
      console.log("stationId", stationId);
      getStationDetail(stationId)
        .then((station) => {
          console.log("station", station);
          station["returnWin"] = infoType;
          station["returnDetail"] = info;
          this.onClickStation(station);
        })
        .catch((err) => {
          console.log(err);
        });
    },
    // 点击驻勤点人员，修改成驻勤点人员撒点
    clickStationEmployees(info) {
      console.log("stationId", info.id);
      let params = {
        pageIndex: 1,
        pageSize: 5000,
        securityStationIds: [info.id + ""],
        searchModel: "SecurityStation",
        deskTypes: this.isCompany ? ["Normal", "Proprietor"] : this.deskTypes,
      };
      if (info.resourceTypes.length === 1 && info.resourceTypes[0] === "Population") {
        //如果是社区警务，传一个resourceType = Population
        params = {
          pageIndex: 1,
          pageSize: 5000,
          securityStationIds: [info.id + ""],
          resourceType: "population",
          searchModel: "SecurityStation",
          deskTypes: this.isCompany ? ["Normal", "Proprietor"] : this.deskTypes,
        };
      }
      getEmployees(params)
        .then((res) => {
          const stationEmployees = [...res].sort(function (x, y) {
            // true values first
            return x.stationResponsible === y.stationResponsible ? 0 : x.stationResponsible ? -1 : 1;
          });
          this.markers = [];
          this.cluster.MarkerClusterOptions = {
            maxZoom: 18,
            gridSize: 10, // 聚合计算时网格的像素大小，默认60
            renderClusterMarker: (context) => this.renderClusterMarker(context),
            renderMarker: ({ marker, data }) => this.renderEmployeeMarker({ marker, data }),
          };
          this.cluster.dataOptions = stationEmployees
            .map((item) => {
              item.active = false;
              item["nameSlice"] = item.name.slice(-2);
              item["idCardNoHide"] = this.parseStringToStar(item.idCardNo);
              item["contactHide"] = this.parseStringToStar(item.contact);
              item["type"] = "employee";
              item["isPhone"] = false;
              item["isIdCardNo"] = false;
              item["companyNameSlice"] = textSlice(item.companyName); //多出部分省略号显示
              item["securityStationNameSlice"] = textSlice(item.securityStationName); //多出部分省略号显示
              let iconUrl;
              const { dutyStatusText } = item;
              if (dutyStatusText === "在岗") {
                console.log("========item======", item);
                if (item.rts.includes("Security")) {
                  iconUrl = require("@/assets/images/mapSearch/在岗_保安员.png");
                } else if (item.rts.includes("Proprietor")) {
                  iconUrl = require("@/assets/images/mapSearch/保卫管理员.png");
                } else {
                  iconUrl = require("@/assets/images/mapSearch/社会力量.png");
                }

                return {
                  ...item,
                  position: [Number(item.longitude), Number(item.latitude)],
                  lnglat: [Number(item.longitude), Number(item.latitude)],
                  anchor: "bottom-center",
                  icon: iconUrl,
                  extData: item,
                };
              }
            })
            .filter((x) => x !== undefined);
          console.log("markers", this.cluster.dataOptions);
          console.log("stationEmployees", this.info); // info.stationEmployees
          this.showInfoByRowClick({ ...info, stationEmployees }, "stationEmployees");
        })
        .catch((err) => {
          console.log(err);
        });
    },
    // 点击内保单位驻勤点
    clickCompanyStations(info, infoType) {
      console.log("clickCompanyStations-info", info);
      let companyId = info.id;
      if (infoType === "back") {
        companyId = info.proprietorCompanyId;
        info["companyName"] = info.proprietorCompanyName;
      } else {
        info["companyName"] = info.name;
      }
      getStations({
        pageIndex: 1,
        pageSize: 1000,
        searchModel: "Organization",
        organizationId: companyId,
        deskTypes: this.isCompany ? ["Normal", "Proprietor"] : this.deskTypes,
      })
        .then((companyStations) => {
          console.log("companyStations", companyStations);
          this.showInfoByRowClick({ ...info, companyStations }, "companyStations");
        })
        .catch((err) => {
          console.log(err);
        });
    },

    /**
     * @切换图层
     * @param types
     */
    changeLayer(types) {
      this.layers = [];
      types.forEach((type) => {
        this.layers.push({
          type,
        });
      });
    },
    // TODO 电子围栏
    setFence() {
      this.$message.info("电子围栏");
    },
    // TODO 视频会商
    setVideo() {
      this.$message.info("视频会商");
    },
    // TODO 批量视频查看
    setPreview() {
      this.$message.info("批量视频查看");
    },
    // TODO 广播/全呼
    setBroadcast() {
      this.$message.info("广播/全呼");
    },
    /**
     * @圈选
     * @param {*} active
     */
    setCircle(active) {
      this.$refs.map.closeCircleEditor();
      this.$refs.map.closeRectangleEditor();
      this.$refs.map.closePolygonEditor();
      this.$refs.map.clearMeasure();
      const editor = this.$refs.map.getCircleEditor();
      if (editor) this.$refs.map.map.remove(editor);
      // this.$refs.map.map.clearMap();
      if (active) {
        this.$refs.map.circle("circle");
      }
    },
    /**
     * @矩形
     * @param {*} active
     */
    setSquare(active) {
      this.$refs.map.closeCircleEditor();
      this.$refs.map.closeRectangleEditor();
      this.$refs.map.closePolygonEditor();
      this.$refs.map.clearMeasure();
      const editor = this.$refs.map.getRectangleEditor();
      if (editor) this.$refs.map.map.remove(editor);
      // this.$refs.map.map.clearMap();
      if (active) {
        this.$refs.map.square("square");
      }
    },
    /**
     * @多边形选择
     * @param {*} active
     */
    setPolygon(active) {
      this.$refs.map.closeCircleEditor();
      this.$refs.map.closeRectangleEditor();
      this.$refs.map.closePolygonEditor();
      this.$refs.map.clearMeasure();
      const editor = this.$refs.map.getPolygonEditor();
      if (editor) this.$refs.map.map.remove(editor);
      if (active) {
        this.$refs.map.polygon("polygon");
      }
    },
    onDraw(evt) {
      console.log("onDraw", evt);
      const { obj, drawType } = evt;
      this.setContain(obj);
      if (drawType === "circle") {
        this.$refs.map
          .setCircleEditor(
            {
              center: obj.getCenter(),
              radius: obj.getRadius(),
            },
            false
          )
          .then(({ editor }) => {
            this.$refs.map.clearMeasure();
            editor.open();
          });
      } else if (drawType === "square") {
        const bounds = obj.getBounds();
        console.log(bounds);
        const { northEast, southWest } = bounds;
        this.$refs.map
          .setRectangleEditor(
            {
              northEast: [northEast.lng, northEast.lat],
              southWest: [southWest.lng, southWest.lat],
            },
            false
          )
          .then(({ editor }) => {
            this.$refs.map.clearMeasure();
            editor.open();
          });
      } else if (drawType === "polygon") {
        this.$refs.map.setPolygonEditor(obj.getPath(), false).then(({ editor }) => {
          this.$refs.map.clearMeasure();
          editor.open();
        });
      }
    },
    // TODO 隐藏路况
    setTraffic() {
      this.$refs.map.toggleTraffic();
    },
    // TODO 显示非关
    setStar() {
      this.$message.info("显示非关");
    },
    /**
     * @测距
     * @param {*} active 是否激活
     */
    setMeasure(active) {
      if (active) {
        this.$refs.map.measure("rule");
      } else {
        this.$refs.map.clearMeasure();
      }
    },
    setChair() {},
    /**
     * @历史消息
     */
    setHistory() {
      // this.$message.info("历史消息");
      this.isSingle = false;
      this.isComplete = true;
      this.conversationVisible = true;
    },
    /**
     * @地图清除覆盖物
     */
    clearMap() {
      // this.markers = [];
      this.cluster.dataOptions = [];
      this.$refs.map.map.clearMap();
    },
    onShowStationTypes() {
      this.markers = [];
    },
    /**
     * @驻勤点类型获取驻勤点信息
     */
    onGetStationsByType(data) {
      console.log(data);
      this.markers = [];

      data.forEach((info) => {
        getStationDetail(info.id)
          .then((station) => {
            this.info = station;
            station["type"] = "station";
            this.markers.push({
              position: [Number(station.longitude), Number(station.latitude)],
              anchor: "bottom-center",
              icon: {
                image: station.stationTypes[0].mapIcon,
                imageSize: [56, 56],
              },
              extData: station,
            });
          })
          .catch((err) => {
            console.log(err);
          });
      });
      if (data && data.length > 0) {
        const coordinates = [data[0].longitude, data[0].latitude]; //取一个经纬度跳转
        this.$refs.map.setZoomAndCenter(7, coordinates);
      }
    },
    /**
     * @文字调度事件-单人
     */
    character(info) {
      im.character(info).then(() => {
        this.isSingle = true;
        this.isComplete = false;
        this.conversationVisible = true;
      });
    },
    openGroupFormDialog() {
      if (this.memberList.length > 0) {
        this.isSingle = false;
        this.form.memberList = this.stationEmployeesList.filter((x) => x.active);
        this.groupFormDialogVisible = true;
      } else {
        this.$store.commit("showMessage", { message: "至少选择一名被调度人" });
      }
      console.log(this.form);
    },
    participantJoined(userId) {
      console.log("on participantJoined", userId);
      // this.memberList.forEach((member) => {
      //   if (member.tencentUserId === userId) {
      //     member.state = "CONNECTED";
      //   }
      // });
    },
    participantLeft(userId) {
      console.log("on participantLeft", userId);
      this.allMembers.forEach((member) => {
        if (member.tencentUserId === userId) {
          member.active = false;
        }
      });
    },
    onHangup() {
      this.allMembers.forEach((member) => {
        member.checked = false;
      });
      this.memberList.forEach((member) => {
        member.state = "CONNECTING";
      });
    },
    // * 发起多人会议
    openGroupCall: _.debounce(function (type) {
      console.log("call type", type);
      this.memberList.forEach((member) => {
        member.state = "CONNECTING";
        member.action = "";
      });
      console.log("openGroupCall", this.memberList);
      if (this.memberList.length > 0) {
        if (this.memberList.length <= 5) {
          if (this.dispatchClient === "wildfire") {
            this.isSingle = false;
            const createOpts = {
              title: "指挥调度",
              audience: true,
              allowTurnOnMic: true,
              advance: false,
            };
            const users = [...this.memberList].map((x) => {
              return {
                uid: x.tencentUserId,
                displayName: x.name,
              };
            });
            console.log(users);
            const audioOnly = type === "audio";
            const muteVideo = type !== "video";
            // type:audio语音，video视频，videoup视频上拉；
            const extraType = audioOnly ? "audio" : muteVideo ? "videoup" : "video";
            this.callType = extraType;
            const extra = `{"type": "${extraType}","initiator": "${this.sysUserInfo.name}","organization": "${this.sysUserInfo.deviceName}"}`;
            createJoinAndInviteConference(createOpts, audioOnly, false, muteVideo, users, "指挥调度", extra);
          } else {
            this.setCallProps(type).then(() => {
              this.startVideoDispatch();
            });
          }
        } else {
          this.$store.commit("showMessage", { message: "最多选择5名被调度人" });
        }
      } else {
        this.$store.commit("showMessage", { message: "至少选择一名被调度人" });
      }
    }, 500),
    /**
     * 创建群聊并打开对讲弹框
     */
    openPPTCall() {
      const users = [...this.memberList].map((x) => {
        return {
          uid: x.tencentUserId,
          displayName: x.name,
        };
      });
      // 创建会话
      store.createConversation(
        users,
        () => {
          // 打开ppt-client弹框
          this.pttVisible = true;
        },
        null,
        "临时组"
      );
    },
    dismissGroup(done) {
      store.dismissGroup(store.state.conversation.currentConversationInfo.conversation.target);
      done();
    },
    setCallProps(type) {
      if (type === "video") {
        this.stream.video = true;
        this.stream.audio = true;
        this.callType = "video";
        this.yardmanType = "1";
      } else if (type === "audio") {
        this.stream.video = false;
        this.stream.audio = true;
        this.callType = "audio";
        this.yardmanType = "1";
      } else if (type === "videoLocalMute") {
        this.stream.video = false;
        this.stream.audio = true;
        this.callType = "video";
        this.yardmanType = "2";
      }
      return Promise.resolve();
    },
    closeGroupFormDialog() {},
    startDispatch(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.createGroup();
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    cancelDispatch(formName) {
      this.$refs[formName].resetFields();
      this.groupFormDialogVisible = false;
    },
    /**
     * @创建多人群聊
     */
    createGroup() {
      im.createGroup(this.form).then(() => {
        // 关闭调度弹框、发送默认信息
        this.groupFormDialogVisible = false;
        this.isComplete = false;
        this.conversationVisible = true;
      });
    },
    showGroupConversation({ group }) {
      console.log("group data ===", group);
      tim.getConversationProfile(`GROUP${group.groupID}`).then(({ data }) => {
        console.log(data);
        this.$store.commit("updateCurrentConversation", data.conversation);
        this.$store.dispatch("checkoutConversation", data.conversation.conversationID);
        const { conversationID } = data.conversation;
        this.$store.dispatch("getMessageList", conversationID);
        console.log(this.currentConversation);
        this.groupFormDialogVisible = false;
        this.isComplete = false;
        this.conversationVisible = true;
      });
      this.closeCreateGroupModel();
    },
    closeCreateGroupModel() {
      this.$store.commit("updateCreateGroupModelVisible", false);
    },
    getOptions() {
      let options = {
        ...this.form,
        memberList: this.form.memberList.map((x) => {
          return { userID: x.tenantImUserId + "" };
        }),
      };
      if ([this.TIM.TYPES.GRP_WORK, this.TIM.TYPES.GRP_AVCHATROOM].includes(this.form.type)) {
        delete options.joinOption;
      }
      return options;
    },
    onCloseConversation() {
      this.conversationVisible = false;
    },
    handleImgError() {
      this.isImgError = true;
    },
    startVideoDispatch() {
      this.$bus.$emit("video-call");
    },
    //ws初始化
    initWs() {
      const dispatchToken = localStorage.getItem("dispatchToken");
      if (!dispatchToken) return false;
      this.webSocketUrl = `/websocket/police_incidents?dispatchToken=${dispatchToken}`;
      this.ws = _webSocket({
        url: this.webSocketUrl,
        onMessage: this.onMessage,
        heart: {
          timer: 5000,
          message: "keep alive",
        },
        isReconnect: true,
        onClose: this.onClose,
      });
    },
    onClose() {
      this.initWs();
    },
    onMessage(evt) {
      if (evt) {
        if (evt.data.includes("keep alive")) {
          //心跳
        } else {
          console.log("eventdata", evt.data);
          const data = JSON.parse(evt.data);
          console.log("ws data ===", data);
          const { type, message } = data;
          if (type === "PoliceIncidents") {
            const content = message.contents[0];
            if (content.category === "Sos") {
              this.SOSHandler(content);
            } else {
              if (this.$refs.mapsearch.policeIncidentsShow) this.$refs.mapsearch.showPoliceIncidents(true);
              let levelName = ""; //警情等级
              let levelNameColor = ""; //警情等级颜色
              this.levelNameList.forEach((item) => {
                if (item.level === content.level) {
                  levelName = item.label;
                  levelNameColor = item.bgColor;
                }
              });
              const h = this.$createElement;
              this.$message({
                customClass: "custom-message",
                dangerouslyUseHTMLString: true, //自定义html
                message: h("div", { class: "warning-message" }, [
                  h("div", { class: "icon-warning" }, ""),
                  h(
                    "div",
                    {
                      style:
                        "padding: 0 2px;margin-right: 8px;background:" +
                        levelNameColor +
                        ";height:24px;line-height: 24px;font-size: 14px;color: #ffffff;",
                    },
                    levelName
                  ),
                  h("div", { class: "message" }, content.reason),
                  h(
                    "div",
                    {
                      class: "btn-handle",
                      on: {
                        click: () => {
                          this.$refs.mapsearch.policeIncidentsShow = true;
                          this.$refs.mapsearch.lookDetail(content, true);
                        },
                      },
                    },
                    "立即处理"
                  ),
                ]),
                duration: 10000, //显示时间 10秒
                // type: "warning",
              });
            }
          } else if (type === "TRTC") {
            const content = message.contents[0];
            console.log(content);
            const { action, tencentUserId, roomId } = content;
            // 如果不是本人的房间直接忽略
            if (this.roomId && roomId === this.roomId) {
              if (action === "handUp" || action === "cheese") {
                this.$message.info("有1人举手");
              }
              this.memberList.forEach((member) => {
                if (member.tencentUserId === tencentUserId) {
                  member.action = action;
                }
              });
              console.log(this.memberList);
            }
          }
        }
      }
    },
    async SOSHandler(content) {
      const { longitude, latitude, empName, reason } = content;
      const employeeData = await getEmployeeDetail(content.employeeId);
      const position = [longitude, latitude];
      // this.markers = [];
      this.markers.push({
        position,
        anchor: "bottom-center",
        icon: require("@/assets/images/mapSearch/在岗_保安员.png"),
        extData: {},
      });
      // TODO: data = await getEmployeeDetail
      const data = {
        name: empName,
        content: reason,
        ...employeeData,
      };
      this.info = { type: "SOS", ...data };
      console.log(this.info);
      // debugger
      this.infoWindow.SOS.position = position;
      this.$refs.map.setZoomAndCenter(12, position);
    },
    openCallBySOS() {
      this.markers = [];
      this.infoWindow.SOS.position = undefined;
      // this.info.id
      this.videoLocalMute();
    },
    onDispatchWindowClose() {
      console.log("onDispatchWindowClose");
      this.allMembers = [];
    },
    onRailDispatchClose() {
      this.allMembers = [];
      this.showDutyCheckbox = false;
      this.railDispatchShow = false;
    },
    clickAllDuty() {
      console.log(this.stationEmployeesList);
      this.stationEmployeesListType = "all";
      this.showDutyCheckbox = false;
    },
    clickOnDuty() {
      this.stationEmployeesListType = "on";
      this.showDutyCheckbox = true;
    },
    clickNoDuty() {
      this.stationEmployeesListType = "off";
      this.showDutyCheckbox = false;
    },
    onCheckDuty(val) {
      console.log(val);
      if (val) {
        this.stationEmployeesListFilter.forEach((x) => (x.active = true));
        this.totalNum = 0;
        this.memberList = [];
        this.stationEmployeesListFilter.forEach((employee) => {
          employee.active = true;
          this.memberList.push(employee);
        });
        this.totalNum = this.memberList.length;
      } else {
        this.stationEmployeesListFilter.forEach((x) => (x.active = false));
        this.totalNum = 0;
        this.memberList = [];
      }
      this.isIndeterminate = false;
    },
    setItemPhoneVisible(item) {
      item.isPhone = !item.isPhone;
    },
    onConnectionStatusChange(status) {
      if (
        status === ConnectionStatus.ConnectionStatusRejected ||
        status === ConnectionStatus.ConnectionStatusLogout ||
        status === ConnectionStatus.ConnectionStatusSecretKeyMismatch ||
        status === ConnectionStatus.ConnectionStatusTokenIncorrect ||
        status === ConnectionStatus.ConnectionStatusKickedOff ||
        // TODO 断网时，显示网络断开状态
        // || status === ConnectionStatus.ConnectionStatusUnconnected
        wfc.getUserId() === ""
      ) {
        // if (this.$router.currentRoute.path !== "/") {
        //   this.$router.replace({ path: "/" });
        // }
        if (this.pageName !== "ConversationPage") {
          // this.pageName = "ConversationPage";
          this.$store.commit("SET_PAGE_NAME", "ConversationPage");
        }
        if (
          status === ConnectionStatus.ConnectionStatusSecretKeyMismatch ||
          status === ConnectionStatus.ConnectionStatusLogout ||
          status === ConnectionStatus.ConnectionStatusTokenIncorrect ||
          status === ConnectionStatus.ConnectionStatusKickedOff ||
          status === ConnectionStatus.ConnectionStatusRejected
        ) {
          removeItem("wfcUserId");
          removeItem("wfcToken");

          avenginekitproxy.forceCloseVoipWindow();
          console.error("连接失败", ConnectionStatus.desc(status));
        }
      }
    },
    closePTT() {
      this.dismissGroup(() => {
        this.pttVisible = false;
      });
    },
  },
  async created() {
    this.initWs();
    // this.loginWithAuthCode();
    this.stationTypes = await getAllStationTypes(); //获取驻勤点信息
    const userInfo = localStorage.getItem("userInfo");
    if (userInfo) {
      this.isCompany = JSON.parse(userInfo).role === "Company" || JSON.parse(userInfo).role === "Proprietor";
    }
    if (this.dispatchClient === "wildfire") {
      wfc.eventEmitter.on(EventType.ConnectionStatusChanged, this.onConnectionStatusChange);
      this.onConnectionStatusChange(wfc.getConnectionStatus());
      if (!isElectron() && !avenginkitSetuped) {
        avenginekit.setup();
        avenginkitSetuped = true;
      }
    }
  },
  mounted() {
    if (this.dispatchClient === "wildfire") {
      avenginekitproxy.onVoipCallErrorCallback = (errorCode) => {
        if (errorCode === -1) {
          this.$notify({
            title: "不能发起或接听新的音视频通话",
            text: "目前有音视频通话正在进行中",
            type: "warn",
          });
        } else if (errorCode === -2) {
          if (isElectron()) {
            console.error(`不支持音视频通话，原因可能是:
                        1. 可通过这个网页测试浏览器对音视频通话的支持情况，https://docs.wildfirechat.cn/webrtc/abilitytest/
                        2. 确保系统已授予当前应用 摄像头 和 麦克风 权限
                    `);
          } else {
            console.error(`不支持音视频通话，原因可能是:
                        1. 浏览器上，只有通过 http://localhost 或 https://xxxx 访问的网页才支持音视频通话
                        2. 可通过这个网页测试浏览器对音视频通话的支持情况，https://docs.wildfirechat.cn/webrtc/abilitytest/
                        3. 确保浏览器已授予网页 摄像头 和 麦克风 权限
                        4. 确保系统已授予浏览器 摄像头 和麦克风 权限
                        5. 配置 https，请参考：https://docs.wildfirechat.cn/faq/web/https.html
                    `);
          }
          this.$notify({
            title: "不支持音视频通话",
            text: "请到手机上接听音视频通话",
            type: "warn",
          });
        }
      };
    }
  },
};
</script>

<style scoped lang="scss">
@import "~@/styles/infoWindow.scss";

.page {
  position: relative;

  .map {
    z-index: 1;
  }

  .map-search {
    z-index: 2;
  }
}

::v-deep .amap-marker-label {
  background: none;
  border: none;
  text-align: center;
  color: #fff;
  font-size: 16px;
}

.rail-dispatch {
  z-index: 2;
  background: #ffffff;
  position: absolute;
  top: 20%;
  right: 30%;
  width: 890px;
  height: 512px;
  box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
  border-radius: 4px 4px 4px 4px;

  .header {
    height: 40px;
    /* border-bottom: 1px solid #bdcfde; */
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 7px 12px 0 12px;
    text-align: right;

    .title {
      font-size: 16px;
      font-weight: 500;
      color: #333333;
    }

    i {
      cursor: pointer;
      font-size: 16px;
      color: #999999;
    }
  }

  .scroll {
    height: 400px;
    overflow-y: auto;
    overflow-x: hidden;
    display: grid;
    gap: 22px;
    grid-template-rows: 1fr;
    margin: 0px auto;
    grid-template-columns: repeat(2, 1fr);
    // padding: 0 24px;

    .scroll-item {
      // width: 340px;
      height: 173px;
      cursor: pointer;
      border-bottom: 1px solid #bdcfde;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .scroll-photo {
        margin: 0 auto;
        flex: 1;

        &-name {
          width: 70px;
          height: 70px;
          background: #0e71ff;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 14px;
          color: #fff;
          margin: 0 auto;
        }

        &-checkbox {
          width: 16px;
          height: 16px;
          margin: 12px auto;

          .gx {
            width: 16px;
            height: 16px;
          }

          .no-select {
            width: 16px;
            height: 16px;
            border: 1px solid #000000;
            border-radius: 4px;
          }

          //修改选择框的颜色
          ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner,
          ::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__inner {
            border-color: #1677ff !important;
            background-color: #1677ff !important;
          }

          ::v-deep .el-checkbox__input.is-focus .el-checkbox__inner {
            border-color: #1677ff !important;
          }

          //修改选中后文本的颜色
          ::v-deep .el-checkbox__input.is-checked + .el-checkbox__label {
            color: #1677ff !important;
          }
        }
      }

      .scroll-detail {
        // width: 246px;
        flex: 2;
        display: flex;
        align-items: center;
        justify-content: space-between;

        .detail-box {
          //width: 196px
        }

        .detail-item {
          display: flex;
          align-items: center;
          margin-left: 14px;
          margin-bottom: 8px;
          color: #000000;
          font-size: 12px;

          .label {
            //width: 100px;
            color: rgba(0, 0, 0, 0.65);
          }

          .value {
            //width: 185px;
            display: flex;
            align-items: center;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;

            img {
              width: 16px;
              height: 16px;
              margin-left: 8px;
            }
          }
        }

        .gx {
          width: 16px;
          height: 16px;
        }

        .no-select {
          width: 16px;
          height: 16px;
          border: 1px solid #000000;
          border-radius: 4px;
        }
      }

      &-SignOut {
        .scroll-detail {
          .detail-item {
            cursor: not-allowed;

            .label {
              //width: 100px;
              color: #d9d9d9;
            }

            color: #d9d9d9;
          }

          .no-select {
            width: 16px;
            height: 16px;
            background: #e6e6e6;
            border: 1px solid #d9d9d9;
          }
        }
      }

      &-None {
        .scroll-detail {
          .detail-item {
            cursor: not-allowed;

            .label {
              //width: 100px;
              color: #d9d9d9;
            }

            color: #d9d9d9;
          }

          .no-select {
            width: 16px;
            height: 16px;
            background: #e6e6e6;
            border: 1px solid #d9d9d9;
          }
        }
      }
    }
  }

  .scroll-footer {
    //margin-top: 5px;
    height: 80px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    padding: 5px 24px 24px 24px;

    .footer-total {
      display: flex;
      align-items: center;
      color: #5e5e5e;
      font-size: 14px;

      span {
        color: #000000;
        margin: 0 8px;
      }
    }

    .footer-btn {
      display: flex;
      align-items: center;
      margin-top: 5px;

      .btn {
        margin-right: 8px;
        width: 88px;
        height: 28px;
        background: #ffffff;
        color: #0e70ff;
        border-radius: 4px;
        border: 1px solid #0e70ff;
        font-size: 14px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
      }

      .active {
        color: #fff;
        background: #0e70ff;
      }
    }
  }
}

.href-to {
  color: #0e70ff;
  text-decoration: underline;
  cursor: pointer;
  margin-top: 16px;
}

.back-to {
  color: #0e70ff;
  cursor: pointer;
  margin-top: 16px;
}

.circle-style {
  width: 60px;
  height: 60px;
  background: #0e71ff;
  border-radius: 30px 30px 30px 30px;
  opacity: 1;
  font-size: 14px;
  font-weight: 400;
  color: #ffffff;
  float: left;
  text-align: center;
  line-height: 60px;
}

.circle-detail {
  margin-left: 84px;

  .detail-item {
    display: flex;
    align-items: center;
    color: #000000;
    font-size: 14px;

    &:nth-last-child(1) {
      margin-bottom: 14px;
    }

    .detail-item-label {
      color: #000000;
    }

    .detail-item-value {
    }

    img {
      width: 16px;
      height: 16px;
      cursor: pointer;
      margin-left: 8px;
    }
  }
}

.employee-item {
  padding-left: 10px;
  width: 220px;
  height: 63px;
  font-size: 12px;
  float: left;
}

::v-deep .group-form {
  .el-dialog__body {
    padding: 0;

    .memberList {
      width: 100%;
      padding: 0 10px;
      height: 110px;
      background-color: #f5f9ff;
      position: relative;
      white-space: nowrap;
      overflow-x: auto;
      overflow-y: hidden;
      display: flex;
      align-items: center;

      .member-item {
        display: flex;
        flex-direction: column;
        align-items: center;

        .avatar {
          width: 100%;
          height: 100%;
          border-radius: 50%;
          overflow: hidden;
          margin-right: 16px;
          background: #0e71ff;
          font-size: 16px;
          font-weight: 400;
          color: #ffffff;

          img {
            width: 100%;
            height: auto;
          }
        }

        .nick {
          font-size: 14px;
          //font-weight: 400;
          //color: #000000;
          //margin-left: 16px;
          line-height: 21px;
        }
      }
    }

    .content {
      .notice {
        color: rgb(236, 173, 32);
      }

      .dispatch-content {
        padding: 24px;
      }
    }
  }
}

.chat-wrapper {
  width: 100vw;
  height: 100vh;
  box-shadow: 0 11px 20px 0 rgba(0, 0, 0, 0.3);

  .official-link {
    display: flex;
    text-decoration: none;
    color: #38c9ff;
    width: fit-content;
    float: right;
    height: 45px;
    align-items: center;
  }
}

.hide-show {
  font-size: 12px;
  font-family: PingFang SC-Regular, PingFang SC;
  font-weight: 400;
  color: #0e70ff;
  cursor: pointer;
  padding-left: 5px;
}

.voip-div-container {
  background: #292929;
  position: absolute;

  //transform: translate(-50%, -50%);
  margin: auto;
  border-radius: 5px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
  display: flex;
  flex-direction: column;
  z-index: 999;
}

.voip-div-container.single {
  //width: 360px;
  //height: 640px;
  top: calc(50vh - 436px);
  left: calc(50vw - 683px);
}

.voip-div-container.multi {
  width: 960px;
  height: 600px;
  top: calc(50vh - 300px);
  left: calc(50vw - 480px);
}

.voip-div-container.conference {
  width: 1366px;
  height: 700px;
  top: calc(50vh - 400px);
  left: calc(50vw - 680px);
}

.voip-div-container .title {
  text-align: center;
  padding: 5px 0;
  background: #b6b6b6;
  display: flex;
  justify-content: center;
  align-content: center;
}

.voip-div-container .title i {
  pointer-events: none;
}

.voip-div-container .title i:hover {
  color: #868686;
}

.voip-div-container .title i:active {
  color: #868686;
}

.voip-div-container .content {
  flex: 1;
  border: none;
}
::v-deep .ptt-dialog {
  .el-dialog__body {
    padding: 10px;
  }
}
</style>
