From c23ac06446a9a1edc41cc13723e5d0b8eabdfd63 Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期三, 16 七月 2025 17:30:50 +0800 Subject: [PATCH] 2025.7.16 动态溯源新增合并异常 --- src/views/sourcetrace/SourceTrace.vue | 280 +++++++++++++++++++++++++++++-------------------------- 1 files changed, 148 insertions(+), 132 deletions(-) diff --git a/src/views/sourcetrace/SourceTrace.vue b/src/views/sourcetrace/SourceTrace.vue index 0145b9a..9cfbd0e 100644 --- a/src/views/sourcetrace/SourceTrace.vue +++ b/src/views/sourcetrace/SourceTrace.vue @@ -1,18 +1,32 @@ <template> - <el-row> + <el-row + :style=" + direction == 'left' + ? 'flex-direction: row;' + : 'flex-direction: row-reverse' + " + > <el-col span="2" class="flex-col"> - <el-row justify="end"> + <el-row :justify="direction == 'left' ? 'end' : 'start'"> <CardButton - direction="left" + :direction="direction" name="鍔ㄦ�佹函婧�" - @click="() => (show = !show)" + @click="handleDisplayChange" ></CardButton> </el-row> <el-row class="flex-col"> + <PollutedWarnItem + :item="selectedWarning" + @showMarksAndPolygon="showMarksAndPolygon" + ></PollutedWarnItem> <PollutedExceptionItem :item="selectedException" @showMarksAndPolygon="showMarksAndPolygon" ></PollutedExceptionItem> + <PollutedClueItem + v-model="clueDialog" + :item="selectedClue" + ></PollutedClueItem> </el-row> </el-col> <el-col v-show="show" span="10"> @@ -35,9 +49,9 @@ <!-- 鏁版嵁鍒囩墖缁熻 --> <div style="border-left: 1px solid white" class="p-l-8"> <el-space direction="vertical"> - <el-text type="primary">婧簮锛歿{ countMsg1.type1 }}鏉�</el-text> - <el-text type="primary">绾跨储锛歿{ countMsg1.type2 }}鏉�</el-text> - <el-text type="primary">鎻愰啋锛歿{ countMsg1.type3 }}鏉�</el-text> + <el-text type="info">婧簮锛歿{ countMsg1.type1 }}鏉�</el-text> + <el-text type="info">绾跨储锛歿{ countMsg1.type2 }}鏉�</el-text> + <el-text type="info">鎻愰啋锛歿{ countMsg1.type3 }}鏉�</el-text> </el-space> </div> </el-row> @@ -57,10 +71,25 @@ </template> </BaseCard> </el-col> - <PollutedClueItem - v-model="clueDialog" - :item="selectedClue" - ></PollutedClueItem> + <!-- <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> + <PollutedClueItem + v-model="clueDialog" + :item="selectedClue" + ></PollutedClueItem> + </el-row> + </el-col> --> </el-row> </template> <script setup> @@ -72,6 +101,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'; @@ -85,30 +115,55 @@ import ClueRecordItem from './component/ClueRecordItem.vue'; import PollutedClueItem from '@/views/sourcetrace/component/PollutedClueItem.vue'; import SourceTraceFilter from '@/views/sourcetrace/component/SourceTraceFilter.vue'; +import PollutedWarnItem from './component/PollutedWarnItem.vue'; const NO_SCENE = 'no_scene'; +const MODE_REALTIME = 'realtime'; +const MODE_HISTORY = 'history'; + const props = defineProps({ - factorType: String + direction: { + type: String, + default: 'right' + }, + 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); const scrollContentRef = ref(); const scrollbarRef = ref(); +const selectedWarning = ref(); const selectedException = ref(); const selectedClue = ref(); +const clueDialog = ref(false); + const selectedMsgTypes = ref(['1', '2', '3']); const selectedFactorTypes = ref([]); const factorOptions = ref([]); 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; @@ -123,9 +178,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 +218,7 @@ type2: 0, type3: 0 }; - streams.forEach((v) => { + streams.value.forEach((v) => { switch (v._type) { case '1': count.type1++; @@ -187,10 +242,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 +261,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); @@ -238,7 +298,7 @@ // 鑻ユ病鏈夋壘鍒伴闄╂簮鏃讹紝灏嗚鍒嗙被璁惧畾涓簄ull if (sceneOptions.value.findIndex((v) => v.value == NO_SCENE) == -1) { sceneOptions.value.push({ - label: '鏃�', + label: '鏈煡', value: NO_SCENE }); selectedSceneTypes.value.push(NO_SCENE); @@ -264,7 +324,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 +338,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); @@ -297,29 +381,50 @@ } }); +watch( + () => props.missionCode, + (nV, oV) => { + if (nV != oV) { + fetchPollutionTraceHistory(); + } + } +); + function handleOpen(item) { + // 鍘婚櫎涓婁竴涓�滄函婧愨�濆拰鈥滄彁閱掆�濇秷鎭殑閫変腑鏍囧織 + if (selectedWarning.value && selectedWarning.value._selected) { + selectedWarning.value._selected = false; + showMarksAndPolygon(selectedWarning.value); + } + if (selectedException.value && selectedException.value._selected) { + selectedException.value._selected = false; + showMarksAndPolygon(selectedException.value); + } + if (selectedClue.value && selectedClue.value._selected) { + selectedClue.value._selected = false; + clueDialog.value = false; + } switch (item._type) { case '1': - case '3': - if (selectedException.value) { - selectedException.value._selected = false; - } + // 鏄剧ず褰撳墠閫変腑鐨勭浉鍏冲湴鍥炬爣璁� showMarksAndPolygon(item); + // 鏇存柊閫変腑鐨勫璞� selectedException.value = item; break; case '2': - if (selectedClue.value) { - selectedClue.value._selected = false; - } selectedClue.value = item; clueDialog.value = true; + break; + case '3': + showMarksAndPolygon(item); + selectedWarning.value = item; break; } item._selected = true; } function hideAll() { - streams.forEach((s) => { + streams.value.forEach((s) => { if (polygonMap.has(s.guid)) { s.showMore = false; map.remove(polygonMap.get(s.guid)); @@ -336,7 +441,7 @@ } else { if (polygonMap.has(item.guid)) { map.remove(polygonMap.get(item.guid)); - selectedException.value._selected = false; + item._selected = false; } } } @@ -368,6 +473,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, [ @@ -384,101 +495,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> :deep(.el-statistic) { @@ -486,7 +502,7 @@ --el-statistic-content-color: white; } -:deep(.el-text.el-text--primary) { +:deep(.el-text.el-text--info) { --el-text-color: white; } @@ -512,7 +528,7 @@ .scrollbar { width: 400px; /* max-width: 60vw; */ - height: 45vh; + height: 65vh; /* color: #02ffea; */ padding-right: 10px; } -- Gitblit v1.9.3