Bladeren bron

增加报警设置界面、设置组件

chenwen 2 jaren geleden
bovenliggende
commit
f38fd9a841
4 gewijzigde bestanden met toevoegingen van 564 en 0 verwijderingen
  1. 41 0
      src/api/alarmDefine.js
  2. 101 0
      src/components/CondExpress.vue
  3. 79 0
      src/components/CondExpressGroup.vue
  4. 343 0
      src/pages/alarm/AlarmDefine.vue

+ 41 - 0
src/api/alarmDefine.js

@@ -0,0 +1,41 @@
+import request from '../utils/request';
+
+const api={}
+
+api.loadWellParam = (wellId)=>{
+	return request({
+	    url: '/base/wellparam/loadByWell',
+	    params:  {wellId}
+	});
+}
+
+api.loadAlarmDefine = (holderId)=>{
+	return request({
+	    url: '/base/alarmdefine/loadByHolder',
+	    method: 'post',
+		params:  {holderId}
+	});
+}
+
+api.save=(data)=>{
+	let url='/base/alarmdefine/add'
+	if(data.alarmId){
+		url='/base/alarmdefine/update'
+	}
+	return request({
+	    url: url,
+	    method: 'post',
+		data: data
+	});
+	
+}
+
+api.del = (data) => {
+	    return request({
+	        url: '/base/alarmdefine/delete',
+	        method: 'post',
+			params:  data
+	    });
+}
+
+export  default api

+ 101 - 0
src/components/CondExpress.vue

@@ -0,0 +1,101 @@
+<template>
+	<div class="express-box">
+		<el-select v-model="condition.param" placeholder="选择参数" style="width: 160px" @change="handleCondChange">
+		  <el-option 
+			v-for="item in paramOpts"
+			:key="item.paramId"
+			:label="item.paramName"
+			:value="item.paramId"
+		  />
+		</el-select>
+		<el-select v-model="condition.symbol" placeholder="比较" style="width: 80px" @change="handleCondChange">
+		  <el-option label=">" value=">" />
+		  <el-option label=">=" value=">=" />
+		  <el-option label="=" value="=" />
+		  <el-option label="<" value="<" />
+		  <el-option label="<=" value="<=" />
+		</el-select>
+		<el-input-number
+		      v-model="condition.val"
+		      placeholder="阀值"
+		      style="width:100px"
+			  :controls="false"
+			  @change="handleCondChange"
+		    >
+		     
+		</el-input-number>
+	</div>
+</template>
+
+<script setup>
+	import {reactive,ref,watch} from 'vue'
+	
+	
+	
+	const condition=reactive({
+		label:null,
+		param:null,
+		symbol:null,
+		val:null
+	})
+	
+	const props=defineProps({
+		paramOpts:{
+			type:Array,
+			default:[{
+				paramName:'',
+				paramId:null
+			}]
+		},
+		initCondition:{
+			type:Object,
+			default:{
+				param:null,
+				symbol:null,
+				val:null
+			}
+		}
+	})
+	
+	
+	watch(
+		[
+			()=>props.paramOpts,
+			()=>props.initCondition
+		],
+		([newVal1, newVal2])=>{
+			if(newVal1.length==1){
+				condition.param=newVal1[0].paramId
+			}
+			if(newVal2){
+				console.log(newVal2)
+				Object.assign(condition,newVal2)
+			}
+			
+		},
+		{immediate:true}
+	)
+	
+	const emit=defineEmits(['conditionChange'])
+	
+	const handleCondChange=(val)=>{
+		let opt={}
+		if(props.paramOpts&&props.paramOpts.length==1){
+			opt=props.paramOpts[0]
+		}
+		else if(props.paramOpts){
+			opt=props.paramOpts.find(item=>item.paramId==condition.param)
+		}
+		
+		condition.label=opt.paramName
+		
+		emit('conditionChange',condition)
+	}
+	
+</script>
+
+<style scoped>
+	.express-box{
+		display: flex;
+	}
+</style>

+ 79 - 0
src/components/CondExpressGroup.vue

@@ -0,0 +1,79 @@
+<template>
+	<div class="cond-express-group">
+		
+			<div v-for="(item,index) in modelValue" style="display: flex;align-items: center;">
+				<div v-if="index>0" class="pretag">且</div>
+				<div v-else class="pretag">当</div>
+				<CondExpress  :initCondition="item"  :paramOpts="paramOpts" class="cond-express-item" @conditionChange="(condition)=>{handleChange(condition,index)}"/>
+				<el-icon size="25" color="#999" @click="delCond(index)" v-if="index>0"><CircleClose/></el-icon>
+			</div>
+			
+		
+		    <el-icon size="25" color="#999" @click="addCond" style="margin:20px"><CirclePlus/></el-icon>
+	</div>
+	
+	
+	
+</template>
+
+<script setup>
+	import {reactive,ref} from 'vue'
+	import CondExpress from './CondExpress.vue'
+	
+	//defineProps(['modelValue'])
+	const emit=defineEmits(['update:modelValue'])
+	
+	const condParamsOpt=ref([])
+	
+	const props=defineProps({
+		modelValue:{
+			type:Array,
+			default:[]
+		},
+		paramOpts:{
+			type:Array,
+			default:[{
+				paramName:'',
+				paramId:null
+			}]
+		},
+	})
+	
+	const handleChange=(condition,index)=>{
+		
+		props.modelValue[index]=condition
+		//console.log(props.modelValue)
+		emit('update:modelValue',props.modelValue)
+	}
+	
+	const addCond=()=>{
+		props.modelValue.push({
+			label:null,
+			param:null,
+			symbol:null,
+			val:null
+		})
+	}
+	
+	const delCond=(index)=>{
+		props.modelValue.splice(index,1)
+	}
+	
+	
+</script>
+
+<style scoped>
+	.cond-express-group .cond-express-item{
+		margin: 10px 20px 10px 0px;
+		
+	}
+	
+	.cond-express-group  .el-icon{
+		cursor:pointer;
+	}
+	
+	.pretag{
+		width:20px;
+		box-sizing: border-box;
+	}
+</style>

+ 343 - 0
src/pages/alarm/AlarmDefine.vue

@@ -0,0 +1,343 @@
+<template>
+	<div class="page-container">
+		<div class="page-side">
+			<el-card class="box-card" style="height: 100%;min-width:180px;">
+			    <template #header>
+			      <div class="card-header" :class="{'side-item-active':activeItemIdx==-1}" @click="handleParamSelect(crtWell,-1)">
+			        <span>{{crtWell.wellName}}</span>
+			        
+			      </div>
+			    </template>
+				<el-scrollbar>
+					<div v-for="(item,index) in wellParamList" :key="index" class="side-item" :class="{'side-item-active':activeItemIdx==index}" @click="handleParamSelect(item,index)">{{ item.paramName }}</div>
+				</el-scrollbar>
+			    
+			  </el-card>
+			
+		</div>
+		<div class="page-main">
+			<el-table :data="alarmList" style="height:200px;" @row-click="handleAlarmRowClick">
+			    <el-table-column prop="alarmSourceName" label="报警源" width="180" />
+			    <el-table-column prop="expressDesc" label="报警条件"  />
+				<el-table-column prop="alarmModeName" label="报警方式" width="160" />
+				<el-table-column prop="alarmGradeName" label="报警等级" width="100" />
+				<el-table-column prop="usingIf" label="状态" width="80">
+					<template #default="scope">
+						<div>{{scope.row.usingIf?'启用':'禁用'}}</div>
+					</template>
+				</el-table-column>
+					
+				<el-table-column prop="modifyTime" label="更新时间"  width="160"/>
+			</el-table>
+			<div class="edit-box">
+				<el-form :model="formModel" ref="formcomp"  label-position="right" label-width="100" :inline="false" :rules="rules" :inline-message="true">
+					
+					<el-form-item label="报警等级">
+						<el-select v-model="formModel.alarmGrade" placeholder="报警等级" style="width:120px">
+						    <el-option label="高" value="3"/>
+							<el-option label="中" value="2"/>
+							<el-option label="低" value="1"/>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="状态">
+					  <el-switch
+					      v-model="formModel.usingIf"
+						  inline-prompt
+						  size="large"
+					      active-text="启用"
+					      inactive-text="禁用"
+						  
+					    />
+					</el-form-item>
+					<el-form-item label="报警方式">
+						<el-checkbox-group v-model="formModel.alarmMode">
+						    <el-checkbox label="color">颜色标识</el-checkbox>
+						    <el-checkbox label="sound">声音报警</el-checkbox>
+						</el-checkbox-group>
+						
+					</el-form-item>
+					
+					<el-form-item label="报警内容">
+					  <el-input v-model="formModel.alarmDesc" autocomplete="off" placeholder="请输入报警内容"  clearable/>
+					</el-form-item>
+					
+					<el-form-item label="报警条件">
+						
+							<CondExpressGroup v-model="formModel.conditions" :paramOpts="condParamsOpt"></CondExpressGroup>
+							
+						
+					</el-form-item>
+					
+					
+					
+					
+					<el-form-item label=" " style="margin-top:30px">
+						<el-button type="primary" @click="saveSubmit('update')">保存</el-button>
+						<el-button type="success" @click="saveSubmit('add')">新增</el-button>
+						<el-button  @click="delSubmit">删除</el-button>
+					</el-form-item>
+				</el-form>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup>
+	import {reactive,ref,toRaw,onMounted,watch} from 'vue'
+	import { storeToRefs } from 'pinia'
+	import { useHomeStore } from "../../store/home.js"
+	import alarmDefineAPI from "../../api/alarmDefine.js"
+	import {ElMessageBox,ElMessage} from 'element-plus'
+	import CondExpressGroup from '@/components/CondExpressGroup.vue'
+	
+	
+	
+	const activeItemIdx=ref(null)
+	
+	const alarmList=ref([])
+	
+	const wellParamList=ref([])
+	
+	const crtWell=reactive({wellId:null,wellName:null})
+	
+	let crtAlarmHolderId=null
+	
+	const condParamsOpt=ref([])
+	
+	const  formModel=reactive({
+			alarmId:null,
+			alarmSource:null,
+			alarmGrade:null,
+			alarmMode:[],
+			usingIf:null,
+			alarmDesc:null,
+			expressDesc:null,
+			alarmExpress:null,
+			conditions:[]
+	})
+	
+	const rules =reactive({
+	})
+	
+	const store=useHomeStore()
+	const  {currentTreeNode} = storeToRefs(store)
+	
+	watch(currentTreeNode,(newNode, oldNode)=>{
+		if(newNode&&newNode.nodeType=='well'){
+			crtWell.wellId=newNode.id 
+			crtWell.wellName=newNode.name
+			
+			setTimeout(()=>{loadParams(newNode.id )},100)
+		}
+		
+	},{ immediate: true })
+	
+	
+	const loadParams=(wellId)=>{
+		alarmDefineAPI.loadWellParam(wellId).then(resp=>{
+			if(resp.code==0){
+				console.log(resp)
+				wellParamList.value=resp.data.data
+			}
+		})
+	}
+	
+	const loadAlarmDefine=(holderId)=>{
+		alarmDefineAPI.loadAlarmDefine(holderId).then(resp=>{
+			if(resp.code==0){
+				alarmList.value=resp.data
+			}
+		})
+	}
+	
+	//选择左侧参数或井,进行条件表达式中的参数选择更新
+	const handleParamSelect=(wellParam,index)=>{
+		activeItemIdx.value=index
+		crtAlarmHolderId=wellParam.paramId||wellParam.wellId
+		loadAlarmDefine(crtAlarmHolderId)
+		
+		if(wellParam.paramId){
+			condParamsOpt.value=[toRaw(wellParam)]
+		}
+		else{
+			condParamsOpt.value=wellParamList.value
+		}
+		
+		initForm()
+	}
+	
+	//报警定义列表中选择了一个记录
+	const handleAlarmRowClick=(row, column, event)=>{
+		let {alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,expressDesc,alarmMode,alarmExpress}=row
+		let conditions=alarmExpress?JSON.parse(alarmExpress):[{}]
+		alarmMode=alarmMode?alarmMode.split("|"):[],
+		initForm({alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,expressDesc,alarmMode,conditions})
+	}
+	
+	const initForm=(initData)=>{
+		if(!initData){
+			let [alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,expressDesc,alarmMode,conditions]=[null,null,null,null,null,null,[],[{param:null,symbol:null,val:null}]]
+			Object.assign(formModel,{alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,expressDesc,alarmMode,conditions})
+		}
+		else{
+			let {alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,expressDesc,alarmMode,conditions}=initData
+			Object.assign(formModel,{alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,expressDesc,alarmMode,conditions})
+			console.log(formModel.conditions)
+			
+		}
+		
+	}
+	
+	const processFormData=(formData)=>{
+		if(!formData.conditions||formData.conditions.length==0){
+			ElMessage.error('没有设定报警条件')
+			return false
+		}
+		formData.expressDesc=""
+		formData.conditions.forEach((item,index)=>{
+			formData.expressDesc+=`${index==0?'当':'且'}${item.label}${item.symbol}${item.val}`
+		})
+		
+		formData.alarmExpress=JSON.stringify(formData.conditions)
+		
+		delete formData.conditions
+		
+		formData.alarmMode=formData.alarmMode?formData.alarmMode.join("|"):null
+		
+		return true
+	}
+	
+	const saveSubmit=(tag)=>{
+		let {alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,alarmMode,conditions}=formModel
+		let formData={alarmId,alarmSource,alarmGrade,usingIf,alarmDesc,alarmMode,conditions}
+		if(!processFormData(formData)){
+			return
+		}
+		if(tag=='add'){
+			formData.alarmId=null
+			formData.alarmSource=crtAlarmHolderId
+		}
+		alarmDefineAPI.save(formData).then(resp=>{
+			if(resp.code!=0){
+				ElMessage.error(resp.msg)
+				return
+			}
+			ElMessage.success('操作成功')
+			loadAlarmDefine(crtAlarmHolderId)
+			initForm()
+			
+		}).catch(err=>{
+			ElMessage.error(err||'操作失败')
+		})
+	}
+	
+	
+	
+	const delSubmit=()=>{
+		if(!formModel.alarmId){
+			ElMessage.error("请先选择一个报警设置,再继续");
+			return;
+		}
+		ElMessageBox.confirm(
+			'确定要删除吗?',
+			'操作确认',
+			{
+				confirmButtonText:'确定',
+				cancelButtonText:'取消',
+				type: 'warning'
+			}
+		).then(()=>{
+			alarmDefineAPI.del({alarmId:formModel.alarmId}).then(resp=>{
+				if(resp.code!=0){
+					ElMessage.error(resp.msg)
+					return
+				}
+				ElMessage.success('操作成功')
+				loadAlarmDefine(crtAlarmHolderId)
+				initForm()
+				
+			}).catch(err=>{
+				ElMessage.error(err||'操作失败')
+			})
+			
+		}).catch(()=>{
+			console.log('cancel del')
+		})
+	}
+	
+</script>
+
+<style scoped>
+	 .page-container{
+		 height:100%;
+		 box-sizing: border-box;
+		 display: flex;
+		 flex-flow: row nowrap;
+		 align-items: flex-start;
+	 }
+	 .page-side{
+		 width:200px;
+		 height:100%;
+		 padding:0px 5px 5px;
+		 box-sizing: border-box;
+	 }
+	 .page-main{
+		 flex:1;
+		 height:100%;
+		 box-sizing: border-box;
+		 padding:0px 5px 5px;
+	 }
+	 
+	 .page-side .card-header{
+		 cursor:pointer;
+		 width:145px;
+		 height:18px;
+		 padding:5px 5px;
+		 border-left:4px solid #ffffff;
+	 }
+	 .page-side .card-header:hover{
+		 
+		 color:#00aaff;
+		 border-left:4px solid #ff7b4f;
+	 }
+	 .page-side .side-item{
+		 font-size: 14px;
+		 margin-bottom: 8px;
+		 padding:5px 5px;
+		 cursor:pointer;
+		 border-left:4px solid #ffffff;
+	 }
+	 
+	 .page-side .side-item:hover{
+		 color:#00aaff;
+		 border-left:4px solid #ff7b4f;
+	 }
+	 
+	 .page-side .side-item-active{
+	 		 color:#0000ff;
+	 		 border-left:4px solid #ff0000;
+	 }
+	 
+	 .page-side:deep(.el-card__body){
+		height: calc(100% - 60px);
+		box-sizing: border-box;
+		padding:10px 5px 10px 10px;
+	 }
+	 .page-side:deep(.el-card__header){
+		 padding-left:10px;
+	 }
+	 
+	 .edit-box{
+		 min-height:200px;
+		 height:calc(100% - 205px);
+		 border:1px solid #f2f2f2;
+		 margin-top:5px;
+		 box-sizing: border-box;
+		 padding:10px;
+		 overflow:auto;
+	 }
+	 
+	 .edit-form-item{
+		 width:240px;
+	 }
+</style>