Преглед изворни кода

增加单井巡查模式-混合模式(分组曲线图、功图、数值)

chenwen пре 1 година
родитељ
комит
2ace492c0b
1 измењених фајлова са 423 додато и 0 уклоњено
  1. 423 0
      src/pages/single/WellPatrolMix.vue

+ 423 - 0
src/pages/single/WellPatrolMix.vue

@@ -0,0 +1,423 @@
+<template>
+	<div class="page-container-wpmix">
+		<div class="page-left">
+			<div class="curve-box">
+				<GroupCurve id="wpmix_grpcurve" :initLoad="initLoad" :timeLoad="timeLoad" :height="curveboxH" ref="mixgroupCurveComp" :key="'wpmix_'+crtWell.id"/>
+			</div>
+		</div>
+		
+		<div class="diagram-box">
+			<div class="single-box">
+				<div class="single-header">{{crtWell.name?(crtWell.name+'生产主要参数'):'还未选择井'}}</div>
+				<div class="single-body">
+					<div class="param-block" v-for="(param,index) in singleParams">
+					  <div class="param-tit">{{param.paramName}}</div>
+					  <div class="param-val" :class="{'param-val-alarm':patrolAlarm[param.paramCode]}"  :title="patrolAlarm[param.paramCode]?.alarmDesc">{{patrolData[param.paramCode]}}</div>
+					  <div class="param-unit" v-if="param.displayUnit&&param.displayUnit!='空'">{{param.displayUnit}}</div>
+					 
+					</div>
+					
+				</div>
+			</div>
+			<template v-for="(elModel,index) in diagramParams" :key="index">
+				<div class="multi"  style="width:405px;height:230px;">
+					<div class="multi-header">
+						<label>{{elModel.paramName}}</label>
+						<div class="multi-tool">
+							<el-icon :size="24" title="前一点数据" @click="diagramCtr(elModel.paramCode,'pre')"><CaretLeft /></el-icon>
+							<el-icon :size="24" title="后一点数据" @click="diagramCtr(elModel.paramCode,'next')"><CaretRight /></el-icon>
+							<el-icon :size="24" title="自动更新" @click="diagramCtr(elModel.paramCode,'last')"><RefreshRight /></el-icon>
+							<el-icon :size="24" title="图形回放" @click="diagramCtr(elModel.paramCode,'replay')"><VideoPlay /></el-icon>
+							<el-icon :size="24" title="更多" @click="showCtxMenu($event,elModel)"><ArrowRight/></el-icon> 
+						</div>
+						
+					</div>
+					<div class="multi-body">
+						<Diagram :id="elModel.paramCode+index+'_wpmix'" :width="400" :height="190"  :ref="elModel.paramCode" :axisRatio="1.2" :ctx="{wellId:crtWell.id,paramCode:elModel.paramCode}" :data="loadDiagramData"/>
+					</div>
+				</div>
+			</template>
+		</div>
+		
+		
+		
+		
+		<context-menu
+		  v-model:show="ctxmenuOpts.show"
+		  :options="ctxmenuOpts.options"
+		>
+			<context-menu-item label="历史图形" @click="onMenuClick('WellHisDiagramDialog','历史图形')" />
+		</context-menu>
+		
+		<el-dialog v-model="dialogCtr.show" :title="dialogCtr.title" :close-on-click-modal="false" :destroy-on-close="true" width="70%">
+			<component :is="dialogInnerComp[dialogCompKey]" :ctxObj="dialogCtx"></component>
+			<template #footer>
+				<el-button @click="dialogCtr.show=false">关闭</el-button>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup>
+	import {reactive,ref,watch,toRaw,onMounted,onUnmounted,nextTick,getCurrentInstance } from 'vue'
+	import Diagram from '../../components/diagram/Diagram.vue'
+	import wellPatrolAPI from '../../api/wellPatrol.js'
+	import wellParamAPI from '../../api/wellParam.js'
+	import tempAPI from '../../api/multiTabTemp.js'
+	import { storeToRefs } from 'pinia'
+	import { useHomeStore } from '../../store/home.js'
+	import utils from '@/utils/utils.js'
+	import {ElMessageBox,ElMessage} from 'element-plus'
+	import WellHisDiagramDialog from '../single/WellHisDiagramDialog.vue'
+	import GroupCurve from '../../components/groupCurve/GroupCurve.vue'
+	
+	import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css'
+	import '@/assets/css/ContextMenu.css'
+	import { ContextMenu, ContextMenuGroup, ContextMenuSeparator, ContextMenuItem } from '@imengyu/vue3-context-menu'
+	
+	
+	let {proxy} = getCurrentInstance()
+	//右键菜单配置
+	const ctxmenuOpts=reactive({
+		show:false,
+		type:'single',
+		options:{
+			zIndex:3,
+			minWidth: 230,
+			x: 500,
+			y: 200
+		}
+	})
+	
+	const showCtxMenu=(event,elModel)=>{
+		event.preventDefault()
+		ctxmenuOpts.type=elModel.elType
+		ctxmenuOpts.show=true
+		ctxmenuOpts.options.x=event.x
+		ctxmenuOpts.options.y=event.y
+		dialogCtx.wellId=crtWell.id
+		dialogCtx.wellName=crtWell.name
+		dialogCtx.paramCode=elModel.paramCode
+		dialogCtx.paramName=elModel.paramName
+	}
+	
+	const onMenuClick=(action,actionName)=>{
+		dialogCompKey.value=action
+		dialogCtr.title=`${actionName}【${dialogCtx.wellName}】`
+		dialogCtr.show=true
+	}
+	//右键菜单配置-结束
+	
+	//弹窗动态组件配置
+	const dialogCtr=reactive({
+		show:false,
+		title:'查看窗口',
+		
+	})
+	
+	const dialogInnerComp={
+		WellHisDiagramDialog
+	}
+	
+	
+	const dialogCtx=reactive({
+		wellName:null,
+		wellId:null,
+		paramCode:null,
+		paramName:null,
+		paramId:null
+	})
+	
+	const dialogCompKey=ref(null)
+	//弹窗动态组件配置-结束
+	
+	const diagramCtr=(paramCode,action)=>{
+		let diagramIns=proxy.$refs[paramCode] 
+		if('replay'==action){
+			diagramIns.replay()
+		}
+		else if('next'==action){
+			diagramIns.next()
+		}
+		else if('pre'==action){
+			diagramIns.pre()
+		}
+		else if('last'==action){
+			diagramIns.last()
+		}
+		
+	}
+	
+	
+	
+	//切换井时进行数据的重置
+	const resetPage=()=>{
+		if(singleTimer){
+			clearInterval(singleTimer)
+			singleTimer= null
+		}
+	}
+	
+	
+	
+	
+	const diagramParams=ref([])
+	
+	const crtWell=reactive({})
+	
+	const loadDiagramData=(reqData)=>{  //Diagram.vue回调该函数
+		return wellPatrolAPI.loadDiagram(reqData)
+	}
+	
+	
+	//单值采集数据获取
+	let singleTimer=null
+	const singleParams=ref([])
+	const patrolData=ref({})
+	const patrolAlarm=ref({})
+	const loadSingleData=(wellId)=>{
+		wellPatrolAPI.loadData(wellId).then(resp=>{
+			//console.log(resp)
+			if(resp.code!=0||!resp.data){
+				ElMessage.error(resp.msg||'未获取到实时数据')
+				return
+			}
+			Object.assign(patrolData.value,resp.data.data)
+			patrolAlarm.value=wellPatrolAPI.processAlarm(resp.data.alarm)
+			
+			
+		}).catch(err=>{
+			ElMessage.error('获取实时数据失败')
+		})
+	}
+	
+	const loadWellParam=(wellId)=>{
+		wellParamAPI.loadWellParam(wellId).then(resp=>{
+			
+			if(resp.code!=0){
+				ElMessage.error(resp.msg||'获取井参数失败')
+				return
+			}
+			diagramParams.value=resp.data.filter(param=>param.paramCode.indexOf('diagram')>=0)
+			singleParams.value = resp.data.filter(param=>param.paramCode.indexOf('diagram')<0)
+			
+			nextTick(()=>{
+				loadSingleData(wellId)
+				singleTimer=setInterval(()=>{loadSingleData(wellId)},30000)
+			})
+			
+		}).catch(err=>{
+			
+		})
+	}
+	
+	
+	//单值采集数据获取-end
+	
+	
+	
+	
+	//分组曲线配置
+	const curveboxH=ref(560)
+	
+	const mixgroupCurveComp=ref(null)
+	
+	const loadGrpCurveTemp=(wellId)=>{
+		 wellPatrolAPI.loadSingleGrpCurveTemp(wellId).then(resp=>{
+			//console.log(resp)
+			if(resp.code!=0){
+				ElMessage.error(resp.msg||'获取分组曲线配置失败')
+				return
+			}
+			let tempDtl=JSON.parse(resp.data.temp.tempContent)
+			bindParamUnit(tempDtl,resp.data.units)
+			
+			let startTime=new Date(utils.getNow('yyyy/MM/dd 00:00:00'))
+			mixgroupCurveComp.value.init(tempDtl,startTime)
+			
+		}).catch(err=>{
+			console.log(err)
+			ElMessage.error('获取分组曲线配置出错')
+		})
+	}
+	
+	const bindParamUnit=(tempDtl,unitMap)=>{
+		if(unitMap==null){
+			return
+		}
+		tempDtl.panels.forEach(panel=>{
+			panel.serials.forEach(serial=>{
+				if(!unitMap[serial.code] || unitMap[serial.code]=='空'){
+					return true
+				}
+				serial.title=`${serial.title}(${unitMap[serial.code]})`
+			})
+		})
+	}
+	
+	const initLoad=async (params)=>{
+		let panelDatas={}
+		let resp=null
+		for(let i=0,len=params.length;i<len;i++){
+			resp=await wellPatrolAPI.loadGrpCurveData(crtWell.id,params[i]).catch(err=>{
+				console.log(err)
+			})
+			
+			panelDatas[params[i]]=(resp&&resp.code==0)?resp.data:[]
+			
+		}
+		return Promise.resolve(panelDatas)
+		
+		
+	}
+	
+	//定时刷新数据
+	const timeLoad=async (params)=>{
+		//console.log('time load...',utils.dateFmt(new Date()))
+		let panelDatas={}
+		let resp=null
+		let endDate=utils.getNow()
+		let startDate=(new Date()).getTime()-120000
+		startDate=utils.dateFmt(new Date(startDate))
+		for(let i=0,len=params.length;i<len;i++){
+			resp=await wellPatrolAPI.loadGrpCurveData(crtWell.id,params[i],startDate,endDate).catch(err=>{
+				console.log(err)
+			})
+			
+			panelDatas[params[i]]=(resp&&resp.code==0)?resp.data:[]
+			
+		}
+		return Promise.resolve(panelDatas)
+	}
+	
+	//分组曲线配置结束
+	
+	onMounted(()=>{
+		let pagebox=document.querySelector('.el-tabs__content').getBoundingClientRect()
+		curveboxH.value=pagebox.height-24
+	})
+	
+	onUnmounted(()=>{
+		resetPage()
+	})
+	
+	const store=useHomeStore()
+	const  {currentTreeNode} = storeToRefs(store)
+	
+	watch(currentTreeNode,(newNode, oldNode)=>{
+			if(newNode&&newNode.nodeType=='well'){
+				crtWell.id=newNode.id
+				crtWell.name=newNode.name
+				resetPage()
+				loadWellParam(newNode.id)
+				loadGrpCurveTemp(newNode.id)
+			}
+	},{ immediate: true })
+	
+	
+</script>
+
+<style scoped>
+	@import url('../../assets/css/wellPatrol.css');
+	.page-container-wpmix{
+		
+		height: 100%;
+		box-sizing: border-box;
+		padding:2px;
+		position: relative;
+		display: flex;
+		flex-flow: row nowrap;
+	}
+	
+	
+	.diagram-box{
+		width:410px;
+		border:1px solid #ccc;
+		border-left:2px solid #ccc;
+		height: 100%;
+		overflow-y: auto;
+		overflow-x:hidden;
+	}
+	.diagram-box .multi{
+		position: relative;
+	}
+	.diagram-box .single-box{
+		padding:0px;
+		border:1px solid #ccc;
+		border-radius: 2px;
+		
+	}
+	.page-left{
+		flex:1 0 0;
+		box-sizing: border-box;
+		padding-bottom:2px;
+		height: 100%;
+		overflow-x: auto;
+	}
+	.curve-box{
+		box-sizing: border-box;
+		padding:0px;
+		height: v-bind(curveboxH)
+		/* display:none; */
+	}
+	.single-header{
+		font-size:14px;
+		font-weight: bolder;
+		text-align: center;
+		background-color: #f2f2f2;
+		padding:5px;
+	}
+	.single-body{
+		display: grid;
+		grid-template-columns: repeat(auto-fill,180px);
+		grid-template-rows: repeat(auto-fill,30px);
+		grid-gap:10px 15px;
+		justify-content: center;
+	}
+	.single-body .param-block{
+		font-size:14px;
+		vertical-align:baseline;
+		display: flex;
+		flex-flow:row nowrap;
+		align-items: center;
+		color:#555;
+		height: 28px;
+		box-sizing: border-box;
+	}
+	
+	.param-block  .param-tit{
+		width:60px;
+	}
+	
+	.param-block  .param-val{
+		background-color: #fff;
+		/* width:60px; */
+		text-align: right;
+		flex:1;
+		padding:5px;
+		height: 100%;
+		box-sizing: border-box;
+		border:1px solid #e4e4e4;
+		border-top-left-radius: 3px;
+		border-bottom-left-radius: 3px;
+	}
+	
+	.param-block  .param-val-alarm{
+		background-color: #d04029;
+		color: #ffff00;
+	}
+	
+	.param-block  .param-unit{
+		background-color: #f2f2f2;
+		padding:5px 0px;
+		border:1px solid #e4e4e4;
+		border-left:0px;
+		font-size: 12px;
+		height: 100%;
+		width:40px;
+		box-sizing: border-box;
+		text-align: center;
+		border-top-right-radius: 3px;
+		border-bottom-right-radius: 3px;
+	}
+</style>