| | |
| | | </div> |
| | | </div> |
| | | <div class="main-content"> |
| | | <div id="bigMap"></div> |
| | | <!-- <div id="bigMap"></div>--> |
| | | <div class="main-left"> |
| | | <div class="left-top withFilter"> |
| | | <div class="chart-head"> |
| | | <div class="chart-tit">预警汇总</div> |
| | | <el-radio-group v-model="chart1Search"> |
| | | <el-radio-group v-model="countTime" @change="changeTotal"> |
| | | <el-radio :label="1" size="small" border>当日</el-radio> |
| | | <el-radio :label="2" size="small" border>近7天</el-radio> |
| | | <el-radio :label="3" size="small" border>近30天</el-radio> |
| | |
| | | </div> |
| | | <div class="chart-cont"> |
| | | <div class="orange"> |
| | | <div><span>30</span><span>橙色预警</span></div> |
| | | <div><span>{{yellowNum}}</span><span>橙色预警</span></div> |
| | | </div> |
| | | <div class="red"> |
| | | <div><span>10</span><span>红色预警</span></div> |
| | | <div><span>{{redNum}}</span><span>红色预警</span></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | @change="timeChange" |
| | | format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | </div> |
| | |
| | | <div class="chart-head"> |
| | | <div class="chart-tit">设备状态</div> |
| | | <div class="sys-status"> |
| | | <Cpu style="width: 1.2em; height: 1.2em; color: #fff" /> |
| | | <div>系统状态:<span>正常</span></div> |
| | | <Cpu :class="online == 3 ? 'onlineIcon':'offlineIcon'"/> |
| | | <div>系统状态:<span :class="online == 3 ? 'online':'offline'">{{online == 3?'正常':'异常'}}</span></div> |
| | | </div> |
| | | </div> |
| | | <div class="chart-cont"> |
| | | <div class="online"> |
| | | <dv-decoration-9 :color="['#22aaff','rgba(34,170,255,.6)']"> |
| | | <div color-green font-600 class="isOnline" bg="~ dark/0"> |
| | | 0 |
| | | {{online}} |
| | | </div> |
| | | </dv-decoration-9> |
| | | <div>在线</div> |
| | |
| | | <div class="online"> |
| | | <dv-decoration-9 :color="['#ee594a','rgba(238,89,74,.6)']"> |
| | | <div color-red font-600 class="isOnline red-font" bg="~ dark/0"> |
| | | 1 |
| | | {{3 - online}} |
| | | </div> |
| | | </dv-decoration-9> |
| | | <div style="color:#ee594a;">离线</div> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="main-middle"> |
| | | <div class="map-filter"> |
| | | <el-radio-group v-model="windQuery.type" @change="changeWindQuery"> |
| | | <el-radio :label="1" size="small" border>按时间段</el-radio> |
| | | <el-radio :label="2" size="small" border>按具体时间</el-radio> |
| | | </el-radio-group> |
| | | <el-select v-if="windQuery.type == 1" v-model="windQuery.countTime" :teleported="false" class="m-2" placeholder="Select" size="small" @change="changeWind"> |
| | | <el-option :key="1" label="1小时内" :value="1"/> |
| | | <el-option :key="2" label="6小时内" :value="2"/> |
| | | <el-option :key="3" label="12小时内" :value="3"/> |
| | | <el-option :key="4" label="24小时内" :value="4"/> |
| | | </el-select> |
| | | <el-date-picker |
| | | v-else |
| | | v-model="windTimeRange" |
| | | size="small" |
| | | :teleported="false" |
| | | type="datetimerange" |
| | | unlink-panels |
| | | range-separator="至" |
| | | start-placeholder="开始时间" |
| | | end-placeholder="结束时间" |
| | | @change="windTimeChange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | /> |
| | | <div style="width: 100%;height: 250px;margin-top: 20px" :id="gasWind"></div> |
| | | </div> |
| | | <Map class="bigMap"></Map> |
| | | <!-- </div>--> |
| | | <div class="mid-bottom"> |
| | | <div class="chart-head"> |
| | | <div class="chart-tit">气象信息</div> |
| | |
| | | <div></div> |
| | | <div></div> |
| | | </div> |
| | | <dv-scroll-board :config="bigConfig" class="scroll-table" @mouseover="mouseoverHandler" @click="clickHandler" /> |
| | | <!-- <dv-scroll-board :config="bigConfig" class="scroll-table" @mouseover="mouseoverHandler" @click="clickHandler" />--> |
| | | <table class="weather"> |
| | | <tr class="weatherTit"><td>时间</td><td>温度</td><td>湿度</td><td>风速</td><td>风向</td><td>气压</td></tr> |
| | | <tr v-for="(item,index) in weatherData" :key="index" class="weatherRow"> |
| | | <td>{{item.time}}</td> |
| | | <td>{{item.temp}}</td> |
| | | <td>{{item.humidity}}</td> |
| | | <td>{{item.windSpeed}}</td> |
| | | <td>{{item.windDirection}}</td> |
| | | <td>{{item.pressure}}</td> |
| | | </tr> |
| | | </table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="right-top withFilterLong"> |
| | | <div class="chart-head"> |
| | | <div class="chart-tit long-tit">气体浓度监测</div> |
| | | <el-select v-model="gasSearch" :teleported="false" class="m-2" placeholder="Select" size="small"> |
| | | <el-option |
| | | v-for="item in gasOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <div class="searchGroup"> |
| | | <el-select v-model="gasSearch" :teleported="false" class="m-2" placeholder="Select" size="small" @change="changeGas1"> |
| | | <el-option |
| | | v-for="item in gasOptions" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | <el-select v-model="positionSearch" :teleported="false" class="m-2" placeholder="Select" size="small" @change="changeGas1"> |
| | | <el-option |
| | | v-for="item in positionOptions" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | <div class="checkMore" @click="toNdPage()"><el-icon><DArrowRight /></el-icon></div> |
| | | </div> |
| | | </div> |
| | | <div class="chart-cont"> |
| | | <div class="echart" :id="gasN"></div> |
| | | <div v-if="hasNd==true" class="echart" :id="gasN"></div> |
| | | <div v-else class="echart" style="display: flex;font-size: 20px;justify-content: center;align-items: center"><span style="color:#11feee;">暂无数据</span></div> |
| | | </div> |
| | | </div> |
| | | <div class="right-mid withFilterLong"> |
| | | <div class="chart-head"> |
| | | <div class="chart-tit long-tit">气体通量监测</div> |
| | | <div class="searchGroup"> |
| | | <el-select v-model="searchParams.gasSearch" :teleported="false" class="m-2" placeholder="Select" size="small"> |
| | | <el-select v-model="tlGasSearch" :teleported="false" class="m-2" placeholder="Select" size="small" @change="changeGas2"> |
| | | <el-option |
| | | v-for="item in gasOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | <el-select v-model="searchParams.areaSearch" :teleported="false" class="m-2" placeholder="Select" size="small"> |
| | | <el-option |
| | | v-for="item in areaOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | <div class="checkMore" @click="toTlPage()"><el-icon><DArrowRight /></el-icon></div> |
| | | <!-- <el-select v-model="searchParams.areaSearch" :teleported="false" class="m-2" placeholder="Select" size="small">--> |
| | | <!-- <el-option--> |
| | | <!-- v-for="item in areaOptions"--> |
| | | <!-- :key="item.id"--> |
| | | <!-- :label="item.name"--> |
| | | <!-- :value="item.id"--> |
| | | <!-- />--> |
| | | <!-- </el-select>--> |
| | | </div> |
| | | </div> |
| | | <div class="chart-cont"> |
| | | <div class="echart" :id="gasT"></div> |
| | | <div v-if="hasTl==true" class="echart" :id="gasT"></div> |
| | | <div v-else class="echart" style="display: flex;font-size: 20px;justify-content: center;align-items: center"><span style="color:#11feee;">暂无数据</span></div> |
| | | </div> |
| | | </div> |
| | | <div class="right-bottom withoutFilter"> |
| | |
| | | </div> |
| | | <div class="chart-cont"> |
| | | <div class="online"> |
| | | <div class="totalNum"><span>1048</span>条</div> |
| | | <div class="totalNum"><span>{{ gasTotal }}</span>条</div> |
| | | <div class="dataPic"></div> |
| | | <div class="totalNum">浓度条数</div> |
| | | </div> |
| | | <div class="online"> |
| | | <div class="totalNum"><span>566</span>条</div> |
| | | <div class="totalNum"><span>{{ tlTotal }}</span>条</div> |
| | | <div class="dataPic"></div> |
| | | <div class="totalNum">通量条数</div> |
| | | </div> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <el-dialog |
| | | v-model="dialogWarning" |
| | | title="预警信息" |
| | | width="35%" |
| | | :append-to-body="true" |
| | | :draggable="true" |
| | | custom-class="warningMsg" |
| | | top="2vh" |
| | | @opened="playAudio" |
| | | @close="confirmWarning" |
| | | > |
| | | <audio ref="audioRef" autoplay muted loop> |
| | | <source src="../../../assets/warning.mp3" type="audio/mpeg"> |
| | | 您的浏览器不支持 audio 元素。 |
| | | </audio> |
| | | <div class="warning-cont"> |
| | | <div><span>预警信息:</span><span>{{warningGas.content}}</span></div> |
| | | <div><span>预警时间:</span><span>{{warningGas.warnTime}}</span></div> |
| | | <div><span>预警气体:</span><span>{{warningGas.gasName}}</span></div> |
| | | <div><span>预警级别:</span><span :class="warningGas.gasThresholdName == '红色预警'?'red':''">{{warningGas.gasThresholdName}}</span></div> |
| | | <div><span>气体单位:</span><span>{{warningGas.gasUnit}}</span></div> |
| | | <div><span>预警浓度:</span><span>{{warningGas.gasConcentration}}</span></div> |
| | | <div><span>处理状态:</span><span>{{warningGas.status == 0?'未处理':warningGas.status == 1?'已处理':'--'}}</span></div> |
| | | <div v-if="warningGas.handlerRealName"><span>处理人:</span><span>{{warningGas.handlerRealName}}</span></div> |
| | | <div v-if="warningGas.handlerTime"><span>处理时间:</span><span>{{warningGas.handlerTime}}</span></div> |
| | | </div> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button type="primary" @click="dialogWarning = false"> |
| | | 确认 |
| | | </el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | | import {toRefs, reactive, onMounted, ref, defineComponent, onUnmounted} from 'vue'; |
| | | import {toRefs, reactive, onMounted, ref, defineComponent, onUnmounted, nextTick} from 'vue'; |
| | | import { ElMessage, ElMessageBox } from 'element-plus'; |
| | | import { useRouter} from "vue-router"; |
| | | import * as echarts from "echarts"; |
| | | import "amfe-flexible"; |
| | | import AMapLoader from '@amap/amap-jsapi-loader' |
| | | import { shallowRef } from '@vue/reactivity' |
| | | import { storeToRefs } from 'pinia'; |
| | | import Map from './map.vue' |
| | | import {BaiduMap, BmMapType, BmNavigation, BmPolygon, BmGround} from 'vue-baidu-map-3x' |
| | | import { useUserInfo } from '/@/stores/userInfo'; |
| | | import {bigScreenApi} from "/@/api/bigScreen"; |
| | | |
| | | // 定义接口来定义对象的类型 |
| | | interface TableDataState { |
| | | socket: any |
| | | timer: any |
| | | heartbeat: any |
| | | heartbeatTimeOut: any |
| | | lockReconnect: boolean |
| | | maxReconnect: number |
| | | reconnectTime: number |
| | | windQuery: { |
| | | type: null | number |
| | | countTime: number | null |
| | | startTime: '', |
| | | endTime:'' |
| | | } |
| | | countTime: null | number |
| | | time: string |
| | | date: string |
| | | weekDay: string |
| | | dayTime:string |
| | | isFull: boolean |
| | | chart1Search: number | null |
| | | chart2Search: Array<string> |
| | | windTimeRange: Array<string> |
| | | infoParams: {} |
| | | gasSearch: number | null |
| | | tlGasSearch: number | null |
| | | positionSearch: number | null |
| | | positionOptions: Array<gasType> |
| | | gasOptions: Array<gasType> |
| | | searchParams: Object |
| | | monthAgo: string, |
| | | today: string, |
| | | gasData: Array<any> |
| | | hasNd: boolean |
| | | gasTlData: Array<any> |
| | | hasTl: boolean |
| | | areaOptions: Array<gasType> |
| | | gasTotal: null | number |
| | | tlTotal: null | number |
| | | online: number |
| | | warningGas: {}, |
| | | dialogWarning: boolean |
| | | yellowNum: null | number |
| | | redNum: null | number |
| | | weatherData: Array<any> |
| | | polygonPath1: Array<location> |
| | | polygonPath2: Array<location> |
| | | polygonPath3: Array<location> |
| | | polygonPath4: Array<location> |
| | | polygonPath5: Array<location> |
| | | polygonPath6: Array<location> |
| | | polygonPath7: Array<location> |
| | | polygonPath8: Array<location> |
| | | polygonPath9: Array<location> |
| | | } |
| | | |
| | | interface location{ |
| | | lng: number | null |
| | | lat: number | null |
| | | } |
| | | interface gasType { |
| | | label: string |
| | | value: number | null |
| | | name: string |
| | | id: number | null |
| | | } |
| | | |
| | | export default defineComponent({ |
| | | name: 'bigScreen', |
| | | components: { }, |
| | | components: {Map,BaiduMap, BmMapType, BmNavigation, BmPolygon }, |
| | | props:{ |
| | | isFull: Boolean |
| | | }, |
| | | setup(props,context) { |
| | | const userInfo = useUserInfo(); |
| | | const { userInfos } = storeToRefs(userInfo); |
| | | const state = reactive<TableDataState>({ |
| | | yellowNum: null, |
| | | redNum: null, |
| | | socket: null, |
| | | timer: null, |
| | | heartbeat: null, |
| | | heartbeatTimeOut: null, |
| | | lockReconnect: false, |
| | | maxReconnect: 3, // 最大重连次数,-1代表无限重连 |
| | | reconnectTime: 0, // 重连尝试次数 |
| | | time: '', |
| | | date: '', |
| | | weekDay: '', |
| | | dayTime: '', |
| | | windQuery: { |
| | | type: 1, |
| | | countTime: 4, |
| | | startTime: '', |
| | | endTime: '' |
| | | }, |
| | | countTime: 1, |
| | | isFull: props.isFull, |
| | | chart1Search: 1, |
| | | chart2Search: [], |
| | | gasSearch: 1, |
| | | gasOptions: [ |
| | | windTimeRange: [], |
| | | infoParams:{ |
| | | startTime: '', |
| | | endTime: '' |
| | | }, |
| | | positionSearch: null, |
| | | gasSearch: null, |
| | | tlGasSearch: null, |
| | | gasOptions: [], |
| | | positionOptions: [ |
| | | { |
| | | label: '气体一', |
| | | value: 1 |
| | | id: null, |
| | | name: '全部' |
| | | }, |
| | | { |
| | | label: '气体二', |
| | | value: 2 |
| | | id: 1, |
| | | name: '方位1' |
| | | }, |
| | | { |
| | | label: '气体三', |
| | | value: 3 |
| | | id: 2, |
| | | name: '方位2' |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: '方位3' |
| | | } |
| | | ], |
| | | searchParams:{ |
| | | gasSearch: 1, |
| | | areaSearch: 1 |
| | | }, |
| | | areaOptions: [ |
| | | { |
| | | label: '区域一', |
| | | value: 1 |
| | | }, |
| | | { |
| | | label: '区域二', |
| | | value: 2 |
| | | }, |
| | | { |
| | | label: '区域三', |
| | | value: 3 |
| | | } |
| | | ] |
| | | monthAgo: '', |
| | | today: '', |
| | | gasData: [], |
| | | hasNd: true, |
| | | gasTlData: [], |
| | | hasTl: true, |
| | | areaOptions: [], |
| | | gasTotal: 0, |
| | | tlTotal: 0, |
| | | online: 3, |
| | | warningGas: {}, |
| | | dialogWarning: false, |
| | | weatherData: [], |
| | | polygonPath1: [], |
| | | polygonPath2: [], |
| | | polygonPath3: [], |
| | | polygonPath4: [], |
| | | polygonPath5: [], |
| | | polygonPath6: [], |
| | | polygonPath7: [], |
| | | polygonPath8: [], |
| | | polygonPath9: [] |
| | | }); |
| | | const router = useRouter(); |
| | | const router = useRouter() |
| | | const audioRef = ref() |
| | | const gasWind = ref("eChartgasWind" + Date.now() + Math.random()) |
| | | const gasN = ref("eChartgasN" + Date.now() + Math.random()) |
| | | const gasT = ref("eChartgasT" + Date.now() + Math.random()) |
| | | const timeForm = { |
| | |
| | | second: '2-digit', |
| | | }; |
| | | |
| | | const updatePolygonPath = (e) => { |
| | | state.polygonPath1 = e.target.getPath() |
| | | }; |
| | | // 页面加载时 |
| | | onMounted(() => { |
| | | initTime() |
| | | getGasData() |
| | | getWindData() |
| | | getWarningNum() |
| | | getWarningInfo() |
| | | getWarning() |
| | | getUnusual() |
| | | getAreaData() |
| | | const baseSize = 38; |
| | | function setRem() { |
| | | const scale = document.documentElement.clientWidth / 1920;/* 当前页面宽度缩放比例,可根据自己需要修改 */ |
| | | document.documentElement.style.fontSize = baseSize * Math.min(scale, 2) + "px";/* 设置页面根节点字体大小 */ |
| | | } |
| | | |
| | | setRem(); |
| | | |
| | | window.onresize = () => { |
| | | setRem();/* 改变窗口大小时重新设置 rem */ |
| | | } |
| | |
| | | setInterval(() => { |
| | | getDateTime(); |
| | | }, 1000); |
| | | initgasN() |
| | | initgasT() |
| | | initMap() |
| | | }); |
| | | }) |
| | | |
| | | onUnmounted(()=>{ |
| | | destroyedWs() |
| | | }) |
| | | const toNdPage = () =>{ |
| | | router.push('/gasData') |
| | | } |
| | | const toTlPage = () =>{ |
| | | router.push('/fluxData') |
| | | } |
| | | |
| | | const playAudio=()=>{ |
| | | audioRef.value.muted = false |
| | | audioRef.value.play() |
| | | } |
| | | |
| | | const confirmWarning =()=>{ |
| | | state.dialogWarning = false |
| | | audioRef.value.pause() |
| | | } |
| | | const getGasData = async ()=>{ |
| | | const res = await bigScreenApi().getGas() |
| | | if(res.data.code == 100){ |
| | | state.gasOptions = res.data.data |
| | | state.gasSearch = state.gasOptions[0].id |
| | | state.tlGasSearch = state.gasOptions[0].id |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | getGasSocket() |
| | | getGasTLSocket() |
| | | getGasNdData() |
| | | getGasTlData() |
| | | } |
| | | const initTime =()=>{ |
| | | state.monthAgo = getPeriod(30) |
| | | state.today = formatDate(new Date(),'end') |
| | | state.chart2Search[0] = state.monthAgo |
| | | state.chart2Search[1] = state.today+' 23:59:59' |
| | | state.infoParams.startTime = state.monthAgo |
| | | state.infoParams.endTime = state.today + ' 23:59:59' |
| | | } |
| | | const getPeriod =(num)=> { |
| | | const currentDate = new Date(); |
| | | const startTime = new Date(); |
| | | startTime.setDate(currentDate.getDate() - num); |
| | | return formatDate(startTime,'start') |
| | | } |
| | | const formatDate =(date,type)=> { |
| | | const year = date.getFullYear().toString(); |
| | | const month = ('0' + (date.getMonth() + 1)).slice(-2); |
| | | const day = ('0' + date.getDate()).slice(-2); |
| | | if(type == 'start'){ |
| | | return `${year}-${month}-${day} 00:00:00`; |
| | | }else{ |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | } |
| | | const getAreaData = async ()=>{ |
| | | const res = await bigScreenApi().getAreas({pageSize: 99, pageIndex: 1, searchParams:{name: ''}}) |
| | | if(res.data.code == 100){ |
| | | state.areaOptions = res.data.data |
| | | // state.searchParams.areaSearch = state.areaOptions[0].id |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const getWarningNum = async ()=>{ |
| | | const res = await bigScreenApi().getWarningNum({countTime: state.countTime}) |
| | | if(res.data.code == 100){ |
| | | state.yellowNum = res.data.data?res.data.data.yellowWarnNum:0 |
| | | state.redNum = res.data.data?res.data.data.redWarnNum:0 |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const getWindData = async ()=>{ |
| | | if(state.windQuery.type == 1){ |
| | | state.windQuery.startTime = '' |
| | | state.windQuery.endTime = '' |
| | | }else{ |
| | | state.windQuery.countTime = 5 |
| | | state.windQuery.startTime = state.windTimeRange[0]?state.windTimeRange[0]: state.today + ' 00:00:00' |
| | | state.windQuery.endTime = state.windTimeRange[1]?state.windTimeRange[1]: state.today + ' 23:59:59' |
| | | } |
| | | const {type,...data} = state.windQuery |
| | | const res = await bigScreenApi().getWindNum(data) |
| | | if(res.data.code == 100){ |
| | | const windData = JSON.parse(JSON.stringify(res.data.data)) |
| | | if(Array.isArray(windData)){ |
| | | let pointFive = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | let twoZone = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | let fourZone = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | let sixZone = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | let eightZone = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | let tenZone = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | let tenAbove = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |
| | | for (let i of windData){ |
| | | if(i.windSpeed<0.5){ |
| | | pointFive[getDirection(i.windDirection)] += 1 |
| | | }else if(i.windSpeed>0.5 && i.windSpeed<=2){ |
| | | twoZone[getDirection(i.windDirection)] += 1 |
| | | }else if(i.windSpeed>2 && i.windSpeed<=4){ |
| | | fourZone[getDirection(i.windDirection)] += 1 |
| | | }else if(i.windSpeed>4 && i.windSpeed<=6){ |
| | | sixZone[getDirection(i.windDirection)] += 1 |
| | | }else if(i.windSpeed>6 && i.windSpeed<=8){ |
| | | eightZone[getDirection(i.windDirection)] += 1 |
| | | }else if(i.windSpeed>8 && i.windSpeed<=10){ |
| | | tenZone[getDirection(i.windDirection)] += 1 |
| | | } else if(i.windSpeed>10){ |
| | | console.log(777,i.windDirection,getDirection(i.windDirection)) |
| | | tenAbove[getDirection(i.windDirection)] += 1 |
| | | }else{ |
| | | console.log('windSpeed为null') |
| | | } |
| | | } |
| | | initgasWind(pointFive,twoZone,fourZone,sixZone,eightZone,tenZone,tenAbove) |
| | | } |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const getDirection=(num:number)=>{ |
| | | if(num<=348.75 ){ |
| | | return Math.floor((num + 11.25) / 22.5) |
| | | }else{ |
| | | return 0 |
| | | } |
| | | } |
| | | |
| | | const getGasNdData = async ()=>{ |
| | | const res = await bigScreenApi().getGasNdData({startTime: state.today+' 00:00:00',endTime: state.today+' 23:59:59',gasName: state.gasSearch,position: state.positionSearch}) |
| | | if(res.data.code == 100){ |
| | | if(res.data.data && res.data.data.length>0){ |
| | | state.hasNd = true |
| | | state.gasTotal = res.data.data.length |
| | | const timeList = res.data.data.map(i=>i.time.slice(11)) |
| | | const dotList = res.data.data.map(i=>i.gasValue) |
| | | const weather = res.data.data.map((item)=>{ |
| | | return { |
| | | time: item.time?item.time.slice(11):'--', |
| | | temp: item.temp?item.temp:'--', |
| | | humidity: item.humidity?item.humidity:'--', |
| | | windSpeed: item.windSpeed?item.windSpeed:'--', |
| | | windDirection: item.windDirection?item.windDirection:'--', |
| | | pressure: item.pressure?item.pressure:'--' |
| | | } |
| | | }) |
| | | state.weatherData = [...weather].reverse().slice(0, 4); |
| | | initgasN(dotList.slice(dotList.length - 50),timeList.slice(timeList.length - 50)) |
| | | }else{ |
| | | state.hasNd = false |
| | | } |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const getGasTlData = async ()=>{ |
| | | const res = await bigScreenApi().getGasTlData({startTime: state.today+' 00:00:00',endTime: state.today+' 23:59:59',gasName: state.tlGasSearch,areaId: null}) |
| | | if(res.data.code == 100){ |
| | | if(res.data.data && res.data.data.length>0){ |
| | | state.hasTl = true |
| | | state.tlTotal = res.data.data.length |
| | | const gasTime = res.data.data.map(i=>i.time?.slice(11)) |
| | | const gasTlTime = [...new Set(gasTime)] |
| | | let areaData = state.areaOptions.map((item)=>{ |
| | | return { |
| | | areaId: item.id, |
| | | name: item.name, |
| | | dotList: [] |
| | | } |
| | | }) |
| | | for(let i of gasTlTime){ |
| | | const sameTimeData = res.data.data.filter(it=>it.time?.slice(11) == i) |
| | | for(let j of areaData){ |
| | | const foundData = sameTimeData.find(k=>k.areaId == j.areaId) |
| | | if(foundData){ |
| | | j.dotList.push(foundData.gasValue) |
| | | }else{ |
| | | j.dotList.push(0) |
| | | } |
| | | } |
| | | } |
| | | const chartData = areaData.map((i)=>{ |
| | | return { |
| | | name: i.name, |
| | | type: 'bar', |
| | | stack: 'total', |
| | | data: i.dotList.slice(i.dotList.length - 20) |
| | | } |
| | | }) |
| | | initgasT(gasTlTime.slice(gasTlTime.length - 20),chartData) |
| | | }else{ |
| | | state.hasTl = false |
| | | } |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | } |
| | | |
| | | const getWarningInfo = async ()=>{ |
| | | const res = await bigScreenApi().getWarningInfo(state.infoParams) |
| | | if(res.data.code == 100){ |
| | | if(res.data.data && res.data.data.length>0){ |
| | | const newData = res.data.data.map((item)=>{ |
| | | let i = [] |
| | | if(item.gasThresholdName == '红色预警'){ |
| | | i[0] = `<span style="color:red;">${item.gasThresholdName}</span>` |
| | | }else{ |
| | | i[0] = item.gasThresholdName |
| | | } |
| | | i[1] = item.gasName |
| | | i[2] = item.gasConcentration |
| | | i[3] = item.warnTime |
| | | return i |
| | | }) |
| | | config.data = newData |
| | | }else{ |
| | | config.data = [] |
| | | } |
| | | }else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | } |
| | | const timeChange = (value:Array<string>)=>{ |
| | | state.infoParams.startTime = value[0] |
| | | state.infoParams.endTime = value[1].replace('00:00:00', '23:59:59') |
| | | getWarningInfo() |
| | | } |
| | | |
| | | const changeGas1 = (value) =>{ |
| | | getGasNdData() |
| | | getGasSocket() |
| | | } |
| | | |
| | | const changeGas2 = (value)=>{ |
| | | getGasTlData() |
| | | getGasTLSocket() |
| | | } |
| | | |
| | | const changeTotal = () =>{ |
| | | getWarningNum() |
| | | } |
| | | |
| | | const windTimeChange = (value:Array<string>)=>{ |
| | | console.log(value) |
| | | state.windQuery.startTime = value[0] |
| | | state.windQuery.endTime = value[1] |
| | | getWindData() |
| | | } |
| | | |
| | | const changeWindQuery = (value) =>{ |
| | | if(value == 2){ |
| | | state.windQuery.countTime = 5 |
| | | }else{ |
| | | state.windQuery.countTime = 4 |
| | | } |
| | | getWindData() |
| | | } |
| | | const changeWind = () =>{ |
| | | getWindData() |
| | | } |
| | | const getWarning = ()=>{ |
| | | initWebSocket('/ws/gas/exc/','预警',60) |
| | | } |
| | | |
| | | const getUnusual = ()=>{ |
| | | initWebSocket('/ws/gas/device/exc/','异常',60) |
| | | } |
| | | |
| | | const getGasSocket = ()=>{ |
| | | initWebSocket('/ws/gas/','气体浓度',30) |
| | | } |
| | | |
| | | const getGasTLSocket = ()=>{ |
| | | initWebSocket('/ws/gas/flux/','气体通量',120) |
| | | } |
| | | const getPath=async()=> { |
| | | try { |
| | | var htt = window.location.protocol;// 获取协议 |
| | | var host = window.location.host;// 获取地址和端口号 |
| | | return htt+"//"+host; |
| | | } catch (error) { |
| | | console.error('Error fetching config:', error); |
| | | return ''; // 返回一个默认值或者空字符串 |
| | | } |
| | | } |
| | | |
| | | const initWebSocket =async (requireUrl: string,type: string,beat: number)=>{ |
| | | if (typeof WebSocket === 'undefined') { |
| | | alert('您的浏览器不支持socket'); |
| | | } else { |
| | | // 实例化socket |
| | | if(import.meta.env.MODE == 'development'){ |
| | | let uid = userInfos.value.uid |
| | | let url = import.meta.env.VITE_API_URL + requireUrl + `${uid}` |
| | | url = url.replace('https', 'ws').replace('http', 'ws') |
| | | state.socket = new WebSocket(url) |
| | | }else{ |
| | | const apiUrl = await getPath(); |
| | | let uid = userInfos.value.uid |
| | | let url = apiUrl + import.meta.env.VITE_API_URL + requireUrl + `${uid}` |
| | | url = url.replace('https', 'ws').replace('http', 'ws') |
| | | state.socket = new WebSocket(url) |
| | | } |
| | | |
| | | // 监听socket连接 |
| | | state.socket.onopen = () => { |
| | | console.log('socket连接成功') |
| | | startHeartbeat(beat) |
| | | |
| | | } |
| | | // 监听socket错误信息 |
| | | state.socket.onerror = () => { |
| | | console.log('socket连接错误') |
| | | console.log(state.socket,'soc') |
| | | // reconnect() |
| | | } |
| | | // 监听socket消息 |
| | | state.socket.onmessage = (msg) => { |
| | | // if (msg.data === '连接成功') return |
| | | const text = msg.data |
| | | //收到服务器信息,心跳重置并发送 |
| | | startHeartbeat(beat); |
| | | if (text.indexOf("连接成功") > 0) { |
| | | return; |
| | | } |
| | | if(type == '预警'){ |
| | | const socketData = JSON.parse(text) |
| | | state.warningGas = JSON.parse(JSON.stringify(socketData)) |
| | | state.dialogWarning = true |
| | | } |
| | | if(type == '异常'){ |
| | | const socketData = JSON.parse(text) |
| | | const deviceStatus = JSON.parse(JSON.stringify(socketData)) |
| | | if(deviceStatus.conState == 1){ |
| | | if(deviceStatus.fluxState == 0){ |
| | | if(deviceStatus.hardwareState.find(i=>i !== 0)){ |
| | | state.online = 1 |
| | | }else{ |
| | | state.online = 2 |
| | | } |
| | | }else{ |
| | | if(deviceStatus.hardwareState.find(i=>i !== 0)){ |
| | | state.online = 0 |
| | | }else{ |
| | | state.online = 1 |
| | | } |
| | | } |
| | | }else{ |
| | | if(deviceStatus.fluxState == 0){ |
| | | if(deviceStatus.hardwareState.find(i=>i !== 0)){ |
| | | state.online = 2 |
| | | }else{ |
| | | state.online = 3 |
| | | } |
| | | }else{ |
| | | if(deviceStatus.hardwareState.find(i=>i !== 0)){ |
| | | state.online = 1 |
| | | }else{ |
| | | state.online = 2 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if(type == '气体浓度'){ |
| | | state.gasData = JSON.parse(text) |
| | | let gasNum = '' |
| | | let newArr = JSON.parse(JSON.stringify(state.gasData)) |
| | | if(Array.isArray(newArr)){ |
| | | state.gasTotal = newArr.length |
| | | const weather = newArr.map((item)=>{ |
| | | return { |
| | | time: item.dataReceivingTime?item.dataReceivingTime.slice(11,19):'--', |
| | | temp: item.temp?item.temp:'--', |
| | | humidity: item.humidity?item.humidity:'--', |
| | | windSpeed: item.windSpeed?item.windSpeed:'--', |
| | | windDirection: item.windDirection?item.windDirection:'--', |
| | | pressure: item.pressure?item.pressure:'--' |
| | | } |
| | | }) |
| | | state.weatherData = [...weather].reverse().slice(0, 4); |
| | | }else{ |
| | | // state.gasTotal = 0 |
| | | getGasNdData() |
| | | } |
| | | for(let key in newArr[0]){ |
| | | if(newArr[0][key] == state.gasSearch && key.indexOf("gasName") !== -1){ |
| | | gasNum = key.substring(7) |
| | | } |
| | | } |
| | | const dotList = newArr.map((item)=>{ |
| | | for(let key in item){ |
| | | if(key.indexOf("gasValue") !== -1 && key.substring(8) == gasNum){ |
| | | return item[key] |
| | | } |
| | | } |
| | | }) |
| | | const gasTime = state.gasData.map(i=>i.dataReceivingTime?.slice(11,19)) |
| | | initgasN(dotList.slice(dotList.length - 50),gasTime.slice(gasTime.length - 50)) |
| | | } |
| | | |
| | | if(type == '气体通量'){ |
| | | state.gasTlData = JSON.parse(text) |
| | | let newArr = JSON.parse(JSON.stringify(state.gasTlData)) |
| | | if(Array.isArray(newArr)){ |
| | | state.tlTotal = newArr.length |
| | | }else{ |
| | | state.tlTotal = 0 |
| | | } |
| | | const gasTime = newArr.map(i=>i.dataReceivingTime?.slice(11,19)) |
| | | const gasTlTime = [...new Set(gasTime)] |
| | | let areaData = state.areaOptions.map((item)=>{ |
| | | return { |
| | | areaId: item.id, |
| | | name: item.name, |
| | | dotList: [] |
| | | } |
| | | }) |
| | | for(let i of gasTlTime){ |
| | | const sameTimeData = newArr.filter(it=>it.dataReceivingTime?.slice(11,19) == i) |
| | | for(let j of areaData){ |
| | | const foundData = sameTimeData.find(k=>k.areaId == j.areaId) |
| | | if(foundData){ |
| | | let gasNum = '' |
| | | for(let key in sameTimeData[0]){ |
| | | if(sameTimeData[0][key] == state.tlGasSearch && key.indexOf("gasName") !== -1){ |
| | | gasNum = key.substring(7) |
| | | } |
| | | } |
| | | for(let key in foundData){ |
| | | if(key.indexOf("gasValue") !== -1 && key.substring(8) == gasNum){ |
| | | j.dotList.push(foundData[key]) |
| | | } |
| | | } |
| | | }else{ |
| | | j.dotList.push(0) |
| | | } |
| | | } |
| | | } |
| | | const chartData = areaData.map((i)=>{ |
| | | return { |
| | | name: i.name, |
| | | type: 'bar', |
| | | stack: 'total', |
| | | data: i.dotList.slice(i.dotList.length - 20) |
| | | } |
| | | }) |
| | | initgasT(gasTlTime.slice(gasTlTime.length - 20),chartData) |
| | | } |
| | | |
| | | } |
| | | state.socket.onclose=()=>{ |
| | | getGasNdData() |
| | | getGasTlData() |
| | | getWindData() |
| | | } |
| | | } |
| | | } |
| | | const reconnect = (beat)=> { |
| | | if (state.socket.readyState === 1) { |
| | | // 如果状态等于1代表 websocket连接正常 |
| | | return; |
| | | } |
| | | if (state.lockReconnect || (state.maxReconnect !== -1 && state.reconnectTime >= state.maxReconnect)) { |
| | | return; |
| | | } |
| | | |
| | | // 让重连锁变为true,阻止进入下一个循环 |
| | | state.lockReconnect = true; |
| | | setTimeout(() => { |
| | | state.reconnectTime++; |
| | | console.log("尝试重连"); |
| | | // 建立新连接 |
| | | // initWebSocket(); |
| | | getGasSocket() |
| | | state.lockReconnect = false; |
| | | }, beat * 1000); |
| | | } |
| | | |
| | | const startHeartbeat = (beat)=> { |
| | | const webSocket = state.socket; |
| | | // 清空定时器 |
| | | clearTimeout(state.heartbeat); |
| | | state.heartbeat = null; |
| | | clearTimeout(state.heartbeatTimeOut); |
| | | state.heartbeatTimeOut = null; |
| | | // 延时发送下一次心跳 |
| | | // console.log("心跳开启"); |
| | | state.heartbeat = setTimeout(() => { |
| | | // 如果连接正常 |
| | | // console.log("连接状态", webSocket.readyState); |
| | | if (webSocket.readyState === 1) { |
| | | //这里发送一个心跳,后端收到后,返回一个心跳消息, |
| | | let params = JSON.stringify({ |
| | | type: "ping", |
| | | toUserId: userInfos.value.uid, |
| | | }); |
| | | webSocket.send(params); |
| | | // 心跳发送后,如果服务器超时未响应则断开,如果响应了会被重置心跳定时器 |
| | | state.heartbeatTimeOut = setTimeout(() => { |
| | | webSocket.close(); |
| | | // 响应超时时间 |
| | | }, beat * 1000); |
| | | } else { |
| | | // 否则重连 |
| | | reconnect(beat); |
| | | } |
| | | // 心跳间隔时间是30s |
| | | }, beat * 1000); |
| | | } |
| | | |
| | | const destroyedWs=()=> { |
| | | console.log("ws销毁"); |
| | | // 关闭使用close方法关闭socket |
| | | if (state.socket) { |
| | | state.socket.close(); |
| | | } |
| | | state.socket = null; |
| | | // 清除定时器 |
| | | state.timer = null; |
| | | clearInterval(state.timer); |
| | | clearTimeout(state.heartbeat); |
| | | state.heartbeat = null; |
| | | clearTimeout(state.heartbeatTimeOut); |
| | | state.heartbeatTimeOut = null; |
| | | } |
| | | |
| | | const config = reactive({ |
| | | header: ['预警级别','气体名称', '气体浓度', '时间'], |
| | | data: [ |
| | | ['红色预警', '甲烷', '19', '2023-08-10'], |
| | | ['<span style="color:red;">红色预警</span>', '甲烷', '19', '2023-08-10'], |
| | | ['红色预警', '甲烷', '19', '2023-08-10'], |
| | | ['红色预警', '甲烷', '19', '2023-08-10'], |
| | | ['红色预警', '甲烷', '19', '2023-08-10'], |
| | | ['红色预警', '甲烷', '19', '2023-08-10'] |
| | | ], |
| | | index: true, |
| | | columnWidth: [38], |
| | | data: [], |
| | | // index: true, |
| | | columnWidth: [200,200,200,200], |
| | | align: ['center','center','center','center','center'], |
| | | headerBGC: '', |
| | | oddRowBGC: '', |
| | | evenRowBGC: '' |
| | | }) |
| | | |
| | | const bigConfig = reactive({ |
| | | header: ['时间','温度', '湿度', '风速', '风向', '气压'], |
| | | data: [ |
| | | ['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'] |
| | | ], |
| | | align: ['center','center','center','center','center','center'], |
| | | headerBGC: '', |
| | | oddRowBGC: '', |
| | | evenRowBGC: '', |
| | | rowNum: 3 |
| | | }) |
| | | // const bigConfig = reactive({ |
| | | // header: ['时间','温度', '湿度', '风速', '风向', '气压'], |
| | | // data: [], |
| | | // align: ['center','center','center','center','center','center'], |
| | | // headerBGC: '', |
| | | // oddRowBGC: '', |
| | | // evenRowBGC: '', |
| | | // rowNum: 3 |
| | | // }) |
| | | |
| | | const mouseoverHandler = (e: any) => { |
| | | console.log(e) |
| | |
| | | } |
| | | |
| | | type EChartsOption = echarts.EChartsOption |
| | | const initgasN =()=>{ |
| | | |
| | | const initgasWind =(pointFive,twoZone,fourZone,sixZone,eightZone,tenZone,tenAbove)=>{ |
| | | let dom = document.getElementById(gasWind.value); |
| | | let myChart = echarts.init(dom) |
| | | let option: EChartsOption; |
| | | option = { |
| | | angleAxis: { |
| | | type: 'category', |
| | | data: ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE','SSE','S','SSW','SW','WSW','W','WNW','NW','NNW'], |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: { |
| | | color: '#11feee' |
| | | } |
| | | } |
| | | }, |
| | | radiusAxis: { |
| | | axisLine: { |
| | | lineStyle: { |
| | | color: '#11feee' |
| | | } |
| | | }, |
| | | nameTextStyle:{ |
| | | fontSize: 10, |
| | | color: '#fff' |
| | | }, |
| | | animation: true |
| | | }, |
| | | polar: { |
| | | center: ['50%','40%'], |
| | | radius: '60%' |
| | | }, |
| | | series: [{ |
| | | type: 'bar', |
| | | data: pointFive, |
| | | coordinateSystem: 'polar', |
| | | name: '<0.5m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | data: twoZone, |
| | | coordinateSystem: 'polar', |
| | | name: '0.5-2m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | data: fourZone, |
| | | coordinateSystem: 'polar', |
| | | name: '2-4m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | data: sixZone, |
| | | coordinateSystem: 'polar', |
| | | name: '4-6m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | data: eightZone, |
| | | coordinateSystem: 'polar', |
| | | name: '6-8m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | data: tenZone, |
| | | coordinateSystem: 'polar', |
| | | name: '8-10m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }, { |
| | | type: 'bar', |
| | | data: tenAbove, |
| | | coordinateSystem: 'polar', |
| | | name: '>10m/s', |
| | | stack: 'a', |
| | | emphasis: { |
| | | focus: 'series' |
| | | } |
| | | }], |
| | | legend: { |
| | | show: true, |
| | | top:'bottom', |
| | | left:'0', |
| | | data: ['<0.5m/s', '0.5-2m/s', '2-4m/s','4-6m/s','6-8m/s','8-10m/s','>10m/s'], |
| | | orient:'horizontal', |
| | | itemWidth: 10, |
| | | itemHeight: 6, |
| | | itemGap: 4, |
| | | textStyle: { |
| | | color: '#11feee', |
| | | fontSize: 12 |
| | | } |
| | | } |
| | | } |
| | | |
| | | option && myChart.setOption(option); |
| | | window.addEventListener("resize",function (){ |
| | | myChart.resize(); |
| | | }); |
| | | } |
| | | |
| | | const initgasN =(data:Array<string>,time: Array<string>)=>{ |
| | | nextTick(() => { |
| | | let dom = document.getElementById(gasN.value); |
| | | let myChart = echarts.init(dom); |
| | | let option: EChartsOption; |
| | | option = { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: ['10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30'], |
| | | data: time, |
| | | axisLabel: { |
| | | color: '#fff' |
| | | }, |
| | | splitLine: { |
| | | show: false |
| | | } |
| | | }, |
| | | yAxis: { |
| | |
| | | }, |
| | | grid: { |
| | | top: '5%', |
| | | bottom: '10%', |
| | | right: '0%' |
| | | bottom: '15%', |
| | | right: '2%' |
| | | }, |
| | | series: [ |
| | | { |
| | | data: [150, 230, 224, 218, 135, 147, 230, 224, 218, 135, 147, 260], |
| | | data: data, |
| | | type: 'line', |
| | | // label:{ |
| | | // show: true, |
| | | // color: '#fff', |
| | | // textBorderColor: 'transparent' |
| | | // }, |
| | | label:{ |
| | | show: true, |
| | | color: '#fff', |
| | | textBorderColor: 'transparent', |
| | | fontSize: 8 |
| | | }, |
| | | // showSymbol: false, |
| | | lineStyle:{ |
| | | color: '#54d5ff' |
| | | }, |
| | | itemStyle:{ |
| | | color: '#54d5ff', |
| | | }, |
| | | areaStyle:{ |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [{ |
| | | offset: 0, color: '#2af' // 0% 处的颜色 |
| | | }, { |
| | | offset: 1, color: 'rgba(255,255,255,.1)' // 100% 处的颜色 |
| | | }], |
| | | global: false // 缺省为 false |
| | | } |
| | | } |
| | | } |
| | | ] |
| | |
| | | window.addEventListener("resize",function (){ |
| | | myChart.resize(); |
| | | }); |
| | | }); |
| | | } |
| | | const initgasT =()=>{ |
| | | const initgasT =(time: Array<string>,data: Array<any>)=>{ |
| | | let dom = document.getElementById(gasT.value); |
| | | let myChart = echarts.init(dom); |
| | | let option: EChartsOption; |
| | |
| | | }, |
| | | xAxis: { |
| | | type: 'category', |
| | | data: ['10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30'], |
| | | data: time, |
| | | axisLabel: { |
| | | color: '#fff' |
| | | } |
| | |
| | | color: '#ccc' |
| | | } |
| | | }, |
| | | series: [ |
| | | { |
| | | name: '2011', |
| | | type: 'bar', |
| | | data: [18, 23, 29, 10, 13, 6], |
| | | label:{ |
| | | show: true, |
| | | color: '#fff', |
| | | textBorderColor: 'transparent' |
| | | } |
| | | }, |
| | | { |
| | | name: '2012', |
| | | type: 'bar', |
| | | data: [19, 23, 31, 12, 13, 6], |
| | | label:{ |
| | | show: true, |
| | | color: '#fff', |
| | | textBorderColor: 'transparent' |
| | | } |
| | | } |
| | | ] |
| | | series: data |
| | | } |
| | | |
| | | option && myChart.setOption(option); |
| | |
| | | }); |
| | | } |
| | | |
| | | const map = shallowRef(null) |
| | | const initMap=()=> { |
| | | let m = map.value |
| | | window._AMapSecurityConfig = { |
| | | securityJsCode: "456045075984862a9806587f0d7fee3c", |
| | | }; |
| | | AMapLoader.load({ |
| | | key: '5dbeedfa28e0d7fffb59684446569773', // 申请好的Web端开发者Key,首次调用 load 时必填 |
| | | version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15 |
| | | plugins: [] // 需要使用的的插件列表,如比例尺'AMap.Scale'等 |
| | | }) |
| | | .then(AMap => { |
| | | if (AMap && typeof AMap.Map === 'function') { |
| | | m = new AMap.Map('bigMap', { |
| | | viewMode: '3D', |
| | | mapStyle: 'amap://styles/normal', |
| | | zoom: 18, |
| | | center: [85.057805, 45.62550], |
| | | // layers:[ |
| | | // new AMap.TileLayer.RoadNet({}), |
| | | // new AMap.TileLayer.Satellite() |
| | | // ], |
| | | zooms:[2,20], |
| | | }) |
| | | |
| | | AMap.plugin(["AMap.DistrictSearch","AMap.ToolBar","AMap.ControlBar"],()=> { |
| | | var district = new AMap.DistrictSearch({ |
| | | extensions: "all", |
| | | subdistrict: 0, |
| | | level: "district", |
| | | }); |
| | | district.search("克拉玛依市", function (status, result) { |
| | | // // 外多边形坐标数组和内多边形坐标数组 |
| | | var outer = [ |
| | | new AMap.LngLat(-360, 90, true), |
| | | new AMap.LngLat(-360, -90, true), |
| | | new AMap.LngLat(360, -90, true), |
| | | new AMap.LngLat(360, 90, true), |
| | | ]; // 使得遮盖填充反向 |
| | | var holes = result.districtList[0].boundaries; // 得到该区域的边界坐标集合 |
| | | |
| | | var pathArray = [outer]; |
| | | pathArray.push.apply(pathArray, holes); |
| | | var polygon = new AMap.Polygon({ |
| | | pathL: pathArray, |
| | | //线条颜色,使用16进制颜色代码赋值。默认值为#006600 |
| | | strokeColor: "#11feee", |
| | | strokeWeight: 3, |
| | | fillColor: "#051342", |
| | | fillOpacity: 1, |
| | | strokeStyle: "solid", |
| | | strokeDasharray: [2, 2], |
| | | }); |
| | | polygon.setPath(pathArray) |
| | | m.add(polygon); |
| | | }) |
| | | m.addControl(new AMap.ToolBar({ |
| | | position: { |
| | | top: '20px', |
| | | left: 'calc(25% + 5px)' |
| | | } |
| | | })) |
| | | m.addControl(new AMap.ControlBar({ |
| | | position: { |
| | | top: '20px', |
| | | right: 'calc(25% + 5px)' |
| | | } |
| | | })) |
| | | }) |
| | | |
| | | } else { |
| | | console.error('AMap 或 AMap.Map 不可用'); |
| | | } |
| | | }) |
| | | .catch(e => { |
| | | console.log('加载高德地图时出错:', e) |
| | | }) |
| | | } |
| | | // 当前时间 |
| | | const getDateTime = () => { |
| | | const curTime = new Date().toLocaleString('zh', timeForm).replace(/\//g, '-'); |
| | |
| | | context.emit('clickFull') |
| | | } |
| | | |
| | | onUnmounted(()=>{ |
| | | map.value && map.value.destroy(); |
| | | }) |
| | | // onUnmounted(()=>{ |
| | | // map.value && map.value.destroy(); |
| | | // }) |
| | | |
| | | return { |
| | | timeForm, |
| | | config, |
| | | bigConfig, |
| | | gasN, |
| | | gasT, |
| | | map, |
| | | gasWind, |
| | | audioRef, |
| | | confirmWarning, |
| | | playAudio, |
| | | updatePolygonPath, |
| | | toNdPage, |
| | | toTlPage, |
| | | timeChange, |
| | | mouseoverHandler, |
| | | changeTotal, |
| | | changeWindQuery, |
| | | changeWind, |
| | | windTimeChange, |
| | | clickHandler, |
| | | changeGas1, |
| | | changeGas2, |
| | | toFull, |
| | | back, |
| | | ...toRefs(state) |
| | |
| | | } |
| | | }); |
| | | </script> |
| | | <style lang="scss"> |
| | | .warningMsg{ |
| | | background: rgba(4,18,67,.8); |
| | | border: 1px solid #00FFFF; |
| | | border-radius: 8px; |
| | | |
| | | .el-dialog__title{ |
| | | color: #fff; |
| | | } |
| | | |
| | | .warning-cont{ |
| | | width: 100%; |
| | | &>div{ |
| | | width: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | color: #fff; |
| | | margin-bottom: 10px; |
| | | span{ |
| | | &:first-of-type{ |
| | | text-align: right; |
| | | } |
| | | &:last-of-type{ |
| | | margin-left: 10px; |
| | | color: #11feee; |
| | | } |
| | | } |
| | | .red{ |
| | | color: red; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | <style lang="scss" scoped> |
| | | .charts-container{ |
| | | width: 100%; |
| | |
| | | display: flex; |
| | | align-items: flex-end; |
| | | justify-content: space-between; |
| | | position: relative; |
| | | //position: relative; |
| | | |
| | | &>div{ |
| | | height: 100%; |
| | |
| | | letter-spacing: 4px; |
| | | font-size: 16px; |
| | | font-weight: bolder; |
| | | line-height: 38px; |
| | | color: #11feee; |
| | | } |
| | | .long-tit{ |
| | |
| | | } |
| | | .el-select{ |
| | | width: 60%; |
| | | height: 20px; |
| | | height: 24px; |
| | | } |
| | | ::v-deep(.el-popper){ |
| | | background-color: rgba(10,31,92,1); |
| | |
| | | |
| | | .sys-status{ |
| | | width: 66%; |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 16px; |
| | | line-height: 40px; |
| | | .onlineIcon{ |
| | | width: 18px; |
| | | height: 18px; |
| | | color: #11feee; |
| | | } |
| | | .offlineIcon{ |
| | | width: 18px; |
| | | height: 18px; |
| | | color: red; |
| | | } |
| | | div{ |
| | | color: #fff; |
| | | margin-left: 2px; |
| | | .online{ |
| | | color: #11feee; |
| | | margin-left: 10px; |
| | | } |
| | | .offline{ |
| | | color: red; |
| | | margin-left: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .sys-offstatus{ |
| | | width: 66%; |
| | | height: 70%; |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | color: #fff; |
| | | margin-left: 2px; |
| | | span{ |
| | | color: #11feee; |
| | | color: red; |
| | | margin-left: 10px; |
| | | font-size: 14px; |
| | | } |
| | |
| | | } |
| | | |
| | | .el-radio-group{ |
| | | height: 90%; |
| | | height: 24px; |
| | | width: 66%; |
| | | flex-flow: row nowrap; |
| | | display: flex; |
| | |
| | | } |
| | | :deep(.el-date-editor){ |
| | | width: 66%; |
| | | height: 20px; |
| | | height: 24px; |
| | | .el-range-separator{ |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-input__wrapper){ |
| | | height: 24px; |
| | | box-shadow: none; |
| | | border: 1px solid #11FEEE; |
| | | background: #005dd6; |
| | | background: rgba(0,0,0,0); |
| | | color: #fff; |
| | | |
| | | input{ |
| | |
| | | |
| | | .searchGroup{ |
| | | width: 60%; |
| | | height: 20px; |
| | | height: 24px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: right; |
| | | padding-right: 4px; |
| | | .checkMore{ |
| | | width: 22px; |
| | | height: 22px; |
| | | cursor: pointer; |
| | | margin-left: 10px; |
| | | line-height: 24px; |
| | | font-size: 14px; |
| | | border-radius: 50%; |
| | | border: 1px solid #11FEEE; |
| | | color: #11FEEE; |
| | | text-align: center; |
| | | &:hover{ |
| | | background-color: rgba(10,31,92,1); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .chart-cont{ |
| | |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 5px 10px; |
| | | padding: 0 10px 5px 15px; |
| | | .bigPic{ |
| | | width: 100%; |
| | | height: 50px; |
| | |
| | | background-size: 90% 90%; |
| | | } |
| | | } |
| | | .weather{ |
| | | width: 100%; |
| | | height: calc(100% - 60px); |
| | | background: url("../../../assets/warningScreen/scroll-bg.png") no-repeat bottom; |
| | | background-size: 100% 82%; |
| | | |
| | | tr{ |
| | | width: 100%; |
| | | height: 20%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-around; |
| | | td{ |
| | | width: calc(100% / 6); |
| | | text-align: center; |
| | | box-sizing: border-box; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | .weatherTit{ |
| | | color: #11feee; |
| | | } |
| | | .weatherRow{ |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | :deep(.dv-scroll-board){ |
| | | width: 100%; |
| | | height: calc(100% - 60px); |
| | | .header{ |
| | | color: #11feee; |
| | | text-align: center; |
| | | } |
| | | .rows{ |
| | | background: url("../../../assets/warningScreen/scroll-bg.png") no-repeat center; |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | #bigMap{ |
| | | position: absolute; |
| | | width: 100%; |
| | | height: 100%; |
| | | left: 0; |
| | | top: 0; |
| | | |
| | | :deep(.amap-logo){ |
| | | display: none!important; |
| | | visibility: hidden!important; |
| | | } |
| | | |
| | | :deep(.amap-copyright) { |
| | | display: none!important; |
| | | visibility: hidden!important; |
| | | } |
| | | } |
| | | |
| | |
| | | background-size: 100% 100%; |
| | | } |
| | | } |
| | | //#bigMap{ |
| | | //position: absolute; |
| | | //width: 100%; |
| | | //height: 100%; |
| | | //left: 0; |
| | | //top: 0; |
| | | |
| | | // :deep(.amap-logo){ |
| | | // display: none!important; |
| | | // visibility: hidden!important; |
| | | // } |
| | | // |
| | | // :deep(.amap-copyright) { |
| | | // display: none!important; |
| | | // visibility: hidden!important; |
| | | // } |
| | | //} |
| | | //.main-middle{ |
| | | // width: calc(50% - 10px); |
| | | // height: calc((100%/3) - (20px/3)); |
| | | // z-index: 9; |
| | | // .mid-bottom{ |
| | | // width: 100%; |
| | | // height: 100%; |
| | | // background: url("../../../assets/warningScreen/chart-bg4.png") no-repeat center; |
| | | // background-size: 100% 100%; |
| | | // } |
| | | //} |
| | | .main-middle{ |
| | | width: calc(50% - 10px); |
| | | height: calc((100%/3) - (20px/3)); |
| | | z-index: 9; |
| | | position: relative; |
| | | .map-filter{ |
| | | position: absolute; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-end; |
| | | width: 270px; |
| | | right: 20px; |
| | | top: 20px; |
| | | padding: 2px; |
| | | z-index: 99; |
| | | border: 1px solid #11FEEE; |
| | | border-radius: 4px; |
| | | //background: url("../../../assets/warningScreen/windbg.png") no-repeat center; |
| | | |
| | | .el-radio-group{ |
| | | height: 24px; |
| | | width: 100%; |
| | | flex-flow: row nowrap; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | .el-radio{ |
| | | width: calc((100% - 6px)/2); |
| | | margin-right: 0; |
| | | margin-left: 2px; |
| | | margin-bottom: 0; |
| | | text-align: center; |
| | | border-color: #ccc; |
| | | &.el-radio--small{ |
| | | height: 20px; |
| | | } |
| | | :deep(.el-radio__inner){ |
| | | display: none; |
| | | } |
| | | :deep(.el-radio__label){ |
| | | width: 100%; |
| | | padding-left: 0; |
| | | font-size: 10px; |
| | | color: #ccc; |
| | | } |
| | | } |
| | | .el-radio.is-bordered.is-checked{ |
| | | border-color: #11FEEE; |
| | | background: rgba(6,24,88,.6); |
| | | box-shadow: 0 3px 8px rgba(0,0,0,.2); |
| | | |
| | | :deep(.el-radio__label){ |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | |
| | | :deep(.el-date-editor){ |
| | | width: 100%; |
| | | height: 24px; |
| | | .el-range-separator{ |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | :deep(.el-input__wrapper){ |
| | | height: 24px; |
| | | box-shadow: none; |
| | | border: 1px solid #11FEEE; |
| | | background: rgba(6,24,88,.6); |
| | | color: #fff; |
| | | |
| | | input{ |
| | | font-size: 10px; |
| | | color: #fff; |
| | | } |
| | | .el-icon{ |
| | | display: none; |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .el-select{ |
| | | width: 100%; |
| | | height: 24px; |
| | | } |
| | | ::v-deep(.el-popper){ |
| | | background-color: rgba(10,31,92,1); |
| | | border: 1px solid rgba(17,254,238,.4); |
| | | color: #11FEEE; |
| | | |
| | | .el-icon{ |
| | | color: #11FEEE; |
| | | } |
| | | .el-select-dropdown__item{ |
| | | color: #11FEEE; |
| | | } |
| | | .el-select-dropdown__item.hover{ |
| | | background: #0049af; |
| | | } |
| | | } |
| | | ::v-deep(.el-popper__arrow){ |
| | | &::before{ |
| | | background-color: rgba(10,31,92,.6) !important; |
| | | border: 1px solid rgba(17,254,238,.4); |
| | | } |
| | | } |
| | | } |
| | | .bigMap{ |
| | | width: 100%; |
| | | height: calc((200% - 40px)/3 + 10px); |
| | | padding: 15px; |
| | | background: url('../../../assets/warningScreen/map-bg.png') no-repeat center; |
| | | background-size: 100% 100%; |
| | | :deep(.BMap_cpyCtrl){ |
| | | display: none!important; |
| | | visibility: hidden!important; |
| | | } |
| | | |
| | | :deep(.anchorBL) { |
| | | display: none!important; |
| | | visibility: hidden!important; |
| | | } |
| | | } |
| | | .mid-bottom{ |
| | | width: 100%; |
| | | height: 100%; |
| | | height: calc((100%/3) - (20px/3)); |
| | | background: url("../../../assets/warningScreen/chart-bg4.png") no-repeat center; |
| | | background-size: 100% 100%; |
| | | } |