Newer
Older
safe_production_front / src / views / ycjg / ssjk / control-hk.vue
wangxitong on 16 Aug 14 KB first commit
<script lang="ts" setup name="videoControl">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { Ref } from 'vue'
import { getCurrentInstance, reactive, ref } from 'vue'
import dayjs from 'dayjs'
import useWebsocketStore from '@/store/modules/websocket'
import { initPlugin, login, logout, onlyLogin, preview } from '@/utils/HKVideo'
import { getDevInfo, restartDev } from '@/api/ptz/dev'
import controlImg from '@/assets/images/control.png'
import {
  devControl,
  devControlWithSpeed,
  devToPosition,
  setPfetchData,

} from '@/api/ptz/control'
import {getPicListPage, pictureAdd} from '@/api/ycjg/ssjk'
import {exportFile} from "@/utils/exportUtils";
import {Search} from "@element-plus/icons-vue";
const { proxy } = getCurrentInstance()

const websocket = useWebsocketStore()
const $route = useRoute()
const deviceData: Ref<any> = ref({
  id: '',
  monitorName: '***********',
  deviceIp: '192.168.1.101',
  devicePort: '',
  deviceUser: '',
  devicePassword: '',
  nvrIp: '',
  nvrPort: '',
  nvrUser: '',
  nvrPassword: '',
  nvrChannel: '',
  deviceType: '',
  deviceTypeName: '',
  longitude: '',
  latitude: '',
  description: '',
  location: '**************************',
  deviceStatus: '',
  deviceStatusName: '',
  createTime: '2022-01-08',
  dept: '',
  deptName: '北京计量测试研究所',
  modelName: 'HA-84282',
})
const realh = ref('****')
const realv = ref('****')
const instance = getCurrentInstance()

const videoControl = ref('videoControl')

const controlSpeed = ref(7)

const loading = ref(false)
const total = ref(1000)
const list = ref([{}, {}, {}, {}, {}, {}])

const divPlugin = ref(null)
const lineList: Ref<any[]> = ref([])
const timeRange = ref<[any, any]>(['', ''])

const defaultQuery = {
  devId: '',
  startTime: '',
  endTime: '',
  offset: 1,
  limit: 6,
}
const listQuery = reactive({ ...defaultQuery })

// socket更新数据
const unwatch = watch(websocket, (newVal) => {
})

// 搜索重置
function fetchData() {
  search()
}

function search(isNowPage = false) {
  if (timeRange.value) {
    listQuery.startTime = timeRange.value[0] as string || ''
    listQuery.endTime = timeRange.value[1] as string || ''
  }
  if (!isNowPage) {
    // 是否显示当前页,否则跳转第一页
    listQuery.offset = 1
  }
  loading.value = true
  getPicListPage(listQuery).then((res: any) => {
    list.value = res.data.rows
    total.value = res.data.total
    loading.value = false
  }).catch(() => {
    loading.value = false
  })
}

// 调整大小
const resize = () => {
  WebVideoCtrl.I_Resize(divPlugin.value.clientWidth, divPlugin.value.clientHeight)
}

// 抓拍
async function takePhoto() {
  const oWndInfo = WebVideoCtrl.I_GetWindowStatus(0)
  if (oWndInfo != null) {
    const oLocalConfig = await WebVideoCtrl.I_GetLocalCfg()
    let szCaptureFileFormat = '0'
    if (oLocalConfig) {
      szCaptureFileFormat = oLocalConfig.captureFileFormat
    }
    const szPicName = `${deviceData.value.monitorName}_${new Date().getTime()}${szCaptureFileFormat === '0' ? '.jpg' : '.bmp'}`

    // plan A
    WebVideoCtrl.I_CapturePicData().then(
      (data: any) => {
        const blob = new Blob([data])
        // 上传
        const fileObj = new File([blob], szPicName, {
          lastModified: new Date().getTime(),
          type: 'image/png',
        })
        pictureAdd({
          devId: $route.query.id,
          file: fileObj,
        }).then((res: any) => {
          // 本地
          exportFile(blob, `${deviceData.value.monitorName}_${new Date().getTime()}${szCaptureFileFormat === '0' ? '.jpg' : '.bmp'}`)
          ElMessage.success('抓图成功')
        })
      },
      (oError: any) => {
        ElMessage.error('抓图失败!')
      })

    // // plan B
    // oLocalConfig.capturePath = 'C:\\capture'
    // oLocalConfig.playbackPicPath = 'C:\\capture'
    // await WebVideoCtrl.I_SetLocalCfg(oLocalConfig).then(() => {}, (oError) => {})
    // WebVideoCtrl.I_CapturePic(szPicName, {
    //   bDateDir: true, // 是否生成日期文件
    // }).then(
    //   () => {
    //     ElMessage.success('抓图成功,文件地址:C:\\capture')
    //   },
    //   (oError) => {
    //     ElMessage.error('抓图失败!')
    //   })
  }
}

// 放大
function zoomIn(isStop: string) {
  console.log(isStop)
  const params = {
    deviceIp: deviceData.value.deviceIp,
    command: 'zoomIn',
    isStop,
  }
  devControl(params).then(() => {
    // ElMessage.success('放大成功')
  })
}

// 缩小
function zoomOut(isStop: string) {
  const params = {
    deviceIp: deviceData.value.deviceIp,
    command: 'zoomOut',
    isStop,
  }
  devControl(params).then(() => {
    // ElMessage.success('缩小成功')
  })
}

// 上下左右
function controlWithSpeed(event, type, isStop) {
  // console.log(event.detail, type, isStop)
  if (event.detail === 1) {
    const params = {
      deviceIp: deviceData.value.deviceIp,
      command: type,
      isStop,
      speed: controlSpeed.value.toString(),
    }
    devControlWithSpeed(params).then(() => {})
  }
  else if (event.detail === 2) {
    // 小角度转动
    let horizontalAngle = Number(realh.value)
    let verticalAngle = Number(realv.value)
    switch (type) {
      case 'up':
        verticalAngle += deviceData.value.deviceType === '1' ? -1 : 1
        break
      case 'down':
        verticalAngle += deviceData.value.deviceType === '1' ? 1 : -1
        break
      case 'left':
        horizontalAngle += -1
        break
      case 'right':
        horizontalAngle += 1
        break
    }
    if (horizontalAngle < 0 || horizontalAngle > 360) { return }
    if (verticalAngle < -90 || verticalAngle > 90) { return }
    const params = {
      deviceIp: deviceData.value.deviceIp,
      horizontalAngle,
      verticalAngle,
    }
    devToPosition(params).then(() => {})
  }
}

const handleDoubleClick = (index, fullSceen, event) => {
  console.log(event.point)
  const x = (event.point[0] - 0.5) * 59.8
  const y = (event.point[1] - 0.5) * 30 // (29.9 * divPlugin.value.clientHeight / divPlugin.value.clientWidth)
  console.log(x, y)
  const params = {
    deviceIp: deviceData.value.deviceIp,
    horizontalAngle: Number(realh.value) + x,
    verticalAngle: Number(realv.value) - y,
  }
  devToPosition(params).then(() => {
    // ElMessage.success('定位成功')
  })
}
// 登录设备
function loginDevice() {
  login(
    deviceData.value.deviceIp,
    '80',
    deviceData.value.deviceUser,
    deviceData.value.devicePassword,
    0)
  if (proxy.NVR) {
    login(
      deviceData.value.nvrIp,
      deviceData.value.nvrPort,
      deviceData.value.nvrUser,
      deviceData.value.nvrPassword,
      0,
      true,
      deviceData.value.nvrChannel)

    // onlyLogin(
    //   deviceData.value.nvrIp,
    //   deviceData.value.nvrPort,
    //   deviceData.value.nvrUser,
    //   deviceData.value.nvrPassword,
    //   0,
    //   true,
    //   deviceData.value.nvrChannel)
  }
}

function handleSizeChange(val: number) {
  // emit('change', { size: val })
  listQuery.limit = val
  search(true)
}

// 改变当前页
function handleCurrentChange(val: number) {
  // emit('change', { page: val })
  listQuery.offset = val
  search(true)
}

onMounted(() => {
  console.log($route.query)
  // 从路由中获取页面类型参数
  if ($route.query && $route.query.id) {
    getDevInfo($route.query.id.toString()).then((response) => {
      deviceData.value = response.data
      setTimeout(() => {
        initPlugin(1, '', false, loginDevice, handleDoubleClick)
        divPlugin.value = document.getElementById('divPlugin')
        window.addEventListener('resize', resize)
      }, 200)
    })
    listQuery.devId = $route.query.id!.toString()
    fetchData()
  }
})

onBeforeUnmount(() => {
  // WebVideoCtrl.JS_HideWnd()
  WebVideoCtrl.I_Resize(0, 0)
  unwatch()
  if (!proxy.NVR) {
    logout(deviceData.value.deviceIp)
  }
  else {
    try {
      logout(deviceData.value.nvrIp)
    }
    catch (e) {}
  }
  window.location.reload()
  window.removeEventListener('resize', resize)
})
</script>

<template>
  <div class="video-wrap">
    <div id="divPlugin" class="plugin" :class="videoControl" />
    <div class="right">
      <el-tabs tab-position="top" style="height: calc(100% - 30px);width: 100%;margin-bottom: 10px;margin-top: -10px">
        <el-tab-pane label="历史截图">
          <div style="display: flex;margin-bottom: 10px">
            <el-date-picker
              v-model="timeRange" type="daterange" clearable size="small"
              format="YYYY-MM-DD" value-format="YYYY-MM-DD"
              start-placeholder="开始时间" end-placeholder="结束时间" range-separator="到"
              style="margin-right: 20px"/>
            <el-button type="primary" @click="fetchData" style="width: 60px" size="small">查 询</el-button>
          </div>
          <div style="background-color: white;overflow-y: hidden;overflow-x: scroll;width: 100%;display: flex;flex-wrap: wrap;">
            <div v-for="(item, index) in list" :key="index" style="height: 100px;width: 160px;margin: 5px">
              <el-image style="width: 160px; height: 100px;" :src="item.url" fit="fill" />
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
      <div  style="z-index: 99999999;margin: 10px 10px 0;">
        <el-pagination
          small
          :current-page="listQuery.offset"
          :page-sizes="[6]"
          :page-size="listQuery.limit"
          :total="total"
          layout="total,prev,pager,next"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>
    <div class="bottom">
      <div class="control-title">设备控制</div>
      <div name="four" style="width: 150px; height: 130px;">
        <el-image style="width: 130px; height: 130px;position: absolute;top: 5px;left: 50px" :src="controlImg" fit="fill" />
        <div>
          <div class="round-btn" style="top: 8px;left: 95px" @mousedown="controlWithSpeed($event, 'up', '0')" @mouseup="controlWithSpeed($event, 'up', '1')" />
          <div class="round-btn" style="top: 90px;left: 95px" @mousedown="controlWithSpeed($event, 'down', '0')" @mouseup="controlWithSpeed($event, 'down', '1')" />
          <div class="round-btn" style="top: 48px;left: 53px" @mousedown="controlWithSpeed($event, 'left', '0')" @mouseup="controlWithSpeed($event, 'left', '1')" />
          <div class="round-btn" style="top: 48px;left: 135px" @mousedown="controlWithSpeed($event, 'right', '0')" @mouseup="controlWithSpeed($event, 'right', '1')" />
        </div>
      </div>
      <div style="display: flex;max-width: 250px;flex-wrap: wrap;margin: 0 20px">
        <el-button type="primary" class="btn" @click="">
          <el-icon style="margin-right: 5px"><svg-icon name="icon-stop" /></el-icon>暂 停
        </el-button>
        <el-button type="primary" class="btn" @click="">
          <el-icon style="margin-right: 5px"><svg-icon name="icon-play" /></el-icon>恢 复
        </el-button>
        <el-button type="primary" class="btn" @mousedown="zoomIn('0')" @mouseup="zoomIn('1')">
          <el-icon style="margin-right: 5px"><svg-icon name="icon-zoomin" /></el-icon>放 大
        </el-button>
        <el-button type="primary" class="btn" @mousedown="zoomOut('0')" @mouseup="zoomOut('1')">
          <el-icon style="margin-right: 5px"><svg-icon name="icon-zoomout" /></el-icon>缩 小
        </el-button>
        <el-button type="primary" class="btn" @click="takePhoto">
          <el-icon style="margin-right: 5px"><svg-icon name="icon-camera" /></el-icon>抓 拍</el-button>
      </div>
      <div style="width: calc(100% - 350px);height: 100%;display: flex;background-color: rgba(255,255,255,0.65);border-radius: 10px">
        <el-tabs tab-position="left" style="height: 100%;width: 100%">
          <el-tab-pane label="设备信息">
            <el-descriptions style="flex: 1" class="margin-top" :column="2" border>
              <el-descriptions-item label="设备名称">{{deviceData.monitorName}}</el-descriptions-item>
              <el-descriptions-item label="所属单位">{{deviceData.deptName}}</el-descriptions-item>
              <el-descriptions-item label="型号"><el-tag size="small">{{deviceData.modelName}}</el-tag></el-descriptions-item>
              <el-descriptions-item label="位置">{{deviceData.location}}</el-descriptions-item>
              <el-descriptions-item label="IP">{{deviceData.deviceIp}}</el-descriptions-item>
              <el-descriptions-item label="安装时间">{{deviceData.createTime}}</el-descriptions-item>
            </el-descriptions>
          </el-tab-pane>
        </el-tabs>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.video-wrap {
  display: flex;
  flex-wrap: wrap;
}
.videoControl {
  height: calc(80vh - 90px);
  width: calc(100% - 390px);
  margin-left: 10px;
  margin-top: 10px;
  position: relative;
  background-color: #111111;
}
.right {
  height: calc(80vh - 90px);
  width: 360px;
  margin-left: 10px;
  margin-top: 10px;
  background-color: white;
  border-radius: 10px;
  padding: 10px;
}
.bottom {
  width: calc(100% - 10px);
  height: calc(20vh);
  position: absolute;
  left: 0px;
  bottom: 5px;
  display: flex;
  overflow: hidden;
  border-radius: 10px;
  margin: 5px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
  overflow: hidden;
  padding: 5px;
  justify-content: space-between;
}
.control-title {
  color: white;
  background-color: #ff9f11;
  border-bottom-right-radius: 10px;
  border-top-right-radius: 10px;
  line-height: 30px;
  font-weight: bold;
  text-align: center;
  letter-spacing: 1px;
  font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif;
  writing-mode: vertical-rl;
  text-orientation: upright;
  width: 30px;
  height: 100px;

}
.b2 {
  height: 100%;
  width: 20%;
  text-align: center;
  overflow: hidden;
}
.btn {
  margin: 3px auto;
  width: 100px;
}
.control-row {
  display: flex;
  position: absolute;
  left: 260px;
  width: 60%;
  overflow: hidden;
  justify-content: flex-start;
  align-items: center;
}
.real-text {
  margin: 6px 10px;
  color: #6e6e6e;
}
.ppm-line {
  padding: 0;
  height: 100%;
  flex: 1;
}
.el-message-box {
  position: absolute !important;
  top: calc(50% - 68px) !important;
  left: 100px !important;
}
.ptz-control {
  width: 400px;
  position: absolute;
  right: 18%;
  top: 5px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
}
.round-btn {
  position: absolute;
  top: 14px;
  left: 129px;
  width: 42px;
  height: 42px;
  z-index: 111111;
  border-radius: 21px;
  cursor: pointer;
}
.round-btn:hover {
  background-color: rgba(61, 125, 254, 0.53);
}
.icon-button {
  background-color: #d6e5fc;
  border-color: #d6e5fc;
  padding: 6px;
  border-radius: 6px;
  color: #4384ff;

  :deep(.el-icon) {
    width: 18px;
    height: 18px;
  }

  //.icon-button-icon {
  //  width: 16px;
  //  height: 16px;
  //}

  &:hover {
    background-color: #c3dafd;
    color: #fff;
  }
}
.add-line {
  width: 250px;
  display: flex;
  margin-left: 10px;
  z-index: 1111111;
}
</style>