From d6e6f8b5b31e132e4597eb531168d3e88f3bda72 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 04 七月 2025 17:26:49 +0800
Subject: [PATCH] 2025.7.4 动态溯源
---
src/styles/animation.scss | 0
src/views/sourcetrace/SourceTrace.vue | 211 ++++-----
src/views/historymode/HistoryMode.vue | 15
src/components/monitor/WeatherData.vue | 54 +-
src/components/monitor/FactorTrend.vue | 21
src/components.d.ts | 171 ++++----
src/views/sourcetrace/component/ClueRecordItem.vue | 19
src/assets/logo.svg | 5
src/views/realtimemode/RealtimeMode.vue | 7
src/views/realtimemode/component/DashBoard.vue | 74 ++-
src/components/monitor/FactorLegend.vue | 116 +++--
/dev/null | 87 ----
src/api/dataAnalysisApi.js | 6
src/components/monitor/FactorRadio.vue | 61 ++
src/assets/wdr.svg | 6
src/components/monitor/VehicleData.vue | 18
src/views/sourcetrace/component/PollutedExceptionItem.vue | 66 --
src/components/monitor/FactorIconText.vue | 72 +++
src/components/monitor/WeatherData_Old.vue | 106 +++++
src/styles/index.scss | 4
src/views/realtimemode/component/DashBoard_Old.vue | 78 +++
21 files changed, 737 insertions(+), 460 deletions(-)
diff --git a/src/api/dataAnalysisApi.js b/src/api/dataAnalysisApi.js
index 9b57b3d..fe9e1b0 100644
--- a/src/api/dataAnalysisApi.js
+++ b/src/api/dataAnalysisApi.js
@@ -10,5 +10,11 @@
return $http
.get(`air/analysis/pollution/trace`, { params: { missionCode } })
.then((res) => res.data);
+ },
+
+ fetchPollutionTraceHistory(missionCode) {
+ return $http
+ .get(`air/analysis/pollution/trace/history`, { params: { missionCode } })
+ .then((res) => res.data);
}
};
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
index 7565660..43c9cba 100644
--- a/src/assets/logo.svg
+++ b/src/assets/logo.svg
@@ -1 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69">
+ <path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883" />
+ <path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e" />
+</svg>
\ No newline at end of file
diff --git a/src/assets/wdr.svg b/src/assets/wdr.svg
new file mode 100644
index 0000000..a3ec37f
--- /dev/null
+++ b/src/assets/wdr.svg
@@ -0,0 +1,6 @@
+<svg t="1751598713381" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4696"
+ width="30" height="30">
+ <path
+ d="M973.824 278.186667l-136.533333-85.333334A34.133333 34.133333 0 0 0 785.066667 221.866667V273.066667H318.122667L88.064 108.885333a34.133333 34.133333 0 0 0-51.541333 40.277334L99.669333 307.2l-63.146666 158.037333A34.133333 34.133333 0 0 0 68.266667 512a34.133333 34.133333 0 0 0 19.797333-6.485333L318.122667 341.333333H477.866667v307.2h-68.266667v341.333334h68.266667v-273.066667h68.266666v273.066667h68.266667V648.533333h-68.266667v-307.2h238.933334v51.2a34.133333 34.133333 0 0 0 17.749333 29.696 34.133333 34.133333 0 0 0 16.384 4.437334 34.133333 34.133333 0 0 0 18.090667-5.12l136.533333-85.333334a34.133333 34.133333 0 0 0 0-58.026666z"
+ p-id="4697" fill="#CCD1D7"></path>
+</svg>
\ No newline at end of file
diff --git a/src/components.d.ts b/src/components.d.ts
index 9231243..0bdadcd 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -7,92 +7,93 @@
declare module 'vue' {
export interface GlobalComponents {
- BaseCard: typeof import('./components/BaseCard.vue')['default']
- BaseMap: typeof import('./components/map/BaseMap.vue')['default']
- CardButton: typeof import('./components/CardButton.vue')['default']
- CardDialog: typeof import('./components/CardDialog.vue')['default']
- 'CardDialog copy': typeof import('./components/CardDialog copy.vue')['default']
- CheckButton: typeof import('./components/common/CheckButton.vue')['default']
- ConfigManage: typeof import('./components/map/ConfigManage.vue')['default']
- copy: typeof import('./components/CardDialog copy.vue')['default']
- CoreHeader: typeof import('./components/core/CoreHeader.vue')['default']
- CoreMenu: typeof import('./components/core/CoreMenu.vue')['default']
- DataSummary: typeof import('./components/monitor/DataSummary.vue')['default']
- DataTable: typeof import('./components/monitor/DataTable.vue')['default']
- DescriptionsList: typeof import('./components/list/DescriptionsList.vue')['default']
- DescriptionsListItem: typeof import('./components/list/DescriptionsListItem.vue')['default']
- DeviceCreate: typeof import('./components/device/DeviceCreate.vue')['default']
- DeviceManage: typeof import('./components/device/DeviceManage.vue')['default']
- ElButton: typeof import('element-plus/es')['ElButton']
- ElCascader: typeof import('element-plus/es')['ElCascader']
- ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
- ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
- ElCol: typeof import('element-plus/es')['ElCol']
- ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
- ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
- ElDialog: typeof import('element-plus/es')['ElDialog']
- ElDivider: typeof import('element-plus/es')['ElDivider']
- ElDropdown: typeof import('element-plus/es')['ElDropdown']
- ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
- ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
- ElForm: typeof import('element-plus/es')['ElForm']
- ElFormItem: typeof import('element-plus/es')['ElFormItem']
- ElIcon: typeof import('element-plus/es')['ElIcon']
- ElInput: typeof import('element-plus/es')['ElInput']
- ElLink: typeof import('element-plus/es')['ElLink']
- ElOption: typeof import('element-plus/es')['ElOption']
- ElPagination: typeof import('element-plus/es')['ElPagination']
- ElPopover: typeof import('element-plus/es')['ElPopover']
- ElRadio: typeof import('element-plus/es')['ElRadio']
- ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
- ElRow: typeof import('element-plus/es')['ElRow']
- ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
- ElSelect: typeof import('element-plus/es')['ElSelect']
- ElSlider: typeof import('element-plus/es')['ElSlider']
- ElSpace: typeof import('element-plus/es')['ElSpace']
- ElStatistic: typeof import('element-plus/es')['ElStatistic']
- ElSwitch: typeof import('element-plus/es')['ElSwitch']
- ElTable: typeof import('element-plus/es')['ElTable']
- ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
- ElTabPane: typeof import('element-plus/es')['ElTabPane']
- ElTabs: typeof import('element-plus/es')['ElTabs']
- ElTag: typeof import('element-plus/es')['ElTag']
- ElText: typeof import('element-plus/es')['ElText']
- FactorCheckbox: typeof import('./components/monitor/FactorCheckbox.vue')['default']
- FactorLegend: typeof import('./components/monitor/FactorLegend.vue')['default']
- FactorRadio: typeof import('./components/monitor/FactorRadio.vue')['default']
- FactorTrend: typeof import('./components/monitor/FactorTrend.vue')['default']
- GaugeChart: typeof import('./components/chart/GaugeChart.vue')['default']
- GridSearch: typeof import('./components/grid/GridSearch.vue')['default']
- HistoricalTrajectory: typeof import('./components/animation/HistoricalTrajectory.vue')['default']
- MapLocate: typeof import('./components/map/MapLocate.vue')['default']
- MapScene: typeof import('./components/map/MapScene.vue')['default']
- MapToolbox: typeof import('./components/map/MapToolbox.vue')['default']
- MessageBox: typeof import('./components/MessageBox.vue')['default']
- MissionEdit: typeof import('./components/mission/MissionEdit.vue')['default']
- MissionImport: typeof import('./components/mission/MissionImport.vue')['default']
- MissionManage: typeof import('./components/mission/MissionManage.vue')['default']
- OptionDevice: typeof import('./components/search/OptionDevice.vue')['default']
- OptionLocation: typeof import('./components/search/OptionLocation.vue')['default']
- OptionLocation2: typeof import('./components/search/OptionLocation2.vue')['default']
- OptionMission: typeof import('./components/search/OptionMission.vue')['default']
- OptionPollutionDegree: typeof import('./components/search/OptionPollutionDegree.vue')['default']
- OptionTime: typeof import('./components/search/OptionTime.vue')['default']
- OptionType: typeof import('./components/search/OptionType.vue')['default']
- ProgressLineChart: typeof import('./components/chart/ProgressLineChart.vue')['default']
- RealTimeLineChart: typeof import('./components/chart/RealTimeLineChart.vue')['default']
- RouterLink: typeof import('vue-router')['RouterLink']
- RouterView: typeof import('vue-router')['RouterView']
- SceneSearch: typeof import('./components/scene/SceneSearch.vue')['default']
- SceneTable: typeof import('./components/scene/SceneTable.vue')['default']
- SearchBar: typeof import('./components/search/SearchBar.vue')['default']
- SliderBar: typeof import('./components/SliderBar.vue')['default']
- TrajectoryState: typeof import('./components/animation/TrajectoryState.vue')['default']
- VehicleData: typeof import('./components/monitor/VehicleData.vue')['default']
- WeatherData: typeof import('./components/monitor/WeatherData.vue')['default']
- WeatherDataCopy: typeof import('./components/monitor/WeatherData-copy.vue')['default']
+ BaseCard: (typeof import('./components/BaseCard.vue'))['default'];
+ BaseMap: (typeof import('./components/map/BaseMap.vue'))['default'];
+ CardButton: (typeof import('./components/CardButton.vue'))['default'];
+ CardDialog: (typeof import('./components/CardDialog.vue'))['default'];
+ 'CardDialog copy': (typeof import('./components/CardDialog copy.vue'))['default'];
+ CheckButton: (typeof import('./components/common/CheckButton.vue'))['default'];
+ ConfigManage: (typeof import('./components/map/ConfigManage.vue'))['default'];
+ copy: (typeof import('./components/monitor/WeatherData_Old.vue'))['default'];
+ CoreHeader: (typeof import('./components/core/CoreHeader.vue'))['default'];
+ CoreMenu: (typeof import('./components/core/CoreMenu.vue'))['default'];
+ DataSummary: (typeof import('./components/monitor/DataSummary.vue'))['default'];
+ DataTable: (typeof import('./components/monitor/DataTable.vue'))['default'];
+ DescriptionsList: (typeof import('./components/list/DescriptionsList.vue'))['default'];
+ DescriptionsListItem: (typeof import('./components/list/DescriptionsListItem.vue'))['default'];
+ DeviceCreate: (typeof import('./components/device/DeviceCreate.vue'))['default'];
+ DeviceManage: (typeof import('./components/device/DeviceManage.vue'))['default'];
+ ElButton: (typeof import('element-plus/es'))['ElButton'];
+ ElCascader: (typeof import('element-plus/es'))['ElCascader'];
+ ElCheckbox: (typeof import('element-plus/es'))['ElCheckbox'];
+ ElCheckboxGroup: (typeof import('element-plus/es'))['ElCheckboxGroup'];
+ ElCol: (typeof import('element-plus/es'))['ElCol'];
+ ElConfigProvider: (typeof import('element-plus/es'))['ElConfigProvider'];
+ ElDatePicker: (typeof import('element-plus/es'))['ElDatePicker'];
+ ElDialog: (typeof import('element-plus/es'))['ElDialog'];
+ ElDivider: (typeof import('element-plus/es'))['ElDivider'];
+ ElDropdown: (typeof import('element-plus/es'))['ElDropdown'];
+ ElDropdownItem: (typeof import('element-plus/es'))['ElDropdownItem'];
+ ElDropdownMenu: (typeof import('element-plus/es'))['ElDropdownMenu'];
+ ElForm: (typeof import('element-plus/es'))['ElForm'];
+ ElFormItem: (typeof import('element-plus/es'))['ElFormItem'];
+ ElIcon: (typeof import('element-plus/es'))['ElIcon'];
+ ElInput: (typeof import('element-plus/es'))['ElInput'];
+ ElLink: (typeof import('element-plus/es'))['ElLink'];
+ ElOption: (typeof import('element-plus/es'))['ElOption'];
+ ElPagination: (typeof import('element-plus/es'))['ElPagination'];
+ ElPopover: (typeof import('element-plus/es'))['ElPopover'];
+ ElRadio: (typeof import('element-plus/es'))['ElRadio'];
+ ElRadioGroup: (typeof import('element-plus/es'))['ElRadioGroup'];
+ ElRow: (typeof import('element-plus/es'))['ElRow'];
+ ElScrollbar: (typeof import('element-plus/es'))['ElScrollbar'];
+ ElSelect: (typeof import('element-plus/es'))['ElSelect'];
+ ElSlider: (typeof import('element-plus/es'))['ElSlider'];
+ ElSpace: (typeof import('element-plus/es'))['ElSpace'];
+ ElStatistic: (typeof import('element-plus/es'))['ElStatistic'];
+ ElSwitch: (typeof import('element-plus/es'))['ElSwitch'];
+ ElTable: (typeof import('element-plus/es'))['ElTable'];
+ ElTableColumn: (typeof import('element-plus/es'))['ElTableColumn'];
+ ElTabPane: (typeof import('element-plus/es'))['ElTabPane'];
+ ElTabs: (typeof import('element-plus/es'))['ElTabs'];
+ ElTag: (typeof import('element-plus/es'))['ElTag'];
+ ElText: (typeof import('element-plus/es'))['ElText'];
+ FactorCheckbox: (typeof import('./components/monitor/FactorCheckbox.vue'))['default'];
+ FactorLegend: (typeof import('./components/monitor/FactorLegend.vue'))['default'];
+ FactorRadio: (typeof import('./components/monitor/FactorRadio.vue'))['default'];
+ FactorTrend: (typeof import('./components/monitor/FactorTrend.vue'))['default'];
+ GaugeChart: (typeof import('./components/chart/GaugeChart.vue'))['default'];
+ GridSearch: (typeof import('./components/grid/GridSearch.vue'))['default'];
+ HistoricalTrajectory: (typeof import('./components/animation/HistoricalTrajectory.vue'))['default'];
+ MapLocate: (typeof import('./components/map/MapLocate.vue'))['default'];
+ MapScene: (typeof import('./components/map/MapScene.vue'))['default'];
+ MapToolbox: (typeof import('./components/map/MapToolbox.vue'))['default'];
+ MessageBox: (typeof import('./components/MessageBox.vue'))['default'];
+ MissionEdit: (typeof import('./components/mission/MissionEdit.vue'))['default'];
+ MissionImport: (typeof import('./components/mission/MissionImport.vue'))['default'];
+ MissionManage: (typeof import('./components/mission/MissionManage.vue'))['default'];
+ OptionDevice: (typeof import('./components/search/OptionDevice.vue'))['default'];
+ OptionLocation: (typeof import('./components/search/OptionLocation.vue'))['default'];
+ OptionLocation2: (typeof import('./components/search/OptionLocation2.vue'))['default'];
+ OptionMission: (typeof import('./components/search/OptionMission.vue'))['default'];
+ OptionPollutionDegree: (typeof import('./components/search/OptionPollutionDegree.vue'))['default'];
+ OptionTime: (typeof import('./components/search/OptionTime.vue'))['default'];
+ OptionType: (typeof import('./components/search/OptionType.vue'))['default'];
+ ProgressLineChart: (typeof import('./components/chart/ProgressLineChart.vue'))['default'];
+ RealTimeLineChart: (typeof import('./components/chart/RealTimeLineChart.vue'))['default'];
+ RouterLink: (typeof import('vue-router'))['RouterLink'];
+ RouterView: (typeof import('vue-router'))['RouterView'];
+ SceneSearch: (typeof import('./components/scene/SceneSearch.vue'))['default'];
+ SceneTable: (typeof import('./components/scene/SceneTable.vue'))['default'];
+ SearchBar: (typeof import('./components/search/SearchBar.vue'))['default'];
+ SliderBar: (typeof import('./components/SliderBar.vue'))['default'];
+ TrajectoryState: (typeof import('./components/animation/TrajectoryState.vue'))['default'];
+ VehicleData: (typeof import('./components/monitor/VehicleData.vue'))['default'];
+ WeatherData: (typeof import('./components/monitor/WeatherData.vue'))['default'];
+ WeatherData_Old: (typeof import('./components/monitor/WeatherData_Old.vue'))['default'];
+ WeatherDataCopy: (typeof import('./components/monitor/WeatherData-copy.vue'))['default'];
}
export interface ComponentCustomProperties {
- vLoading: typeof import('element-plus/es')['ElLoadingDirective']
+ vLoading: (typeof import('element-plus/es'))['ElLoadingDirective'];
}
}
diff --git a/src/components/monitor/FactorIconText.vue b/src/components/monitor/FactorIconText.vue
new file mode 100644
index 0000000..0fbaede
--- /dev/null
+++ b/src/components/monitor/FactorIconText.vue
@@ -0,0 +1,72 @@
+<template>
+ <el-row justify="start" class="wrap">
+ <el-col :span="6">
+ <el-space direction="vertical" :size="0">
+ <font-awesome-icon v-if="faIcon" :icon="faIcon" class="fa-icon-size" />
+ <component v-if="elIcon" class="el-icon-size" :is="elIcon"></component>
+ <img v-if="img" :src="img" class="icon-size" />
+ <el-text class="factor-text">{{ label }}</el-text>
+ </el-space>
+ </el-col>
+ <el-col :span="18">
+ <el-space direction="vertical" :size="0">
+ <div>
+ <el-text class="factor-number">{{ value }}</el-text>
+ <el-text class="factor-unit"
+ ><sub>{{ unit }}</sub></el-text
+ >
+ </div>
+ <el-text class="factor-text">{{ des }}</el-text>
+ </el-space>
+ <!-- <div >
+ <el-text class="factor-number">{{ value }}</el-text>
+ <el-text class="factor-unit"
+ ><sub>{{ unit }}</sub></el-text
+ >
+ </div> -->
+ </el-col>
+ </el-row>
+</template>
+<script setup>
+defineProps({
+ faIcon: String,
+ elIcon: String,
+ img: String,
+ svg: String,
+ label: String,
+ value: String || Number,
+ unit: String,
+ des: String
+});
+</script>
+<style scoped>
+.wrap {
+ /* border: 1px solid white; */
+ width: 120px;
+}
+.factor-text {
+ color: whitesmoke;
+ font-size: 9px;
+}
+.factor-number {
+ color: whitesmoke;
+ font-size: 20px;
+ line-height: 30px;
+ padding-left: 2px;
+}
+.factor-unit {
+ color: whitesmoke;
+ font-size: 12px;
+ margin-left: 2px;
+}
+
+.fa-icon-size {
+ width: 26px;
+ height: 26px;
+ padding: 2px;
+}
+.el-icon-size {
+ width: 30px;
+ height: 30px;
+}
+</style>
diff --git a/src/components/monitor/FactorLegend.vue b/src/components/monitor/FactorLegend.vue
index bcd447d..caba203 100644
--- a/src/components/monitor/FactorLegend.vue
+++ b/src/components/monitor/FactorLegend.vue
@@ -1,44 +1,66 @@
<template>
- <BaseCard>
+ <transition
+ name="el-zoom-in-left"
+ @before-enter="onBeforeEnter"
+ @after-leave="onAfterLeave"
+ >
+ <BaseCard v-show="show">
+ <template #content>
+ <el-row justify="space-between" align="middle">
+ <el-row align="middle">
+ <img src="@/assets/mipmap/data_chart.png" class="ff-img m-r-4" />
+ <span>璧拌埅鍥句緥</span>
+ <span v-if="factor.factorName">锛坽{ factor.factorName }}锛�</span>
+ </el-row>
+ <span @click="show = !show" class="btn-show">
+ <el-icon v-if="show"><ArrowLeftBold /></el-icon>
+ <el-icon v-else><ArrowRightBold /></el-icon>
+ </span>
+ </el-row>
+ <div
+ v-for="(item, index) in legends"
+ :key="index"
+ class="flexbox align-items margin-top"
+ >
+ <div
+ class="rectangle"
+ :style="'background-color: ' + item.color"
+ ></div>
+ <el-row v-if="item.max">
+ <span class="w-40 text-right">{{ item.min }}</span>
+ <span class="w-20 text-center">~</span>
+ <span class="w-40 text-right">{{ item.max }}</span>
+ <span class="w-60 m-l-8">{{ item.unit }}</span>
+ </el-row>
+ <el-row v-else>
+ <span class="w-40 text-right"></span>
+ <span class="w-20 text-center">></span>
+ <span class="w-40 text-right">{{ item.min }}</span>
+ <span class="w-60 m-l-8">{{ item.unit }}</span>
+ </el-row>
+ </div>
+ <div>
+ 鍒囨崲缁樺浘妯″紡锛�
+ <el-switch
+ v-model="legendType"
+ width="60"
+ inline-prompt
+ style=""
+ active-text="鍔ㄦ��"
+ inactive-text="鏍囧噯"
+ @change="handleChange"
+ />
+ </div>
+ </template>
+ </BaseCard>
+ </transition>
+ <BaseCard v-show="btnShow">
<template #content>
- <el-row justify="space-between" align="middle">
- <el-row align="middle">
- <img src="@/assets/mipmap/data_chart.png" class="ff-img m-r-4" />
- <span>璧拌埅鍥句緥</span>
- </el-row>
- <span>{{ factor.factorName }}</span>
- </el-row>
- <div
- v-for="(item, index) in legends"
- :key="index"
- class="flexbox align-items margin-top"
- >
- <div class="rectangle" :style="'background-color: ' + item.color"></div>
- <el-row v-if="item.max">
- <span class="w-40 text-right">{{ item.min }}</span>
- <span class="w-20 text-center">~</span>
- <span class="w-40 text-right">{{ item.max }}</span>
- <span class="w-60 m-l-8">{{ item.unit }}</span>
- </el-row>
- <el-row v-else>
- <span class="w-40 text-right"></span>
- <span class="w-20 text-center">></span>
- <span class="w-40 text-right">{{ item.min }}</span>
- <span class="w-60 m-l-8">{{ item.unit }}</span>
- </el-row>
- </div>
- <div>
- 鍒囨崲缁樺浘妯″紡锛�
- <el-switch
- v-model="legendType"
- width="60"
- inline-prompt
- style=""
- active-text="鍔ㄦ��"
- inactive-text="鏍囧噯"
- @change="handleChange"
- />
- </div>
+ <span @click="show = !show" class="btn-show">
+ <img src="@/assets/mipmap/data_chart.png" class="ff-img m-r-4" />
+ <el-icon v-if="show"><ArrowLeftBold /></el-icon>
+ <el-icon v-else><ArrowRightBold /></el-icon>
+ </span>
</template>
</BaseCard>
</template>
@@ -60,7 +82,9 @@
return {
// 缁樺浘妯″紡锛宖alse: 鏍囧噯妯″紡锛泃rue锛氬姩鎬佹ā寮�
legendType: false,
- legends: []
+ legends: [],
+ show: true,
+ btnShow: false
};
},
watch: {
@@ -149,6 +173,12 @@
this.factor.max
);
});
+ },
+ onBeforeEnter() {
+ this.btnShow = false;
+ },
+ onAfterLeave() {
+ this.btnShow = true;
}
}
};
@@ -166,4 +196,10 @@
--el-switch-on-color: #1f9956;
--el-switch-off-color: #8b8b8b;
}
+.btn-show {
+ cursor: pointer;
+}
+.btn-show:hover {
+ color: #23dad1;
+}
</style>
diff --git a/src/components/monitor/FactorRadio.vue b/src/components/monitor/FactorRadio.vue
index e95e72d..e133e8e 100644
--- a/src/components/monitor/FactorRadio.vue
+++ b/src/components/monitor/FactorRadio.vue
@@ -1,11 +1,32 @@
<template>
- <BaseCard>
+ <transition
+ name="el-zoom-in-left"
+ @before-enter="onBeforeEnter"
+ @after-leave="onAfterLeave"
+ >
+ <BaseCard v-show="show" direction="left">
+ <template #content>
+ <!-- <el-collapse-transition> -->
+ <el-radio-group v-model="radio" size="default" @change="handleChange">
+ <el-radio v-for="(item, i) in options" :key="i" :value="item.value">{{
+ item.label
+ }}</el-radio>
+ </el-radio-group>
+ <!-- </el-collapse-transition> -->
+ <span @click="show = !show" class="btn-show">
+ <el-icon v-if="show"><ArrowLeftBold /></el-icon>
+ <el-icon v-else><ArrowRightBold /></el-icon>
+ </span>
+ </template>
+ </BaseCard>
+ </transition>
+ <BaseCard v-show="btnShow">
<template #content>
- <el-radio-group v-model="radio" size="default" @change="handleChange">
- <el-radio v-for="(item, i) in options" :key="i" :value="item.value">{{
- item.label
- }}</el-radio>
- </el-radio-group>
+ <el-row @click="show = !show" class="btn-show">
+ <font-awesome-icon icon="fa-check-circle" />
+ <el-icon v-if="show"><ArrowLeftBold /></el-icon>
+ <el-icon v-else><ArrowRightBold /></el-icon>
+ </el-row>
</template>
</BaseCard>
</template>
@@ -30,7 +51,9 @@
emits: ['change', 'update:modelValue'],
data() {
return {
- radio: defaultOptions(TYPE0).value
+ radio: defaultOptions(TYPE0).value,
+ show: true,
+ btnShow: false
};
},
computed: {
@@ -42,12 +65,12 @@
deviceType(nV, oV) {
if (nV != oV) {
this.radio = this.options[0].value;
- this.$emit('update:modelValue', this.radio)
+ this.$emit('update:modelValue', this.radio);
}
},
- modelValue(nV, oV){
+ modelValue(nV, oV) {
if (nV != oV) {
- this.radio = nV
+ this.radio = nV;
}
}
},
@@ -55,17 +78,31 @@
handleChange(value) {
const item = this.options.find((v) => v.value == value);
this.$emit('change', item.value, item);
- this.$emit('update:modelValue', item.value)
+ this.$emit('update:modelValue', item.value);
// todo 鍦板浘3d鍥惧儚鍒囨崲灞曠ず鐩戞祴鍥犲瓙
+ },
+ onBeforeEnter() {
+ this.btnShow = false;
+ },
+ onAfterLeave() {
+ this.btnShow = true;
}
}
};
</script>
<style scoped>
-.el-radio {
+:deep(.el-radio) {
--el-radio-text-color: white;
--el-color-primary: #23dad1;
margin-right: 10px;
height: initial;
}
+
+.btn-show {
+ cursor: pointer;
+ padding: 4px 0;
+}
+.btn-show:hover {
+ color: #23dad1;
+}
</style>
diff --git a/src/components/monitor/FactorTrend.vue b/src/components/monitor/FactorTrend.vue
index 8256d81..babe6f1 100644
--- a/src/components/monitor/FactorTrend.vue
+++ b/src/components/monitor/FactorTrend.vue
@@ -1,7 +1,8 @@
<template>
<BaseCard size="medium" direction="left">
<template #content>
- <el-scrollbar height="calc(49vh - var(--bevel-length-2))" always>
+ <DashBoard ref="dashBoardRef" :factor-datas="factorDatas"></DashBoard>
+ <el-scrollbar :height="height" always>
<div v-for="item in seriesList" :key="item.key">
<el-row
v-show="selectFactorType.includes(item.series.key)"
@@ -34,8 +35,10 @@
import { checkboxOptions } from '@/constant/checkbox-options';
import { factorName } from '@/constant/factor-name';
import { factorUnit } from '@/constant/factor-unit';
+import DashBoard from '@/views/realtimemode/component/DashBoard.vue';
export default {
+ components: { DashBoard },
props: {
loading: Boolean,
factorDatas: FactorDatas,
@@ -56,16 +59,13 @@
},
data() {
return {
+ height: 'calc(99vh - var(--bevel-length-2))',
xAxis: [],
allSeries: new Map(),
seriesList: []
};
},
- computed: {
- // factorTypes() {
- // return checkboxOptions(this.deviceType);
- // }
- },
+ computed: {},
watch: {
factorDatas: {
handler() {
@@ -165,7 +165,16 @@
getUnit(label) {
// fixeme 2024.5.15 淇CO灞曠ず鍗曚綅鍜屽師濮嬫暟鎹笉涓�鑷撮棶棰�
return label == 'CO' ? '渭g/m鲁' : factorUnit[label].unit;
+ },
+ calcHeight() {
+ const h1 = this.$refs.dashBoardRef
+ ? this.$refs.dashBoardRef.$el.offsetHeight
+ : 0;
+ this.height = `calc(98vh - var(--bevel-length-2) - ${h1}px)`;
}
+ },
+ mounted() {
+ this.calcHeight();
}
};
</script>
diff --git a/src/components/monitor/VehicleData.vue b/src/components/monitor/VehicleData.vue
index 7f7ff70..cef00bd 100644
--- a/src/components/monitor/VehicleData.vue
+++ b/src/components/monitor/VehicleData.vue
@@ -1,11 +1,25 @@
<template>
- <el-row justify="center" class="wrap">
+ <el-row justify="start" class="wrap">
+ <!-- <el-space direction="vertical" :size="0">
+ <el-icon size="30"><Stopwatch /></el-icon>
+ <el-text class="speed-text">SPD</el-text>
+ </el-space>
+ <div>
+ <el-text class="speed-number">{{ speed }}</el-text>
+ <el-text class="speed-unit"><sub>km/h</sub></el-text>
+ </div> -->
+ <FactorIconText
+ elIcon="Odometer"
+ label="SPD"
+ :value="speed"
+ unit="km/h"
+ ></FactorIconText>
<!-- <el-form :inline="true">
<el-form-item label="杞﹂�燂細" class="tag-2">
{{ speed }}km/h
</el-form-item>
</el-form> -->
- <GaugeChart name="杞﹂��" :value="speed"></GaugeChart>
+ <!-- <GaugeChart name="杞﹂��" :value="speed"></GaugeChart> -->
</el-row>
</template>
<script>
diff --git a/src/components/monitor/WeatherData-copy.vue b/src/components/monitor/WeatherData-copy.vue
deleted file mode 100644
index 6d53a7e..0000000
--- a/src/components/monitor/WeatherData-copy.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-<template>
- <el-row class="wrap">
- <el-form :inline="true" class="form">
- <el-form-item label="娓╁害锛�" class="w-tag">
- {{ temprature }}
- </el-form-item>
- <el-form-item label="婀垮害锛�" class="w-tag">
- {{ humidity }}
- </el-form-item>
- </el-form>
- <!-- <div class="w-tag">{{ temprature }}</div>
- <div class="w-tag">{{ humidity }}</div> -->
- </el-row>
- <el-row class="wrap">
- <el-form :inline="true" class="form">
- <el-form-item label="椋庡悜锛�" class="w-tag">
- {{ windDirection }}
- </el-form-item>
- <el-form-item label="椋庨�燂細" class="w-tag">
- {{ windSpeed }}
- </el-form-item>
- </el-form>
- <!-- <div class="w-tag">{{ windDirection }}</div>
- <div class="w-tag">{{ windSpeed }}</div> -->
- </el-row>
-</template>
-<script>
-import { FactorDatas } from '@/model/FactorDatas';
-
-export default {
- props: {
- loading: Boolean,
- factorDatas: FactorDatas
- },
- data() {
- return {
- temprature: '--鈩�',
- humidity: '--%',
- windDirection: '--',
- windSpeed: '--m/s',
- };
- },
- watch: {
- factorDatas: {
- handler(nV) {
- this.temprature = this.lastOne(nV, '8') + '鈩�';
- this.humidity = this.lastOne(nV, '9') + '%';
- this.windDirection = this.lastOne(nV, '17');
- this.windSpeed = this.lastOne(nV, '16') + 'm/s';
- },
- deep: true
- }
- },
- methods: {
- lastOne(factorDatas, key) {
- const f = factorDatas.factor[key];
- if (f) {
- const lastIndex = f.datas.length - 1;
- return factorDatas.factor[key].datas[lastIndex].factorData;
- } else {
- return '--';
- }
- }
- }
-};
-</script>
-<style scoped>
-.w-tag {
- padding: 2px 4px;
- /* background-color: green; */
- border: 1px solid white;
- border-radius: 2px;
- -moz-border-radius: 25px;
- width: 130px;
- /* Old Firefox */
-}
-
-.form {
- display: flex;
- gap: 4px;
-}
-
-.el-form-item {
- margin-bottom: 4px;
- margin-right: 0px !important;
-}
-</style>
diff --git a/src/components/monitor/WeatherData.vue b/src/components/monitor/WeatherData.vue
index af32269..c6614c1 100644
--- a/src/components/monitor/WeatherData.vue
+++ b/src/components/monitor/WeatherData.vue
@@ -1,32 +1,38 @@
<template>
- <el-row class="wrap">
- <el-form :inline="true" class="form">
- <el-form-item label="娓╁害锛�" class="w-tag">
- {{ temprature }}鈩�
- </el-form-item>
- <el-form-item label="婀垮害锛�" class="w-tag">
- {{ humidity }}%
- </el-form-item>
- </el-form>
- <!-- <div class="w-tag">{{ temprature }}</div>
- <div class="w-tag">{{ humidity }}</div> -->
- </el-row>
- <el-row class="wrap">
- <el-form :inline="true" class="form">
- <el-form-item label="椋庡悜锛�" class="w-tag">
- {{ _windDir }}
- </el-form-item>
- <el-form-item label="椋庨�燂細" class="w-tag">
- {{ windSpeed }}m/s
- </el-form-item>
- </el-form>
- <!-- <div class="w-tag">{{ windDirection }}</div>
- <div class="w-tag">{{ windSpeed }}</div> -->
- </el-row>
+ <div>
+ <el-row justify="space-between">
+ <FactorIconText
+ faIcon="fa-solid fa-temperature-half"
+ label="TEMP"
+ :value="temprature"
+ unit="鈩�"
+ ></FactorIconText>
+ <FactorIconText
+ faIcon="fa-droplet"
+ label="HUM"
+ :value="humidity"
+ unit="%"
+ ></FactorIconText>
+ </el-row>
+ <el-row justify="space-between" class="m-t-4">
+ <FactorIconText
+ img="/src/assets/wdr.svg"
+ label="WDR"
+ :value="_windDir"
+ ></FactorIconText>
+ <FactorIconText
+ faIcon="fa-wind"
+ label="WS"
+ :value="windSpeed"
+ unit="m/s"
+ ></FactorIconText>
+ </el-row>
+ </div>
</template>
<script>
import { FactorDatas } from '@/model/FactorDatas';
import { windDir } from '@/constant/wind-dir';
+import FactorIconText from './FactorIconText.vue';
export default {
props: {
diff --git a/src/components/monitor/WeatherData_Old.vue b/src/components/monitor/WeatherData_Old.vue
new file mode 100644
index 0000000..98acf23
--- /dev/null
+++ b/src/components/monitor/WeatherData_Old.vue
@@ -0,0 +1,106 @@
+<template>
+ <div>
+ <el-row class="wrap">
+ <el-form :inline="true" class="form">
+ <el-form-item label="娓╁害锛�" class="w-tag">
+ {{ temprature }}鈩�
+ </el-form-item>
+ <el-form-item label="婀垮害锛�" class="w-tag">
+ {{ humidity }}%
+ </el-form-item>
+ </el-form>
+ <!-- <div class="w-tag">{{ temprature }}</div>
+ <div class="w-tag">{{ humidity }}</div> -->
+ </el-row>
+ <el-row class="wrap">
+ <el-form :inline="true" class="form">
+ <el-form-item label="椋庡悜锛�" class="w-tag">
+ {{ _windDir }}
+ </el-form-item>
+ <el-form-item label="椋庨�燂細" class="w-tag">
+ {{ windSpeed }}m/s
+ </el-form-item>
+ </el-form>
+ <!-- <div class="w-tag">{{ windDirection }}</div>
+ <div class="w-tag">{{ windSpeed }}</div> -->
+ </el-row>
+ </div>
+</template>
+<script>
+import { FactorDatas } from '@/model/FactorDatas';
+import { windDir } from '@/constant/wind-dir';
+
+export default {
+ props: {
+ loading: Boolean,
+ factorDatas: FactorDatas,
+ temprature: {
+ type: String,
+ default: '--'
+ },
+ humidity: {
+ type: String,
+ default: '--'
+ },
+ windDirection: {
+ type: String,
+ default: '--'
+ },
+ windSpeed: {
+ type: String,
+ default: '--'
+ }
+ },
+ data() {
+ return {};
+ },
+ watch: {
+ factorDatas: {
+ handler(nV) {
+ // this.temprature = this.lastOne(nV, '8') + '鈩�';
+ // this.humidity = this.lastOne(nV, '9') + '%';
+ // this.windDirection = this.lastOne(nV, '17');
+ // this.windSpeed = this.lastOne(nV, '16') + 'm/s';
+ },
+ deep: true
+ }
+ },
+ computed: {
+ _windDir() {
+ return windDir(this.windDirection);
+ }
+ },
+ methods: {
+ lastOne(factorDatas, key) {
+ const f = factorDatas.factor[key];
+ if (f) {
+ const lastIndex = f.datas.length - 1;
+ return factorDatas.factor[key].datas[lastIndex].factorData;
+ } else {
+ return '--';
+ }
+ }
+ }
+};
+</script>
+<style scoped>
+.w-tag {
+ padding: 2px 4px;
+ /* background-color: green; */
+ border: 1px solid white;
+ border-radius: 2px;
+ -moz-border-radius: 25px;
+ width: 130px;
+ /* Old Firefox */
+}
+
+.form {
+ display: flex;
+ gap: 4px;
+}
+
+.el-form-item {
+ margin-bottom: 4px;
+ margin-right: 0px !important;
+}
+</style>
diff --git a/src/styles/animation.scss b/src/styles/animation.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/styles/animation.scss
diff --git a/src/styles/index.scss b/src/styles/index.scss
index 23285cd..7f53a8b 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -1,2 +1,6 @@
@use './base.scss';
@use './elementUI.scss';
+
+body {
+ font-family: fantasy;
+}
diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue
index 2ced9f5..5e72264 100644
--- a/src/views/historymode/HistoryMode.vue
+++ b/src/views/historymode/HistoryMode.vue
@@ -28,7 +28,6 @@
:factor="factorDatas.factor[factorType]"
@change="handleLegendTypeChange"
></FactorLegend>
- <!-- <SourceTrace></SourceTrace> -->
</el-row>
<el-row class="historical" justify="center">
<HistoricalTrajectory
@@ -53,6 +52,13 @@
:device-type="deviceType"
:device-code="deviceCode"
></DataSheet>
+ <SourceTrace
+ class="source-trace"
+ v-model:factorType="factorType"
+ direction="right"
+ mode="history"
+ :mission-code="missionCode"
+ ></SourceTrace>
</div>
</template>
@@ -87,6 +93,7 @@
},
data() {
return {
+ missionCode: undefined,
// 鐩戞祴璁惧绫诲瀷
deviceType: TYPE0,
// 鐩戞祴璁惧缂栧彿
@@ -227,6 +234,7 @@
this.deviceType = deviceType;
this.deviceCode = deviceCode;
this.mission = mission;
+ this.missionCode = mission.missionCode;
let startTime, endTime;
if (timeArray && timeArray.length == 2) {
startTime = moment(timeArray[0]).format('YYYY-MM-DD HH:mm:ss');
@@ -307,4 +315,9 @@
left: 0;
right: 0;
}
+.source-trace {
+ position: absolute;
+ right: 0;
+ bottom: 0px;
+}
</style>
diff --git a/src/views/realtimemode/RealtimeMode.vue b/src/views/realtimemode/RealtimeMode.vue
index 6935614..9eb4352 100644
--- a/src/views/realtimemode/RealtimeMode.vue
+++ b/src/views/realtimemode/RealtimeMode.vue
@@ -19,7 +19,7 @@
</el-col>
<el-col span="1"> </el-col>
</el-row>
- <DashBoard class="dash-board" :factor-datas="factorDatas"></DashBoard>
+ <!-- <DashBoard class="dash-board" :factor-datas="factorDatas"></DashBoard> -->
<RealTimeTrend
class="real-time-trend"
:factor-datas="factorDatas"
@@ -28,6 +28,7 @@
<SourceTrace
class="source-trace"
v-model:factorType="factorType"
+ :deviceCode="deviceCode"
></SourceTrace>
<!-- <PollutedClueItem></PollutedClueItem> -->
</div>
@@ -219,7 +220,7 @@
<style scoped>
.dash-board {
position: absolute;
- left: 0;
+ right: 0;
bottom: 0px;
}
.real-time-trend {
@@ -229,7 +230,7 @@
}
.source-trace {
position: absolute;
- right: 0;
+ left: 0;
bottom: 0px;
}
</style>
diff --git a/src/views/realtimemode/component/DashBoard.vue b/src/views/realtimemode/component/DashBoard.vue
index 30c87e6..00e6ccc 100644
--- a/src/views/realtimemode/component/DashBoard.vue
+++ b/src/views/realtimemode/component/DashBoard.vue
@@ -1,26 +1,42 @@
<template>
- <el-row class="wrap">
- <el-col v-show="show" span="10">
- <BaseCard>
- <template #content>
- <WeatherData
- :factor-datas="factorDatas"
- :temprature="temprature"
- :humidity="humidity"
- :wind-direction="windDirection"
- :wind-speed="windSpeed"
- ></WeatherData>
- <VehicleData :factor-datas="factorDatas" :speed="speed"></VehicleData>
- <el-row justify="center">
- <div class="tag-time">鏃堕棿锛歿{ time }}</div>
- </el-row>
- </template>
- </BaseCard>
- </el-col>
- <el-col span="2">
- <CardButton name="瀹炴椂鐩戞祴" @click="() => (show = !show)"></CardButton>
- </el-col>
- </el-row>
+ <div>
+ <!-- <el-row justify="end">
+ <el-text class="tag-time" size="default">
+ <el-icon><Timer /></el-icon>
+ {{ time }}
+ </el-text>
+ </el-row> -->
+ <el-row class="dash-wrap">
+ <el-col :span="8">
+ <FactorIconText
+ elIcon="Timer"
+ label="TIME"
+ :value="hms"
+ :des="date"
+ ></FactorIconText>
+ <VehicleData
+ :factor-datas="factorDatas"
+ :speed="speed"
+ class="m-t-4"
+ ></VehicleData>
+ <!-- <el-text class="tag-time" size="default">
+ <el-icon><Timer /></el-icon>
+ {{ time }}
+ </el-text> -->
+ </el-col>
+ <el-col :span="16">
+ <WeatherData
+ :factor-datas="factorDatas"
+ :temprature="temprature"
+ :humidity="humidity"
+ :wind-direction="windDirection"
+ :wind-speed="windSpeed"
+ ></WeatherData>
+ </el-col>
+ </el-row>
+ <!-- <el-row justify="center"> -->
+ <!-- </el-row> -->
+ </div>
</template>
<script>
import { FactorDatas } from '@/model/FactorDatas';
@@ -41,7 +57,9 @@
windDirection: '--',
windSpeed: '--',
speed: '0',
- time: '----/--/--'
+ time: '----/--/--',
+ date: '----/--/--',
+ hms: '--:--:--'
};
},
methods: {
@@ -61,6 +79,8 @@
this.windSpeed = this.getFactorData(factorDatas, index, '16') + '';
this.speed = this.getFactorData(factorDatas, index, '14', 1);
this.time = factorDatas.times[index];
+ this.date = this.time.split(' ')[0];
+ this.hms = this.time.split(' ')[1];
}
},
mounted() {
@@ -69,10 +89,14 @@
};
</script>
<style scoped>
+.dash-wrap {
+ border-bottom: 1px solid rgba(255, 255, 255, 0.445);
+}
.tag-time {
+ color: rgba(255, 255, 255, 0.815);
padding: 2px 4px;
- border: 1px solid white;
+ /* border: 1px solid white;
border-radius: 2px;
- -moz-border-radius: 25px;
+ -moz-border-radius: 25px; */
}
</style>
diff --git a/src/views/realtimemode/component/DashBoard_Old.vue b/src/views/realtimemode/component/DashBoard_Old.vue
new file mode 100644
index 0000000..30c87e6
--- /dev/null
+++ b/src/views/realtimemode/component/DashBoard_Old.vue
@@ -0,0 +1,78 @@
+<template>
+ <el-row class="wrap">
+ <el-col v-show="show" span="10">
+ <BaseCard>
+ <template #content>
+ <WeatherData
+ :factor-datas="factorDatas"
+ :temprature="temprature"
+ :humidity="humidity"
+ :wind-direction="windDirection"
+ :wind-speed="windSpeed"
+ ></WeatherData>
+ <VehicleData :factor-datas="factorDatas" :speed="speed"></VehicleData>
+ <el-row justify="center">
+ <div class="tag-time">鏃堕棿锛歿{ time }}</div>
+ </el-row>
+ </template>
+ </BaseCard>
+ </el-col>
+ <el-col span="2">
+ <CardButton name="瀹炴椂鐩戞祴" @click="() => (show = !show)"></CardButton>
+ </el-col>
+ </el-row>
+</template>
+<script>
+import { FactorDatas } from '@/model/FactorDatas';
+import { realTimeMapAnimation } from '@/utils/map/animation';
+
+export default {
+ props: {
+ deviceType: {
+ type: String
+ },
+ factorDatas: FactorDatas
+ },
+ data() {
+ return {
+ show: true,
+ temprature: '--',
+ humidity: '--',
+ windDirection: '--',
+ windSpeed: '--',
+ speed: '0',
+ time: '----/--/--'
+ };
+ },
+ methods: {
+ getFactorData(factorDatas, index, key, scale = 10) {
+ const _factor = factorDatas.factor[key];
+ if (_factor != undefined) {
+ let d = _factor.datas[index].factorData;
+ return Math.round(d * scale) / scale;
+ } else {
+ return '--';
+ }
+ },
+ refresh(factorDatas, index) {
+ this.temprature = this.getFactorData(factorDatas, index, '8') + '';
+ this.humidity = this.getFactorData(factorDatas, index, '9') + '';
+ this.windDirection = this.getFactorData(factorDatas, index, '17') + '';
+ this.windSpeed = this.getFactorData(factorDatas, index, '16') + '';
+ this.speed = this.getFactorData(factorDatas, index, '14', 1);
+ this.time = factorDatas.times[index];
+ }
+ },
+ mounted() {
+ realTimeMapAnimation.setOnEachFrameCallback(this.refresh);
+ }
+};
+</script>
+<style scoped>
+.tag-time {
+ padding: 2px 4px;
+ border: 1px solid white;
+ border-radius: 2px;
+ -moz-border-radius: 25px;
+}
+</style>
diff --git a/src/views/sourcetrace/SourceTrace.vue b/src/views/sourcetrace/SourceTrace.vue
index 0145b9a..19012f9 100644
--- a/src/views/sourcetrace/SourceTrace.vue
+++ b/src/views/sourcetrace/SourceTrace.vue
@@ -1,11 +1,11 @@
<template>
<el-row>
- <el-col span="2" class="flex-col">
+ <el-col v-if="direction == 'right'" span="2" class="flex-col">
<el-row justify="end">
<CardButton
direction="left"
name="鍔ㄦ�佹函婧�"
- @click="() => (show = !show)"
+ @click="handleDisplayChange"
></CardButton>
</el-row>
<el-row class="flex-col">
@@ -57,6 +57,21 @@
</template>
</BaseCard>
</el-col>
+ <el-col v-if="direction == 'left'" span="2" class="flex-col">
+ <el-row justify="start">
+ <CardButton
+ direction="right"
+ name="鍔ㄦ�佹函婧�"
+ @click="handleDisplayChange"
+ ></CardButton>
+ </el-row>
+ <el-row class="flex-col">
+ <PollutedExceptionItem
+ :item="selectedException"
+ @showMarksAndPolygon="showMarksAndPolygon"
+ ></PollutedExceptionItem>
+ </el-row>
+ </el-col>
<PollutedClueItem
v-model="clueDialog"
:item="selectedClue"
@@ -72,6 +87,7 @@
import moment from 'moment';
import websocket from '@/api/websocket';
+import dataAnalysisApi from '@/api/dataAnalysisApi';
import sector from '@/utils/map/sector';
import mapUtil from '@/utils/map/util';
import { sceneTypes, sceneIcon } from '@/constant/scene-types';
@@ -88,14 +104,25 @@
const NO_SCENE = 'no_scene';
+const MODE_REALTIME = 'realtime';
+const MODE_HISTORY = 'history';
+
const props = defineProps({
- factorType: String
+ direction: {
+ type: String,
+ default: 'left'
+ },
+ factorType: String,
+ // 妯″紡锛宺ealtime锛氬疄鏃舵ā寮忥紱history锛氬巻鍙叉暟鎹ā寮�
+ mode: {
+ type: String,
+ default: 'realtime'
+ },
+ missionCode: String,
+ deviceCode: String
});
const emits = defineEmits(['update:factorType']);
-
-const height = `30vh`;
-const width = `60vh`;
const show = ref(false);
const clueDialog = ref(false);
@@ -110,6 +137,17 @@
const selectedSceneTypes = ref([]);
const sceneOptions = ref([]);
+function handleDisplayChange() {
+ show.value = !show.value;
+ if (
+ !show.value &&
+ selectedException.value &&
+ selectedException.value.showMore
+ ) {
+ showMarksAndPolygon(selectedException.value);
+ }
+}
+
function scrollToBottom() {
const h1 = scrollContentRef.value.clientHeight + 100;
setTimeout(() => {
@@ -123,9 +161,9 @@
}, 100);
}
-const streams = reactive([]);
+const streams = ref([]);
const filterStreams = computed(() => {
- return streams.filter((v) => {
+ return streams.value.filter((v) => {
// 鍒ゆ柇娑堟伅绫诲瀷鏄惁閫変腑
const b1 = selectedMsgTypes.value.indexOf(v._type) != -1;
let b2, b3;
@@ -163,7 +201,7 @@
type2: 0,
type3: 0
};
- streams.forEach((v) => {
+ streams.value.forEach((v) => {
switch (v._type) {
case '1':
count.type1++;
@@ -187,10 +225,15 @@
function dealMsg(data) {
const { type, content } = websocketMsgParser.parseMsg(data);
const obj = reactive(JSON.parse(content));
- obj._type = type;
+ if (obj.deviceCode == props.deviceCode) {
+ obj._type = type;
+ dealObj(obj);
+ }
+}
+function dealObj(obj) {
// 姹℃煋绾跨储 PollutedClue
- if (type == '1') {
+ if (obj._type == '1') {
obj.showMore = false;
console.log('姹℃煋寮傚父鍒囩墖: ', obj);
@@ -201,13 +244,13 @@
// scrollToTop();
// drawPolygon(obj.pollutedArea);
parseChartData(obj);
- } else if (type == '2') {
+ } else if (obj._type == '2') {
// const obj = JSON.parse(content);
// obj._type = type;
console.log('姹℃煋绾跨储缁撴灉: ', obj);
obj._timestr = timeFormatter(obj.time);
addNewMsg(obj);
- } else if (type == '3') {
+ } else if (obj._type == '3') {
console.log('姹℃煋鎻愰啋鍒囩墖: ', obj);
addNewMsg(obj);
parseChartData(obj);
@@ -264,7 +307,7 @@
const leftMsgList = [];
function addNewMsg(msg, inside) {
if (!addNewMsgTask && (leftMsgList.length == 0 || inside)) {
- streams.splice(0, 0, msg);
+ streams.value.splice(0, 0, msg);
addNewMsgTask = setTimeout(() => {
clearTimeout(addNewMsgTask);
addNewMsgTask = undefined;
@@ -278,8 +321,32 @@
}
}
+function fetchPollutionTraceHistory() {
+ dataAnalysisApi.fetchPollutionTraceHistory(props.missionCode).then((res) => {
+ const objList = JSON.parse(res.data);
+ objList.forEach((obj) => {
+ obj._type = obj.msgType + '';
+ if (obj._type == '1') {
+ obj.showMore = false;
+ show.value = true;
+ parseChartData(obj);
+ } else if (obj._type == '2') {
+ obj._timestr = timeFormatter(obj.time);
+ } else if (obj._type == '3') {
+ parseChartData(obj);
+ }
+ optionsFilte(obj);
+ });
+ streams.value = objList;
+ });
+}
+
onMounted(() => {
- websocket.registerReceiveEvent(dealMsg);
+ if (props.mode == MODE_REALTIME) {
+ websocket.registerReceiveEvent(dealMsg);
+ } else if (props.missionCode) {
+ fetchPollutionTraceHistory();
+ }
});
onUnmounted(() => {
websocket.removeReceiveEvent(dealMsg);
@@ -296,6 +363,15 @@
selectedClue.value._selected = false;
}
});
+
+watch(
+ () => props.missionCode,
+ (nV, oV) => {
+ if (nV != oV) {
+ fetchPollutionTraceHistory();
+ }
+ }
+);
function handleOpen(item) {
switch (item._type) {
@@ -319,7 +395,7 @@
}
function hideAll() {
- streams.forEach((s) => {
+ streams.value.forEach((s) => {
if (polygonMap.has(s.guid)) {
s.showMore = false;
map.remove(polygonMap.get(s.guid));
@@ -368,6 +444,12 @@
function parseChartData(obj) {
// console.log('鎶樼嚎鍥撅細start');
+ obj.pollutedData._startTime = moment(obj.pollutedData.startTime).format(
+ 'HH:mm:ss'
+ );
+ obj.pollutedData._endTime = moment(obj.pollutedData.endTime).format(
+ 'HH:mm:ss'
+ );
const factorDatas = new FactorDatas();
factorDatas.setData(obj.pollutedData.historyDataList, 0, () => {
obj._chartOptions = factorDataParser.parseData(factorDatas, [
@@ -383,101 +465,6 @@
function timeFormatter(time) {
return moment(time).format('YYYY-MM-DD HH:mm:ss');
-}
-
-/******************************************************************************************************************** */
-
-/**
- * 娣诲姞涓�鏉″伐浣滄祦淇℃伅
- * @param {*} data
- */
-const putWorkStream = (data) => {
- data.substring();
- const obj = JSON.parse(data);
- console.log('sourcetrace: ', obj);
-
- obj._statusStr = exceptionStatus(obj.status);
-
- if (streams.length == 0) {
- streams.push(obj);
- } else {
- const index = streams.findIndex((v) => {
- return v.guid == obj.guid;
- });
- if (index != -1) {
- const old = streams[index];
- obj.showMore = old.showMore;
- old.relatedSceneList.forEach((s) => {
- const index = obj.relatedSceneList.findIndex((v) => {
- return v.guid == s.guid;
- });
- if (index == -1) {
- obj.relatedSceneList.push(s);
- }
- });
- streams.splice(index, 1, obj);
- } else {
- streams.unshift(obj);
- }
-
- show.value = true;
- }
-
- // scrollToBottom();
- scrollToTop();
-
- const excObj = streams.find((v) => {
- return v.factorId + '' == props.factorType;
- });
- if (excObj) {
- drawSector(excObj);
- }
-};
-
-function exceptionStatus(value) {
- switch (value) {
- case 1:
- return '寮傚父鍙戠敓涓�';
- case 2:
- return '寮傚父宸茬粨鏉�';
- default:
- return '寮傚父宸茬粨鏉�';
- }
-}
-
-let lastDrawObjGuid;
-function drawSector(exceptionObj) {
- emits('update:factorType', exceptionObj.factorId + '');
- setTimeout(() => {
- if (exceptionObj.guid != lastDrawObjGuid) {
- sector.clearSectorPt();
- lastDrawObjGuid = exceptionObj.guid;
- }
- // 1. 缁樺埗鏂版墖褰㈠尯鍩�
- const datavo = exceptionObj.midData;
- const factorDatas = new FactorDatas();
- factorDatas.setData([datavo], 0, () => {
- const pr = sector.drawSectorPt(factorDatas, 0);
- // 璋冩暣瑙嗚灞呬腑鏄剧ず
- // mapUtil.setCenter(pr.p);
- drawMarks(exceptionObj.relatedSceneList);
- });
- }, 1000);
-}
-
-let layer = undefined;
-function drawMarks(sceneList) {
- if (layer != undefined) {
- mapUtil.removeViews(layer);
- // layer = undefined;
- }
- if (sceneList.length != 0) {
- const icons = [];
- sceneList.forEach((s) => {
- icons.push(sceneIcon(s.typeId));
- });
- layer = marks.createLabelMarks(icons, sceneList, true);
- }
}
</script>
<style scoped>
@@ -512,7 +499,7 @@
.scrollbar {
width: 400px;
/* max-width: 60vw; */
- height: 45vh;
+ height: 65vh;
/* color: #02ffea; */
padding-right: 10px;
}
diff --git a/src/views/sourcetrace/component/ClueRecordItem.vue b/src/views/sourcetrace/component/ClueRecordItem.vue
index a8aecbb..5237bb5 100644
--- a/src/views/sourcetrace/component/ClueRecordItem.vue
+++ b/src/views/sourcetrace/component/ClueRecordItem.vue
@@ -12,7 +12,9 @@
<el-text type="primary" size="default">
<el-icon><Timer /></el-icon>
{{
- item.pollutedData.startTime + ' - ' + item.pollutedData.endTime
+ item.pollutedData._startTime +
+ ' - ' +
+ item.pollutedData._endTime
}}
</el-text>
</el-space>
@@ -22,6 +24,7 @@
<el-tag
effect="plain"
type="info"
+ style="color: black"
size="small"
hit
round
@@ -64,7 +67,10 @@
<el-tag type="danger" effect="dark" size="small">绾跨储</el-tag>
<el-link type="primary" @click="emits('open')"> 璇︽儏 </el-link>
</el-row>
- <el-text type="danger">{{ item.advice }}</el-text>
+ <el-space>
+ <el-icon color="#F56C6C" :size="40"><WarnTriangleFilled /></el-icon>
+ <el-text type="primary">{{ item.advice }}</el-text>
+ </el-space>
</div>
<el-row v-else-if="item._type == '3'">
<el-col :span="3">
@@ -76,17 +82,20 @@
<el-text type="primary" size="default">
<el-icon><Timer /></el-icon>
{{
- item.pollutedData.startTime + ' - ' + item.pollutedData.endTime
+ item.pollutedData._startTime +
+ ' - ' +
+ item.pollutedData._endTime
}}
</el-text>
</el-space>
- <el-link type="primary" @click="emits('open', item)"> 璇︽儏 </el-link>
+ <!-- <el-link type="primary" @click="emits('open', item)"> 璇︽儏 </el-link> -->
</el-row>
<div>
<el-tag
effect="plain"
type="info"
size="small"
+ style="color: black"
hit
round
class="m-r-4"
@@ -158,7 +167,7 @@
function formatDistanceType(value) {
switch (value) {
case 'TYPE1':
- return '50绫充互鍐�';
+ return '100绫充互鍐�';
case 'TYPE2':
return '50绫� - 500绫充互鍐�';
case 'TYPE3':
diff --git a/src/views/sourcetrace/component/PollutedExceptionItem.vue b/src/views/sourcetrace/component/PollutedExceptionItem.vue
index 0aeedff..9351fb8 100644
--- a/src/views/sourcetrace/component/PollutedExceptionItem.vue
+++ b/src/views/sourcetrace/component/PollutedExceptionItem.vue
@@ -27,9 +27,9 @@
<el-icon><Timer /></el-icon>
{{
'鍒囩墖鏃舵锛�' +
- item.pollutedData.startTime +
+ item.pollutedData._startTime +
' - ' +
- item.pollutedData.endTime
+ item.pollutedData._endTime
}}
</el-text>
</div>
@@ -46,7 +46,7 @@
</div> -->
<div>
<el-text type="primary">
- <el-icon><BellFilled /></el-icon>
+ <el-icon><Bell /></el-icon>
寮傚父绫诲瀷锛歿{ item.pollutedData.exception }}
</el-text>
</div>
@@ -105,7 +105,8 @@
></RealTimeLineChart>
<!-- </div> -->
<div class="border-dashed">
- <el-text type="" tag="mark">
+ <el-icon color="#ffbc58" size="20"><WarningFilled /></el-icon>
+ <el-text type="primary" tag="b">
{{ item.pollutedSource.conclusion }}
</el-text>
</div>
@@ -113,57 +114,6 @@
:show-marks="item.showMore"
:scene-list="item.pollutedSource.sceneList"
></SceneTable>
-
- <!-- <el-space gap="4">
- <el-tag :type="item.status == 1 ? 'danger' : 'info'">{{
- item._statusStr
- }}</el-tag>
- <el-text type="default">{{ item.exception }}</el-text>
- </el-space>
- <el-row gap="4">
- <el-text type="primary">鍙戠敓鏃堕棿锛�</el-text>
- <el-text type="primary">{{
- item.startTime + ' 鑷� '
- }}</el-text>
- <el-text type="primary">{{
- item.status == 1 ? '褰撳墠' : item.endTime
- }}</el-text>
- </el-row>
- <el-row>
- <el-col :span="6">
- <el-statistic title="鍥犲瓙" :value="item.factorName" />
- </el-col>
- <el-col :span="6">
- <el-statistic title="鍧囧��" :value="item.avg" />
- </el-col>
- <el-col :span="6">
- <el-statistic title="宄板��" :value="item.max" />
- </el-col>
- <el-col :span="6">
- <el-statistic title="璋峰��" :value="item.min" />
- </el-col>
- </el-row>
- <el-row justify="space-between">
- <el-link
- type="primary"
- @click="item.showMore = !item.showMore"
- >
- {{
- (item.showMore ? '鏀惰捣婧簮鍦烘櫙' : '鏌ョ湅婧簮鍦烘櫙') +
- '锛�' +
- item.relatedSceneList.length +
- '锛�'
- }}
- </el-link>
- <el-link type="primary" @click="drawSector(item)">
- 鏌ョ湅寮傚父
- </el-link>
- </el-row>
- <SceneTable
- v-show="item.showMore"
- :scene-list="item.relatedSceneList"
- ></SceneTable>
- <el-divider /> -->
</el-scrollbar>
</template>
</BaseCard>
@@ -233,13 +183,15 @@
padding: 0 4px;
/* margin-right: 2px; */
width: 340px;
- height: 35vh;
- border-right: 1px solid white;
+ height: 400px;
+ /* border-right: 1px solid white; */
border-radius: 2px;
}
.border-dashed {
/* border: 1px dashed white; */
+ display: flex;
+ /* align-items: center; */
border: 1px dashed #ffbc58;
padding: 0px 1px;
margin-bottom: 4px;
--
Gitblit v1.9.3