<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>