From 306ef09707d6bcf9ffa67de55f86ab6f4362deee Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期五, 18 七月 2025 10:04:01 +0800
Subject: [PATCH] 2025.7.18 动态溯源-测试版本
---
src/utils/chart/chart-option.js | 34 ++++++
src/views/sourcetrace/SourceTrace.vue | 100 ++++++++++++-------
src/views/historymode/HistoryMode.vue | 10 +
src/views/sourcetrace/component/PollutedWarnItem.vue | 41 +++++++
src/api/index.js | 24 ++--
src/views/sourcetrace/component/PollutedExceptionItem.vue | 36 +++++--
src/components.d.ts | 2
src/views/sourcetrace/component/ClueRecordItem.vue | 4
src/components/chart/RealTimeLineChart.vue | 10 +
9 files changed, 190 insertions(+), 71 deletions(-)
diff --git a/src/api/index.js b/src/api/index.js
index efcd5a1..fb3b440 100644
--- a/src/api/index.js
+++ b/src/api/index.js
@@ -2,7 +2,7 @@
import { ElMessage } from 'element-plus';
const openLog = false;
-const debug = true;
+const debug = false;
let ip1 = 'http://47.100.191.150:9029/';
let ws = `47.100.191.150:9030`;
@@ -30,13 +30,13 @@
i.interceptors.request.use(
function (config) {
// 鍦ㄥ彂閫佽姹備箣鍓嶅仛浜涗粈涔�
- if (import.meta.env.DEV && openLog) {
- console.log('==>璇锋眰寮�濮�');
- console.log(`${config.baseURL}${config.url}`);
- if (config.data) {
- console.log('==>璇锋眰鏁版嵁', config.data);
- }
- }
+ // if (import.meta.env.DEV && openLog) {
+ // console.log('==>璇锋眰寮�濮�');
+ // console.log(`${config.baseURL}${config.url}`);
+ // if (config.data) {
+ // console.log('==>璇锋眰鏁版嵁', config.data);
+ // }
+ // }
return config;
},
function (error) {
@@ -59,8 +59,12 @@
// 2xx 鑼冨洿鍐呯殑鐘舵�佺爜閮戒細瑙﹀彂璇ュ嚱鏁般��
// 瀵瑰搷搴旀暟鎹仛鐐逛粈涔�
if (import.meta.env.DEV && openLog) {
- console.log(response);
- console.log('==>璇锋眰缁撴潫');
+ console.log('|------------------------------------------');
+ console.log('|--璇锋眰: ', `${response.request.responseURL}`);
+ if (response.config.data) {
+ console.log('|--鏁版嵁: ', response.config.data);
+ }
+ console.log('|--缁撴灉: ', response.data);
}
if (response.status == 200) {
if (
diff --git a/src/components.d.ts b/src/components.d.ts
index 80dc883..fa422c5 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -14,7 +14,6 @@
'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']
@@ -39,6 +38,7 @@
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
+ ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
diff --git a/src/components/chart/RealTimeLineChart.vue b/src/components/chart/RealTimeLineChart.vue
index cc72183..bd75435 100644
--- a/src/components/chart/RealTimeLineChart.vue
+++ b/src/components/chart/RealTimeLineChart.vue
@@ -9,7 +9,7 @@
</template>
<script>
import * as echarts from 'echarts';
-import { smallLineOption } from '@/utils/chart/chart-option';
+import { smallLineOption, baseVisualMap } from '@/utils/chart/chart-option';
export default {
props: {
@@ -31,7 +31,9 @@
yMinInterval: {
type: Number,
default: 1
- }
+ },
+ // 寮傚父鏁版嵁绱㈠紩鑼冨洿闆嗗悎锛孾[i1,i2], [i3,i4],...]
+ exceptionIndexArr: Array
},
data() {
return {
@@ -52,6 +54,10 @@
const { xAxis, series } = this.modelValue;
if (!this.option) {
this.option = smallLineOption(xAxis, series, this.yMinInterval);
+ if (this.exceptionIndexArr) {
+ const visualMap = baseVisualMap(this.exceptionIndexArr);
+ this.option.visualMap = visualMap;
+ }
} else {
this.option.xAxis[0].data = xAxis;
this.option.series = series;
diff --git a/src/utils/chart/chart-option.js b/src/utils/chart/chart-option.js
index 99337d0..3395e29 100644
--- a/src/utils/chart/chart-option.js
+++ b/src/utils/chart/chart-option.js
@@ -14,6 +14,38 @@
return fontSize;
}
+function baseVisualMap(area) {
+ const _pieces = [];
+ area.forEach((v, i) => {
+ // if (i == 0) {
+ // _pieces.push({
+ // lt: v[0],
+ // color: 'green'
+ // });
+ // }
+ _pieces.push({
+ gte: v[0],
+ lte: v[1],
+ color: 'red'
+ });
+ });
+ // const lastOne = area[area.length - 1];
+ // _pieces.push({
+ // gt: lastOne[1],
+ // color: 'green'
+ // });
+ return {
+ type: 'piecewise',
+ // type: 'continuous',
+ show: false,
+ dimension: 0,
+ pieces: _pieces,
+ outOfRange: {
+ color: ['#5470c6']
+ }
+ };
+}
+
// 鎶樼嚎鍥�
function factorLineOption(_xAxis, _series) {
var fontSize = fGetChartFontSize();
@@ -301,4 +333,4 @@
return option;
}
-export { factorLineOption, smallLineOption, gaugeOption };
+export { factorLineOption, smallLineOption, gaugeOption, baseVisualMap };
diff --git a/src/views/historymode/HistoryMode.vue b/src/views/historymode/HistoryMode.vue
index 2865dec..452fc0d 100644
--- a/src/views/historymode/HistoryMode.vue
+++ b/src/views/historymode/HistoryMode.vue
@@ -126,7 +126,7 @@
factorType(nValue, oValue) {
if (nValue != oValue && this.status == 0) {
Layer.clear();
- this.draw();
+ this.draw(true);
// this.drawHighlightPollution();
}
}
@@ -169,13 +169,17 @@
done();
this.draw();
},
- draw() {
+ draw(notSetBound) {
// 鍒锋柊鍥句緥
const factor = this.factorDatas.factor[this.factorType];
sector.clearSector();
// this.drawRoadLine(factor);
this.drawRoadMap(factor);
this.drawMassMarks(factor);
+ // 璋冩暣鍦板浘瑙嗚
+ if (!notSetBound) {
+ mapUtil.setBound(this.factorDatas.lnglats_GD);
+ }
},
// 缁樺埗3D璧拌璺嚎鍥�
drawRoadMap(e) {
@@ -190,8 +194,6 @@
marks.drawMassMarks(this.factorDatas, e, (index) => {
this.handelIndexChange(index);
});
- // 璋冩暣鍦板浘瑙嗚
- mapUtil.setBound(this.factorDatas.lnglats_GD);
},
drawSector(index) {
// 1. 缁樺埗鏂版墖褰㈠尯鍩�
diff --git a/src/views/sourcetrace/SourceTrace.vue b/src/views/sourcetrace/SourceTrace.vue
index 9cfbd0e..2ef9353 100644
--- a/src/views/sourcetrace/SourceTrace.vue
+++ b/src/views/sourcetrace/SourceTrace.vue
@@ -41,8 +41,8 @@
<SourceTraceFilter
v-model:data-slice="selectedMsgTypes"
v-model:factor-type="selectedFactorTypes"
- :factor-options="factorOptions"
v-model:scene-type="selectedSceneTypes"
+ :factor-options="factorOptions"
:scene-options="sceneOptions"
></SourceTraceFilter>
<!-- <el-divider direction="vertical"></el-divider> -->
@@ -55,7 +55,11 @@
</el-space>
</div>
</el-row>
- <el-scrollbar ref="scrollbarRef" class="scrollbar">
+ <el-scrollbar
+ ref="scrollbarRef"
+ class="scrollbar"
+ v-loading="loading"
+ >
<TransitionGroup name="list">
<div
v-for="item in filterStreams"
@@ -154,6 +158,8 @@
const selectedSceneTypes = ref([]);
const sceneOptions = ref([]);
+const loading = ref(false);
+
function handleDisplayChange() {
show.value = !show.value;
if (
@@ -188,7 +194,11 @@
case '1':
case '3':
// 鍒ゆ柇鐩戞祴鍥犲瓙绫诲瀷鏄惁閫変腑
- b2 = selectedFactorTypes.value.indexOf(v.pollutedData.factorId) != -1;
+ for (const key in v.pollutedData.statisticMap) {
+ const value = v.pollutedData.statisticMap[key];
+ b2 = b2 || selectedFactorTypes.value.indexOf(value.factorId) != -1;
+ }
+
// 鍒ゆ柇鍦烘櫙绫诲瀷鏄惁閫変腑
if (v.pollutedSource.sceneList.length == 0) {
b3 = selectedSceneTypes.value.indexOf(NO_SCENE) != -1;
@@ -282,17 +292,19 @@
case '1':
case '3':
// 绛涢�夌洃娴嬪洜瀛愮被鍨�
- if (
- factorOptions.value.findIndex(
- (v) => v.value == objData.pollutedData.factorId
- ) == -1
- ) {
- factorOptions.value.push({
- label: objData.pollutedData.factorName,
- value: objData.pollutedData.factorId
- });
- selectedFactorTypes.value.push(objData.pollutedData.factorId);
+ for (const key in objData.pollutedData.statisticMap) {
+ const value = objData.pollutedData.statisticMap[key];
+ if (
+ factorOptions.value.findIndex((v) => v.value == value.factorId) == -1
+ ) {
+ factorOptions.value.push({
+ label: value.factorName,
+ value: value.factorId
+ });
+ selectedFactorTypes.value.push(value.factorId);
+ }
}
+
// 绛涢�夊満鏅被鍨�
if (objData.pollutedSource.sceneList.length == 0) {
// 鑻ユ病鏈夋壘鍒伴闄╂簮鏃讹紝灏嗚鍒嗙被璁惧畾涓簄ull
@@ -339,23 +351,27 @@
}
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;
- });
+ loading.value = true;
+ 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;
+ })
+ .finally(() => (loading.value = false));
}
onMounted(() => {
@@ -481,13 +497,23 @@
);
const factorDatas = new FactorDatas();
factorDatas.setData(obj.pollutedData.historyDataList, 0, () => {
- obj._chartOptions = factorDataParser.parseData(factorDatas, [
- {
- label: obj.pollutedData.factorName,
- name: obj.pollutedData.factorName,
- value: obj.pollutedData.factorId + ''
- }
- ]);
+ for (const key in obj.pollutedData.statisticMap) {
+ const value = obj.pollutedData.statisticMap[key];
+ value._chartOptions = factorDataParser.parseData(factorDatas, [
+ {
+ label: value.factorName,
+ name: value.factorName,
+ value: value.factorId + ''
+ }
+ ]);
+ }
+ // obj._chartOptions = factorDataParser.parseData(factorDatas, [
+ // {
+ // label: obj.pollutedData.factorName,
+ // name: obj.pollutedData.factorName,
+ // value: obj.pollutedData.factorId + ''
+ // }
+ // ]);
// console.log('鎶樼嚎鍥撅細', obj._chartOptions);
});
}
diff --git a/src/views/sourcetrace/component/ClueRecordItem.vue b/src/views/sourcetrace/component/ClueRecordItem.vue
index 25a1b59..ab8223c 100644
--- a/src/views/sourcetrace/component/ClueRecordItem.vue
+++ b/src/views/sourcetrace/component/ClueRecordItem.vue
@@ -108,7 +108,7 @@
</el-tag>
<el-text type="info">{{ item.pollutedData.exception }}</el-text>
</div>
- <div v-if="item.pollutedSource.sceneList.length > 0">
+ <!-- <div v-if="item.pollutedSource.sceneList.length > 0">
<div v-for="s in item.pollutedSource.sceneList" :key="s.guid">
<img style="width: 24px" :src="sceneIcon(s.typeId)" :alt="s.type" />
<el-text
@@ -121,7 +121,7 @@
{{ s.name }}
</el-text>
</div>
- </div>
+ </div> -->
</el-col>
</el-row>
</div>
diff --git a/src/views/sourcetrace/component/PollutedExceptionItem.vue b/src/views/sourcetrace/component/PollutedExceptionItem.vue
index d269ccd..2482d6c 100644
--- a/src/views/sourcetrace/component/PollutedExceptionItem.vue
+++ b/src/views/sourcetrace/component/PollutedExceptionItem.vue
@@ -38,7 +38,10 @@
<div>
<el-text type="info">
<el-icon><MapLocation /></el-icon>
- {{ '椋庨櫓鍖哄煙锛�' + item.pollutedArea.address }}
+ {{
+ '椋庨櫓鍖哄煙锛�' +
+ (item.pollutedArea.address ? item.pollutedArea.address : '')
+ }}
</el-text>
</div>
<!-- <div>
@@ -52,7 +55,7 @@
寮傚父绫诲瀷锛歿{ item.pollutedData.exception }}
</el-text>
</div>
- <div v-for="s in item.pollutedData.statisticMap" :key="s">
+ <div v-for="s in item.pollutedData.statisticMap" :key="s.factorId">
<el-row style="border-top: 1px solid white">
<el-col :span="6">
<el-statistic title="绐佸彉鍥犲瓙" :value="s.factorName" />
@@ -77,10 +80,19 @@
<el-statistic
title="骞冲潎椋庨��"
:value="item.pollutedData.windSpeed"
+ :precision="1"
suffix="m/s"
/>
</el-col>
</el-row>
+ <RealTimeLineChart
+ v-for="(item1, index1) in s._chartOptions"
+ :key="index1"
+ :model-value="item1"
+ chart-height="80px"
+ :y-min-interval="20"
+ :exception-index-arr="exceptionIndexArr"
+ ></RealTimeLineChart>
</div>
<el-row justify="space-between">
<!-- <el-link
@@ -97,13 +109,6 @@
</el-link> -->
</el-row>
<!-- <div style="width: 320px; height: 80px"> -->
- <RealTimeLineChart
- v-for="(item1, index1) in item._chartOptions"
- :key="index1"
- :model-value="item1"
- chart-height="80px"
- :y-min-interval="20"
- ></RealTimeLineChart>
<!-- </div> -->
<div class="border-dashed">
<el-icon color="#ffbc58" size="20"><WarningFilled /></el-icon>
@@ -122,13 +127,24 @@
</CardDialog> -->
</template>
<script setup>
-import { ref } from 'vue';
+import { ref, computed } from 'vue';
const props = defineProps({
modelValue: Boolean,
item: Object
});
+const exceptionIndexArr = computed(() => {
+ const indexArr = [];
+ props.item.pollutedData.dataVoList.forEach((e) => {
+ const i = props.item.pollutedData.historyDataList.findIndex(
+ (v) => v.time == e.time
+ );
+ indexArr.push([i - 1 < 0 ? 0 : i - 1, i]);
+ });
+ return indexArr;
+});
+
const emits = defineEmits(['showMarksAndPolygon', 'update:modelValue']);
function showMarksAndPolygon(item) {
diff --git a/src/views/sourcetrace/component/PollutedWarnItem.vue b/src/views/sourcetrace/component/PollutedWarnItem.vue
index d047320..90a8456 100644
--- a/src/views/sourcetrace/component/PollutedWarnItem.vue
+++ b/src/views/sourcetrace/component/PollutedWarnItem.vue
@@ -30,7 +30,10 @@
<div>
<el-text type="info">
<el-icon><MapLocation /></el-icon>
- {{ '鎵�鍦ㄥ尯鍩燂細' + item.pollutedArea.address }}
+ {{
+ '鎵�鍦ㄥ尯鍩燂細' +
+ (item.pollutedArea.address ? item.pollutedArea.address : '')
+ }}
</el-text>
</div>
<!-- <div>
@@ -45,11 +48,23 @@
</el-text>
</div>
<el-row style="border-top: 1px solid white"> </el-row>
- <RealTimeLineChart
+ <div v-for="s in item.pollutedData.statisticMap" :key="s.factorId">
+ <el-row justify="space-between" class="wrap">
+ <div class="flex-col m-r-4">
+ <div class="factor-name">{{ s.factorName }}</div>
+ </div>
+ <RealTimeLineChart
+ v-for="(item1, index1) in s._chartOptions"
+ :key="index1"
+ :model-value="item1"
+ ></RealTimeLineChart>
+ </el-row>
+ </div>
+ <!-- <RealTimeLineChart
v-for="(item1, index1) in item._chartOptions"
:key="index1"
:model-value="item1"
- ></RealTimeLineChart>
+ ></RealTimeLineChart> -->
</el-scrollbar>
</template>
</BaseCard>
@@ -117,7 +132,7 @@
padding: 0 4px;
/* margin-right: 2px; */
width: 340px;
- height: 240px;
+ height: 260px;
/* border-right: 1px solid white; */
border-radius: 2px;
}
@@ -130,4 +145,22 @@
padding: 0px 1px;
margin-bottom: 4px;
}
+
+.wrap {
+ border-bottom: 1px solid rgba(255, 255, 255, 0.329);
+}
+
+.flex-col {
+ display: flex;
+ flex-direction: column;
+}
+
+.factor-value {
+ font-weight: 600;
+ font-size: 20px;
+}
+
+.factor-name {
+ color: #23dad1;
+}
</style>
--
Gitblit v1.9.3