| | |
| | | <div class="p-events-none m-t-2"> |
| | | <el-row justify="center" align="middle" class="top-wrap"> |
| | | <DeviceChange @change="onDeviceChange"></DeviceChange> |
| | | <el-button |
| | | type="primary" |
| | | class="p-events-auto el-button-custom" |
| | | @click="pauseTask" |
| | | > |
| | | {{ pause ? '继续' : '暂停' }} |
| | | </el-button> |
| | | </el-row> |
| | | <el-row class="m-t-2"> |
| | | <FactorRadio |
| | | :device-type="deviceType" |
| | | @change="(e) => (factorType = e)" |
| | | ></FactorRadio> |
| | | <FactorRadio :device-type="deviceType" v-model="factorType"></FactorRadio> |
| | | </el-row> |
| | | <el-row class="m-t-2"> |
| | | <FactorLegend |
| | | class="m-t-2" |
| | | :factor="factorDatas.factor[factorType]" |
| | | ></FactorLegend> |
| | | <el-col span="1"> |
| | | <FactorLegend :factor="factorDatas.factor[factorType]"></FactorLegend> |
| | | </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" |
| | | :device-type="deviceType" |
| | | ></RealTimeTrend> |
| | | <SourceTrace |
| | | class="source-trace" |
| | | v-model:factorType="factorType" |
| | | :deviceCode="deviceCode" |
| | | ></SourceTrace> |
| | | <!-- <PollutedClueItem></PollutedClueItem> --> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import moment from 'moment'; |
| | | import mapUtil from '@/utils/map/util'; |
| | | import { useFetchData } from '@/composables/fetchData'; |
| | | import { TYPE0 } from '@/constant/device-type'; |
| | | import { defaultOptions } from '@/constant/radio-options'; |
| | | import { FactorDatas } from '@/model/FactorDatas'; |
| | | import monitorDataApi from '@/api/monitorDataApi'; |
| | | import DashBoard from './component/DashBoard.vue'; |
| | | import RealTimeTrend from './component/RealTimeTrend.vue'; |
| | | import DeviceChange from './component/DeviceChange.vue'; |
| | | import SourceTrace from '@/views/sourcetrace/SourceTrace.vue'; |
| | | import UnderwayAdvice from '@/views/sourcetrace/UnderwayAdvice.vue'; |
| | | import PollutedClueItem from '@/views/sourcetrace/component/PollutedClueItem.vue'; |
| | | import { realTimeMapAnimation } from '@/utils/map/animation'; |
| | | import { |
| | | fetchHistoryData, |
| | | startLoopFetchRealTimeData, |
| | | clearFetchingTask, |
| | | pauseTask |
| | | } from '@/utils/factor/data'; |
| | | import thirdPartyDataApi from '@/api/thirdPartyDataApi'; |
| | | import websocket from '@/api/websocket'; |
| | | |
| | | // const mapAnimation = new MapAnimation(); |
| | | |
| | | // 调试模式 |
| | | const mode = 'debug'; |
| | | // const mode = 'product'; |
| | | |
| | | export default { |
| | | components: { DashBoard, RealTimeTrend, DeviceChange }, |
| | | components: { |
| | | DashBoard, |
| | | RealTimeTrend, |
| | | DeviceChange, |
| | | SourceTrace, |
| | | UnderwayAdvice, |
| | | PollutedClueItem |
| | | }, |
| | | setup() { |
| | | const { loading, fetchData } = useFetchData(10000); |
| | | return { loading, fetchData }; |
| | |
| | | return { |
| | | // 监测设备类型 |
| | | deviceType: TYPE0, |
| | | deviceCode: '0a0000000001', |
| | | deviceCode: '', |
| | | // 监测因子的类型编号 |
| | | factorType: '1', |
| | | factorType: defaultOptions(TYPE0).value, |
| | | // 新获取的监测数据 |
| | | factorDatas: new FactorDatas(), |
| | | // 全部监测数据 |
| | | allFactorDatas: new FactorDatas() |
| | | allFactorDatas: new FactorDatas(), |
| | | pause: false |
| | | }; |
| | | }, |
| | | watch: { |
| | |
| | | } |
| | | }, |
| | | computed: { |
| | | // 数据最新时间(最新数据的采样时间加1秒;没有数据时,采用当前时间的前6分钟) |
| | | latestTime() { |
| | | if (this.factorDatas.times.length == 0) { |
| | | return ''; |
| | | return moment().subtract(6, 'm').format('YYYY-MM-DD HH:mm:ss'); |
| | | } else { |
| | | return this.factorDatas.times[this.factorDatas.times.length - 1]; |
| | | const _time = this.factorDatas.times[this.factorDatas.times.length - 1]; |
| | | return moment(_time).add(1, 's').format('YYYY-MM-DD HH:mm:ss'); |
| | | } |
| | | } |
| | | }, |
| | |
| | | // this.draw(); |
| | | this.factorDatas = fDatas; |
| | | }); |
| | | }, |
| | | fetchRealTimeData() { |
| | | // fixme 2024.5.3 此处初始获取的数据,参数应该由searchbar决定,后续修改 |
| | | this.fetchData((page) => { |
| | | return monitorDataApi |
| | | .fetchHistroyData({ |
| | | deviceCode: this.deviceCode, |
| | | // startTime: '2021-11-04 09:53:35', |
| | | page, |
| | | perPage: 100 |
| | | }) |
| | | .then((res) => { |
| | | this.onFetchData(res.data); |
| | | this.onMapData(res.data); |
| | | this.fetchNextData(); |
| | | }); |
| | | }); |
| | | }, |
| | | clearFetchingTask() { |
| | | if (this.fetchingTask) { |
| | | clearInterval(this.fetchingTask); |
| | | this.fetchingTask = undefined; |
| | | if (mode == 'debug') { |
| | | websocket.send(JSON.stringify(data)); |
| | | } |
| | | }, |
| | | fetchNextData() { |
| | | this.clearFetchingTask(); |
| | | this.fetchingTask = setInterval(() => { |
| | | if (this.isFetching) { |
| | | return; |
| | | } |
| | | |
| | | this.isFetching = true; |
| | | this.fetchData(() => { |
| | | return monitorDataApi |
| | | .fetchNextData({ |
| | | deviceCode: this.deviceCode, |
| | | updateTime: this.latestTime, |
| | | perPage: 10 |
| | | }) |
| | | .then((res) => { |
| | | this.onFetchData(res.data); |
| | | this.onMapData(res.data); |
| | | }) |
| | | .finally(() => (this.isFetching = false)); |
| | | fetchRealTimeData() { |
| | | this.fetchData((page) => { |
| | | const param = |
| | | mode == 'debug' |
| | | ? { |
| | | deviceCode: this.deviceCode, |
| | | // startTime: '2025-01-16 11:34:00', |
| | | // endTime: '2025-01-16 11:35:00', |
| | | // startTime: '2025-01-20 12:40:00', |
| | | // startTime: '2024-12-27 08:30:00', |
| | | // startTime: '2024-12-13 16:35:00', |
| | | // startTime: '2024-11-27 11:50:41', // Pm, 中距离工地 |
| | | // startTime: '2024-08-30 15:27:00', // voc 近距离汽修 |
| | | startTime: '2024-07-23 15:21:30', |
| | | // startTime: '2024-07-23 14:39:00', |
| | | endTime: '2025-01-16 11:51:41', |
| | | page, |
| | | perPage: 10 |
| | | } |
| | | : { |
| | | deviceCode: this.deviceCode, |
| | | page, |
| | | perPage: 100 |
| | | }; |
| | | return fetchHistoryData(param, false).then((res) => { |
| | | this.onFetchData(res.data); |
| | | this.onMapData(res.data); |
| | | this.fetchNextData(); |
| | | thirdPartyDataApi.fetchLatestData(this.deviceType, this.deviceCode); |
| | | }); |
| | | }, 10000); |
| | | }); |
| | | }, |
| | | pauseTask() { |
| | | this.pause = pauseTask(); |
| | | }, |
| | | clearFetchingTask() { |
| | | clearFetchingTask(); |
| | | }, |
| | | fetchNextData() { |
| | | startLoopFetchRealTimeData( |
| | | () => { |
| | | return { |
| | | deviceCode: this.deviceCode, |
| | | updateTime: this.latestTime, |
| | | perPage: mode == 'debug' ? 1 : 10 |
| | | }; |
| | | }, |
| | | (res) => { |
| | | this.onFetchData(res.data); |
| | | this.onMapData(res.data); |
| | | thirdPartyDataApi.fetchLatestData(this.deviceType, this.deviceCode); |
| | | }, |
| | | mode == 'debug' ? 4000 : undefined |
| | | ); |
| | | }, |
| | | onMapData(dataList) { |
| | | let startIndex = this.allFactorDatas.length() - 1; |
| | |
| | | this.notFirstFetch = true; |
| | | } |
| | | startIndex = startIndex < 0 ? 0 : startIndex; |
| | | return new Promise((resolve, reject) => { |
| | | return new Promise(() => { |
| | | this.allFactorDatas.addData(dataList, this.drawMode, () => { |
| | | realTimeMapAnimation.moveAnimation( |
| | | this.allFactorDatas, |
| | |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.fetchRealTimeData(); |
| | | if (mode == 'debug') { |
| | | websocket.send('start'); |
| | | } |
| | | }, |
| | | unmounted() { |
| | | this.clearFetchingTask(); |
| | | realTimeMapAnimation.stop(); |
| | | mapUtil.clearMap(); |
| | | } |
| | | }; |
| | | </script> |
| | | <style scoped> |
| | | .dash-board { |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: 2px; |
| | | right: 0; |
| | | bottom: 0px; |
| | | } |
| | | .real-time-trend { |
| | | position: absolute; |
| | | right: 0; |
| | | top: 0; |
| | | } |
| | | .source-trace { |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: 0px; |
| | | } |
| | | </style> |