33 changed files with 425 additions and 7941 deletions
File diff suppressed because it is too large
@ -1,109 +0,0 @@ |
|||
<template> |
|||
<el-card class="box-card"> |
|||
<el-empty v-if="noData" description="暂无数据"></el-empty> |
|||
<div id="realtimeContainer"></div> |
|||
</el-card> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { defineExpose, onMounted, ref } from 'vue'; |
|||
import { Line } from '@antv/g2plot'; |
|||
import { formatChartTime } from 'utils/time'; |
|||
|
|||
const show = ref(false); |
|||
const noData = ref(true); |
|||
let bar = null; |
|||
|
|||
// 设置图表 |
|||
onMounted(() => { |
|||
show.value = true; |
|||
}); |
|||
|
|||
// 设置图表 |
|||
const setDate = data => { |
|||
if (bar) { |
|||
bar.destroy(); |
|||
} |
|||
bar = new Line('realtimeContainer', { |
|||
data, |
|||
padding: 'auto', |
|||
xField: 'time', |
|||
yField: 'value', |
|||
seriesField: 'category', |
|||
slider: { |
|||
start: 0.5, |
|||
end: 1, |
|||
}, |
|||
height: 700, |
|||
// smooth: true, |
|||
point: { |
|||
size: 2, |
|||
shape: 'circular', |
|||
style: { |
|||
fill: 'white', |
|||
lineWidth: 2, |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
bar.render(); |
|||
}; |
|||
|
|||
// 处理数据 |
|||
const changeDate = value => { |
|||
if (!value || !value.length) { |
|||
noData.value = true; |
|||
return; |
|||
} |
|||
noData.value = false; |
|||
|
|||
const arr = []; |
|||
value.forEach(element => { |
|||
const item = { ...element }; |
|||
|
|||
const so2Item = { category: 'SO2(ppb)' }; |
|||
const saltItem = { category: '盐分阻抗(Ω)' }; |
|||
const environmentTemperatureItem = { category: '环温(℃)' }; |
|||
const environmentHumidityItem = { category: '环湿(RH%)' }; |
|||
const corrosion1Item = { category: '锌腐蚀电流(nA)' }; |
|||
const corrosion2Item = { category: '铜腐蚀电流(nA)' }; |
|||
const corrosion3Item = { category: '铝腐蚀电流(nA)' }; |
|||
const corrosion4Item = { category: '钢腐蚀电流(nA)' }; |
|||
|
|||
so2Item.time = formatChartTime(item.time); |
|||
so2Item.value = item.so2; |
|||
arr.push(so2Item); |
|||
|
|||
saltItem.time = formatChartTime(item.time); |
|||
saltItem.value = item.salt; |
|||
arr.push(saltItem); |
|||
|
|||
environmentTemperatureItem.time = formatChartTime(item.time); |
|||
environmentTemperatureItem.value = item.environmentTemperature; |
|||
arr.push(environmentTemperatureItem); |
|||
|
|||
environmentHumidityItem.time = formatChartTime(item.time); |
|||
environmentHumidityItem.value = item.environmentHumidity; |
|||
arr.push(environmentHumidityItem); |
|||
|
|||
corrosion1Item.time = formatChartTime(item.time); |
|||
corrosion1Item.value = item.corrosion1; |
|||
arr.push(corrosion1Item); |
|||
|
|||
corrosion2Item.time = formatChartTime(item.time); |
|||
corrosion2Item.value = item.corrosion2; |
|||
arr.push(corrosion2Item); |
|||
|
|||
corrosion3Item.time = formatChartTime(item.time); |
|||
corrosion3Item.value = item.corrosion3; |
|||
arr.push(corrosion3Item); |
|||
|
|||
corrosion4Item.time = formatChartTime(item.time); |
|||
corrosion4Item.value = item.corrosion4; |
|||
arr.push(corrosion4Item); |
|||
}); |
|||
setDate(arr); |
|||
}; |
|||
|
|||
defineExpose({ changeDate }); |
|||
</script> |
@ -1,65 +0,0 @@ |
|||
<template> |
|||
<el-form :inline="true" :model="searchDevice" ref="searchDeviceForm"> |
|||
<el-form-item label="选择站点"> |
|||
<el-select v-model="searchDevice.deviceId" placeholder="请选择站点" @change="change"> |
|||
<el-option label="全部" value=""></el-option> |
|||
<el-option :label="item.address" :value="item.deviceId" v-for="item in devices" :key="item.deviceId"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="选择日期"> |
|||
<el-date-picker |
|||
v-model="searchDevice.date" |
|||
type="monthrange" |
|||
range-separator="~" |
|||
start-placeholder="开始月份" |
|||
end-placeholder="结束月份" |
|||
> |
|||
</el-date-picker> |
|||
</el-form-item> |
|||
<el-form-item class="ml-6"> |
|||
<el-button type="primary" @click="onSubmit"><i class="el-icon-search mr-2"></i> 查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { reactive, ref, computed, defineEmits, watch } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
import dayjs from 'dayjs'; |
|||
|
|||
const emit = defineEmits(['search']); |
|||
const searchDevice = reactive({ deviceId: '', date: '' }); |
|||
const searchDeviceForm = ref(null); // form |
|||
const store = useStore(); |
|||
const devices = computed(() => store.state.device.devices); |
|||
const currentDeviceId = computed(() => store.state.device.currentDeviceId); // 正在操作的设备的id |
|||
|
|||
// 监听currentDeviceId |
|||
watch( |
|||
() => currentDeviceId.value, |
|||
newValue => { |
|||
if (newValue && searchDevice.deviceId !== newValue) { |
|||
searchDevice.deviceId = newValue; |
|||
} |
|||
}, |
|||
{ immediate: true }, |
|||
); |
|||
|
|||
const change = e => { |
|||
store.commit('device/setCurrentDeviceId', e); |
|||
}; |
|||
|
|||
const onSubmit = () => { |
|||
searchDeviceForm.value.validate(() => { |
|||
const { deviceId, date } = { ...searchDevice }; |
|||
if (date) { |
|||
const start = dayjs(date[0]).valueOf(); |
|||
const end = dayjs(date[1]).valueOf(); |
|||
const daterange = [start, end]; |
|||
emit('search', { deviceId, date: daterange }); |
|||
} else { |
|||
emit('search', { deviceId, date }); |
|||
} |
|||
}); |
|||
}; |
|||
</script> |
@ -1,152 +0,0 @@ |
|||
<template> |
|||
<el-row :gutter="10"> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置金属腐蚀采样频率(分钟):</span> |
|||
<span>{{ data.frequency.metal }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置温湿度采样频率(分钟):</span> |
|||
<span>{{ data.frequency.th }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置SO2采样频率(分钟):</span> |
|||
<span>{{ data.frequency.so2 }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置盐雾采样频率(分钟):</span> |
|||
<span>{{ data.frequency.salt }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置时间:</span> |
|||
<span>{{ formatMsTime(data.time) }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置金属腐蚀采集个数:</span> |
|||
<span>{{ data.count }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置电池电压低阈值:</span> |
|||
<span>{{ data.batteryLow }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置电池电压高阈值:</span> |
|||
<span>{{ data.batteryHigh }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置太阳能电压高阈值:</span> |
|||
<span>{{ data.sunHigh }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置湿度高阈值:</span> |
|||
<span>{{ data.humidityHigh }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置温度低阈值:</span> |
|||
<span>{{ data.temperatureLow }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>设置温度高阈值:</span> |
|||
<span>{{ data.temperatureHigh }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>选择金属通道1类型:</span> |
|||
<span>{{ formatCorrosiveType(data.corrosiveType1) }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>选择金属通道2类型:</span> |
|||
<span>{{ formatCorrosiveType(data.corrosiveType2) }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>选择金属通道3类型:</span> |
|||
<span>{{ formatCorrosiveType(data.corrosiveType3) }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>选择金属通道4类型:</span> |
|||
<span>{{ formatCorrosiveType(data.corrosiveType4) }}</span> |
|||
</el-col> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>安全模式:</span> |
|||
<span>{{ formatMode(data.securityMode) }}</span> |
|||
</el-col> |
|||
</el-row> |
|||
|
|||
<el-row> |
|||
<el-col :lg="8" :md="12" :xl="6" :xs="24" class="text-sm text-gray-500 py-3"> |
|||
<span>上报类型:</span> |
|||
<span class="mr-8">{{ formatReportType(data.report.type) }}</span> |
|||
|
|||
<span v-if="data.report.type === 'POINT'">{{ data.report.reportTimePoints }}</span> |
|||
<span v-else>{{ data.report.cycle }}分钟</span> |
|||
</el-col> |
|||
</el-row> |
|||
|
|||
<!-- 刷新下发按钮 --> |
|||
<!-- <Refresh @refresh="onSearch(currentDeviceI, 1)" /> --> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { computed, defineEmits, defineProps, ref, watch } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
import { getConfigAppliedFunction } from 'apis'; |
|||
import { formatMsTime } from 'utils/time'; |
|||
import { corrosiveTypes, functionConfig } from '@/config/config'; |
|||
|
|||
const store = useStore(); |
|||
const currentDeviceId = computed(() => store.state.device.currentDeviceId); |
|||
const data = ref(functionConfig); // 实际数据 |
|||
const emit = defineEmits(['status']); |
|||
const props = defineProps({ activeName: String }); |
|||
|
|||
/** |
|||
* 查询网络参数配置 设备真实参数 |
|||
* @param {string} deviceId 设备id |
|||
*/ |
|||
const onSearch = async deviceId => { |
|||
try { |
|||
const params = { deviceId }; |
|||
const resData = await getConfigAppliedFunction(params); |
|||
data.value = resData || functionConfig; |
|||
if (resData && resData.status) { |
|||
emit('status', resData.status); |
|||
} else { |
|||
emit('status', ''); |
|||
} |
|||
} catch (error) { |
|||
throw new Error(error); |
|||
} |
|||
}; |
|||
|
|||
watch( |
|||
currentDeviceId, |
|||
newDeviceId => { |
|||
newDeviceId && props.activeName === 'applied' && onSearch(newDeviceId); |
|||
}, |
|||
{ immediate: true }, |
|||
); |
|||
|
|||
/** |
|||
* 转化安全模式 |
|||
* @param {string} mode OPEN->加密 |
|||
*/ |
|||
function formatMode(mode) { |
|||
return mode === 'OPEN' ? '不加密' : '加密'; |
|||
} |
|||
|
|||
/** |
|||
* 转化上报类型显示 |
|||
* @param {string} reportType 上报类型 |
|||
*/ |
|||
function formatReportType(reportType) { |
|||
return reportType === 'POINT' ? '按时间点上报' : '按周期上报'; |
|||
} |
|||
|
|||
/** |
|||
* 格式化金属腐蚀类型 |
|||
* @param {string} type 服务端返回的类型 |
|||
* @return {string} type 对应的文字名称 |
|||
*/ |
|||
function formatCorrosiveType(type) { |
|||
const target = corrosiveTypes.find(item => item.value === type); |
|||
return target && target.type ? target.type : ''; |
|||
} |
|||
</script> |
@ -1,51 +0,0 @@ |
|||
<template> |
|||
<el-card class="box-card"> |
|||
<div class="text-sm">积分电量(C)</div> |
|||
<el-empty description="暂无数据" v-if="noData"></el-empty> |
|||
<div id="container"></div> |
|||
</el-card> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { onMounted, ref, defineExpose } from 'vue'; |
|||
import { Column } from '@antv/g2plot'; |
|||
|
|||
const show = ref(false); |
|||
const noData = ref(true); |
|||
let bar = null; |
|||
|
|||
// 设置图表 |
|||
onMounted(() => { |
|||
show.value = true; |
|||
}); |
|||
|
|||
const setDate = data => { |
|||
noData.value = false; |
|||
if (bar) { |
|||
bar.destroy(); |
|||
} |
|||
bar = new Column('container', { |
|||
data, |
|||
layout: 'vertical', |
|||
xField: 'time', |
|||
yField: 'value', |
|||
padding: [30, 16, 60, 50], |
|||
columnWidthRatio: 0.6, // 宽度占比 |
|||
yAxis: { |
|||
title: { |
|||
text: '积分电量', |
|||
spacing: 20, |
|||
}, |
|||
}, |
|||
slider: { |
|||
start: 0.1, |
|||
end: 0.5, |
|||
}, |
|||
meta: { value: { alias: '积分电量(C)' } }, |
|||
}); |
|||
|
|||
bar.render(); |
|||
}; |
|||
|
|||
defineExpose({ setDate }); |
|||
</script> |
@ -1,53 +0,0 @@ |
|||
<template> |
|||
<el-card class="box-card"> |
|||
<div class="text-sm">月累计湿润时间(h)</div> |
|||
<el-empty description="暂无数据" v-if="noData"></el-empty> |
|||
<div id="moistTimeDataContainer"></div> |
|||
</el-card> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { onMounted, ref, defineExpose } from 'vue'; |
|||
import { Column } from '@antv/g2plot'; |
|||
|
|||
const show = ref(false); |
|||
const noData = ref(true); |
|||
let bar = null; |
|||
|
|||
// 设置图表 |
|||
onMounted(() => { |
|||
show.value = true; |
|||
}); |
|||
|
|||
const setDate = data => { |
|||
noData.value = false; |
|||
if (bar) { |
|||
bar.destroy(); |
|||
} |
|||
bar = new Column('moistTimeDataContainer', { |
|||
data, |
|||
layout: 'vertical', |
|||
xField: 'time', |
|||
yField: 'value', |
|||
// height: 200, |
|||
padding: [30, 16, 60, 50], |
|||
color: '#C280FF', |
|||
columnWidthRatio: 0.6, // 宽度占比 |
|||
yAxis: { |
|||
title: { |
|||
text: '月累计湿润时间', |
|||
spacing: 20, |
|||
}, |
|||
}, |
|||
slider: { |
|||
start: 0.1, |
|||
end: 0.5, |
|||
}, |
|||
meta: { value: { alias: '月累计湿润时间(h)' } }, |
|||
}); |
|||
|
|||
bar.render(); |
|||
}; |
|||
|
|||
defineExpose({ setDate }); |
|||
</script> |
@ -1,99 +0,0 @@ |
|||
<template> |
|||
<el-row :gutter="10"> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报IP地址1:</span> |
|||
<span>{{ appliedData.ip1 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报端口号1:</span> |
|||
<span>{{ appliedData.port1 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报IP地址2:</span> |
|||
<span>{{ appliedData.ip2 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报端口号2:</span> |
|||
<span>{{ appliedData.port2 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报IP地址3:</span> |
|||
<span>{{ appliedData.ip3 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报端口号3:</span> |
|||
<span>{{ appliedData.port3 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报IP地址4:</span> |
|||
<span>{{ appliedData.ip4 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>上报端口号4:</span> |
|||
<span>{{ appliedData.port4 }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>备用ip地址:</span> |
|||
<span>{{ appliedData.ipBackup }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>备用端口号:</span> |
|||
<span>{{ appliedData.portBackup }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>用户名:</span> |
|||
<span>{{ appliedData.account }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>密码:</span> |
|||
<span>{{ appliedData.password }}</span> |
|||
</el-col> |
|||
<el-col :xs="24" :md="12" :lg="8" :xl="6" class="text-sm text-gray-500 py-3"> |
|||
<span>APN:</span> |
|||
<span>{{ appliedData.apn }}</span> |
|||
</el-col> |
|||
</el-row> |
|||
|
|||
<!-- 刷新下发按钮 --> |
|||
<!-- <Refresh @refresh="onSearch(currentDeviceI, 1)" /> --> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { computed, ref, watch, defineEmits, defineProps } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
import { getConfigAppliedNetwork } from 'apis/index'; |
|||
import { networkConfig } from '@/config/config'; |
|||
|
|||
const store = useStore(); |
|||
const currentDeviceId = computed(() => store.state.device.currentDeviceId); |
|||
const appliedData = ref(networkConfig); // 实际数据 |
|||
const emit = defineEmits(['status']); |
|||
const props = defineProps({ activeName: String }); |
|||
|
|||
/** |
|||
* 查询网络参数配置 设备真实参数 |
|||
* @param {string} deviceId 设备id |
|||
*/ |
|||
const onSearch = async deviceId => { |
|||
try { |
|||
const params = { deviceId }; |
|||
const resData = await getConfigAppliedNetwork(params); |
|||
appliedData.value = resData || networkConfig; |
|||
if (resData && resData.status) { |
|||
emit('status', resData.status); |
|||
} else { |
|||
emit('status', ''); |
|||
} |
|||
} catch (error) { |
|||
throw new Error(error); |
|||
} |
|||
}; |
|||
|
|||
watch( |
|||
currentDeviceId, |
|||
newDeviceId => { |
|||
newDeviceId && props.activeName === 'applied' && onSearch(newDeviceId); |
|||
}, |
|||
{ immediate: true }, |
|||
); |
|||
</script> |
@ -1,125 +0,0 @@ |
|||
<template> |
|||
<el-card class="box-card"> |
|||
<el-empty v-if="noData" description="暂无数据"></el-empty> |
|||
<div v-show="!noData" id="realtimeContainer"></div> |
|||
</el-card> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { defineExpose, onMounted, ref } from 'vue'; |
|||
import { Line } from '@antv/g2plot'; |
|||
import { formatChartTime } from 'utils/time'; |
|||
|
|||
const show = ref(false); |
|||
const noData = ref(true); |
|||
let bar = null; |
|||
|
|||
// 设置图表 |
|||
onMounted(() => { |
|||
show.value = true; |
|||
}); |
|||
|
|||
// 设置图表 |
|||
const setDate = data => { |
|||
if (bar) { |
|||
bar.changeData(data); |
|||
return; |
|||
} |
|||
|
|||
bar = new Line('realtimeContainer', { |
|||
data, |
|||
padding: 'auto', |
|||
xField: 'time', |
|||
yField: 'value', |
|||
seriesField: 'category', |
|||
slider: { |
|||
start: 0.5, |
|||
end: 1, |
|||
}, |
|||
height: 700, |
|||
// smooth: true, |
|||
point: { |
|||
size: 2, |
|||
shape: 'circular', |
|||
style: { |
|||
fill: 'white', |
|||
lineWidth: 2, |
|||
}, |
|||
}, |
|||
}); |
|||
|
|||
// bar.on('slider:drag', function (event) { |
|||
// console.log('event: ', event); |
|||
// }); |
|||
|
|||
bar.render(); |
|||
}; |
|||
|
|||
// 处理数据 |
|||
const changeDate = value => { |
|||
if (!value || !value.length) { |
|||
noData.value = true; |
|||
return; |
|||
} |
|||
noData.value = false; |
|||
|
|||
const arr = []; |
|||
value.forEach(element => { |
|||
const item = { ...element }; |
|||
|
|||
const so2Item = { category: 'SO2' }; |
|||
const saltItem = { category: '盐分' }; |
|||
const environmentTemperatureItem = { category: '环温' }; |
|||
const environmentHumidityItem = { category: '环湿' }; |
|||
const deviceTemperatureItem = { category: '机温' }; |
|||
const deviceHumidityItem = { category: '机湿' }; |
|||
const corrosion1Item = { category: '腐流1' }; |
|||
const corrosion2Item = { category: '腐流2' }; |
|||
const corrosion3Item = { category: '腐流3' }; |
|||
const corrosion4Item = { category: '腐流4' }; |
|||
|
|||
so2Item.time = formatChartTime(item.time); |
|||
so2Item.value = item.so2; |
|||
arr.push(so2Item); |
|||
|
|||
saltItem.time = formatChartTime(item.time); |
|||
saltItem.value = item.salt; |
|||
arr.push(saltItem); |
|||
|
|||
environmentTemperatureItem.time = formatChartTime(item.time); |
|||
environmentTemperatureItem.value = item.environmentTemperature; |
|||
arr.push(environmentTemperatureItem); |
|||
|
|||
environmentHumidityItem.time = formatChartTime(item.time); |
|||
environmentHumidityItem.value = item.environmentHumidity; |
|||
arr.push(environmentHumidityItem); |
|||
|
|||
deviceTemperatureItem.time = formatChartTime(item.time); |
|||
deviceTemperatureItem.value = item.deviceTemperature; |
|||
arr.push(deviceTemperatureItem); |
|||
|
|||
deviceHumidityItem.time = formatChartTime(item.time); |
|||
deviceHumidityItem.value = item.deviceHumidity; |
|||
arr.push(deviceHumidityItem); |
|||
|
|||
corrosion1Item.time = formatChartTime(item.time); |
|||
corrosion1Item.value = item.corrosion1; |
|||
arr.push(corrosion1Item); |
|||
|
|||
corrosion2Item.time = formatChartTime(item.time); |
|||
corrosion2Item.value = item.corrosion2; |
|||
arr.push(corrosion2Item); |
|||
|
|||
corrosion3Item.time = formatChartTime(item.time); |
|||
corrosion3Item.value = item.corrosion3; |
|||
arr.push(corrosion3Item); |
|||
|
|||
corrosion4Item.time = formatChartTime(item.time); |
|||
corrosion4Item.value = item.corrosion4; |
|||
arr.push(corrosion4Item); |
|||
}); |
|||
setDate(arr); |
|||
}; |
|||
|
|||
defineExpose({ changeDate }); |
|||
</script> |
@ -0,0 +1,66 @@ |
|||
<template> |
|||
<el-card class="box-card"> |
|||
<el-empty v-if="noData" description="暂无数据"></el-empty> |
|||
<div id="realtimeContainer"></div> |
|||
</el-card> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { defineExpose, defineProps, onMounted, ref } from 'vue'; |
|||
import { generateChartOption } from 'utils/statistical'; |
|||
import * as echarts from 'echarts/core'; |
|||
import { DataZoomComponent, GridComponent, LegendComponent, ToolboxComponent, TooltipComponent } from 'echarts/components'; |
|||
import { LineChart } from 'echarts/charts'; |
|||
import { UniversalTransition } from 'echarts/features'; |
|||
import { CanvasRenderer } from 'echarts/renderers'; |
|||
|
|||
echarts.use([ |
|||
ToolboxComponent, |
|||
TooltipComponent, |
|||
GridComponent, |
|||
LegendComponent, |
|||
LineChart, |
|||
CanvasRenderer, |
|||
UniversalTransition, |
|||
DataZoomComponent, |
|||
]); |
|||
|
|||
const props = defineProps({ searchHeight: Number }); |
|||
|
|||
const show = ref(false); |
|||
const noData = ref(true); |
|||
let myChart = null; |
|||
|
|||
// 设置图表 |
|||
onMounted(() => { |
|||
show.value = true; |
|||
initChart(); |
|||
}); |
|||
|
|||
// 初始化chart |
|||
function initChart() { |
|||
const chartDom = document.getElementById('realtimeContainer'); |
|||
const canvasHeight = document.documentElement.clientHeight - props.searchHeight - 150; |
|||
console.log(canvasHeight, document.documentElement.clientHeight, props.searchHeight); |
|||
chartDom.style.height = `${canvasHeight}px`; |
|||
myChart && myChart.dispose(); |
|||
myChart = echarts.init(chartDom); |
|||
} |
|||
|
|||
function render(data) { |
|||
myChart && myChart.clear(); |
|||
if (!data || !data.length) { |
|||
noData.value = true; |
|||
return; |
|||
} |
|||
noData.value = false; |
|||
|
|||
if (!myChart) { |
|||
initChart(); |
|||
} |
|||
const option = generateChartOption(data); |
|||
option && myChart.setOption(option); |
|||
} |
|||
|
|||
defineExpose({ render }); |
|||
</script> |
@ -1,52 +0,0 @@ |
|||
<template> |
|||
<el-card class="box-card"> |
|||
<div class="text-sm">月累计腐蚀(g/m²)</div> |
|||
<el-empty description="暂无数据" v-if="noData"></el-empty> |
|||
<div id="corrosionContainer"></div> |
|||
</el-card> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { onMounted, ref, defineExpose } from 'vue'; |
|||
import { Column } from '@antv/g2plot'; |
|||
|
|||
const show = ref(false); |
|||
const noData = ref(true); |
|||
let bar = null; |
|||
|
|||
// 设置图表 |
|||
onMounted(() => { |
|||
show.value = true; |
|||
}); |
|||
|
|||
const setDate = data => { |
|||
noData.value = false; |
|||
if (bar) { |
|||
bar.destroy(); |
|||
} |
|||
bar = new Column('corrosionContainer', { |
|||
data, |
|||
layout: 'vertical', |
|||
xField: 'time', |
|||
yField: 'value', |
|||
padding: [30, 16, 60, 50], |
|||
color: '#70B603', |
|||
columnWidthRatio: 0.6, // 宽度占比 |
|||
yAxis: { |
|||
title: { |
|||
text: '月累计腐蚀', |
|||
spacing: 20, |
|||
}, |
|||
}, |
|||
slider: { |
|||
start: 0.1, |
|||
end: 0.5, |
|||
}, |
|||
meta: { value: { alias: '月累计腐蚀(g/m²)' } }, |
|||
}); |
|||
|
|||
bar.render(); |
|||
}; |
|||
|
|||
defineExpose({ setDate }); |
|||
</script> |
@ -0,0 +1,221 @@ |
|||
/* eslint-disable max-len,object-curly-newline */ |
|||
import dayjs from 'dayjs'; |
|||
|
|||
const colors = ['#5470C6', '#91CC75', '#EE6666', '#5470C6', '#91CC75', '#EE6666', '#5470C6', '#91CC75']; |
|||
|
|||
/** |
|||
* 生成chart所需参数 |
|||
* @param {Object[]} data 服务端返回数据 |
|||
* @param {string} data[].time 时间 ms |
|||
* @param {string} data[].so2 SO2 |
|||
* @param {string} data[].salt 盐阻 |
|||
* @param {string} data[].environmentTemperature 环温 |
|||
* @param {string} data[].environmentHumidity 环湿 |
|||
* @param {string} data[].corrosion1 锌 |
|||
* @param {string} data[].corrosion2 铜 |
|||
* @param {string} data[].corrosion3 铝 |
|||
* @param {string} data[].corrosion4 钢 |
|||
* @returns {{environmentTemperature: *[], corrosionXIN: *[], corrosionGANG: *[], salt: *[], corrosionTONG: *[], so2: *[], corrosionLV: *[], time: *[], environmentHumidity: *[]}} |
|||
*/ |
|||
function generateParams(data) { |
|||
const result = { |
|||
time: [], |
|||
so2: [], |
|||
salt: [], |
|||
environmentTemperature: [], |
|||
environmentHumidity: [], |
|||
corrosionXIN: [], |
|||
corrosionTONG: [], |
|||
corrosionLV: [], |
|||
corrosionGANG: [], |
|||
}; |
|||
data.forEach(item => { |
|||
result.time.push(dayjs(+item.time).format('YY/MM/MM HH:mm')); |
|||
result.so2.push(+item.so2); |
|||
result.salt.push(+item.salt); |
|||
result.environmentTemperature.push(+item.environmentTemperature); |
|||
result.environmentHumidity.push(+item.environmentHumidity); |
|||
result.corrosionXIN.push(+item.corrosion1); |
|||
result.corrosionTONG.push(+item.corrosion2); |
|||
result.corrosionLV.push(+item.corrosion3); |
|||
result.corrosionGANG.push(+item.corrosion4); |
|||
}); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 生成chart参数 |
|||
* @param {Object[]} rawData 返回段返回的data数据 |
|||
* @returns {{yAxis: [{axisLabel: {formatter: string}, axisLine: {lineStyle: {color: string}, show: boolean}, name: string, position: string, type: string},{axisLabel: {formatter: string}, offset: number, axisLine: {lineStyle: {color: string}, show: boolean}, name: string, position: string, type: string},{axisLabel: {formatter: string}, axisLine: {lineStyle: {color: string}, show: boolean}, name: string, position: string, type: string},{axisLabel: {formatter: string}, axisLine: {lineStyle: {color: string}, show: boolean}, name: string, position: string, type: string},{axisLabel: {formatter: string}, axisLine: {lineStyle: {color: string}, show: boolean}, name: string, position: string, type: string},null,null,null], xAxis: [{data: *[], axisTick: {alignWithLabel: boolean}, type: string}], color: string[], grid: {right: string}, legend: {data: string[]}, series: [{data: *[], name: string, type: string},{data: *[], name: string, type: string, yAxisIndex: number},{data: *[], name: string, type: string, yAxisIndex: number},{data: *[], name: string, type: string, yAxisIndex: number},{data: *[], name: string, type: string, yAxisIndex: number},null,null,null], tooltip: {axisPointer: {type: string}, trigger: string}, toolbox: {feature: {saveAsImage: {show: boolean}, restore: {show: boolean}, dataView: {show: boolean, readOnly: boolean}}}}} |
|||
*/ |
|||
// eslint-disable-next-line import/prefer-default-export
|
|||
export function generateChartOption(rawData) { |
|||
const data = generateParams(rawData); |
|||
const option = { |
|||
color: colors, |
|||
tooltip: { |
|||
trigger: 'axis', |
|||
axisPointer: { type: 'cross' }, |
|||
}, |
|||
grid: { |
|||
right: '30%', |
|||
left: '20%', |
|||
}, |
|||
legend: { |
|||
data: ['SO2(ppb)', '盐分阻抗(Ω)', '环温(℃)', '环湿(RH%)', '锌腐蚀电流(nA)', '铜腐蚀电流(nA)', '铝腐蚀电流(nA)', '钢腐蚀电流(nA)'], |
|||
}, |
|||
dataZoom: [{ type: 'inside' }, { type: 'slider' }], |
|||
xAxis: [ |
|||
{ |
|||
type: 'category', |
|||
axisTick: { alignWithLabel: true }, |
|||
data: data.time, |
|||
}, |
|||
], |
|||
yAxis: [ |
|||
{ |
|||
type: 'value', |
|||
name: 'SO2(ppb)', |
|||
position: 'left', |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[0] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}ppb' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '盐分阻抗(Ω)', |
|||
// min: 0,
|
|||
// max: 250,
|
|||
position: 'left', |
|||
offset: 70, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[1] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}Ω' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '环温(℃)', |
|||
// min: 0,
|
|||
// max: 25,
|
|||
position: 'left', |
|||
offset: 135, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[2] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}°C' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '环湿(RH%)', |
|||
// min: 0,
|
|||
// max: 25,
|
|||
position: 'left', |
|||
offset: 200, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[3] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}RH%' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '锌腐蚀电流(nA)', |
|||
position: 'right', |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[4] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '铜腐蚀电流(nA)', |
|||
offset: 100, |
|||
position: 'right', |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[5] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '铝腐蚀电流(nA)', |
|||
offset: 200, |
|||
position: 'right', |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[6] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}' }, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '钢腐蚀电流(nA)', |
|||
offset: 300, |
|||
position: 'right', |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { color: colors[7] }, |
|||
}, |
|||
axisLabel: { formatter: '{value}' }, |
|||
}, |
|||
], |
|||
series: [ |
|||
{ |
|||
name: 'SO2(ppb)', |
|||
type: 'line', |
|||
data: data.so2, |
|||
}, |
|||
{ |
|||
name: '盐分阻抗(Ω)', |
|||
type: 'line', |
|||
yAxisIndex: 1, |
|||
data: data.salt, |
|||
}, |
|||
{ |
|||
name: '环温(℃)', |
|||
type: 'line', |
|||
yAxisIndex: 2, |
|||
data: data.environmentTemperature, |
|||
}, |
|||
{ |
|||
name: '环湿(RH%)', |
|||
type: 'line', |
|||
yAxisIndex: 3, |
|||
data: data.environmentHumidity, |
|||
}, |
|||
{ |
|||
name: '锌腐蚀电流(nA)', |
|||
type: 'line', |
|||
yAxisIndex: 4, |
|||
data: data.corrosionXIN, |
|||
}, |
|||
{ |
|||
name: '铜腐蚀电流(nA)', |
|||
type: 'line', |
|||
yAxisIndex: 5, |
|||
data: data.corrosionTONG, |
|||
}, |
|||
{ |
|||
name: '铝腐蚀电流(nA)', |
|||
type: 'line', |
|||
yAxisIndex: 6, |
|||
data: data.corrosionLV, |
|||
}, |
|||
{ |
|||
name: '钢腐蚀电流(nA)', |
|||
type: 'line', |
|||
yAxisIndex: 7, |
|||
data: data.corrosionGANG, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
return option; |
|||
} |
@ -1,68 +0,0 @@ |
|||
<template> |
|||
<el-row :gutter="24" class="flex flex-column"> |
|||
<el-col :xs="24" :md="12" v-for="(list, index) in lists" :key="index"> |
|||
<el-card class="box-card mb-3"> |
|||
<div class="flex flex-column"> |
|||
<el-avatar icon="el-icon-user-solid" :size="46" :src="circleUrl"></el-avatar> |
|||
<div class="ml-4 flex-1 flex-col"> |
|||
<span class="font-bold"> |
|||
{{ list.name }} |
|||
</span> |
|||
<div class="flex flex-col mt-5 text-sm text-gray-400"> |
|||
<span class="mb-1">{{ list.operation }}</span> |
|||
<span>{{ list.time }}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</el-card> |
|||
</el-col> |
|||
</el-row> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
|
|||
const circleUrl = 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png'; |
|||
const lists = ref([ |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
{ |
|||
name: '管理员01', |
|||
operation: '管理员01', |
|||
time: '2021年10月19日', |
|||
}, |
|||
]); |
|||
</script> |
@ -1,5 +0,0 @@ |
|||
<template> |
|||
<div>通讯日志</div> |
|||
</template> |
|||
|
|||
<script setup></script> |
@ -1,28 +0,0 @@ |
|||
<template> |
|||
<!-- 设置站点选择 和 设备下发状态 --> |
|||
<DeviceSelectAndStatus :status="status" /> |
|||
|
|||
<el-tabs v-model="activeName"> |
|||
<el-tab-pane :lazy="true" label="下发参数" name="pending"> |
|||
<FunctionConfigPending v-if="activeName === 'pending'" :active-name="activeName" @status="setStatus" /> |
|||
</el-tab-pane> |
|||
<el-tab-pane :lazy="true" label="设备参数" name="applied"> |
|||
<FunctionConfigApplied v-if="activeName === 'applied'" :active-name="activeName" @status="setStatus" /> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
import DeviceSelectAndStatus from 'components/config/device-select-and-status.vue'; |
|||
import FunctionConfigPending from 'components/config/function-config-pending.vue'; |
|||
import FunctionConfigApplied from 'components/function-config-applied.vue'; |
|||
|
|||
const activeName = ref('pending'); |
|||
const status = ref('PENDING'); |
|||
|
|||
// 设置 设置状态 |
|||
function setStatus(event) { |
|||
status.value = event; |
|||
} |
|||
</script> |
@ -1,73 +0,0 @@ |
|||
<template> |
|||
<DataSearchBar @search="onSearch" /> |
|||
<IntegralElectric ref="child1" class="mt-4" /> |
|||
<TotalCorrosion ref="child2" class="mt-4" /> |
|||
<MoistTime ref="child3" class="mt-4" /> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import DataSearchBar from 'components/data-search-bar.vue'; |
|||
import IntegralElectric from 'components/integral-electric.vue'; |
|||
import TotalCorrosion from 'components/total-corrosion.vue'; |
|||
import MoistTime from 'components/moist-time.vue'; |
|||
import { computed, ref } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
|
|||
const child1 = ref(null); |
|||
const child2 = ref(null); |
|||
const child3 = ref(null); |
|||
|
|||
const search = ref({}); |
|||
const page = ref({ page: 2, size: 10 }); |
|||
let timer = null; |
|||
const store = useStore(); |
|||
const token = computed(() => store.getters['user/token']); |
|||
const electricData = computed(() => store.state.statistics.electricData); |
|||
const corrosionData = computed(() => store.state.statistics.corrosionData); |
|||
const moistTimeData = computed(() => store.state.statistics.moistTimeData); |
|||
const currentDeviceId = computed(() => store.state.device.currentDeviceId); // 正在操作的设备的id |
|||
|
|||
/** |
|||
* 获取月累计数据 |
|||
* @param {*} deviceId // 站点 设备id |
|||
* @param {*} date // 年月时间段 |
|||
* @param {*} sort // 1 -> 按时间正序 -1->按时间倒序 |
|||
*/ |
|||
const getDate = async () => { |
|||
try { |
|||
if (token && token.value) { |
|||
const options = { ...search.value }; |
|||
const date = options && options.date ? options.date : []; |
|||
const params = { |
|||
search: { deviceId: currentDeviceId.value, date }, |
|||
page: { page: page.value.page, size: page.value.size }, |
|||
}; |
|||
|
|||
await store.dispatch('statistics/getMonthsDate', params); |
|||
timer && clearTimeout(timer); |
|||
timer = null; |
|||
// 渲染图表 |
|||
child1.value.setDate(electricData.value); |
|||
child2.value.setDate(corrosionData.value); |
|||
child3.value.setDate(moistTimeData.value); |
|||
} else { |
|||
timer = setTimeout(() => { |
|||
getDate(); |
|||
}); |
|||
} |
|||
} catch (error) { |
|||
console.log('error: ', error); |
|||
} |
|||
}; |
|||
|
|||
getDate(); |
|||
|
|||
/** |
|||
* 监听search信息 |
|||
* @param {object} payload search组件emit的数据 |
|||
*/ |
|||
const onSearch = payload => { |
|||
search.value = { ...payload }; |
|||
getDate(); |
|||
}; |
|||
</script> |
@ -1,28 +0,0 @@ |
|||
<template> |
|||
<!-- 设置站点选择 和 设备下发状态 --> |
|||
<DeviceSelectAndStatus :status="status" /> |
|||
|
|||
<el-tabs v-model="activeName"> |
|||
<el-tab-pane :lazy="true" label="下发参数" name="pending"> |
|||
<NetworkConfigPending v-if="activeName === 'pending'" :active-name="activeName" @status="setStatus" /> |
|||
</el-tab-pane> |
|||
<el-tab-pane :lazy="true" label="设备参数" name="applied"> |
|||
<NetworkConfigApplied v-if="activeName === 'applied'" :active-name="activeName" @status="setStatus" /> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
import DeviceSelectAndStatus from 'components/config/device-select-and-status.vue'; |
|||
import NetworkConfigPending from 'components/config/network-config-pending.vue'; |
|||
import NetworkConfigApplied from 'components/network-config-applied.vue'; |
|||
|
|||
const activeName = ref('pending'); |
|||
const status = ref(''); |
|||
|
|||
// 设置 设置状态 |
|||
function setStatus(event) { |
|||
status.value = event; |
|||
} |
|||
</script> |
@ -1,69 +0,0 @@ |
|||
<template> |
|||
<SearchBar @search="getData" @refresh="onRefresh" :show-refresh="true" /> |
|||
<RealtimeData ref="childRef" class="mt-4" /> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import SearchBar from 'components/search-bar.vue'; |
|||
import RealtimeData from 'components/realtime-data.vue'; |
|||
import { computed, ref, onUnmounted } from 'vue'; |
|||
import { useStore } from 'vuex'; |
|||
import dayjs from 'dayjs'; |
|||
import { REALTIME_DATA_INTERVAL } from '@/config/config'; |
|||
|
|||
const childRef = ref(null); |
|||
let timer = null; |
|||
let apiTimer = null; |
|||
const store = useStore(); |
|||
const token = computed(() => store.getters['user/token']); |
|||
const realtimeData = computed(() => store.state.statistics.realtimeData); |
|||
const currentDeviceId = computed(() => store.state.device.currentDeviceId); // 正在操作的设备的id |
|||
|
|||
/** |
|||
* 实时数据统计 |
|||
*/ |
|||
const getData = async () => { |
|||
try { |
|||
if (token && token.value) { |
|||
const start = +dayjs().startOf('day').format('x'); |
|||
const end = +dayjs().format('x'); |
|||
const params = { |
|||
deviceId: currentDeviceId.value, |
|||
date: [start, end], |
|||
type: 0, |
|||
}; |
|||
await store.dispatch('statistics/getRealtimeData', params); |
|||
timer && clearTimeout(timer); |
|||
timer = null; |
|||
childRef.value.changeDate(realtimeData.value.data); |
|||
|
|||
// 定时轮询请求新数据 |
|||
if (!apiTimer) { |
|||
apiTimer = setInterval(() => { |
|||
getData(); |
|||
}, REALTIME_DATA_INTERVAL); |
|||
} |
|||
} else { |
|||
timer = setTimeout(() => { |
|||
getData(); |
|||
}, 20); |
|||
} |
|||
} catch (error) { |
|||
console.log('error: ', error); |
|||
} |
|||
}; |
|||
|
|||
getData(); |
|||
|
|||
onUnmounted(() => { |
|||
apiTimer && clearInterval(apiTimer); |
|||
apiTimer = null; |
|||
}); |
|||
|
|||
// 手动刷新 清除定时器 重新获取数据 |
|||
function onRefresh() { |
|||
apiTimer && clearInterval(apiTimer); |
|||
apiTimer = null; |
|||
getData(); |
|||
} |
|||
</script> |
Loading…
Reference in new issue