<script lang="ts" setup name="maintc"> import type { Ref } from 'vue' import { getCurrentInstance, reactive, ref } from 'vue' import useWebsocketStore from '@/store/modules/websocket' import controlImg from '@/assets/images/control.png' import type { lineDataI } from '@/components/Echart/echart-interface' import { getDataHisList, getDevInfo, restartDev } from '@/api/ptz/dev' 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"; const settingsStore = useSettingsStore() const websocket = useWebsocketStore() const $route = useRoute() const mcaData: Ref<any[]> = ref([ {name: 'mca', data: []}, {name: '', data: []} ]) const psdData: Ref<any[]> = ref([ {name: 'psd', data: []}, {name: '', data: []} ]) const roiData: Ref<any[]> = ref([ {name: 'ROI', data: []} ]) const instance = getCurrentInstance() const x1 = ref(0) const x2 = ref(4095) const x3 = ref(0) const x4 = ref(4095) const loading = ref(false) const total = ref('****') const roi = ref('****') 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() let mcaobj0 = {} let mcaobj1 = {} let psdobj0 = {} let psdobj1 = {} // socket更新数据 const unwatch = watch(websocket, (newVal) => { if (newVal.detectorHData && Object.keys(newVal.detectorHData).length >= 1 && isRun.value) { if(minValue.value === null) { minValue.value = 0 maxValue.value = newVal.detectorHData.mcaX } if(mcaobj0.hasOwnProperty(newVal.detectorHData.mcaX)) { mcaobj0[newVal.detectorHData.mcaX] += newVal.detectorHData.mcaY } else { mcaobj0[newVal.detectorHData.mcaX] = newVal.detectorHData.mcaY } if(mcaobj1.hasOwnProperty(newVal.detectorHData.mcaX1)) { mcaobj1[newVal.detectorHData.mcaX1] += newVal.detectorHData.mcaY1 } else { mcaobj1[newVal.detectorHData.mcaX1] = newVal.detectorHData.mcaY1 } if(psdobj0.hasOwnProperty(newVal.detectorHData.psdX)) { psdobj0[newVal.detectorHData.psdX] += newVal.detectorHData.psdY } else { psdobj0[newVal.detectorHData.psdX] = newVal.detectorHData.psdY } if(psdobj1.hasOwnProperty(newVal.detectorHData.psdX1)) { psdobj1[newVal.detectorHData.psdX1] += newVal.detectorHData.psdY1 } else { psdobj1[newVal.detectorHData.psdX1] = newVal.detectorHData.psdY1 } } }) let pause = 0 let startTime = new Date().getTime(); const elapsedTime = ref(0); const currTaskId = ref('') function rateFunc() { roi.value = mcaData.value[0].data.filter((item: any) => item[0]>= minValue.value && item[0] <= maxValue.value ).length total.value = roi.value + psdData.value[0].data.filter((item: any) => item[0]>= minValue.value && item[0] <= maxValue.value ).length if(realtime.value === '0.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) } } 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 roiData.value[0].data = [] mcaData.value[0].data = [] mcaData.value[1].data = [] psdData.value[0].data = [] psdData.value[1].data = [] mcaobj0 = {} mcaobj1 = {} psdobj0 = {} psdobj1 = {} } import { exportFile } from '@/utils/exportUtils' function exportFileFuc() { const loading = ElLoading.service({ lock: true, text: '下载中请稍后', background: 'rgba(255, 255, 255, 0.8)', }) psdExport({ taskId: currTaskId.value, psdX1: x1.value, psdX2: x2.value, }).then((res) => { const blob = new Blob([res.data]) exportFile(blob, 'psd导出数据.xlsx') }) loading.close() } function hs(type: any) { if(isRun.value && type === 1) { return } if(type === 0) { pause = Number(realtime.value) isRun.value = false } else { startTime = new Date().getTime(); isRun.value = 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) { mcaData.value[0].data = Object.entries(mcaobj0) roiData.value[0].data = mcaData.value[0].data mcaData.value[1].data = Object.entries(mcaobj1) psdData.value[0].data = Object.entries(psdobj0) psdData.value[1].data = Object.entries(psdobj1) console.log(minValue.value, maxValue.value, '_hs') rateFunc() timercount = 0 } } }; // 每10毫秒更新计时器 const timer = setInterval(updateTimer, 100); const lineScale = ref() // 组件 const minValue = ref(0) const maxValue = ref(null) const leftScale = ref(0) const rightScale = ref(0) let width = 0 onMounted(() => { 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() width = (document.getElementById('line-scale').clientWidth - 20) / 100 lineScale.value.getChart().on('dataZoom', function (params) { const xAxisIndex = 0; // 假设只有一个 x 轴,索引为 0 // 获取整个 x 轴的最小和最大值 const xAxis = lineScale.value.getChart().getModel().getComponent('xAxis', xAxisIndex); const minX = xAxis.axis.scale.getExtent()[0]; const maxX = xAxis.axis.scale.getExtent()[1]; let startValue,endValue if(params.hasOwnProperty('batch')) { startValue = params.batch[0].start endValue = params.batch[0].end } else { startValue = params.start endValue = params.end } minValue.value = (minX + (maxX - minX) * startValue / 100) maxValue.value = (minX + (maxX - minX) * endValue / 100) console.log('X Range:', minValue.value, maxValue.value) rateFunc() }) }, 200) }) onBeforeUnmount(() => { 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: 10, bottom: 20, containLabel: true }" /> </div> <div ref="psd" style="height: 40%;background-color: #000000"> <bar-chart-vertical id="psd" width="100%" :yType="yType" :data="psdData" unit="" :grid="{ top: 10, left: 10, right: 10, bottom: 20, containLabel: true }" /> </div> <div style="height: calc(20% - 10px);background-color: #000000;margin-top: 10px"> <bar-chart-vertical ref="lineScale" id="line-scale" :yType="yType" :min-value="minValue" :max-value="maxValue" width="100%" :data="roiData" unit="" :grid="{ top: 20, left: 10, right: 10, bottom: 20, containLabel: true }" /> </div> </div> <div class="right-container"> <el-switch v-model="yType" active-text="常数" inactive-text="对数"> </el-switch> <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: 5px 0"> <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> <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"> <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>