Newer
Older
intelligentRobot / src / views / detector / main / index.vue
wangxitong on 3 Sep 13 KB first commit
<script lang="ts" setup name="maintc">
import type { Ref } from 'vue'
import { getCurrentInstance, reactive, ref } from 'vue'
import useWebsocketStore from '@/store/modules/websocket'
import useSettingsStore from "@/store/modules/settings";
import BarChartVertical from "@/components/Echart/BarChartVertical.vue";
import {getConfigList, getDevList, hsList, psdExport, tcyControl} from "@/api/home/tcy/tcy";
import {ElLoading, ElMessage} from "element-plus";
import html2canvas from "html2canvas";
import {fileUpload, saveImg} from "@/api/home/task/task";
import {robotDetail} from "@/api/home/robot/robot";
import { exportFile } from '@/utils/exportUtils'
import detectorHSStore from "@/store/modules/detectorHS";
import dayjs from "dayjs";

const settingsStore = useSettingsStore()
const websocket = useWebsocketStore()
const hsStore = detectorHSStore()
const $route = useRoute()
const lineScale = ref() // 组件

const minValue = ref(0)
const maxValue = ref(4095)
const leftScale = ref(0)
const rightScale = ref(0)
const mcaData: Ref<any[]> = ref([
  {name: 'mca', data:  [], z: 4},
  {name: '', data: [], z: 7}
])
const psdData: Ref<any[]> = ref([
  {name: 'psd', data:  [], z: 4},
  {name: '', data: [], z: 7}
])
const roiData: Ref<any[]> = ref([
  {name: 'ROI', data:  [], z: 1}
])


const instance = getCurrentInstance()
const x1 = ref(0)
const x2 = ref(4095)
const x3 = ref(0)
const x4 = ref(4095)
// x轴最大值
const max = ref(4095)
const loading = ref(false)
const total = ref(0)
const roi = ref(0)
const rate = ref('0.0')
const total_rate = ref('****')
const roi_rate = ref('****')
const realtime = ref('0.0')
const yType = ref(true)
const robot = ref({
})
const isRun = ref(false)
const mca = ref()
const psd = ref()
const hsStartTime = ref('')
const hsEndTime = ref('')

// socket更新数据
const unwatch = watch(websocket, (newVal) => {
  if (newVal.detectorHData && Object.keys(newVal.detectorHData).length >= 1 && isRun.value) {
    rateNum++

    if(minValue.value === null) {
      minValue.value = 0
      maxValue.value = newVal.detectorHData.mcaX
    }
  }
})

let pause = 0
let startTime: any
const elapsedTime = ref(0);
const currTaskId = ref('')
let rateNum = 0

function rateFunc() {
  roiData.value[0].data = Object.entries(hsStore.mcaobj0)
  mcaData.value[1].data = Object.entries(hsStore.mcaobj1)
  psdData.value[1].data = Object.entries(hsStore.psdobj1)
  // mcaData.value[0].data = Object.entries(hsStore.mcaobj0)
  // psdData.value[0].data = Object.entries(hsStore.psdobj0)
  let mca = []
  for (const key in hsStore.mcaobj0) {
    if (!hsStore.mcaobj1.hasOwnProperty(key) || hsStore.mcaobj1[key] !== hsStore.mcaobj0[key]) {
      mca.push([key, hsStore.mcaobj0[key]])
    }
  }
  let psd = []
  for (const key in hsStore.psdobj0) {
    if (!hsStore.psdobj1.hasOwnProperty(key) || hsStore.psdobj1[key] !== hsStore.psdobj0[key]) {
      psd.push([key, hsStore.psdobj0[key]])
    }
  }
  mcaData.value[0].data = mca
  psdData.value[0].data = psd

  total.value = hsStore.total
  const arr = roiData.value[0].data.filter((item: any) => item[0]>= minValue.value && item[0] <= maxValue.value )
  let count = 0
  arr.forEach((item: any) => {
    count += item[1]
  })

  roi.value = count

  if(Number(realtime.value) === 0) {
    roi_rate.value = '****'
    total_rate.value = '****'
  } else {
    roi_rate.value = (roi.value / realtime.value).toFixed(5)
    total_rate.value = (total.value / realtime.value).toFixed(5)
  }
  rate.value = rateNum.toString()
  rateNum = 0
}

function uploadImg() {
  nextTick(() => {
    html2canvas(mca.value).then((res) => {
      const imgUrl = res.toDataURL('image/png')
      console.log(imgUrl)
      fileUpload({
        file: imgUrl,
      }).then((response) => {
        if (response.code === 200) {
          saveImg({
            taskId: currTaskId.value,
            mcaImg: response.data,
          }).then((res) => {
            if (res.code === 200) {
              ElMessage.success('mca图片已上传')
            }
          })
        }
      })
    })
    html2canvas(psd.value).then((res) => {
      const imgUrl = res.toDataURL('image/png')
      console.log(imgUrl)
      fileUpload({
        file: imgUrl,
      }).then((response) => {
        if (response.code === 200) {
          saveImg({
            taskId: currTaskId.value,
            psdImg: response.data,
          }).then((res) => {
            if (res.code === 200) {
              ElMessage.success('psd图片已上传')
            }
          })
        }
      })
    })
  })
}

function clear() {
  realtime.value = '0.0';
  startTime = new Date().getTime();
  pause = 0
  total.value = 0
  roi.value = 0
  roiData.value[0].data = []
  mcaData.value[0].data = []
  mcaData.value[1].data = []
  psdData.value[0].data = []
  psdData.value[1].data = []
  hsStore.clear()
  rateNum = 0
  rateFunc()
}


function exportFileFuc() {
  const loading = ElLoading.service({
    lock: true,
    text: '下载中请稍后',
    background: 'rgba(255, 255, 255, 0.8)',
  })
  psdExport({
    robotId: settingsStore.robot.id,
    startTime: hsStartTime.value,
    endTime: isRun.value? dayjs().format('YYYY-MM-DD HH:mm:ss'): hsEndTime.value,
    // taskId: currTaskId.value,
    psdX1: x3.value,
    psdX2: x4.value,
  }).then((res) => {
      const blob = new Blob([res.data])
      exportFile(blob, 'psd导出数据.xlsx')
  })
  loading.close()
}
function hs(type: any) {
  if((isRun.value && type === 1) || (!isRun.value && type === 0)) {
    return
  }
  if(type === 0) {
    hsEndTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss')
    pause = Number(realtime.value)
    isRun.value = false
    hsStore.setIsOn(false)
  } else {
    hsStartTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss')
    startTime = new Date().getTime()
    isRun.value = true
    hsStore.setIsOn(true)
  }
  hsList({
    detectorId: robot.value.id,
    type,
    x1: x1.value,
    x2: x2.value,
    x3: x3.value,
    x4: x4.value,
  }).then((res) => {
    if(res.code === 200) {
      ElMessage.success('指令下发成功')
    }
  })
}

let timercount = 0
// 更新计时器
const updateTimer = () => {
  if(isRun.value) {
    const currentTime = new Date().getTime();
    const diff = (currentTime - startTime) / 1000;
    elapsedTime.value = Math.floor(Number(pause) * 100 + diff * 100) / 100;
    realtime.value = elapsedTime.value.toFixed(2);
    timercount++
    if (timercount === 10) {
      rateFunc()
      timercount = 0
    }
  }
};

// 每10毫秒更新计时器
const timer = setInterval(updateTimer, 100);

onMounted(() => {
  isRun.value = hsStore.isOn
  hsStartTime.value = hsStore.startTime
  hsEndTime.value = hsStore.endTime
  if(!isRun.value){
    realtime.value = hsStore.realtime.toString()
    startTime = new Date().getTime()
    pause = Number(realtime.value)
  } else {
    startTime = new Date().getTime()
    // 累计realTime
    pause = Number(hsStore.realtime.toString()) + (new Date().getTime() - hsStore.levelPageTime) / 1000
  }

  minValue.value = 0
  maxValue.value = max.value

  rateFunc()
  setTimeout(() => {
    // 探测仪详情
    getDevList({}).then((response) => {
      if (response.code === 200) {
        robot.value = response.data.filter((item: { robotId: any; }) => item.robotId === settingsStore.robot.id)[0]
        // 当前任务
        robotDetail({
          id: settingsStore.robot.id,
        }).then((res) => {
          if (res.code === 200) {
            currTaskId.value = res.data.currTaskId // 任务
          }
        })
      }
    })
    // 计时器
    updateTimer()
    lineScale.value.getChart().on('brushEnd', function (params: any) {
      var coordRange = params.areas[0].coordRange
      minValue.value = coordRange[0]
      maxValue.value = coordRange[1]
      console.log('X Range:', minValue.value, maxValue.value)
      rateFunc()
    })

    lineScale.value.getChart().dispatchAction({
      type: 'takeGlobalCursor',
      // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
      key: 'brush',
      brushOption: {
        // 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
        brushType: 'lineX',
      }
    })
  }, 200)

})

onBeforeUnmount(() => {
  hsStore.setIsOn(isRun.value)
  hsStore.setRealTime(realtime.value)
  hsStore.setTime(hsStartTime.value, hsEndTime.value)
  hsStore.setLevelPageTime(new Date().getTime())
  unwatch()
  clearInterval(timer);
})
</script>

<template>
  <div class="video-wrap">
    <div class="left-container">
      <div ref="mca" style="height: 40%;background-color: #000000">
        <bar-chart-vertical id="mca" width="100%" :yType="yType" :data="mcaData" unit="" :grid="{ top: 10, left: 10, right: 20, bottom: 10, containLabel: true }" :min="0" :max="max"/>
      </div>
      <div ref="psd" style="height: 40%;background-color: #000000;margin-top: 5px">
        <bar-chart-vertical id="psd" width="100%" :yType="yType" :data="psdData" unit="" :grid="{ top: 10, left: 10, right: 20, bottom: 10, containLabel: true }" :min="0" :max="max"/>
      </div>
      <div style="height: calc(20% - 10px);background-color: #000000;margin-top: 5px">
        <bar-chart-vertical
          ref="lineScale"
          id="line-scale"
          :yType="yType"
          :is-data-zoom="false"
          :min-value="minValue" :max-value="maxValue"
          width="100%" :data="roiData" unit=""
          :min="0" :max="max"
          :grid="{ top: 20, left: 10, right: 20, bottom: 10, containLabel: true }" />
      </div>
    </div>
    <div class="right-container">
      <div>
      <el-switch
        v-model="yType"
        active-text="常数"
        inactive-text="对数">
      </el-switch>
      </div>
      <span style="color: #4b4b4b;">x轴最大值
        <el-input-number v-model="max" :precision="0" :step="1" size="small" :min="0" style="width: 100px;"/>
      </span>
      <div class="control-title">information HS</div>
      <div class="data-monitor">Time:<h>{{realtime}}</h></div>
      <div class="data-monitor">Dead:<h>0.0</h></div>
      <div class="data-monitor">Live:<h>{{Math.floor(realtime)}}.0</h></div>
      <div class="data-monitor">Total:<h>{{total}}</h></div>
      <div class="data-monitor">ROI:<h>{{roi}}</h></div>
      <div class="data-monitor">Rate:<h>{{rate}}</h></div>
      <div class="data-monitor">Total Rate:<h>{{total_rate}}</h></div>
      <div class="data-monitor">ROI Rate:<h>{{roi_rate}}</h></div>
      <div class="control-title" style="width: 60px">HS</div>
      <div style="margin-top: -35px;float: right;">
        <el-button type="primary" icon="VideoPlay" circle style="font-size: 24px;" @click="hs(1)" title="Start" size="small"/>
        <el-button type="info" icon="VideoPause" circle style="font-size: 24px;" @click="hs(0)" title="Stop" size="small"/>
        <el-button type="info" icon="RefreshLeft" circle style="font-size: 16px;" @click="clear" title="Clear" size="small"/>
      </div>
      <el-form ref="dataFormRef" label-position="left" label-width="30px" style="margin-top: 5px">
        <el-form-item label="X1" style="height: 10px">
          <el-input-number v-model="x1" :precision="0" :step="1" size="small" :min="0" :max="4095" style="margin-top: 4px"/>
        </el-form-item>
        <el-form-item label="X2" style="height: 10px">
          <el-input-number v-model="x2" :precision="0" :step="1" size="small" :min="0" :max="4095" style="margin-top: 4px"/>
        </el-form-item>
        <el-form-item label="X3" style="height: 10px">
          <el-input-number v-model="x3" :precision="0" :step="1" size="small" :min="0" :max="4095" style="margin-top: 4px"/>
        </el-form-item>
        <el-form-item label="X4" style="height: 10px">
          <el-input-number v-model="x4" :precision="0" :step="1" size="small" :min="0" :max="4095" style="margin-top: 4px"/>
        </el-form-item>
        <el-form-item label="" style="margin-top: 10px;height: 20px">
          <el-button type="primary" @click="hs(isRun?0:1)" style="margin-top: 5px;width: 120px">
            <el-icon style="vertical-align: middle">
              <Bottom />
            </el-icon>
            参数下发</el-button>
        </el-form-item>
      </el-form>
      <div class="control-title" style="width: 100px;margin-top: 25px">Timing</div>
      <el-form ref="dataFormRef" label-position="left" label-width="40px">
        <el-form-item label="ch1" >
          <el-input-number :precision="1" :step="0.1"  size="small"/>
        </el-form-item>
<!--        <el-form-item label="积分阈值" label-width="70px">-->
<!--          <el-input-number :precision="1" :step="0.1"  size="small"/>-->
<!--        </el-form-item>-->
      </el-form>
      <div style="text-align: center;margin-top: -10px">
        <el-button type="primary" @click="exportFileFuc">
          <el-icon style="vertical-align: middle">
            <Download />
          </el-icon>
          <span style="vertical-align: middle"> 导出 </span>
        </el-button>
      </div>
<!--      <el-button type="primary" icon="UploadFilled" style="margin-left: 40px" @click="uploadImg">图片上传</el-button>-->
    </div>
  </div>
</template>

<style lang="scss" scoped>
.video-wrap {
  width: 100%;
  height: calc(100vh - 60px);
  display: flex;
  flex-wrap: wrap;
  background: white;
  padding: 10px;
}
.left-container {
  width: calc(100% - 200px);
  height: 100%;
}
.right-container {
  width: 200px;
  height: 100%;
  position: absolute;
  bottom: 5px;
  right: 10px;
  padding: 10px;
}
.control-title {
  color: white;
  background-color: #ff9f11;
  border-radius: 10px;
  width: 160px;
  height: 30px;
  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;
  margin: 5px 0;
}
.data-monitor {
  margin: 0px 5px;
  color: #2a2a2a;
  font-weight: normal;
  letter-spacing: 1px;
  padding: 5px;
  width: 100%;
  height: 28px;
  font-size: 14px;
  h {
    padding-left: 10px;
    color: #5b9dfc;
    font-weight: bold;
    font-size: 15px;
  }
}
</style>