浏览代码

增加滚动报警模块

chenwen 1 年之前
父节点
当前提交
ef205338c6

+ 12 - 0
src/api/noticeBar.js

@@ -0,0 +1,12 @@
+import request from '../utils/request';
+
+const api={}
+
+api.loadAlarms=()=>{
+	return request({
+	    url: '/alarm/log/loadAllRtAlarms',
+		method: 'get'
+	})
+}
+
+export  default api

二进制
src/assets/img/sound_close.png


二进制
src/assets/img/sound_open.png


+ 2 - 2
src/components/Header.vue

@@ -23,14 +23,14 @@
         <div class="header-right">
             <div class="header-user-con">
                 <!-- 消息中心 -->
-                <div class="btn-bell">
+               <!-- <div class="btn-bell">
                     <el-tooltip effect="dark" :content="message?`有${message}条未读消息`:`消息中心`" placement="bottom">
                         <router-link to="/my">
                             <el-icon  color="#ffffff"><Bell/></el-icon>
                         </router-link>
                     </el-tooltip>
                     <span class="btn-bell-badge" v-if="message"></span>
-                </div>
+                </div> -->
                
                 <!-- 用户名下拉菜单 -->
                 <el-dropdown class="user-name"  @command="handleCommand">

+ 214 - 0
src/components/noticeBar/NoticeBar.vue

@@ -0,0 +1,214 @@
+<template>
+	<div class="notice-bar-wrap">
+		<div class="icon-wrap" :class="{'sound-open':soundOpen,'sound-close':!soundOpen}" @click="soundHandler">
+			<audio loop   ref="audio">
+				<source src="./assets/alarm.mp3" />
+			</audio>
+		</div>
+		<div class="notice-box" @mouseover="animationPlayState='paused'" @mouseout="animationPlayState='running'" @click="openDrawer">
+			<div class="notice-content" :style="{
+				animationDuration: animationDuration,
+				animationPlayState:animationPlayState
+			}">
+				<span class="notice-text" v-for="alarm in alarmList">{{alarm.wellName+alarm.alarmDesc+'【'+alarm.alarmTime+'】'}}</span>
+				
+			</div>
+		</div>
+		<div class="icon-wrap"></div>
+		
+		<el-drawer
+		    v-model="drawerShowCtr"
+		    title="报警列表"
+		    direction="rtl"
+		  >
+		    <el-table :data="alarmList" style="width: 100%">
+				<el-table-column prop="wellName" label="井名" width="120" />
+		       <el-table-column prop="alarmTime" label="报警时间" width="180" />
+		       <el-table-column prop="alarmDesc" label="报警内容"/>
+			</el-table>
+		</el-drawer>
+	</div>
+</template>
+
+<script setup>
+	import {ref,onMounted,onUnmounted,watch} from 'vue'
+	import noticeBarAPI from "../../api/noticeBar.js"
+	import {ElMessageBox,ElMessage} from "element-plus"
+	
+	const alarmList=ref([])
+	
+	const drawerShowCtr=ref(false)
+	
+	const props=defineProps({
+		contents: {
+			type: Array,
+			default() {
+				return ['通知内容3','通知内容2'];
+			}
+		},
+		speed: {
+			type: [Number, String],
+			default: 80
+		}
+	})
+	
+	
+	const openDrawer=(well)=>{
+		drawerShowCtr.value=true
+	}
+	
+	
+	const animationPlayState=ref('running')
+	const animationDuration=ref('10s')
+	
+	const audio=ref(null)
+	const soundOpen=ref(false)
+	
+	const soundHandler=()=>{
+		soundOpen.value=!soundOpen.value
+		if(!soundOpen.value){
+			audio.value.pause()
+		}
+		
+	}
+	
+	const soundAlarmCheck=()=>{
+		if(!alarmList.value || alarmList.value.length==0){
+			audio.value.pause()
+			return
+		}
+		let needSound=false
+		alarmList.value.forEach(alarm=>{
+			if(alarm.alarmMode.indexOf('sound')>=0){
+				needSound=true
+				return false
+			}
+		})
+		
+		if(needSound&&soundOpen.value&&audio.value.paused){
+			audio.value.play()
+		}
+		else if(!needSound){
+			audio.value.pause()
+		}
+	}
+	
+	const loadAlarm=()=>{
+		noticeBarAPI.loadAlarms().then(resp=>{
+			console.log(resp)
+			if(resp.code!=0 || !resp.data){
+				alarmList.value=[]
+			}
+			else{
+				let alarms=[]
+				resp.data.forEach(alarmObj=>{
+					for(let code in alarmObj){
+						alarms.push(JSON.parse(alarmObj[code]))
+					}
+				})
+				alarmList.value=alarms
+			}
+			
+			soundAlarmCheck()
+			
+		}).catch(err=>{
+			console.log(err)
+		})
+	}
+	
+	let alarmTimer=null
+	
+	onMounted(()=>{
+		let nboxRect=document.querySelector('.notice-box').getBoundingClientRect()
+		
+		animationDuration.value=`${nboxRect.width / props.speed}s`
+		
+		loadAlarm()
+		
+		alarmTimer=setInterval(()=>{loadAlarm()},30000)
+		
+		if(!soundOpen.value){
+			ElMessage.warning("声音报警处于关闭状态")
+		}
+	})
+	
+	onUnmounted(()=>{
+		if(alarmTimer!=null){
+			clearInterval(alarmTimer)
+		}
+	})
+	
+	
+	watch(
+		()=>props.contents,
+		(newcons,oldcons)=>{
+			
+		},
+		{ immediate: true }
+	)
+</script>
+
+<style scoped>
+	.notice-bar-wrap{
+		width:100%;
+		height: 100%;
+		box-sizing: border-box;
+		display: flex;
+		flex-flow:row nowrap;
+		background-color: #fef0f0;
+		align-items: center;
+	}
+	
+	.notice-box{
+		flex:1;
+		height: 100%;
+	}
+	.icon-wrap{
+		padding:0px 5px;
+		width:18px;
+		height: 18px;
+		cursor: pointer;
+		position: relative;
+		z-index: 10;
+	}
+	
+	
+	.sound-open{
+		background-size:contain;
+		background: transparent url('../../assets/img/sound_open.png') no-repeat center center;
+	}
+	.sound-close{
+		background-size:cover;
+		background: transparent url('../../assets/img/sound_close.png') no-repeat center center;
+	}
+	
+	
+	.notice-content {
+		animation: marquee-animation 10s linear infinite both;
+		text-align: right;
+		padding-left: 100%; /*关键设置保证无缝衔接*/
+		display: flex;
+		flex-flow:row nowrap;
+		align-items: center;
+		height: 100%;
+		color:#fa3534;
+	}
+	/*关键设置保证滚动内容不换行*/
+	.notice-text{
+		font-size: 14px;
+		word-break: keep-all;
+		white-space: nowrap;
+		margin-right:20px;
+		
+	}
+	
+	@keyframes marquee-animation {
+		0% {
+			transform: translate3d(0, 0, 0);
+		}
+	
+		100% {
+			transform: translate3d(-100%, 0, 0);
+		}
+	}
+</style>

二进制
src/components/noticeBar/assets/alarm.mp3


+ 11 - 2
src/pages/Home.vue

@@ -2,7 +2,9 @@
 	<div class="about">
 		<v-header />
 		<v-sidetree />
+		
 		<div class="content-box" :class="{ 'content-collapse': collapse }">
+			<div class="notice-bar"><NoticeBar/></div>
 			<el-tabs type="card" v-model="activeTab" closable class="tabWrap" @tab-remove="removeTabHandle">
 				 <el-tab-pane v-for="(item, index) in menuTabs" :key="item.name" :label="item.title" :name="item.name">
 					<transition name="fade">
@@ -22,6 +24,8 @@
 	
 	import vHeader from "../components/Header.vue"
 	import vSidetree from "../components/Sidetree.vue"
+	import NoticeBar from "../components/noticeBar/NoticeBar.vue"
+	
 	import { storeToRefs } from "pinia"
 	import { useHomeStore } from "../store/home.js"
 	import app from "../utils/app.js"
@@ -125,7 +129,7 @@
 		height:100%;
 	}
 	.tabWrap:deep(.el-tabs__content){
-		height: calc(100% - 45px);
+		height: calc(100% - 72px);
 		overflow:auto;
 	}
 	
@@ -135,7 +139,7 @@
 	}
 	
 	.tabWrap:deep(.el-tabs__header){
-		margin:0px;
+		margin:0px 0px 2px;
 	}
 	
 	.content-box:deep(.el-tabs--card>.el-tabs__header .el-tabs__item .is-icon-close){
@@ -148,4 +152,9 @@
 	/* .content-box:deep(.el-tabs--card>.el-tabs__header .el-tabs__item:hover){
 		padding:0 20px;
 	} */
+	
+	.notice-bar{
+		height:30px;
+		border-bottom:1px solid #e2e2e2;
+	}
 </style>

+ 2 - 2
src/pages/alarm/AlarmDefine.vue

@@ -136,8 +136,8 @@
 	const loadParams=(wellId)=>{
 		alarmDefineAPI.loadWellParam(wellId).then(resp=>{
 			if(resp.code==0){
-				console.log(resp)
-				wellParamList.value=resp.data.data
+				//console.log(resp)
+				wellParamList.value=resp.data
 			}
 		})
 	}

+ 1 - 1
src/pages/single/Liquid.vue

@@ -295,7 +295,7 @@
 		flex-flow:column nowrap;
 	}
 	.liquid-tab{
-		height: calc(100vh - 485px);
+		height: calc(100vh - 515px);
 	}
 	.liquid-curve{
 		height:320px;