Browse Source

refactor: 日志重构;补传记录等未完

master
wally 4 years ago
parent
commit
0a74274c95
  1. 9
      src/apis/index.js
  2. 39
      src/components/commands/search-commands.vue
  3. 127
      src/components/history/device.vue
  4. 113
      src/components/history/history-log-table.vue
  5. 35
      src/components/history/history-log.vue
  6. 111
      src/components/history/local.vue
  7. 36
      src/components/history/search-bar-data.vue
  8. 77
      src/components/history/search-history-log.vue
  9. 8
      src/config/config.js
  10. 1
      src/config/log.js
  11. 6
      src/utils/overview.js
  12. 105
      src/views/commands.vue
  13. 11
      src/views/data-realtime.vue
  14. 2
      src/views/device-list.vue
  15. 4
      src/views/history.vue

9
src/apis/index.js

@ -28,7 +28,7 @@ export const getDevicesAll = (
sort: [ sort: [
{ {
col: 'createdAt', col: 'createdAt',
order: 'ASC', order: 'DESC',
}, },
], ],
}, },
@ -76,5 +76,8 @@ export const exportHistory = params => http.post(`${corrosion}/history/export`,
// 发送查询历史记录的指令 // 发送查询历史记录的指令
export const sendCommand = params => http.post(`${corrosion}/history`, params); export const sendCommand = params => http.post(`${corrosion}/history`, params);
// 查询下发指令状态 // 补传记录
export const getCommansStatus = params => http.get(`${corrosion}/history`, { params }); export const getSendHistory = params => http.get(`${corrosion}/history`, { params });
// 查询平台日志
export const getLog = params => http.post(`${corrosion}/tpclog/query`, params);

39
src/components/commands/search-commands.vue

@ -2,7 +2,7 @@
<el-form ref="searchDeviceForm" :inline="true" :model="searchDevice"> <el-form ref="searchDeviceForm" :inline="true" :model="searchDevice">
<el-form-item label="选择站点"> <el-form-item label="选择站点">
<el-select v-model="searchDevice.deviceId" placeholder="请选择站点" @change="change"> <el-select v-model="searchDevice.deviceId" placeholder="请选择站点" @change="change">
<!-- <el-option label="全部" value></el-option> --> <el-option label="全部" value></el-option>
<el-option <el-option
v-for="item in devices" v-for="item in devices"
:key="item.deviceId" :key="item.deviceId"
@ -12,21 +12,21 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="类型"> <!-- <el-form-item label="类型">-->
<el-select v-model="searchDevice.type" placeholder="选择查询类型"> <!-- <el-select v-model="searchDevice.type" placeholder="选择查询类型">-->
<el-option label="全部" value=""></el-option> <!-- <el-option label="全部" value=""></el-option>-->
<el-option label="事件上报" value="EVENT"></el-option> <!-- <el-option label="事件上报" value="EVENT"></el-option>-->
<el-option label="业务上报" value="DATA"></el-option> <!-- <el-option label="业务上报" value="DATA"></el-option>-->
</el-select> <!-- </el-select>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item label="状态"> <!-- <el-form-item label="状态">-->
<el-select v-model="searchDevice.status" placeholder="选择查询类型"> <!-- <el-select v-model="searchDevice.status" placeholder="选择查询类型">-->
<el-option label="全部" value=""></el-option> <!-- <el-option label="全部" value=""></el-option>-->
<el-option label="PENDING" value="PENDING"></el-option> <!-- <el-option label="PENDING" value="PENDING"></el-option>-->
<el-option label="SUCCESS" value="SUCCESS"></el-option> <!-- <el-option label="SUCCESS" value="SUCCESS"></el-option>-->
</el-select> <!-- </el-select>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item> <el-form-item>
<el-button type="primary" @click="onSubmit"> <el-button type="primary" @click="onSubmit">
@ -44,6 +44,15 @@ import { useStore } from 'vuex';
const emit = defineEmits(['search']); const emit = defineEmits(['search']);
const searchDevice = reactive({ const searchDevice = reactive({
deviceId: '', deviceId: '',
paging: true,
page: 1,
size: 50,
sort: [
{
col: 'createdAt',
order: 'DESC',
},
],
type: '', type: '',
status: '', status: '',
}); });

127
src/components/history/device.vue

@ -1,3 +1,62 @@
<template>
<SearchBar :loading-search="loadingSearch" :show-command="true" :show-export="true" @search="onSearch" />
<template v-if="data">
<el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
<el-table-column align="center" fixed label="设备ID" min-width="80" prop="deviceNo" />
<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="锌腐蚀电流(nA)" min-width="130" prop="corrosion1" />
<el-table-column align="center" label="铜腐蚀电流(nA)" min-width="130" prop="corrosion2" />
<el-table-column align="center" label="铝腐蚀电流(nA)" min-width="130" prop="corrosion3" />
<el-table-column align="center" label="钢腐蚀电流(nA)" min-width="130" prop="corrosion4" />
<el-table-column align="center" label="环境温度(℃)" min-width="110" prop="environmentTemperature" />
<el-table-column align="center" label="环境湿度(RH%)" min-width="130" prop="environmentHumidity" />
<el-table-column align="center" label="SO2(ppb)" min-width="90" prop="so2" />
<!-- TODO:-->
<el-table-column align="center" label="盐分温度(℃)" min-width="110" prop="salt" />
<el-table-column align="center" label="盐分阻抗(Ω)" min-width="110" prop="salt" />
<el-table-column align="center" label="机箱温度(℃)" min-width="110" prop="deviceTemperature" />
<el-table-column align="center" label="机箱湿度(RH%)" min-width="130" prop="deviceHumidity" />
<el-table-column align="center" label="太阳能板电压(V)" min-width="140" prop="solarVoltage" />
<el-table-column align="center" label="蓄电池电压(V)" min-width="120" prop="batteryVoltage" />
<el-table-column align="center" label="电压百分比" min-width="94" prop="batteryVoltagePercentage" />
<el-table-column align="center" label="剩余电量(mAH)" min-width="140" prop="batteryVoltageRemain" />
<el-table-column align="center" label="消耗电量(mAH)" min-width="140" prop="batteryLoss" />
<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>
<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>
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
@ -34,11 +93,14 @@ const getData = async () => {
} }
const params = { const params = {
deviceId: currentDeviceId.value, deviceId: currentDeviceId.value,
date, gatheredDateRange: date,
paging: true,
page: page.value.page, page: page.value.page,
size: page.value.size, size: page.value.size,
type: 1, sort: {
sort: -1, col: 'gathered_at',
order: 'DESC',
},
}; };
loadingSearch.value = true; loadingSearch.value = true;
@ -112,62 +174,3 @@ function formatTime(time) {
return dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss'); return dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss');
} }
</script> </script>
<template>
<SearchBar :loading-search="loadingSearch" :show-command="true" :show-export="true" @search="onSearch" />
<template v-if="data">
<el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
<el-table-column align="center" fixed label="设备ID" min-width="80" prop="deviceNo" />
<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="锌腐蚀电流(nA)" min-width="130" prop="corrosion1" />
<el-table-column align="center" label="铜腐蚀电流(nA)" min-width="130" prop="corrosion2" />
<el-table-column align="center" label="铝腐蚀电流(nA)" min-width="130" prop="corrosion3" />
<el-table-column align="center" label="钢腐蚀电流(nA)" min-width="130" prop="corrosion4" />
<el-table-column align="center" label="环境温度(℃)" min-width="110" prop="environmentTemperature" />
<el-table-column align="center" label="环境湿度(RH%)" min-width="130" prop="environmentHumidity" />
<el-table-column align="center" label="SO2(ppb)" min-width="90" prop="so2" />
<!-- TODO:-->
<el-table-column align="center" label="盐分温度(℃)" min-width="110" prop="salt" />
<el-table-column align="center" label="盐分阻抗(Ω)" min-width="110" prop="salt" />
<el-table-column align="center" label="机箱温度(℃)" min-width="110" prop="deviceTemperature" />
<el-table-column align="center" label="机箱湿度(RH%)" min-width="130" prop="deviceHumidity" />
<el-table-column align="center" label="太阳能板电压(V)" min-width="140" prop="solarVoltage" />
<el-table-column align="center" label="蓄电池电压(V)" min-width="120" prop="batteryVoltage" />
<el-table-column align="center" label="电压百分比" min-width="94" prop="batteryVoltagePercentage" />
<el-table-column align="center" label="剩余电量(mAH)" min-width="140" prop="batteryVoltageRemain" />
<el-table-column align="center" label="消耗电量(mAH)" min-width="140" prop="batteryLoss" />
<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>
<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>

113
src/components/history/history-log-table.vue

@ -0,0 +1,113 @@
<template>
<template v-if="devicesAll && devicesAll.data">
<el-table :data="devicesAll.data" :max-height="contentHeight" border class="mt-6" stripe style="width: 100%">
<el-table-column align="center" label="设备ID" min-min-width="100" prop="deviceId" />
<el-table-column align="center" label="开始时间" min-width="200">
<template #default="scope">
{{ dayjs(+scope.row.startTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column align="center" label="截止时间" min-width="200">
<template #default="scope">
{{ dayjs(+scope.row.endTime).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="下发状态" min-width="150">
<template #default="scope">
<StatusTagPending :type="scope.row.status" />
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="类型" min-width="150">
<template #default="scope">
<span v-if="scope.row && scope.row.type && PENDING_TYPE[scope.row.type]">{{ PENDING_TYPE[scope.row.type].text }}</span>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="devicesAll.page.page"
:default-page-size="50"
:page-count="devicesAll.page.count"
:page-size="devicesAll.page.size"
:page-sizes="[1, 10, 20, 50, 100]"
:total="devicesAll.page.total"
background
class="my-3 float-right"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onSizeChange"
@current-change="onCurrentPageChange"
></el-pagination>
</template>
<!-- 编辑设备信息 -->
<DeviceEdit :show="editing" @toggle-mdoal="editing = false" />
</template>
<script setup>
import { computed, onMounted, ref } from 'vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
import DeviceEdit from 'components/device/device-edit.vue';
import StatusTagPending from 'components/config/status-tag-pending.vue';
import { PENDING_TYPE } from '@/config/config';
let timer = null;
const store = useStore();
const token = computed(() => store.getters['user/token']);
const devicesAll = computed(() => {
return store.state.device.devicesAll;
});
const currentDeviceId = computed(() => store.state.device.currentDeviceId);
const contentHeight = ref(600);
const editing = ref(false);
//
const getDevicesAllData = () => {
try {
if (token && token.value) {
store.dispatch('device/getDevicesAll');
timer && clearTimeout(timer);
timer = null;
} else {
timer = setTimeout(() => {
getDevicesAllData();
});
}
} catch (error) {
throw new Error(error);
}
};
getDevicesAllData();
//
onMounted(() => {
const winHeight = document.documentElement.clientHeight;
contentHeight.value = winHeight - 250;
});
/**
* 删除
* @param {number} page 页码
* @param {number} size 每页条数
*/
function onSearch(page, size = 50) {
const deviceId = currentDeviceId.value;
const params = {
deviceId,
page,
size,
};
store.dispatch('device/getDevicesAll', params);
}
//
const onCurrentPageChange = page => {
onSearch(page, devicesAll.value.page.size || 50);
};
//
const onSizeChange = size => {
onSearch(1, size);
};
</script>

35
src/components/history/history-log.vue

@ -0,0 +1,35 @@
<template>
<SearchHistoryLog @search="onSearch" />
<TableHistoryLog />
</template>
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
import { getSendHistory } from 'apis';
import SearchHistoryLog from 'components/history/search-history-log.vue';
import TableHistoryLog from 'components/history/history-log-table.vue';
const store = useStore();
const currentDeviceId = computed(() => store.state.device.currentDeviceId); // id
async function getData() {
try {
const params = {
deviceId: currentDeviceId.value,
status: 'DATA',
type: 'EVENT',
};
const resData = await getSendHistory(params);
console.log(resData);
} catch (error) {
console.error(error);
}
}
getData();
function onSearch(event) {
console.log(event);
}
</script>

111
src/components/history/local.vue

@ -1,3 +1,52 @@
<template>
<SearchBar :show-export="true" :show-type-select="true" @search="onSearch" />
<template v-if="data">
<el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
<el-table-column align="center" fixed label="设备ID" min-width="80" prop="deviceNo" />
<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="锌腐蚀电流(nA)" min-width="130" prop="corrosion1" />
<el-table-column align="center" label="铜腐蚀电流(nA)" min-width="130" prop="corrosion2" />
<el-table-column align="center" label="铝腐蚀电流(nA)" min-width="130" prop="corrosion3" />
<el-table-column align="center" label="钢腐蚀电流(nA)" min-width="130" prop="corrosion4" />
<el-table-column align="center" label="环境温度(℃)" min-width="110" prop="environmentTemperature" />
<el-table-column align="center" label="环境湿度(RH%)" min-width="130" prop="environmentHumidity" />
<el-table-column align="center" label="SO2(ppb)" min-width="90" prop="so2" />
<el-table-column align="center" label="盐分温度(℃)" min-width="110" prop="salt" />
<el-table-column align="center" label="盐分阻抗(Ω)" min-width="110" prop="salt" />
<el-table-column align="center" label="太阳能板电压(V)" min-width="140" prop="solarVoltage" />
<el-table-column align="center" label="蓄电池电压(V)" min-width="120" prop="batteryVoltage" />
<el-table-column align="center" label="机箱温度(℃)" min-width="110" prop="deviceTemperature" />
<el-table-column align="center" label="机箱湿度(RH%)" min-width="130" prop="deviceHumidity" />
</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>
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
@ -27,18 +76,23 @@ const getData = async () => {
} }
const options = { ...search.value }; const options = { ...search.value };
console.log('options:', options);
const date = options && options.date ? options.date : []; const date = options && options.date ? options.date : [];
if (!date || date.length !== 2) { if (!date || date.length !== 2) {
return ElMessage.error('请选择时间 '); return ElMessage.error('请选择时间 ');
} }
const params = { const params = {
deviceId: currentDeviceId.value, deviceId: currentDeviceId.value,
date, gatheredDateRange: date,
dataType: options.dataType, paging: true,
page: page.value.page, page: page.value.page,
size: page.value.size, size: page.value.size,
type: 1, sort: [
sort: -1, {
col: 'gathered_at',
order: 'DESC',
},
],
}; };
const resData = await getHistory(params); const resData = await getHistory(params);
data.value = resData.data; data.value = resData.data;
@ -108,52 +162,3 @@ function formatTime(time) {
return dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss'); return dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss');
} }
</script> </script>
<template>
<SearchBar :show-export="true" :show-type-select="true" @search="onSearch" />
<template v-if="data">
<el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
<el-table-column align="center" fixed label="设备ID" min-width="80" prop="deviceNo" />
<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="锌腐蚀电流(nA)" min-width="130" prop="corrosion1" />
<el-table-column align="center" label="铜腐蚀电流(nA)" min-width="130" prop="corrosion2" />
<el-table-column align="center" label="铝腐蚀电流(nA)" min-width="130" prop="corrosion3" />
<el-table-column align="center" label="钢腐蚀电流(nA)" min-width="130" prop="corrosion4" />
<el-table-column align="center" label="环境温度(℃)" min-width="110" prop="environmentTemperature" />
<el-table-column align="center" label="环境湿度(RH%)" min-width="130" prop="environmentHumidity" />
<el-table-column align="center" label="SO2(ppb)" min-width="90" prop="so2" />
<el-table-column align="center" label="盐分温度(℃)" min-width="110" prop="salt" />
<el-table-column align="center" label="盐分阻抗(Ω)" min-width="110" prop="salt" />
<el-table-column align="center" label="太阳能板电压(V)" min-width="140" prop="solarVoltage" />
<el-table-column align="center" label="蓄电池电压(V)" min-width="120" prop="batteryVoltage" />
<el-table-column align="center" label="机箱温度(℃)" min-width="110" prop="deviceTemperature" />
<el-table-column align="center" label="机箱湿度(RH%)" min-width="130" prop="deviceHumidity" />
</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>

36
src/components/history/search-bar-data.vue

@ -22,8 +22,8 @@
<!--TODO:--> <!--TODO:-->
<el-form-item> <el-form-item>
<template v-if="showCommand"> <template v-if="showCommand">
<el-button type="primary" @click="onSend('DATA')">查询历史数据</el-button> <el-button type="primary" @click="onSubmit">查询历史数据</el-button>
<el-button type="warning" @click="onSend('EVENT')">查询历史事件</el-button> <!-- <el-button type="warning" @click="onSend('EVENT')">查询历史事件</el-button>-->
</template> </template>
<el-button v-else :loading="loadingSearch" type="primary" @click="onSubmit"> <el-button v-else :loading="loadingSearch" type="primary" @click="onSubmit">
<i class="el-icon-search mr-2"></i> <i class="el-icon-search mr-2"></i>
@ -45,7 +45,6 @@ import { computed, defineEmits, defineProps, reactive, ref, watch } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { exportHistory } from 'apis'; import { exportHistory } from 'apis';
import { ElMessage } from 'element-plus';
const emit = defineEmits(['search']); const emit = defineEmits(['search']);
const searchDevice = reactive({ const searchDevice = reactive({
@ -114,6 +113,14 @@ async function onExport() {
try { try {
loadingExport.value = true; loadingExport.value = true;
const params = generateParams(); const params = generateParams();
params.sort = [
{
col: 'gathered_at',
order: 'DESC',
},
];
params.paging = false;
params.gatheredDateRange = params.date;
const resData = await exportHistory(params); const resData = await exportHistory(params);
loadingExport.value = false; loadingExport.value = false;
resData && (window.location.href = resData); resData && (window.location.href = resData);
@ -122,27 +129,4 @@ async function onExport() {
throw new Error(error); throw new Error(error);
} }
} }
/**
* 发送查询指令
* @param {string} dataType ('data', 'event')
*/
async function onSend(dataType) {
try {
console.log(dataType);
// const { date, deviceId } = props.search.value;
// const params = {
// deviceId,
// type: dataType,
// };
// // eslint-disable-next-line prefer-destructuring
// date && date[0] && (params.startTime = date[0]);
// // eslint-disable-next-line prefer-destructuring
// date && date[1] && (params.endTime = date[1]);
// await sendCommand(params);
// ElMessage.success('');
} catch (e) {
ElMessage.error('指令发送失败');
}
}
</script> </script>

77
src/components/history/search-history-log.vue

@ -0,0 +1,77 @@
<template>
<el-form ref="searchDeviceForm" :inline="true" :model="searchDevice">
<el-form-item label="选择站点">
<el-select v-model="searchDevice.deviceId" placeholder="请选择站点" @change="change">
<el-option label="全部" value></el-option>
<el-option
v-for="item in devices"
:key="item.deviceId"
:label="`${item.address}-${item.deviceId}`"
:value="item.deviceId"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="类型">
<el-select v-model="searchDevice.type" placeholder="选择查询类型">
<el-option label="全部" value=""></el-option>
<el-option label="事件上报" value="EVENT"></el-option>
<el-option label="业务上报" value="DATA"></el-option>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="searchDevice.status" placeholder="选择查询类型">
<el-option label="全部" value=""></el-option>
<el-option label="待下发" value="PENDING"></el-option>
<el-option label="下发成功" value="SUCCESS"></el-option>
<el-option label="下发失败" value="FAIL"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<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 { computed, defineEmits, reactive, ref, watch } from 'vue';
import { useStore } from 'vuex';
const emit = defineEmits(['search']);
const searchDevice = reactive({
deviceId: '',
type: '',
status: '',
});
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(() => {
emit('search', { ...searchDevice });
});
};
</script>

8
src/config/config.js

@ -112,7 +112,7 @@ export const deviceRules = {
export const PEND_TYPE = { export const PEND_TYPE = {
PENDING: { PENDING: {
type: 'primary', type: 'primary',
text: '下发', text: '下发',
}, },
FAIL: { FAIL: {
type: 'danger', type: 'danger',
@ -130,6 +130,12 @@ export const REPORT_TYPE = {
POINT: '定时上报', POINT: '定时上报',
}; };
// 下发类型
export const PENDING_TYPE = {
DATA: { text: '业务上报' },
EVENT: { text: '事件上报' },
};
// 实时查询数据的轮询时间 1分钟 // 实时查询数据的轮询时间 1分钟
export const REALTIME_DATA_INTERVAL = 60000 * 5; export const REALTIME_DATA_INTERVAL = 60000 * 5;

1
src/config/log.js

@ -82,6 +82,7 @@ export const ASDU_TYPE = {
export const INFO_ORDER = { export const INFO_ORDER = {
NoOrder: '无序', NoOrder: '无序',
HasOrder: '有序', HasOrder: '有序',
None: '无',
}; };
// 传输原因 // 传输原因

6
src/utils/overview.js

@ -57,11 +57,13 @@ export function generateChartOption(count) {
value: count.online, value: count.online,
name: STATUS_COLOR.ONLINE.text, name: STATUS_COLOR.ONLINE.text,
itemStyle: { color: STATUS_COLOR.ONLINE.color }, itemStyle: { color: STATUS_COLOR.ONLINE.color },
label: { show: count.online },
}, },
{ {
value: count.offline, value: count.offline,
name: STATUS_COLOR.OFFLINE.text, name: STATUS_COLOR.OFFLINE.text,
itemStyle: { color: STATUS_COLOR.OFFLINE.color }, itemStyle: { color: STATUS_COLOR.OFFLINE.color },
label: { show: count.offline },
}, },
], ],
}, },
@ -96,16 +98,19 @@ export function generateChartOption(count) {
value: count.fault, value: count.fault,
name: STATUS_COLOR.FAULT.text, name: STATUS_COLOR.FAULT.text,
itemStyle: { color: STATUS_COLOR.FAULT.color }, itemStyle: { color: STATUS_COLOR.FAULT.color },
label: { show: count.fault },
}, },
{ {
value: count.warning, value: count.warning,
name: STATUS_COLOR.WARNING.text, name: STATUS_COLOR.WARNING.text,
itemStyle: { color: STATUS_COLOR.WARNING.color }, itemStyle: { color: STATUS_COLOR.WARNING.color },
label: { show: count.warning },
}, },
{ {
value: count.normal, value: count.normal,
name: STATUS_COLOR.NORMAL.text, name: STATUS_COLOR.NORMAL.text,
itemStyle: { color: STATUS_COLOR.NORMAL.color }, itemStyle: { color: STATUS_COLOR.NORMAL.color },
label: { show: count.normal },
}, },
{ {
value: count.offline, value: count.offline,
@ -114,6 +119,7 @@ export function generateChartOption(count) {
color: STATUS_COLOR.OFFLINE.color, color: STATUS_COLOR.OFFLINE.color,
opacity: 0, opacity: 0,
}, },
label: { show: count.offline },
}, },
], ],
}, },

105
src/views/commands.vue

@ -1,8 +1,13 @@
<template> <template>
<SearchCommands @search="onSearch" /> <SearchCommands @search="onSearch" />
<template v-if="data"> <template v-if="data">
<el-table :data="data" :style="{ 'max-height': contentHeight + 'px' }" border stripe style="width: 100%"> <el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
<el-table-column align="center" fixed label="设备ID" min-width="100" prop="deviceId" /> <el-table-column align="center" fixed label="设备ID" min-width="100" prop="deviceId" />
<el-table-column align="center" label="时间" min-width="200">
<template #default="scope">
{{ dayjs(+scope.row.createdAt).format('YYYY-MM-DD HH:mm:ss') }}
</template>
</el-table-column>
<el-table-column align="center" label="传输方向" min-width="80"> <el-table-column align="center" label="传输方向" min-width="80">
<template #default="scope"> <template #default="scope">
{{ log.DIRECTION[scope.row.dir] }} {{ log.DIRECTION[scope.row.dir] }}
@ -34,7 +39,7 @@
<el-table-column align="center" label="类型标识" min-width="80"> <el-table-column align="center" label="类型标识" min-width="80">
<template #default="scope"> <template #default="scope">
{{ log.ASDU_TYPE[scope.row.type] }} {{ log.ASDU_TYPE[scope.row.asduType].text }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="信息体顺序" min-width="100"> <el-table-column align="center" label="信息体顺序" min-width="100">
@ -46,38 +51,63 @@
<el-table-column align="center" label="传输原因" min-width="180"> <el-table-column align="center" label="传输原因" min-width="180">
<template #default="scope"> <template #default="scope">
{{ log.REASON[scope.row.reason] }} {{ log.REASON[scope.row.reason].text }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="协议内容" min-width="80"> <el-table-column align="center" label="协议内容" min-width="80">
<template #default="scope"> <template #default="scope">
<el-button type="text" @click="openContent(scope.row.contents)">查看</el-button> <el-button type="text" @click="openContent(scope.row.content)">查看</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </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"
@size-change="onSizeChange"
@current-change="onCurrentPageChange"
></el-pagination>
</template>
<!-- 弹出框--> <!-- 弹出框-->
<el-dialog v-model="showContent" title="协议内容"> <el-dialog v-model="showContent" title="协议内容">
<p>{{ contents }}</p> <code class="font-mono">{{ contents }}</code>
</el-dialog> </el-dialog>
</template> </template>
</template>
<script setup> <script setup>
import SearchCommands from 'components/commands/search-commands.vue'; import { computed, onMounted, ref } from 'vue';
import { onMounted, ref } from 'vue'; import dayjs from 'dayjs';
import { useStore } from 'vuex';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import SearchCommands from 'components/commands/search-commands.vue';
import { getLog } from 'apis';
import * as log from '@/config/log'; import * as log from '@/config/log';
const data = ref([]); const data = ref([]);
const page = ref({
page: 1,
size: 50,
count: 0,
total: 0,
});
const showContent = ref(false); // const showContent = ref(false); //
const contents = ref(''); // const contents = ref(''); //
let contentHeight = 600; const contentHeight = ref(700);
const store = useStore();
const currentDeviceId = computed(() => store.state.device.currentDeviceId);
// //
onMounted(() => { onMounted(() => {
const winHeight = document.documentElement.clientHeight; const winHeight = document.documentElement.clientHeight;
contentHeight = winHeight - 150; contentHeight.value = winHeight - 150;
onSearch();
}); });
/** /**
@ -85,19 +115,66 @@ onMounted(() => {
* @param {object} options * @param {object} options
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async function onSearch(options) { async function onSearch(
options = {
...page.value,
sort: [
{
col: 'createdAt',
order: 'DESC',
},
],
deviceId: currentDeviceId.value,
},
) {
try { try {
console.log(options); const resData = await getLog(options);
// data.value = await getCommandsStatus(options); page.value = resData.page;
data.value = resData.data;
} catch (error) { } catch (error) {
ElMessage.error('查询失败'); ElMessage.error('查询失败');
throw new Error(error); throw new Error(error);
} }
} }
/**
* 打开协议内容的弹出框 并记录值
* @param {string} content 协议内容
*/
function openContent(content) { function openContent(content) {
showContent.value = true; showContent.value = true;
contents.value = content; contents.value = content;
console.log('open content', content);
} }
//
const onCurrentPageChange = pageEvent => {
const options = {
page: pageEvent,
size: page.value.size || 50,
sort: [
{
col: 'createdAt',
order: 'DESC',
},
],
deviceId: currentDeviceId.value,
};
onSearch(options);
};
//
const onSizeChange = size => {
const options = {
page: 1,
size,
sort: [
{
col: 'createdAt',
order: 'DESC',
},
],
deviceId: currentDeviceId.value,
};
onSearch(options);
};
</script> </script>

11
src/views/data-realtime.vue

@ -90,11 +90,16 @@ const getData = async () => {
const date = [dayjs().startOf('day').format('x'), dayjs().endOf('day').format('x')]; const date = [dayjs().startOf('day').format('x'), dayjs().endOf('day').format('x')];
const params = { const params = {
deviceId: currentDeviceId.value, deviceId: currentDeviceId.value,
date, dateRange: date,
paging: true,
page: page.value.page, page: page.value.page,
size: page.value.size, size: page.value.size,
type: 1, sort: [
sort: -1, {
col: 'gathered_at',
order: 'DESC',
},
],
}; };
loadingSearch.value = true; loadingSearch.value = true;

2
src/views/device-list.vue

@ -27,7 +27,7 @@
</el-row> </el-row>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="设备ID" min-min-width="100" prop="deviceId" /> <el-table-column align="center" label="设备ID" min-width="100" prop="deviceId" />
<el-table-column align="center" label="设备完整ID" min-width="150" prop="deviceFullId" /> <el-table-column align="center" label="设备完整ID" min-width="150" prop="deviceFullId" />
<el-table-column align="left" header-align="center" label="站点" min-width="150" prop="address" /> <el-table-column align="left" header-align="center" label="站点" min-width="150" prop="address" />
<el-table-column align="left" header-align="center" label="地区" min-width="120" prop="area" /> <el-table-column align="left" header-align="center" label="地区" min-width="120" prop="area" />

4
src/views/history.vue

@ -6,6 +6,9 @@
<el-tab-pane :lazy="true" label="设备数据" name="device"> <el-tab-pane :lazy="true" label="设备数据" name="device">
<Device v-if="activeName === 'device'" :active-name="activeName" /> <Device v-if="activeName === 'device'" :active-name="activeName" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :lazy="true" label="补传记录" name="log">
<HistoryLog v-if="activeName === 'log'" :active-name="activeName" />
</el-tab-pane>
</el-tabs> </el-tabs>
</template> </template>
@ -13,6 +16,7 @@
import { ref } from 'vue'; import { ref } from 'vue';
import Local from 'components/history/local.vue'; import Local from 'components/history/local.vue';
import Device from 'components/history/device.vue'; import Device from 'components/history/device.vue';
import HistoryLog from 'components/history/history-log.vue';
const activeName = ref('local'); const activeName = ref('local');
</script> </script>

Loading…
Cancel
Save