Browse Source

feat: 细节调整;补传

master
wally 4 years ago
parent
commit
15027ddb56
  1. 2
      src/apis/index.js
  2. 2
      src/components/config/config-log-function.vue
  3. 2
      src/components/config/config-log-network.vue
  4. 63
      src/components/history/device.vue
  5. 4
      src/components/history/history-log-table.vue
  6. 48
      src/components/history/missing-data.vue
  7. 35
      src/components/history/search-bar-data.vue
  8. 11
      src/components/overview/device-table.vue
  9. 2
      src/components/statistical/stastistical-chart.vue
  10. 2
      src/utils/statistical.js
  11. 2
      src/utils/time.js
  12. 2
      src/views/commands.vue
  13. 13
      src/views/statistical-report.vue

2
src/apis/index.js

@ -73,7 +73,7 @@ export const getHistory = params => http.post(`${corrosion}/history/datas`, para
// 导出历史数据 // 导出历史数据
export const exportHistory = params => http.post(`${corrosion}/export`, params); export const exportHistory = params => http.post(`${corrosion}/export`, params);
// 发送查询历史记录的指令 // 发送补传指令
export const sendCommand = params => http.post(`${corrosion}/history`, params); export const sendCommand = params => http.post(`${corrosion}/history`, params);
// 补传记录 // 补传记录

2
src/components/config/config-log-function.vue

@ -11,7 +11,7 @@
<el-table-column align="center" label="设备ID" min-min-width="100" prop="deviceId" /> <el-table-column align="center" label="设备ID" min-min-width="100" prop="deviceId" />
<el-table-column align="center" label="上次配置时间" min-width="200"> <el-table-column align="center" label="上次配置时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.settingTime).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.settingTime)).format('YYYY-MM-DD HH:mm:ss') }}
</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">

2
src/components/config/config-log-network.vue

@ -12,7 +12,7 @@
<el-table-column align="center" label="上次配置时间" min-width="200"> <el-table-column align="center" label="上次配置时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.settingTime).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.settingTime)).format('YYYY-MM-DD HH:mm:ss') }}
</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">

63
src/components/history/device.vue

@ -1,5 +1,5 @@
<template> <template>
<SearchBar :loading-search="loadingSearch" :show-command="true" :show-export="true" @search="onSearch" /> <SearchBar :loading-search="loadingSearch" :show-command="true" :show-export="true" :show-pass-setting="true" @search="onSearch" />
<template v-if="data"> <template v-if="data">
<el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%"> <el-table :data="data" :max-height="contentHeight" border stripe style="width: 100%">
@ -21,7 +21,6 @@
<el-table-column align="center" label="环境温度(℃)" min-width="110" prop="environmentTemperature" /> <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="环境湿度(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="SO2(ppb)" min-width="90" prop="so2" />
<!-- TODO:-->
<el-table-column align="center" label="盐分温度(℃)" min-width="110" prop="saltT" /> <el-table-column align="center" label="盐分温度(℃)" min-width="110" prop="saltT" />
<el-table-column align="center" label="盐分阻抗(Ω)" min-width="110" prop="saltR" /> <el-table-column align="center" label="盐分阻抗(Ω)" min-width="110" prop="saltR" />
<el-table-column align="center" label="机箱温度(℃)" min-width="110" prop="deviceTemperature" /> <el-table-column align="center" label="机箱温度(℃)" min-width="110" prop="deviceTemperature" />
@ -55,6 +54,16 @@
@next-click="onNext" @next-click="onNext"
></el-pagination> ></el-pagination>
</template> </template>
<el-badge v-if="missingData && missingData.length" :max="99" :value="missingData.length" class="pass-button animate-bounce">
<div circle class="shadow-xl btn" type="primary" @click="showMissing = true">
<i class="el-icon-upload"></i>
</div>
</el-badge>
<el-dialog v-model="showMissing" custom-class="device-dialog" title="待补传列表" top="30px" width="80%">
<MissingData :data="missingData" @on-success="onPassSuccess" />
</el-dialog>
</template> </template>
<script setup> <script setup>
@ -64,6 +73,7 @@ import { getDatas } from 'apis';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import SearchBar from 'components/history/search-bar-data.vue'; import SearchBar from 'components/history/search-bar-data.vue';
import MissingData from 'components/history/missing-data.vue';
const search = ref({}); const search = ref({});
const page = ref({ const page = ref({
@ -77,6 +87,8 @@ const currentDeviceId = computed(() => store.state.device.currentDeviceId); //
const contentHeight = ref(600); const contentHeight = ref(600);
const loadingSearch = ref(false); const loadingSearch = ref(false);
const data = ref(null); const data = ref(null);
const showMissing = ref(false);
const missingData = ref([]);
// //
const getData = async () => { const getData = async () => {
@ -86,8 +98,7 @@ const getData = async () => {
return ElMessage.error('请选择站点'); return ElMessage.error('请选择站点');
} }
const options = { ...search.value }; const { date, missingIntervalInMs } = search.value;
const date = options && options.date ? options.date : [];
if (!date || date.length !== 2) { if (!date || date.length !== 2) {
return ElMessage.error('请选择时间 '); return ElMessage.error('请选择时间 ');
} }
@ -95,6 +106,7 @@ const getData = async () => {
deviceId: currentDeviceId.value, deviceId: currentDeviceId.value,
gatheredDateRange: date, gatheredDateRange: date,
paging: true, paging: true,
missingIntervalInMs,
page: page.value.page, page: page.value.page,
size: page.value.size, size: page.value.size,
sort: [ sort: [
@ -113,6 +125,13 @@ const getData = async () => {
page.value = resData.page; page.value = resData.page;
timer && clearTimeout(timer); timer && clearTimeout(timer);
timer = null; timer = null;
if (resData.missingData) {
missingData.value = [...resData.missingData];
missingData.value.forEach(item => {
item.uuid = `${item.deviceId}-${item.startTime}-${item.endTime}`;
});
}
} else { } else {
timer = setTimeout(() => { timer = setTimeout(() => {
getData(); getData();
@ -175,4 +194,40 @@ const onPrev = e => {
function formatTime(time) { 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');
} }
//
function onPassSuccess(uuid) {
// eslint-disable-next-line no-restricted-syntax
for (const item of missingData.value) {
if (item.uuid === uuid) {
item.disabled = true;
}
}
}
</script> </script>
<style scoped>
.device-dialog :deep(.el-dialog__body) {
padding-top: 0 !important;
}
.pass-button {
z-index: 999;
position: fixed;
right: 30px;
bottom: 40px;
}
.pass-button .btn {
width: 56px;
height: 56px;
display: flex;
justify-content: center;
align-items: center;
background-color: #409eff;
border-radius: 50%;
color: #fff;
font-size: 26px;
cursor: pointer;
}
</style>

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

@ -4,12 +4,12 @@
<el-table-column align="center" label="设备ID" min-min-width="100" prop="deviceId" /> <el-table-column align="center" label="设备ID" min-min-width="100" prop="deviceId" />
<el-table-column align="center" label="开始时间" min-width="200"> <el-table-column align="center" label="开始时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.startTime).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.startTime)).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="截止时间" min-width="200"> <el-table-column align="center" label="截止时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.endTime).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.endTime)).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" header-align="center" label="下发状态" min-width="150"> <el-table-column align="center" header-align="center" label="下发状态" min-width="150">

48
src/components/history/missing-data.vue

@ -0,0 +1,48 @@
<template>
<el-table :data="data" :max-height="contentHeight" border class="mt-6" stripe style="width: 100%; margin-top: 0">
<el-table-column align="center" label="设备ID" min-width="100" prop="deviceId" />
<el-table-column align="center" label="起始时间" min-width="200">
<template #default="scope">
{{ dayjs(new Date(+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(new Date(+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="100">
<template #default="scope">
<el-button :disabled="scope.row.disabled" plain size="small" type="success" @click="handlePass(scope.row)">补传 </el-button>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
import { defineProps, defineEmits, ref } from 'vue';
import dayjs from 'dayjs';
import { sendCommand } from 'apis';
import { ElMessage } from 'element-plus';
defineProps({ data: Object });
const emit = defineEmits(['on-success']);
const contentHeight = ref(600);
/**
* 发送补传指令
* @param { Object } item
* @returns {Promise<void>}
*/
async function handlePass(item) {
try {
await sendCommand({ ...item });
ElMessage.success('发送成功');
emit('on-success', item.uuid);
} catch (error) {
ElMessage.error(error.message || '发送补传指令失败');
}
}
</script>

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

@ -13,13 +13,29 @@
</el-form-item> </el-form-item>
<el-form-item label="起始时间:"> <el-form-item label="起始时间:">
<el-date-picker v-model="searchDevice.date[0]" format="YYYY-MM-DD HH:mm" placeholder="起始时间" type="datetime"></el-date-picker> <el-date-picker
v-model="searchDevice.date[0]"
format="YYYY-MM-DD HH:mm"
placeholder="起始时间"
style="width: 180px"
type="datetime"
></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="截止时间:"> <el-form-item label="截止时间:">
<el-date-picker v-model="searchDevice.date[1]" format="YYYY-MM-DD HH:mm" placeholder="截止时间" type="datetime"></el-date-picker> <el-date-picker
v-model="searchDevice.date[1]"
format="YYYY-MM-DD HH:mm"
placeholder="截止时间"
style="width: 180px"
type="datetime"
></el-date-picker>
</el-form-item> </el-form-item>
<!--TODO:-->
<el-form-item v-if="showPassSetting" label="补传间隔(h):">
<el-input-number v-model="searchDevice.missingIntervalInMs" :min="0" controls-position="right" style="width: 100px" />
</el-form-item>
<el-form-item> <el-form-item>
<template v-if="showCommand"> <template v-if="showCommand">
<el-button type="primary" @click="onSubmit">查询历史数据</el-button> <el-button type="primary" @click="onSubmit">查询历史数据</el-button>
@ -50,6 +66,7 @@ const emit = defineEmits(['search']);
const searchDevice = reactive({ const searchDevice = reactive({
deviceId: '', deviceId: '',
date: [dayjs().subtract(7, 'day').startOf('day'), new Date()], date: [dayjs().subtract(7, 'day').startOf('day'), new Date()],
missingIntervalInMs: 1,
}); });
const searchDeviceForm = ref(null); // form const searchDeviceForm = ref(null); // form
const store = useStore(); const store = useStore();
@ -61,6 +78,7 @@ defineProps({
showExport: Boolean, showExport: Boolean,
loadingSearch: Boolean, loadingSearch: Boolean,
showCommand: Boolean, showCommand: Boolean,
showPassSetting: Boolean,
}); });
// currentDeviceId // currentDeviceId
@ -81,19 +99,16 @@ const change = e => {
// //
function generateParams() { function generateParams() {
const { deviceId, date } = searchDevice; const { deviceId, date, missingIntervalInMs } = searchDevice;
let params = { const params = {
deviceId, deviceId,
date, missingIntervalInMs: missingIntervalInMs * 60 * 60 * 1000,
}; };
if (date) { if (date) {
const start = +dayjs(date[0]).format('x'); const start = +dayjs(date[0]).format('x');
const end = +dayjs(date[1]).format('x'); const end = +dayjs(date[1]).format('x');
params = { params.date = [start, end];
deviceId,
date: [start, end],
};
} }
return params; return params;

11
src/components/overview/device-table.vue

@ -2,15 +2,15 @@
<template v-if="devicesAll && devicesAll.data"> <template v-if="devicesAll && devicesAll.data">
<el-table :data="devicesAll.data" :max-height="contentHeight" border class="mt-6" stripe style="width: 100%"> <el-table :data="devicesAll.data" :max-height="contentHeight" border class="mt-6" stripe style="width: 100%">
<el-table-column align="center" label="站点名称" min-width="150" prop="address" /> <el-table-column align="center" label="站点名称" min-width="150" prop="address" />
<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="注册时间" min-width="200"> <el-table-column align="center" label="注册时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.signupTime).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.signupTime)).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="最近上传时间" min-width="200"> <el-table-column align="center" label="最近上传时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.lastUploadTime).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.lastUploadTime)).format('YYYY-MM-DD HH:mm:ss') }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" header-align="center" label="设备状态" min-width="150"> <el-table-column align="center" header-align="center" label="设备状态" min-width="150">
@ -42,16 +42,12 @@
@current-change="onCurrentPageChange" @current-change="onCurrentPageChange"
></el-pagination> ></el-pagination>
</template> </template>
<!-- 编辑设备信息 -->
<DeviceEdit :show="editing" @toggle-mdoal="editing = false" />
</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';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import DeviceEdit from 'components/device/device-edit.vue';
import { STATUS_COLOR } from '@/config/config'; import { STATUS_COLOR } from '@/config/config';
import { ASDU_TYPE } from '@/config/log'; import { ASDU_TYPE } from '@/config/log';
@ -63,7 +59,6 @@ const devicesAll = computed(() => {
}); });
const currentDeviceId = computed(() => store.state.device.currentDeviceId); const currentDeviceId = computed(() => store.state.device.currentDeviceId);
const contentHeight = ref(600); const contentHeight = ref(600);
const editing = ref(false);
// //
const getDevicesAllData = () => { const getDevicesAllData = () => {

2
src/components/statistical/stastistical-chart.vue

@ -72,7 +72,7 @@ function render(data, selected) {
noData.value = false; noData.value = false;
if (!myChart) { if (!myChart) {
initChart(); initChart(data);
} }
const option = generateChartOption(data, selected); const option = generateChartOption(data, selected);
option && myChart.setOption(option); option && myChart.setOption(option);

2
src/utils/statistical.js

@ -32,7 +32,7 @@ function generateParams(data) {
corrosionGANG: [], corrosionGANG: [],
}; };
data.forEach(item => { data.forEach(item => {
result.time.push(dayjs(+item.time).format('YY/MM/MM HH:mm')); result.time.push(dayjs(new Date(+item.time)).format('YY/MM/DD HH:mm'));
result.so2.push(+item.so2); result.so2.push(+item.so2);
result.saltR.push(+item.saltR); result.saltR.push(+item.saltR);
result.saltT.push(+item.saltT); result.saltT.push(+item.saltT);

2
src/utils/time.js

@ -7,7 +7,7 @@ import dayjs from 'dayjs';
* @returns * @returns
*/ */
export function formatMsTime(time, formatStyle = 'YYYY-MM-DD HH:mm:ss') { export function formatMsTime(time, formatStyle = 'YYYY-MM-DD HH:mm:ss') {
return dayjs(+time).format(formatStyle); return dayjs(new Date(+time)).format(formatStyle);
} }
// 图表时间轴的时间格式化 // 图表时间轴的时间格式化

2
src/views/commands.vue

@ -5,7 +5,7 @@
<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"> <el-table-column align="center" label="时间" min-width="200">
<template #default="scope"> <template #default="scope">
{{ dayjs(+scope.row.createdAt).format('YYYY-MM-DD HH:mm:ss') }} {{ dayjs(new Date(+scope.row.createdAt)).format('YYYY-MM-DD HH:mm:ss') }}
</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">

13
src/views/statistical-report.vue

@ -9,6 +9,7 @@ import HistoryData from 'components/statistical/stastistical-chart.vue';
import { computed, onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import dayjs from 'dayjs';
const searchBar = ref(null); const searchBar = ref(null);
let timer = null; let timer = null;
@ -38,11 +39,17 @@ const getData = async () => {
if (!currentDeviceId.value) return; if (!currentDeviceId.value) return;
loadingSearch.value = true; loadingSearch.value = true;
const options = { ...search.value }; const options = { ...search.value };
const date = options && options.date ? options.date : []; const date = options && options.date ? options.date : [+dayjs().subtract(7, 'day').startOf('day').format('x'), +dayjs().format('x')];
const params = { const params = {
deviceId: currentDeviceId.value, deviceId: currentDeviceId.value,
date, gatheredDateRange: date,
type: 0, paging: false,
sort: [
{
col: 'time',
order: 'ASC',
},
],
}; };
await store.dispatch('statistics/getRealtimeData', params); await store.dispatch('statistics/getRealtimeData', params);
timer && clearTimeout(timer); timer && clearTimeout(timer);

Loading…
Cancel
Save