|
|
|
|
<template>
|
|
|
|
|
<el-drawer
|
|
|
|
|
v-model="drawer"
|
|
|
|
|
:direction="'btt'"
|
|
|
|
|
:before-close="handleClose"
|
|
|
|
|
:destroy-on-close="true"
|
|
|
|
|
resizable
|
|
|
|
|
size="480px"
|
|
|
|
|
>
|
|
|
|
|
<template #header>
|
|
|
|
|
<h4
|
|
|
|
|
>{{ currentMarker?.name }}手持表
|
|
|
|
|
<span class="gasChemical">{{ currentMarker?.gasChemical }}检测</span></h4
|
|
|
|
|
>
|
|
|
|
|
</template>
|
|
|
|
|
<template #default>
|
|
|
|
|
<!-- <div> 数据统计截止:{{ currentMarker?.timeStr }} </div> -->
|
|
|
|
|
<div>
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
<div class="chart-title"> {{ currentMarker?.gasChemical }}浓度与电量趋势 </div>
|
|
|
|
|
<div>
|
|
|
|
|
<el-date-picker
|
|
|
|
|
v-model="gasDateTimeRange"
|
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
type="datetimerange"
|
|
|
|
|
start-placeholder="开始日期"
|
|
|
|
|
end-placeholder="结束日期"
|
|
|
|
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
|
|
|
|
@change="handleDateChange"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="drawer && !loading">
|
|
|
|
|
<Echart :options="gasLineOptions" :height="325" />
|
|
|
|
|
</div>
|
|
|
|
|
<!-- <div v-if="drawer && !loading">
|
|
|
|
|
<Echart :options="gasSigLineOptions" :height="325" />
|
|
|
|
|
</div> -->
|
|
|
|
|
</div>
|
|
|
|
|
<!-- <div>
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
<div> 电量趋势 </div>
|
|
|
|
|
<div>
|
|
|
|
|
<el-date-picker
|
|
|
|
|
v-model="gasDateTimeRange"
|
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
type="daterange"
|
|
|
|
|
start-placeholder="开始日期"
|
|
|
|
|
end-placeholder="结束日期"
|
|
|
|
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
|
|
|
|
class="!w-240px"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="drawer && !loading">
|
|
|
|
|
<Echart :options="batteryLineOptions" :height="300" />
|
|
|
|
|
</div>
|
|
|
|
|
</div> -->
|
|
|
|
|
</template>
|
|
|
|
|
<!-- <template #footer>
|
|
|
|
|
<div style="flex: auto">
|
|
|
|
|
<el-button @click="cancelClick">cancel</el-button>
|
|
|
|
|
<el-button type="primary" @click="confirmClick">confirm</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template> -->
|
|
|
|
|
</el-drawer>
|
|
|
|
|
</template>
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { ref, computed } from 'vue'
|
|
|
|
|
import type { MarkerData } from './types/map.types'
|
|
|
|
|
|
|
|
|
|
import { tdengineApi, tdStruct } from '@/api/gas/tdengine/index'
|
|
|
|
|
|
|
|
|
|
import { EChartsOption } from 'echarts'
|
|
|
|
|
import Echart from '@/components/Echart/src/Echart.vue'
|
|
|
|
|
|
|
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
|
|
|
|
|
|
export type tdStruct2 = tdStruct & {
|
|
|
|
|
timeStr: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const drawer = ref(false)
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const currentMarker = ref<MarkerData | null>()
|
|
|
|
|
const historicalData = ref<tdStruct2[]>([])
|
|
|
|
|
async function getData(row: MarkerData) {
|
|
|
|
|
try {
|
|
|
|
|
const data = await tdengineApi.getHistoricalSn({
|
|
|
|
|
sn: row.sn,
|
|
|
|
|
startTime: gasDateTimeRange.value[0],
|
|
|
|
|
endTime: gasDateTimeRange.value[1]
|
|
|
|
|
})
|
|
|
|
|
if (!data || data.length === 0) {
|
|
|
|
|
ElMessage.error('没有数据')
|
|
|
|
|
historicalData.value = []
|
|
|
|
|
}
|
|
|
|
|
historicalData.value = data.map((item) => ({
|
|
|
|
|
...item,
|
|
|
|
|
timeStr: dayjs(item.ts).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
}))
|
|
|
|
|
console.log(historicalData.value)
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// ElMessage.error(error.message)
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
// console.log(data)
|
|
|
|
|
}
|
|
|
|
|
function openDrawer(row: MarkerData) {
|
|
|
|
|
reset()
|
|
|
|
|
historicalData.value = []
|
|
|
|
|
currentMarker.value = row
|
|
|
|
|
drawer.value = true
|
|
|
|
|
loading.value = true
|
|
|
|
|
getData(row)
|
|
|
|
|
}
|
|
|
|
|
const handleClose = (done) => {
|
|
|
|
|
reset()
|
|
|
|
|
done()
|
|
|
|
|
}
|
|
|
|
|
const reset = () => {
|
|
|
|
|
loading.value = false
|
|
|
|
|
historicalData.value = []
|
|
|
|
|
currentMarker.value = null
|
|
|
|
|
gasDateTimeRange.value = [
|
|
|
|
|
dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const gasDateTimeRange = ref(['', ''])
|
|
|
|
|
const handleDateChange = () => {
|
|
|
|
|
if (!currentMarker.value) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
getData(currentMarker.value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const gas = computed(() => {
|
|
|
|
|
var value: (number | null)[] = []
|
|
|
|
|
var battery: (number | null)[] = []
|
|
|
|
|
var mem: (number | null)[] = []
|
|
|
|
|
var rssi: (number | null)[] = []
|
|
|
|
|
var rsrp: (number | null)[] = []
|
|
|
|
|
var rsrq: (number | null)[] = []
|
|
|
|
|
var sinr: (number | null)[] = []
|
|
|
|
|
|
|
|
|
|
var time: string[] = []
|
|
|
|
|
historicalData.value
|
|
|
|
|
// .filter((item) => typeof item.value === 'number')
|
|
|
|
|
.forEach((item) => {
|
|
|
|
|
if (item.battery !== '') {
|
|
|
|
|
battery.push(Number(item.battery))
|
|
|
|
|
} else {
|
|
|
|
|
battery.push(null)
|
|
|
|
|
}
|
|
|
|
|
if (typeof item.value === 'number') {
|
|
|
|
|
value.push(Number(item.value))
|
|
|
|
|
} else {
|
|
|
|
|
value.push(null)
|
|
|
|
|
}
|
|
|
|
|
if (item.mem) {
|
|
|
|
|
mem.push(item.mem / 1024)
|
|
|
|
|
} else {
|
|
|
|
|
mem.push(null)
|
|
|
|
|
}
|
|
|
|
|
if (item.sig) {
|
|
|
|
|
try {
|
|
|
|
|
let sig = JSON.parse(item.sig)
|
|
|
|
|
if (sig.length == 5) {
|
|
|
|
|
rssi.push(sig[0])
|
|
|
|
|
rsrp.push(sig[1])
|
|
|
|
|
rsrq.push(sig[2])
|
|
|
|
|
sinr.push(sig[4])
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
rssi.push(null)
|
|
|
|
|
rsrp.push(null)
|
|
|
|
|
rsrq.push(null)
|
|
|
|
|
sinr.push(null)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
rssi.push(null)
|
|
|
|
|
rsrp.push(null)
|
|
|
|
|
rsrq.push(null)
|
|
|
|
|
sinr.push(null)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
time.push(item.timeStr)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
value,
|
|
|
|
|
battery,
|
|
|
|
|
mem,
|
|
|
|
|
rssi,
|
|
|
|
|
rsrp,
|
|
|
|
|
rsrq,
|
|
|
|
|
sinr,
|
|
|
|
|
time
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
const gasLineOptions = computed<EChartsOption>(() => {
|
|
|
|
|
const option: EChartsOption = {
|
|
|
|
|
title: {
|
|
|
|
|
text: '',
|
|
|
|
|
left: 'center'
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
data: gas.value.time,
|
|
|
|
|
boundaryGap: false,
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'cross'
|
|
|
|
|
},
|
|
|
|
|
padding: [5, 10]
|
|
|
|
|
},
|
|
|
|
|
yAxis: [
|
|
|
|
|
{
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
legend: {
|
|
|
|
|
// data: [],
|
|
|
|
|
top: 50
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: currentMarker.value?.gasChemical + '浓度',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: gas.value.value,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
|
|
|
|
|
animationEasing: 'cubicInOut'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '电池电量',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 1,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
data: gas.value.battery,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
animationEasing: 'cubicInOut'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '内存占用',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 1,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
data: gas.value.mem,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
animationEasing: 'cubicInOut',
|
|
|
|
|
tooltip: {
|
|
|
|
|
valueFormatter: function (value) {
|
|
|
|
|
if (value === null || value === undefined || isNaN(value)) {
|
|
|
|
|
return '-'
|
|
|
|
|
}
|
|
|
|
|
return Number(value).toFixed(3) + 'KB' // 返回带单位的字符串
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'RSSI',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
data: gas.value.rssi,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
animationEasing: 'cubicInOut'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'RSRP',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
data: gas.value.rsrp,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
animationEasing: 'cubicInOut'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'RSRQ',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
data: gas.value.rsrq,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
animationEasing: 'cubicInOut'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'SINR',
|
|
|
|
|
smooth: true,
|
|
|
|
|
type: 'line',
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
symbol: 'none',
|
|
|
|
|
data: gas.value.sinr,
|
|
|
|
|
animationDuration: 2800,
|
|
|
|
|
animationEasing: 'cubicInOut'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
const grid = {
|
|
|
|
|
left: 20,
|
|
|
|
|
right: 20,
|
|
|
|
|
bottom: 10,
|
|
|
|
|
top: 80,
|
|
|
|
|
containLabel: true
|
|
|
|
|
}
|
|
|
|
|
if (gas.value.time.length >= 100) {
|
|
|
|
|
grid.bottom = 50
|
|
|
|
|
|
|
|
|
|
// 缩放
|
|
|
|
|
option.dataZoom = [
|
|
|
|
|
{
|
|
|
|
|
type: 'slider',
|
|
|
|
|
xAxisIndex: [0],
|
|
|
|
|
bottom: 10,
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 100
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'inside',
|
|
|
|
|
xAxisIndex: [0],
|
|
|
|
|
start: 0,
|
|
|
|
|
end: 100
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
option.grid = grid
|
|
|
|
|
|
|
|
|
|
return option
|
|
|
|
|
})
|
|
|
|
|
// const gasSigLineOptions = computed<EChartsOption>(() => {
|
|
|
|
|
// const option: EChartsOption = {
|
|
|
|
|
// title: {
|
|
|
|
|
// text: '',
|
|
|
|
|
// left: 'center'
|
|
|
|
|
// },
|
|
|
|
|
// xAxis: {
|
|
|
|
|
// data: gas.value.time,
|
|
|
|
|
// boundaryGap: false,
|
|
|
|
|
// axisTick: {
|
|
|
|
|
// show: false
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
|
|
// tooltip: {
|
|
|
|
|
// trigger: 'axis',
|
|
|
|
|
// axisPointer: {
|
|
|
|
|
// type: 'cross'
|
|
|
|
|
// },
|
|
|
|
|
// padding: [5, 10]
|
|
|
|
|
// },
|
|
|
|
|
// yAxis: [
|
|
|
|
|
// {
|
|
|
|
|
// axisTick: {
|
|
|
|
|
// show: false
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// axisTick: {
|
|
|
|
|
// show: false
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// ],
|
|
|
|
|
// legend: {
|
|
|
|
|
// // data: [],
|
|
|
|
|
// top: 50
|
|
|
|
|
// },
|
|
|
|
|
// series: [
|
|
|
|
|
// {
|
|
|
|
|
// name: '电池电量',
|
|
|
|
|
// smooth: true,
|
|
|
|
|
// type: 'line',
|
|
|
|
|
// yAxisIndex: 1,
|
|
|
|
|
// symbol: 'none',
|
|
|
|
|
// data: gas.value.battery,
|
|
|
|
|
// animationDuration: 2800,
|
|
|
|
|
// animationEasing: 'cubicInOut'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// name: '内存占用',
|
|
|
|
|
// smooth: true,
|
|
|
|
|
// type: 'line',
|
|
|
|
|
// yAxisIndex: 1,
|
|
|
|
|
// symbol: 'none',
|
|
|
|
|
// data: gas.value.mem,
|
|
|
|
|
// animationDuration: 2800,
|
|
|
|
|
// animationEasing: 'cubicInOut'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// name: 'RSSI',
|
|
|
|
|
// smooth: true,
|
|
|
|
|
// type: 'line',
|
|
|
|
|
// yAxisIndex: 0,
|
|
|
|
|
// symbol: 'none',
|
|
|
|
|
// data: gas.value.rssi,
|
|
|
|
|
// animationDuration: 2800,
|
|
|
|
|
// animationEasing: 'cubicInOut'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// name: 'RSRP',
|
|
|
|
|
// smooth: true,
|
|
|
|
|
// type: 'line',
|
|
|
|
|
// yAxisIndex: 0,
|
|
|
|
|
// symbol: 'none',
|
|
|
|
|
// data: gas.value.rsrp,
|
|
|
|
|
// animationDuration: 2800,
|
|
|
|
|
// animationEasing: 'cubicInOut'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// name: 'RSRQ',
|
|
|
|
|
// smooth: true,
|
|
|
|
|
// type: 'line',
|
|
|
|
|
// yAxisIndex: 0,
|
|
|
|
|
// symbol: 'none',
|
|
|
|
|
// data: gas.value.rsrq,
|
|
|
|
|
// animationDuration: 2800,
|
|
|
|
|
// animationEasing: 'cubicInOut'
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// name: 'SINR',
|
|
|
|
|
// smooth: true,
|
|
|
|
|
// type: 'line',
|
|
|
|
|
// yAxisIndex: 0,
|
|
|
|
|
// symbol: 'none',
|
|
|
|
|
// data: gas.value.sinr,
|
|
|
|
|
// animationDuration: 2800,
|
|
|
|
|
// animationEasing: 'cubicInOut'
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// const grid = {
|
|
|
|
|
// left: 20,
|
|
|
|
|
// right: 20,
|
|
|
|
|
// bottom: 10,
|
|
|
|
|
// top: 80,
|
|
|
|
|
// containLabel: true
|
|
|
|
|
// }
|
|
|
|
|
// if (gas.value.time.length >= 100) {
|
|
|
|
|
// grid.bottom = 50
|
|
|
|
|
|
|
|
|
|
// // 缩放
|
|
|
|
|
// option.dataZoom = [
|
|
|
|
|
// {
|
|
|
|
|
// type: 'slider',
|
|
|
|
|
// xAxisIndex: [0],
|
|
|
|
|
// bottom: 10,
|
|
|
|
|
// start: 0,
|
|
|
|
|
// end: 100
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// type: 'inside',
|
|
|
|
|
// xAxisIndex: [0],
|
|
|
|
|
// start: 0,
|
|
|
|
|
// end: 100
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// } else {
|
|
|
|
|
// }
|
|
|
|
|
// option.grid = grid
|
|
|
|
|
|
|
|
|
|
// return option
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
defineExpose({
|
|
|
|
|
openDrawer
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
.chart-title {
|
|
|
|
|
position: relative;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
padding-left: 10px;
|
|
|
|
|
|
|
|
|
|
&::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
left: 0px;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
top: 0;
|
|
|
|
|
width: 4px;
|
|
|
|
|
height: 100%;
|
|
|
|
|
background-color: rgba(22, 119, 255, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.gasChemical {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
padding: 2px 6px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #f59a23;
|
|
|
|
|
background-color: rgba(245, 154, 35, 0.09);
|
|
|
|
|
}
|
|
|
|
|
</style>
|