Browse Source

refactor: 添加实时数据查看、按时间倒序等

master
wally 4 years ago
parent
commit
65fe950aa5
  1. 3
      src/config/config.js
  2. 17
      src/routers/index.js
  3. 8
      src/views/data-history.vue
  4. 171
      src/views/data-realtime.vue
  5. 10
      src/views/data-report.vue
  6. 27
      src/views/device-list.vue
  7. 19
      src/views/statistical-realtime.vue

3
src/config/config.js

@ -89,3 +89,6 @@ export const PEND_TYPE = {
text: '下发成功',
},
};
// 实时查询数据的轮询时间
export const REALTIME_DATA_INTERVAL = 15000;

17
src/routers/index.js

@ -34,16 +34,25 @@ export const routes = [
name: 'device-create',
meta: {
title: '设备添加',
icon: 'el-icon-plus',
icon: 'el-icon-first-aid-kit',
},
component: () => import('@/views/device-create.vue'),
},
{
path: '/corrosion/data-realtime',
name: 'data-realtime',
meta: {
title: '实时数据查看',
icon: 'el-icon-odometer',
},
component: () => import('@/views/data-realtime.vue'),
},
{
path: '/corrosion/statistical-realtime',
name: 'statistical-realtime',
meta: {
title: '实时数据统计',
icon: 'el-icon-time',
icon: 'el-icon-data-analysis',
},
component: () => import('@/views/statistical-realtime.vue'),
},
@ -52,7 +61,7 @@ export const routes = [
name: 'data-report',
meta: {
title: '上报数据查看',
icon: 'el-icon-document-copy',
icon: 'el-icon-stopwatch',
},
component: () => import('@/views/data-report.vue'),
},
@ -79,7 +88,7 @@ export const routes = [
name: 'commands',
meta: {
title: '历史数据指令下发状态',
icon: 'el-icon-document-copy',
icon: 'el-icon-moon-night',
},
component: () => import('@/views/commands.vue'),
},

8
src/views/data-history.vue

@ -38,6 +38,7 @@ const getData = async () => {
page: page.value.page,
size: page.value.size,
type: 1,
sort: -1,
};
const resData = await getHistory(params);
data.value = resData.data;
@ -163,11 +164,16 @@ function formatTime(time) {
<el-table-column align="center" label="腐流2" min-width="60" prop="corrosion2" />
<el-table-column align="center" label="腐流3" min-width="60" prop="corrosion3" />
<el-table-column align="center" label="腐流4" min-width="60" prop="corrosion4" />
<el-table-column align="center" label="时间" min-width="170">
<el-table-column align="center" label="采集时间" min-width="170">
<template #default="scope">
{{ formatTime(+scope.row.time) }}
</template>
</el-table-column>
<el-table-column align="center" label="后台接受时间" min-width="170">
<template #default="scope">
{{ formatTime(+scope.row.createdAt) }}
</template>
</el-table-column>
</el-table>
<el-pagination

171
src/views/data-realtime.vue

@ -0,0 +1,171 @@
<script setup>
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useStore } from 'vuex';
import SearchBar from 'components/search-bar.vue';
import { getDatas } from 'apis';
import { ElMessage } from 'element-plus';
import dayjs from 'dayjs';
import { REALTIME_DATA_INTERVAL } from '@/config/config';
const page = ref({
page: 1,
size: 50,
});
let timer = null;
let apiTimer = null;
const store = useStore();
const token = computed(() => store.getters['user/token']);
const currentDeviceId = computed(() => store.state.device.currentDeviceId); // id
const contentHeight = ref(600);
const loadingSearch = ref(false);
const data = ref(null);
//
const getData = async () => {
try {
if (token && token.value) {
if (!currentDeviceId.value) {
return ElMessage.error('请选择站点');
}
const date = [dayjs().startOf('day').format('x'), dayjs().endOf('day').format('x')];
const params = {
deviceId: currentDeviceId.value,
date,
page: page.value.page,
size: page.value.size,
type: 1,
sort: -1,
};
loadingSearch.value = true;
const resData = await getDatas(params);
loadingSearch.value = false;
data.value = resData.data;
page.value = resData.page;
timer && clearTimeout(timer);
timer = null;
//
if (!apiTimer) {
apiTimer = setInterval(() => {
getData();
}, REALTIME_DATA_INTERVAL);
}
} else {
timer = setTimeout(() => {
getData();
}, 20);
}
} catch (error) {
ElMessage.error(error.message || '获取数据失败');
console.log('error: ', error);
}
};
//
onMounted(() => {
const winHeight = document.documentElement.clientHeight;
contentHeight.value = winHeight - 170;
currentDeviceId.value && getData();
});
onUnmounted(() => {
apiTimer && clearInterval(apiTimer);
apiTimer = null;
});
/**
* 当前 码变化
* 更新page 重新 取数据
* @param {number} e 的页码
*/
const onCurrentPageChange = e => {
page.value.page = e;
getData();
};
const onSizeChange = e => {
page.value.size = e;
getData();
};
//
const onNext = e => {
page.value.page = e + 1;
getData();
};
//
const onPrev = e => {
page.value.page = e - 1;
getData();
};
/**
* 格式化时间
* @param {number} time 时间戳
* @returns {string}
*/
function formatTime(time) {
return dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss');
}
</script>
<template>
<SearchBar @search="getData" />
<template v-if="data">
<el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
<el-table-column align="center" fixed label="设备编号" min-width="80" prop="deviceNo" />
<el-table-column align="center" label="ICCID" min-width="190" prop="iccid" />
<el-table-column align="center" label="IMEI" min-width="150" prop="imei" />
<el-table-column align="center" label="信号强度" min-width="80" prop="signal" />
<el-table-column align="center" label="基站编号" min-width="130" prop="stationNo" />
<el-table-column align="center" label="硬件版本" min-width="80" prop="hardwareVersion" />
<el-table-column align="center" label="软件版本" min-width="80" prop="softwareVersion" />
<el-table-column align="center" label="采集时间" min-width="170">
<template #default="scope">
{{ formatTime(+scope.row.time) }}
</template>
</el-table-column>
<el-table-column align="center" label="后台接受时间" min-width="170">
<template #default="scope">
{{ formatTime(+scope.row.createdAt) }}
</template>
</el-table-column>
<el-table-column align="center" label="太阳能电压" min-width="94" prop="solarVoltage" />
<el-table-column align="center" label="蓄电池电压" min-width="94" prop="batteryVoltage" />
<el-table-column align="center" label="电压百分比" min-width="94" prop="batteryVoltagePercentage" />
<el-table-column align="center" label="剩余电量" min-width="94" prop="batteryVoltageRemain" />
<el-table-column align="center" label="电池损耗量" min-width="94" prop="batteryLoss" />
<el-table-column align="center" label="机箱温度" min-width="80" prop="deviceTemperature" />
<el-table-column align="center" label="机箱湿度" min-width="80" prop="deviceHumidity" />
<el-table-column align="center" label="环境温度" min-width="80" prop="environmentTemperature" />
<el-table-column align="center" label="环境湿度" min-width="80" prop="environmentHumidity" />
<el-table-column align="center" label="SO2" min-width="50" prop="so2" />
<el-table-column align="center" label="盐分" min-width="50" prop="salt" />
<el-table-column align="center" label="腐流1" min-width="60" prop="corrosion1" />
<el-table-column align="center" label="腐流2" min-width="60" prop="corrosion2" />
<el-table-column align="center" label="腐流3" min-width="60" prop="corrosion3" />
<el-table-column align="center" label="腐流4" min-width="60" prop="corrosion4" />
</el-table>
<el-pagination
:current-page="page.page"
:default-page-size="50"
:page-count="page.count"
:page-size="page.size"
:page-sizes="[1, 10, 20, 50, 100]"
:total="page.total"
background
class="my-3 float-right"
layout="total, sizes, prev, pager, next, jumper"
@current-change="onCurrentPageChange"
@size-change="onSizeChange"
@prev-click="onPrev"
@next-click="onNext"
></el-pagination>
</template>
</template>

10
src/views/data-report.vue

@ -38,6 +38,7 @@ const getData = async () => {
page: page.value.page,
size: page.value.size,
type: 1,
sort: -1,
};
loadingSearch.value = true;
@ -121,14 +122,19 @@ function formatTime(time) {
<el-table-column align="center" label="ICCID" min-width="190" prop="iccid" />
<el-table-column align="center" label="IMEI" min-width="150" prop="imei" />
<el-table-column align="center" label="信号强度" min-width="80" prop="signal" />
<el-table-column align="center" label="基站编号" min-width="120" prop="stationNo" />
<el-table-column align="center" label="基站编号" min-width="130" prop="stationNo" />
<el-table-column align="center" label="硬件版本" min-width="80" prop="hardwareVersion" />
<el-table-column align="center" label="软件版本" min-width="80" prop="softwareVersion" />
<el-table-column align="center" label="时间" min-width="170">
<el-table-column align="center" label="采集时间" min-width="170">
<template #default="scope">
{{ formatTime(+scope.row.time) }}
</template>
</el-table-column>
<el-table-column align="center" label="后台接受时间" min-width="170">
<template #default="scope">
{{ formatTime(+scope.row.createdAt) }}
</template>
</el-table-column>
<el-table-column align="center" label="太阳能电压" min-width="94" prop="solarVoltage" />
<el-table-column align="center" label="蓄电池电压" min-width="94" prop="batteryVoltage" />
<el-table-column align="center" label="电压百分比" min-width="94" prop="batteryVoltagePercentage" />

27
src/views/device-list.vue

@ -29,7 +29,7 @@
<el-table-column align="center" label="联系电话" min-width="150" prop="phone" />
<el-table-column align="center" label="安装时间" min-width="200" prop="installTime" />
<el-table-column align="center" label="正式运行时间" min-width="200" prop="runTime" />
<el-table-column align="center" fixed="right" label="操作" min-width="200">
<el-table-column align="center" fixed="right" label="操作" min-width="270">
<template #default="props">
<el-tooltip class="item" content="网络参数配置" effect="dark" placement="top">
<i class="el-icon-setting text-base text-yellow-600 mx-1" @click="openPage(props.row, 'network-config')"></i>
@ -37,15 +37,24 @@
<el-tooltip class="item" content="功能参数配置" effect="dark" placement="top">
<i class="el-icon-set-up text-base text-yellow-600 mx-1" @click="openPage(props.row, 'function-config')"></i>
</el-tooltip>
<el-tooltip class="item" content="实时数据查看" effect="dark" placement="top">
<i class="el-icon-odometer text-base text-green-600 mx-1" @click="openPage(props.row, 'data-realtime')"></i>
</el-tooltip>
<el-tooltip class="item" content="实时数据统计" effect="dark" placement="top">
<i class="el-icon-stopwatch text-base text-green-600 mx-1" @click="openPage(props.row, 'statistical-realtime')"></i>
<i class="el-icon-data-analysis text-base text-green-600 mx-1" @click="openPage(props.row, 'statistical-realtime')"></i>
</el-tooltip>
<el-tooltip class="item" content="数据查看及导出" effect="dark" placement="top">
<i class="el-icon-tickets text-base text-green-600 mx-1" @click="openPage(props.row, 'data-report')"></i>
<el-tooltip class="item" content="上报数据查看" effect="dark" placement="top">
<i class="el-icon-stopwatch text-base text-green-600 mx-1" @click="openPage(props.row, 'data-report')"></i>
</el-tooltip>
<el-tooltip class="item" content="数据统计" effect="dark" placement="top">
<el-tooltip class="item" content="上报数据统计" effect="dark" placement="top">
<i class="el-icon-data-line text-base text-green-600 mx-1" @click="openPage(props.row, 'statistical-report')"></i>
</el-tooltip>
<el-tooltip class="item" content="历史数据查看" effect="dark" placement="top">
<i class="el-icon-document-copy text-base text-green-600 mx-1" @click="openPage(props.row, 'data-history')"></i>
</el-tooltip>
<el-tooltip class="item" content="历史数据下发状态指令" effect="dark" placement="top">
<i class="el-icon-moon-night text-base text-green-600 mx-1" @click="openPage(props.row, 'commands')"></i>
</el-tooltip>
<el-popconfirm title="确定要删除此设备吗?" @confirm="handleDelete(props.row.deviceId)">
<template #reference>
<i class="el-icon-delete text-base text-red-600 mx-1"></i>
@ -85,7 +94,7 @@ import { useStore } from 'vuex';
import { useRoute, useRouter } from 'vue-router';
import SearchBar from 'components/search-bar.vue';
import DeviceEdit from 'components/device-edit.vue';
import { deleteDevice } from 'apis/index';
import { deleteDevice } from 'apis';
import { ElMessage } from 'element-plus';
let timer = null;
@ -132,11 +141,7 @@ onMounted(() => {
*/
function onSearch(page, size = 50) {
const deviceId = currentDeviceId.value;
const params = {
deviceId,
page,
size,
};
const params = { deviceId, page, size };
store.dispatch('device/getDevicesAll', params);
}

19
src/views/statistical-realtime.vue

@ -1,5 +1,5 @@
<template>
<SearchBar @search="getDate" />
<SearchBar @search="getData" />
<RealtimeData ref="childRef" class="mt-4" />
</template>
@ -9,6 +9,7 @@ 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;
@ -20,14 +21,8 @@ const currentDeviceId = computed(() => store.state.device.currentDeviceId); //
/**
* 实时数据统计
* @param {*} deviceId // id
* @param {*} date //
* @param {*} sort // 1 -> -1->
* @param {*} page //
* @param {*} size //
* @param {*} type // 0
*/
const getDate = async () => {
const getData = async () => {
try {
if (token && token.value) {
const start = +dayjs().startOf('day').format('x');
@ -45,12 +40,12 @@ const getDate = async () => {
//
if (!apiTimer) {
apiTimer = setInterval(() => {
getDate();
}, 5000);
getData();
}, REALTIME_DATA_INTERVAL);
}
} else {
timer = setTimeout(() => {
getDate();
getData();
}, 20);
}
} catch (error) {
@ -58,7 +53,7 @@ const getDate = async () => {
}
};
getDate();
getData();
onUnmounted(() => {
apiTimer && clearInterval(apiTimer);

Loading…
Cancel
Save