<template>
  <div class="DPcomputer16Box">
    <!-- 人工调度 -->
    <div class="DPcomputer16Box_1">
      <div class="intelligentSchScrView_leftView_title">人工调度</div>
      <div class="intelligentSchScrView_leftView_content">
        <div class="voiceAppContent_1">
          <div>选择车队：</div>
          <el-select v-model="selectCarFleet" placeholder="请选择车队" style="width:14vw;" @change="toSearchFn()">
            <el-option v-for="(item,index) in carFleetData" :key="index" :label="item.name" :value="item.name"
                       style="font-size:18px;"></el-option>
          </el-select>
        </div>
        <div class="voiceAppContent_2">
          <div class="voiceAppContent_2_title">选择车辆</div>
          <div class="voiceAppContent_2_content">
            <el-checkbox-group v-model="selectCarRadioArray">
              <el-checkbox v-for="(item,index) in carsInforData" :label="item" :key="index" style="margin-top:7px;">
                <div style="width:12vw;margin-left:1.7vw;text-align: center;">
                  {{ item.number }}({{ item.odo == 0 ? '离线' : item.odo == 1 ? '智能调度' : item.odo == 2 ? '人工调度' : item.odo == 3 ? '在线' : '其他作业' }})
                </div>
              </el-checkbox>
            </el-checkbox-group>
          </div>
        </div>
        <div class="voiceAppContent_3">
          <div class="voiceAppContent_2_title">已选中车辆</div>
          <div class="voiceAppContent_3_content">
            <div v-for="(item,index) in selectCarRadioArray" :key="index" class="voiceAppContent_3_content_selectCar">
              <div>{{ item.number }}</div>
              <div
                style="width:20px;height:20px;background-color: rgb(4,112,171);text-align: center;font-size:30px;line-height:20px;cursor: pointer;"
                @click="cancelSelect(index)">
                <span>×</span>
              </div>
            </div>
          </div>
        </div>
        <div class="voiceAppContent_4">
          <button class="voiceAppContent_4_btns" @click="toNoticeFn('广播')">广播</button>
          <button class="voiceAppContent_4_btns" @click="toNoticeFn('紧急通知')">紧急通知</button>
          <button class="voiceAppContent_4_btns" @click="toNoticeFn('通话')">通话</button>
          <button class="voiceAppContent_4_btns" @click="todispatchChange()">{{ dispatchBtnTitle }}</button>
        </div>
      </div>
    </div>

    <!-- 语音所需内容，隐藏无需展示 -->
    <div class="main">
      <slot name="top"></slot>

      <div class="mainBox">
        <div class="btns">
          <div>
            <button @click="recOpen">打开录音,请求权限</button>
            <button @click="recClose">关闭录音,释放资源</button>
          </div>

          <button @click="recStart">录制</button>
          <button @click="recStop" style="margin-right:80px">停止</button>

          <span style="display: inline-block;">
						<button @click="recPause">暂停</button>
						<button @click="recResume">继续</button>
					</span>
          <span style="display: inline-block;">
						<button @click="recPlayLast">播放</button>
						<button @click="recUploadLast">上传</button>
					</span>
        </div>
      </div>

      <div class="mainBox">
        <div
          style="height:100px;width:300px;border:1px solid #ccc;box-sizing: border-box;display:inline-block;vertical-align:bottom"
          class="ctrlProcessWave"></div>
        <div
          style="height:40px;width:300px;display:inline-block;background:#999;position:relative;vertical-align:bottom">
          <div class="ctrlProcessX" style="height:40px;background:#0B1;position:absolute;"
               :style="{width:powerLevel+'%'}"></div>
          <div class="ctrlProcessT" style="padding-left:50px; line-height:40px; position: relative;">
            {{ duration + "/" + powerLevel }}
          </div>
        </div>
      </div>

      <div class="mainBox">
        <audio ref="LogAudioPlayer" style="width:100%"></audio>

        <div class="mainLog">

        </div>
      </div>

      <div v-if="recOpenDialogShow"
           style="z-index:99999;width:100%;height:100%;top:0;left:0;position:fixed;background:rgba(0,0,0,0.3);">

      </div>

      <slot name="bottom"></slot>
    </div>

    <div class="mengceng1" v-if="mengcengshow"></div>

    <!-- 语音区域组件 -->
    <div class="videoListView" v-if="dialogVisible">
      <div class="videoListView_title">{{ dialogTitle }}</div>
      <div style="color:white;font-size:14px;margin-bottom:1vh;">若无选中车辆，默认对所有车辆发起</div>
      <div class="videoListView_content">
        <div v-for="(item,index) in tanchuCarListArray" :label="item" :key="index">{{ item.number }}</div>
      </div>
      <div style="margin-top:10px;display: flex;justify-content: space-evenly;flex-wrap: wrap;">
        <el-button type="primary" style="height:3.5vh;width:40%;font-size: 16px;" @click="recStart">录制语音</el-button>
        <el-button type="primary" style="height:3.5vh;width:40%;font-size: 16px;" @click="recStop">结束语音</el-button>
      </div>
      <div style="margin-top:10px;display: flex;justify-content: space-evenly;flex-wrap: wrap;">
        <el-button type="primary" style="height:3.5vh;width:40%;font-size: 16px;" @click="recUploadLast">上传语音
        </el-button>
        <el-button style="height:3.5vh;width:40%;font-size: 16px;" @click="quxiaoVideo()">取消语音</el-button>
      </div>
    </div>

    <!-- 人工调度组件 -->
    <div class="peopleScheAssembly" v-if="peopleScheAssemblyShow">
      <div style="color:white;font-size:14px;margin-bottom:1vh;font-size: 18px;font-weight: 600;">人工调度详情</div>

      <el-form size="small" label-width="100px" :rules="rules">
        <el-form-item label="装载区" style="display: inline-block;" class="des1">
          <el-cascader v-model="zaDestination" :options="caiquData1" :props="{checkStrictly:true}"></el-cascader>
        </el-form-item>
        <el-form-item label="卸点区" style="display: inline-block;" class="des1">
          <el-select v-model="xzDestination" placeholder="请选择卸点区">
            <el-option v-for="(obj,index) in xiequData1" :label="obj.name" :value="obj.name" :key="index"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="时长" style="display: inline-block;" class="des1">
          <el-select v-model="desform.duration" placeholder="请选择调度时长">
            <el-option label="单次" value="单次"></el-option>
            <el-option label="一天" value="一天"></el-option>
            <el-option label="长期" value="长期"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="截止日期" style="display: inline-block;" class="des1">
          <el-date-picker v-model="desform.endTime" type="datetime" placeholder="选择日期时间" style="width:200px;"
                          :disabled='desform.duration != "长期" '></el-date-picker>
        </el-form-item>
        <el-form-item label="说明" style="display: inline-block;" class="des1">
          <el-input type="textarea" v-model="desform.carshow" style="width:200px;"></el-input>
        </el-form-item>
      </el-form>

      <div class="peopleScheAssemblyBtns">
        <el-button type="primary" style="height:40px;width:100px;font-size: 16px;" round
                   @click="peopleScheAssemblyFn()">确定
        </el-button>
        <el-button style="height:40px;width:100px;font-size: 16px;" round @click="peopleScheAssemblyCloseFn()">取消
        </el-button>
      </div>

    </div>

  </div>
</template>

<script>
import {Tools, HttpReq, Dates} from '@/assets/js/common.js';
//加载必须要的core，demo简化起见采用的直接加载类库，实际使用时应当采用异步按需加载
import Recorder from 'recorder-core'
// //需要使用到的音频格式编码引擎的js文件统统加载进来，这些引擎文件会比较大
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
// //可选的扩展
import 'recorder-core/src/extensions/waveview'


export default {
  data() {
    return {
      DPcomputer16BoxTimer: null,
      heartbeatTimer: null,
      websocket: null,
      selectCarFleet: '', //搜索对应车队
      carFleetData: [], //车队信息
      carsInforData: [], //车辆信息
      selectCarRadioArray: [], //多选选中车辆
      dispatchBtnTitle: '人工调度',
      dispatchBtnTitle1: '人工调度',
      dialogTitle: '广播车辆',
      dialogTitle1: '',
      dialogVisible: false,
      resultBlob: null,
      tanchuCarListArray: [], //弹出列表选中车辆
      mengcengshow: false,//蒙层

      //录音相关数据
      type: "mp3",
      bitRate: 16,
      sampleRate: 16000,
      rec: 0,
      duration: 0,
      powerLevel: 0,
      recOpenDialogShow: 0,
      logs: [],

      //人工调度配置
      desform: {},
      caiquData1: [],
      xiequData1: [],
      zaDestination: [],
      xzDestination: '',
      destinationDataAll: [],//人工调度调度目的地列表
      peopleScheAssemblyShow: false,
      rules: {
        // odd: [
        // 	{required: true, message: '请输入调度单号', trigger: 'blur' }
        // ],
      },

    }
  },
  mounted() {
    this.loadData();
  },
  methods: {
    loadData() {
      this.selectCarFleet = '';
      this.dialogVisible = false;
      this.mengcengshow = false;
      this.selectCarRadioArray = [];
      this.tanchuCarListArray = [];
      this.peopleScheAssemblyShow = false;
      this.desform = {};
      this.zaDestination = [];
      this.xzDestination = '';

      this.$nextTick(() => {
        //车队信息
        HttpReq.truckDispatching.carFleetQuery({size: 9999}).then((res) => {
          if (res.code == 200) {
            this.carFleetData = res.data.content;
          }
          ;
        })
        //车辆信息
        this.loadData2();
        //开启长连接
        this.loadData3();
        //获取区域信息
        this.loadData4();
        //定时器
        this.DPcomputer16BoxTimer = setInterval(() => {
          //车辆信息
          this.loadData2();
        }, 10000)
      })

      //开启录音
      this.recOpen();

    },
    //获取车辆信息
    loadData2() {
      let query = {};
      query.size = 9999;
      query.road = this.selectCarFleet;
      HttpReq.truckDispatching.carInformationQuery(query).then((res) => {
        if (res.code == 200) {
          this.carsInforData = res.data.content;
        }
        ;
      })
    },
    //页面刚进入时开启长连接
    loadData3() {
      this.initWebSocket();
      this.heartbeatTimer = setInterval(() => {
        this.reconnect();
      }, 20000)
    },
    //获取区域信息
    loadData4() {
      HttpReq.truckDispatching.RegionalInformationQuery({size: 9999}).then((res) => {
        if (res.code == 200) {
          let caiqu1 = [];
          let xiequ1 = [];
          res.data.content.forEach((item, index) => {
            if (item.areaclass == '采区') {
              caiqu1.push(item);
            } else if (item.areaclass == '卸区') {
              xiequ1.push(item);
            }
          });
          this.$nextTick(() => {
            let caiquCenArr1 = [];
            caiqu1.forEach((item1, index1) => {
              let caiquCenObj1 = {};
              caiquCenObj1.value = item1.name;
              caiquCenObj1.label = item1.name;
              HttpReq.truckDispatching.RegionalCaiDianQuery({size: 9999, areaName: item1.name}).then((res1) => {
                if (res1.code == 200 && res1.data.totalElements != 0) {
                  let caiquCenArr2 = [];
                  res1.data.content.forEach((item2, index2) => {
                    let caiquCenObj2 = {};
                    caiquCenObj2.value = item2.name;
                    caiquCenObj2.label = item2.name;
                    caiquCenArr2.push(caiquCenObj2);
                  })
                  caiquCenObj1.children = caiquCenArr2;
                }
                ;
              })
              caiquCenArr1.push(caiquCenObj1);
            });
            this.caiquData1 = caiquCenArr1;
            this.xiequData1 = xiequ1;
          })
        }
        ;
      })
    },
    //关闭长连接
    xintiaoCloseFn() {
      //页面销毁时关闭长连接
      this.websocketclose();
      //关闭录音
      this.recClose();
    },
    //搜索车辆
    toSearchFn() {
      this.loadData2();
    },
    //车辆多选取消
    cancelSelect(index) {
      let handleArray = [...this.selectCarRadioArray];
      handleArray.splice(index, 1);
      this.selectCarRadioArray = handleArray;
    },
    //发起通知
    toNoticeFn(text) {
      if (text == '广播') {
        this.dialogTitle = '广播车辆';
      } else if (text == '紧急通知') {
        this.dialogTitle = '接到通知的车辆';
      } else if (text == '通话') {
        this.dialogTitle = '连麦的车辆';
      }
      this.dialogTitle1 = text;
      if (JSON.stringify(this.selectCarRadioArray) == '[]') {
        this.tanchuCarListArray = this.carsInforData;
      } else {
        this.tanchuCarListArray = this.selectCarRadioArray;
      }
      this.dialogVisible = true;
      this.mengcengshow = true;
      //关闭人工调度组件
      this.peopleScheAssemblyShow = false;
      this.desform = {};
      this.zaDestination = [];
      this.xzDestination = '';
    },
    //人工调度和智能调度切换
    todispatchChange() {
      if (this.dispatchBtnTitle == '人工调度') {
        this.peopleScheAssemblyShow = true;
      }
      //关闭发起通知组件
      this.dialogVisible = false;
      this.mengcengshow = true;
      this.tanchuCarListArray = [];
    },
    //取消发送语音
    quxiaoVideo() {
      this.dialogVisible = false;
      this.mengcengshow = false;
      this.tanchuCarListArray = [];
      this.selectCarRadioArray = [];
    },
    //发起人工调度
    peopleScheAssemblyFn() {
      if (JSON.stringify(this.selectCarRadioArray) == '[]') {
        this.$notify({
          title: '请选择调度车辆！',
          type: 'warning',
          duration: 2500
        });
        return
      }
      if (JSON.stringify(this.zaDestination) == '[]' && !this.xzDestination) {
        this.$notify({
          title: '请选择调度装载区或卸点区！',
          type: 'warning',
          duration: 2500
        });
        return
      }
      if (!this.desform.duration) {
        this.$notify({
          title: '请选择调度时长！',
          type: 'warning',
          duration: 2500
        });
        return
      }
      if (this.desform.duration == '长期' && !this.desform.endTime) {
        this.$notify({
          title: '请选择调度截止日期！',
          type: 'warning',
          duration: 2500
        });
        return
      }
      this.selectCarRadioArray.forEach((item, index) => {
        if (JSON.stringify(this.zaDestination) != '[]') {
          let query1 = {...this.desform};
          query1.carNo = item.number;
          query1.flag = 1;
          if (this.zaDestination.length == 1) {
            HttpReq.truckDispatching.RegionalCaiDianQuery({
              size: 9999,
              areaName: this.zaDestination[0]
            }).then((res1Reg) => {
              if (res1Reg.code == 200 && res1Reg.data.totalElements != 0) {
                query1.destination = this.zaDestination[0] + '/' + res1Reg.data.content[0].name;
                HttpReq.truckDispatching.manualSchedulingAdd(query1).then((res) => {
                  if (res.code == 200) {

                  } else {
                    this.$notify({
                      title: res.msg,
                      type: 'error',
                      duration: 2500
                    })
                  }
                }).catch(function (error) {
                });
                HttpReq.truckDispatching.manualOrderAdd(query1).then((res) => {
                  if (res.code == 200) {

                  } else {
                    this.$notify({
                      title: res.msg,
                      type: 'error',
                      duration: 2500
                    })
                  }
                }).catch(function (error) {
                });
              }
              ;
            })
          } else {
            query1.destination = this.zaDestination[0] + '/' + this.zaDestination[1];
            HttpReq.truckDispatching.manualSchedulingAdd(query1).then((res) => {
              if (res.code == 200) {

              } else {
                this.$notify({
                  title: res.msg,
                  type: 'error',
                  duration: 2500
                })
              }
            }).catch(function (error) {
            });
            HttpReq.truckDispatching.manualOrderAdd(query1).then((res) => {
              if (res.code == 200) {

              } else {
                this.$notify({
                  title: res.msg,
                  type: 'error',
                  duration: 2500
                })
              }
            }).catch(function (error) {
            });
          }
        }
        if (this.xzDestination) {
          let query2 = {...this.desform};
          query2.carNo = item.number;
          query2.flag = 1;
          query2.destination = this.xzDestination;
          HttpReq.truckDispatching.manualSchedulingAdd(query2).then((res) => {
            if (res.code == 200) {

            } else {
              this.$notify({
                title: res.msg,
                type: 'error',
                duration: 2500
              })
            }
          }).catch(function (error) {
          });
          HttpReq.truckDispatching.manualOrderAdd(query2).then((res) => {
            if (res.code == 200) {

            } else {
              this.$notify({
                title: res.msg,
                type: 'error',
                duration: 2500
              })
            }
          }).catch(function (error) {
          });
        }
      })
      this.$notify({
        title: '人工调度发起成功！',
        type: 'success',
        duration: 2500
      });
      this.peopleScheAssemblyShow = false;
      this.mengcengshow = false;
      this.desform = {},
        this.zaDestination = [];
      this.xzDestination = '';
      this.selectCarRadioArray = [];

      //切换智能调度
      this.dispatchBtnTitle = '人工调度';
      this.dispatchBtnTitle1 = '人工调度';
      HttpReq.truckDispatching.recentNoticeAdd({noticeClass: this.dispatchBtnTitle1, flag: 0}).then((res) => {
        if (res.code == 200) {
          //近期通知列表
          HttpReq.truckDispatching.recentNoticeQuery({size: 50, sort: 'id,desc',}).then((res) => {
            if (res.code == 200) {
              this.recentNoticeData = res.data.content;
            }
            ;
          })
          //发起添加调度类型
          //HttpReq.truckDispatching.screenDispatchWayAdd({dispatcher:this.dispatchBtnTitle1}).then((res) => {})
        } else {
          this.$notify({
            title: res.msg,
            type: 'error',
            duration: 2500
          })
        }
      }).catch(function (error) {
      });

    },
    //取消人工调度
    peopleScheAssemblyCloseFn() {
      this.peopleScheAssemblyShow = false;
      this.mengcengshow = false;
      this.desform = {};
      this.zaDestination = [];
      this.xzDestination = '';
      this.selectCarRadioArray = [];
    },


    //初始化weosocket
    initWebSocket() {
      //const wsuri = "ws://114.116.108.246:81/websocket/socketServer?userId="+userId;//连接地址，可加参数
      const wsuri = process.env.VUE_APP_WS_API + "/" + 'pcBigScreen';
      this.websocket = new WebSocket(wsuri);
      this.websocket.onopen = this.websocketonopen;
      this.websocket.onerror = this.websocketonerror;
      this.websocket.onmessage = this.websocketonmessage;
      this.websocket.onclose = this.websocketclose;
      this.websocketonmessage();
    },
    //WebSocket连接成功
    websocketonopen() {
      console.log("WebSocket连接成功");
    },
    //WebSocket连接错误
    websocketonerror(e) {
      console.log("WebSocket连接发生错误");
    },
    //WebSocket数据接收
    websocketonmessage(e) {
      //console.log("e",e);
      if (e == undefined) {
        return
      } else {
        let obj1 = JSON.parse(e.data);
        HttpReq.truckDispatching.recentNoticeAdd({
          noticeClass: obj1.fromUserId,
          flag: 1,
          videoContent: obj1.contentText
        }).then((res) => {
        }).catch(function (error) {
        });
      }
    },
    //WebSocket数据发送
    websocketsend(agentData) {
      this.websocket.send(agentData);
    },
    //WebSocket关闭
    websocketclose(e) {
      //console.log("connection closed (" + e.code + ")");
      console.log("connection closed !");
    },
    //WebSocket重连
    reconnect() {
      var This = this;
      if (this.websocket.readyState === 1) { // that.websock.readyState = 1 表示连接成功，可以立即发送信息
        This.websocketonmessage();
      } else if (this.websocket.readyState === 0) { // 表示正在连接，设置300ms后发送信息
        setTimeout(function () {
          This.websocketonmessage();
        }, 300);
      } else { // 连接未创建或者创建失败，则重新创建连接，并设置500ms后发送信息
        This.initWebSocket();
        setTimeout(function () {
          This.websocketonmessage();
        }, 500);
      }
    },
    recOpen: function () {
      var This = this;
      var rec = this.rec = Recorder({
        type: This.type
        , bitRate: This.bitRate
        , sampleRate: This.sampleRate
        , onProcess: function (buffers, powerLevel, duration, sampleRate) {
          This.duration = duration;
          This.powerLevel = powerLevel;

          This.wave.input(buffers[buffers.length - 1], powerLevel, sampleRate);
        }
      });

      This.dialogInt = setTimeout(function () {//定时8秒后打开弹窗，用于监测浏览器没有发起权限请求的情况
        This.showDialog();
      }, 8000);

      rec.open(function () {
        This.dialogCancel();
        This.reclog("已打开:" + This.type + " " + This.sampleRate + "hz " + This.bitRate + "kbps", 2);

        This.wave = Recorder.WaveView({elem: ".ctrlProcessWave"});
      }, function (msg, isUserNotAllow) {
        This.dialogCancel();
        This.reclog((isUserNotAllow ? "UserNotAllow，" : "") + "打开失败：" + msg, 1);
      });

      This.waitDialogClickFn = function () {
        This.dialogCancel();
        This.reclog("打开失败：权限请求被忽略，用户主动点击的弹窗", 1);
      };
    },
    recClose: function () {
      var rec = this.rec;
      this.rec = null;
      if (rec) {
        rec.close();
        this.reclog("已关闭");
      } else {
        this.reclog("未打开录音", 1);
      }
    },
    recStart: function () {

      if (!this.rec || !Recorder.IsOpen()) {
        //this.reclog("未打开录音",1);
        this.recOpen()
        //return;
      }
      this.rec.start();

      var set = this.rec.set;
      this.reclog("录制中：" + set.type + " " + set.sampleRate + "hz " + set.bitRate + "kbps");
      this.$notify({
        title: '录制中！',
        type: 'success',
        duration: 5000
      });

    },
    recPause: function () {
      if (this.rec && Recorder.IsOpen()) {
        this.rec.pause();
      } else {
        this.reclog("未打开录音", 1);
      }
    },
    recResume: function () {
      if (this.rec && Recorder.IsOpen()) {
        this.rec.resume();
      } else {
        this.reclog("未打开录音", 1);
      }
    },
    recStop: function () {
      if (!(this.rec && Recorder.IsOpen())) {
        This.reclog("未打开录音", 1);
        This.$notify({
          title: '未打开录音！',
          type: 'warning',
          duration: 2500
        });
        return;
      }

      var This = this;
      var rec = This.rec;
      rec.stop(function (blob, duration) {
        This.reclog("已录制:", "", {
          blob: blob,
          duration: duration,
          rec: rec
        });
        This.$notify({
          title: '已录制！',
          type: 'success',
          duration: 2500
        });
      }, function (s) {
        This.$notify({
          title: '录音失败,' + s,
          type: 'warning',
          duration: 2500
        });
        This.reclog("录音失败：" + s, 1);
      });
      this.recOpen();
    },


    recPlayLast: function () {
      if (!this.recLogLast) {
        this.reclog("请先录音，然后停止后再播放", 1);
        return;
      }

      this.recplay(this.recLogLast.idx);
    },
    recUploadLast: function () {
      let carNumberString = '';
      this.tanchuCarListArray.forEach((item, index) => {
        carNumberString = carNumberString + item.number + ';';
      })
      carNumberString = carNumberString + 'pcBigScreen';
      this.carAllNumberString = carNumberString;

      var This = this;
      if (!this.recLogLast) {
        this.reclog("请先录音，然后停止后再上传", 1);
        This.$notify({
          title: '请先录音，然后停止后再上传！',
          type: 'warning',
          duration: 2500
        });
        return;
      }

      var blob = this.recLogLast.res.blob;
      this.blobToDataURI(blob);

      /***方式一：将blob文件转成base64纯文本编码 ***/
      var reader = new FileReader();
      reader.onloadend = function () {
        var postData = "";
        // postData+="mime="+encodeURIComponent(blob.type);//告诉后端，这个录音是什么格式的，可能前后端都固定的mp3可以不用写
        // postData+="&upfile_b64="+encodeURIComponent((/.+;\s*base64\s*,\s*(.+)$/i.exec(reader.result)||[])[1]) //录音文件内容，后端进行base64解码成二进制
        //postData = btoa(reader.result); //录音文件内容
        postData = This.resultBlob; //录音文件内容

        //发送语音数据
        if (This.websocket.readyState == 1) { // that.websock.readyState = 1 表示连接成功，可以立即发送信息
          This.websocketsend(`{"toUserId":"${This.carAllNumberString}","contentText":"${postData}","fromUserId":"${This.dialogTitle1}"}`);
          This.$notify({
            title: '上传成功！',
            type: 'success',
            duration: 2500
          });
        } else if (This.websocket.readyState == 0) { // 表示正在连接，设置300ms后发送信息
          setTimeout(function () {
            This.websocketsend(`{"toUserId":"${This.carAllNumberString}","contentText":"${postData}","fromUserId":"${This.dialogTitle1}"}`);
            This.$notify({
              title: '上传成功！',
              type: 'success',
              duration: 2500
            });
          }, 300);
        } else { // 连接未创建或者创建失败，则重新创建连接，并设置500ms后发送信息
          This.initWebSocket();
          setTimeout(function () {
            This.websocketsend(`{"toUserId":"${This.carAllNumberString}","contentText":"${postData}","fromUserId":"${This.dialogTitle1}"}`);
            This.$notify({
              title: '上传成功！',
              type: 'success',
              duration: 2500
            });
          }, 500);
        }
      };
      reader.readAsDataURL(blob);
    },


    reclog: function (msg, color, res) {
      var obj = {
        idx: this.logs.length
        , msg: msg
        , color: color
        , res: res

        , playMsg: ""
        , down: 0
        , down64Val: ""
      };
      if (res && res.blob) {
        this.recLogLast = obj;
      }
      this.logs.splice(0, 0, obj);
    },
    recplay: function (idx) {
      var This = this;
      var o = this.logs[this.logs.length - idx - 1];
      o.play = (o.play || 0) + 1;
      var logmsg = function (msg) {
        o.playMsg = '<span style="color:green">' + o.play + '</span> ' + This.getTime() + " " + msg;
      };
      logmsg("");

      var audio = this.$refs.LogAudioPlayer;
      audio.controls = true;
      if (!(audio.ended || audio.paused)) {
        audio.pause();
      }
      audio.onerror = function (e) {
        logmsg('<span style="color:red">播放失败[' + audio.error.code + ']' + audio.error.message + '</span>');
      };
      audio.src = (window.URL || webkitURL).createObjectURL(o.res.blob);
      audio.play();
    },
    recdown: function (idx) {
      var This = this;
      var o = this.logs[this.logs.length - idx - 1];
      o.down = (o.down || 0) + 1;

      o = o.res;
      var name = "rec-" + o.duration + "ms-" + (o.rec.set.bitRate || "-") + "kbps-" + (o.rec.set.sampleRate || "-") + "hz." + (o.rec.set.type || (/\w+$/.exec(o.blob.type) || [])[0] || "unknown");
      var downA = document.createElement("A");
      downA.href = (window.URL || webkitURL).createObjectURL(o.blob);
      downA.download = name;
      downA.click();
    },
    recdown64: function (idx) {
      var This = this;
      var o = this.logs[this.logs.length - idx - 1];
      var reader = new FileReader();
      reader.onloadend = function () {
        o.down64Val = reader.result;
      };
      reader.readAsDataURL(o.res.blob);
    },
    getTime: function () {
      var now = new Date();
      var t = ("0" + now.getHours()).substr(-2)
        + ":" + ("0" + now.getMinutes()).substr(-2)
        + ":" + ("0" + now.getSeconds()).substr(-2);
      return t;
    },
    intp: function (s, len) {
      s = s == null ? "-" : s + "";
      if (s.length >= len) return s;
      return ("_______" + s).substr(-len);
    },


    showDialog: function () {
      //我们可以选择性的弹一个对话框：为了防止移动端浏览器存在第三种情况：用户忽略，并且（或者国产系统UC系）浏览器没有任何回调
      if (!/mobile/i.test(navigator.userAgent)) {
        return;//只在移动端开启没有权限请求的检测
      }
      this.recOpenDialogShow = 1;
    },
    dialogCancel: function () {
      clearTimeout(this.dialogInt);
      this.recOpenDialogShow = 0;
    },
    waitDialogClick: function () {
      this.dialogCancel();
      this.waitDialogClickFn();
    },
    //blob流转base64编码
    blobToDataURI(blob) {
      let that = this;
      var reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = function () {
        that.resultBlob = reader.result;
      }
    },

  },
  beforeDestroy() {
    if (this.DPcomputer16BoxTimer) {
      clearInterval(this.DPcomputer16BoxTimer);
      this.DPcomputer16BoxTimer = null;
    }
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
    this.xintiaoCloseFn();
  }
}
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
}

.DPcomputer16Box {
  overflow: hidden;
  height: 64vh;
  position: relative;
}

.DPcomputer16Box_1 {
  width: 20vw;
  height: 64vh;
  background-color: rgba(32, 42, 67, 0.95);
  padding: 5px 7px;
  box-sizing: border-box;
  overflow: hidden;
}

.DPcomputer16Box .mengceng1 {
  width: 20vw;
  height: 64vh;
  background-color: black;
  opacity: 0.7;
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 40;
}

.DPcomputer16Box .intelligentSchScrView_leftView_title {
  margin-bottom: 5px;
  width: 100%;
  height: 3.5vh;
  background: no-repeat center center url('~@/assets/images/cutGraph/biaoti1.png');
  background-size: 100% 100%;
  padding-left: 10px;
  box-sizing: border-box;
  font-size: 18px;
  line-height: 3.5vh;
  color: #FAFAFB;
  letter-spacing: 1px;
  text-shadow: 1px 1px 1px #92CBFF;
}

.DPcomputer16Box .intelligentSchScrView_leftView_content {
  width: 100%;
}

.DPcomputer16Box .voiceAppContent_1 {
  display: flex;
  justify-content: space-around;
}

.DPcomputer16Box .voiceAppContent_1 > div {
  height: 40px;
  line-height: 40px;
  color: rgb(24, 228, 240);
  font-size: 16px;
  font-weight: 600;
}

.DPcomputer16Box .voiceAppContent_2 {
  width: 100%;
  height: 27vh;
  border: 2px solid rgb(24, 228, 240);
  border-radius: 10px;
}

.DPcomputer16Box .voiceAppContent_2_title {
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  background-color: #274088;
  height: 3vh;
  line-height: 3vh;
  color: rgb(24, 228, 240);
  display: flex;
  justify-content: space-around;
  font-size: 16px;
}

.DPcomputer16Box .voiceAppContent_2_content {
  height: 23vh;
  width: 100%;
  overflow-y: auto;
  padding: 0px 10px;
  box-sizing: border-box;
  background-color: #020C39;
}

.DPcomputer16Box .voiceAppContent_2_content::-webkit-scrollbar {
  /*滚动条整体样式*/
  width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
  height: 1px;
}

.DPcomputer16Box .voiceAppContent_2_content::-webkit-scrollbar-thumb {
  /*滚动条里面小方块*/
  border-radius: 10px;
  background-color: #274088;
  background-image: -webkit-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.2) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.2) 75%,
    transparent 75%,
    transparent
  );
}

.DPcomputer16Box .voiceAppContent_2_content::-webkit-scrollbar-track {
  /*滚动条里面轨道*/
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  background: #ededed;
  border-radius: 10px;
}

.DPcomputer16Box .voiceAppContent_3 {
  margin-top: 1vh;
  width: 100%;
  height: 18vh;
  border: 2px solid rgb(24, 228, 240);
  border-radius: 10px;
}

.DPcomputer16Box .voiceAppContent_3_content {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 14vh;
  width: 100%;
  overflow-y: auto;
  padding: 0px 10px;
  box-sizing: border-box;
  background-color: #020C39;
}

.DPcomputer16Box .voiceAppContent_3_content::-webkit-scrollbar {
  /*滚动条整体样式*/
  width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
  height: 1px;
}

.DPcomputer16Box .voiceAppContent_3_content::-webkit-scrollbar-thumb {
  /*滚动条里面小方块*/
  border-radius: 10px;
  background-color: #274088;
  background-image: -webkit-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.2) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.2) 75%,
    transparent 75%,
    transparent
  );
}

.DPcomputer16Box .voiceAppContent_3_content::-webkit-scrollbar-track {
  /*滚动条里面轨道*/
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  background: #ededed;
  border-radius: 10px;
}

.DPcomputer16Box .voiceAppContent_3_content_selectCar {
  width: 45%;
  margin-top: 5px;
  color: #A6F6F9;
  font-size: 16px;
  display: flex;
  justify-content: space-between;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.DPcomputer16Box .voiceAppContent_3_content_selectCar > div {
  height: 20px;
  line-height: 20px;
  font-size: 18px;
}

.DPcomputer16Box .el-checkbox__label {
  vertical-align: -3px;
}

.DPcomputer16Box .el-checkbox__label > div {
  display: inline-block;
  color: #A6F6F9;
  font-size: 16px;
  font-family: 'SourceHanSansCN-Regular';
}

.DPcomputer16Box .el-checkbox {
  display: block;
}

.DPcomputer16Box .el-checkbox__inner {
  width: 30px !important;
  height: 30px !important;
}

.DPcomputer16Box .el-checkbox__input .el-checkbox__inner::after {
  border: 2px solid #fff;
  box-sizing: content-box;
  content: "";
  border-left: 0;
  border-top: 0;
  height: 12px;
  width: 5px;
  position: absolute;
  top: 1px;
  left: 8px;
  transform: rotate(45deg) scaleY(1);
}

.DPcomputer16Box .voiceAppContent_4 {
  margin-top: 1vh;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
}

.DPcomputer16Box .voiceAppContent_4_btns {
  background-color: #112251;
  border: 1px solid #00FCF9;
  color: #00FFFF;
  border-radius: 5px;
  height: 3.5vh;
  font-size: 17px;
  margin: 0px 2vw 10px;
  width: 25%;
  font-size: 15px;
  cursor: pointer;
}

.DPcomputer16Box .voiceAppContent_4_btns:active {
  background: linear-gradient(to top, #007EFF, #30CFBE);
  border: 0px solid #00FCF9;
  color: white;
  border-radius: 5px;
  height: 3.5vh;
  font-size: 17px;
  margin: 0px 2vw 10px;
  width: 25%;
  font-size: 15px;
  cursor: pointer;
}

.DPcomputer16Box .videoListView {
  position: absolute;
  bottom: 1vh;
  left: 1.1vw;
  height: 47vh;
  width: 18vw;
  z-index: 50;
  background: no-repeat center center url('~@/assets/images/cutGraph/guzhangshenbankuang1.png');
  background-size: 100% 100%;
  padding: 10px 10px 0px;
  box-sizing: border-box;
}

.DPcomputer16Box .videoListView_title {
  color: white;
  font-size: 18px;
}

.DPcomputer16Box .videoListView_content {
  width: 100%;
  height: 30vh;
  border: 1px solid rgb(24, 144, 255);
  border-radius: 5px;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  padding-top: 10px;
  box-sizing: border-box;
  overflow-y: scroll;
  background-color: rgba(32, 42, 67, 0.95);

}

.DPcomputer16Box .videoListView_content::-webkit-scrollbar {
  /*滚动条整体样式*/
  width: 8px; /*高宽分别对应横竖滚动条的尺寸*/
  height: 1px;
}

.DPcomputer16Box .videoListView_content::-webkit-scrollbar-thumb {
  /*滚动条里面小方块*/
  border-radius: 10px;
  background-color: #274088;
  background-image: -webkit-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.2) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.2) 75%,
    transparent 75%,
    transparent
  );
}

.DPcomputer16Box .videoListView_content::-webkit-scrollbar-track {
  /*滚动条里面轨道*/
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  background: #ededed;
  border-radius: 10px;
}

.DPcomputer16Box .videoListView_content > div {
  margin-bottom: 10px;
  width: 49%;
  color: rgb(24, 228, 240);
  text-align: center;
}

.DPcomputer16Box .peopleScheAssembly {
  position: absolute;
  bottom: 1vh;
  left: 0.7vw;
  height: 50vh;
  width: 18.5vw;
  z-index: 50;
  background: no-repeat center center url('~@/assets/images/cutGraph/guzhangshenbankuang1.png');
  background-size: 100% 100%;
  padding: 10px 10px 0px;
  box-sizing: border-box;
}

.DPcomputer16Box .peopleScheAssemblyBtns {
  position: absolute;
  bottom: 5px;
  padding: 0 15% 10px;
  box-sizing: border-box;
}
</style>

<style>
.DPcomputer16Box .des1 .el-form-item__label {
  color: white;
  font-size: 15px;
}

.DPcomputer16Box .el-input--small .el-input__inner {
  background-color: #021445;
  border: 2px solid #01f5fe;
  color: #01f5fe;
}

.DPcomputer16Box .el-input--small .el-input__inner {
  background-color: #021445;
  border: 2px solid #01f5fe;
  color: #01f5fe;
}

.DPcomputer16Box .el-input--small .el-input__inner::placeholder {
  color: #31E5F5;
}

.DPcomputer16Box .el-select .el-input .el-select__caret {
  color: #01f5fe;
}

.DPcomputer16Box .el-textarea__inner {
  background-color: #021445;
  color: #01f5fe;
  border: 2px solid #01f5fe;
}

.el-cascader-node.is-selectable.in-active-path {
  color: #1890ff;
}

.el-select-dropdown__list {
  background-color: #021445 !important;
  border: 1px solid #01f5fe;
  color: #31E5F5;
}

.el-select-dropdown__item.hover, .el-select-dropdown__item:hover {
  background-color: #021445 !important;
  color: #31E5F5;
}

.el-select-dropdown__item {
  padding: 0px 20px;
  box-sizing: border-box;
  background-color: #021445 !important;
  color: #31E5F5;
  font-size: 16px;
}

.el-cascader-panel {
  background-color: #021445 !important;
  color: #31E5F5;
  font-size: 16px;
}

.el-cascader-menu {
  border: 0px;
}

.el-cascader-menu__list {
  color: #31E5F5;
  border: 1px solid #01f5fe;
}

.el-cascader-node:not(.is-disabled):hover, .el-cascader-node:not(.is-disabled):focus {
  background-color: #021445 !important;
}
</style>
