sige 1 year ago
parent
commit
b751074d58
  1. 48
      src/assets/img/icon/operation-home.svg
  2. 357
      src/device/pipeline/Progress.vue
  3. 2
      src/pages/Home.vue

48
src/assets/img/icon/operation-home.svg
File diff suppressed because it is too large
View File

357
src/device/pipeline/Progress.vue

@ -0,0 +1,357 @@
<template>
<div class="progress_container">
<div class="header_wrap">
<div class="left_time">
<p class="time">{{timeleft}}</p>
</div>
<div>
<span v-if="operatorStore.disinfectStatus == 1" style="color: #F74104;font-size: 2.3rem;font-weight: 600;">预热中</span>
<span v-if="operatorStore.disinfectStatus == 2" style="color: #17F179;font-size: 2.3rem;font-weight: 600;">消毒中</span>
<span v-if="operatorStore.disinfectStatus == 4" style="color: #2485FF;font-size: 2.3rem;font-weight: 600;">降解中</span>
<span v-if="operatorStore.disinfectStatus == 6" style="color: #2485FF;font-size: 2.3rem;font-weight: 600;">除湿中</span>
<span v-if="operatorStore.disinfectStatus == 7" style="color: #2485FF;font-size: 2.3rem;font-weight: 600;">除湿中</span>
<span v-if="operatorStore.disinfectStatus == 8" style="color: #2485FF;font-size: 2.3rem;font-weight: 600;">排空管路</span>
</div>
<div class="left_log_wrap" v-if="[1, 2, 3, 4].includes(operatorStore.disinfectStatus)">
<p class="text">当前剩余</p>
<p class="val">{{logLeft}}log</p>
</div>
<div v-if="!([0,5].includes(operatorStore.disinfectStatus))" class="btn" @click="actionDisinfectionStop">结束消毒</div>
<div v-if="operatorStore.disinfectStatus == 0 || operatorStore.disinfectStatus == 5" class="btn" @click="actionBackToHome">返回</div>
</div>
<div class="echarts_wrap">
<div class="single_wrap">
<p class="title">设备</p>
<div v-if="operatorStore.disinfectStatus != 0 || binLocal" ref="chartContainer" class="echarts_box"></div>
</div>
</div>
<div class="detail_wrap">
<div class="tip_info">警报信息</div>
<div class="speed_wrap">
<p class="speed">{{ settingStore.sprinklerPumpGPM }}</p>
</div>
<img src="@/assets/img/icon/operation-home.svg" @click="actionBackToHome" />
</div>
<van-overlay :show="operatorStore.showStopReady" z-index="3">
<div class="wrapper" @click.stop>
<div class="block">
<van-loading />
<p class="shutdown_text">结束消毒中</p>
</div>
</div>
</van-overlay>
<my-dialog ref="myDialog" />
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import Common from '../../utils/Common';
import MyDialog from '@/components/dialogs/MyDialog.vue';
import { onMounted, computed, onUnmounted, ref } from 'vue';
import {useWebSocketStore,useOperatorStore,useEchartsStore, useSettingStore, useDeviceStore,} from '@/store'
import { useRouter } from 'vue-router'
// router
const router = useRouter()
// operation
const operatorStore = useOperatorStore()
// websocket
const ws = useWebSocketStore()
// echart
const echartsStore = useEchartsStore()
// setting
const settingStore = useSettingStore()
// device
const deviceStore = useDeviceStore()
// timeleft
const timeleft = computed(computeTimeleft)
// log left
const logLeft = computed(computeLogLeft);
/** @var {Component} */
const myDialog = ref(null);
// chart container
const chartContainer = ref(null);
// chart
let chart = null;
// chart options
let chartOptions = {
tooltip: {trigger: 'axis'},
legend: {data: ['温度', '湿度', 'H2O2浓度', 'H2O2饱和度']},
grid: {left: '3%', right: '4%', bottom: '3%', containLabel: true},
xAxis: {type: 'category',boundaryGap: false,data: echartsStore.abscissaFormater},
yAxis: {type: 'value'},
series: [
{name: '温度', type: 'line', stack: 'binTemp', data: echartsStore.binTemp},
{name: '湿度', type: 'line', stack: 'binHumidity', data: echartsStore.binHumidity},
{name: 'H2O2浓度', type: 'line', stack: 'binHP', data: echartsStore.binHP},
{name: 'H2O2饱和度',type: 'line',stack: 'binSaturation',data: echartsStore.binSaturation},
],
};
// chart refresh timer
let chartRefreshTimer = null;
// on mounted
onMounted(mounted);
// on unmonted
onUnmounted(unmounted);
// mounted
async function mounted() {
chart = echarts.init(document.getElementById('bin'))
chart.setOption(chartOptions);
chartRefresh();
}
// unmounted
function unmounted() {
clearTimeout(chartRefreshTimer);
}
// refresh chart
function chartRefresh() {
chart.setOption({
series: [
{data: echartsStore.binTemp},
{data: echartsStore.binHumidity},
{data: echartsStore.binHP},
{data: echartsStore.binSaturation},
],
});
chartRefreshTimer = setTimeout(chartRefresh, 1000);
}
// compute time left
function computeTimeleft() {
if ( operatorStore.estimatedRemainingTimeS == 0 ) {
return '已结束';
}
if ( operatorStore.disinfectStatus == 1 ) {
return Common.formatTimestampAsHHMMSS(operatorStore.estimatedRemainingTimeS);
}
if ( operatorStore.estimatedRemainingTimeS < 0 ) {
return '评估中';
}
return Common.formatTimestampAsHHMMSS(operatorStore.estimatedRemainingTimeS);
}
function computeLogLeft() {
if ( (deviceStore.targetlog - (deviceStore.nowlog || 0)).toFixed(2) < 0 ) {
return 0;
}
return Math.abs((deviceStore.targetlog - (deviceStore.nowlog || 0)).toFixed(2));
}
// disinfection stop
async function actionDisinfectionStop() {
let confirm = await myDialog.value.confirm({
content : "消毒正在进行中,是否终止消毒!",
duration : 10 * 1000,
timeoutValue : false,
});
if ( !confirm ) {
return;
}
await ws.call('stopDisinfection');
}
// go home
function actionBackToHome() {
router.replace({path:'/home'});
}
</script>
<style lang="scss" scoped>
.progress_container {
margin-bottom: 19px;
height: 580px;
box-sizing: border-box;
background: #ffffff;
border-radius: 16px;
padding-bottom: 30px;
.header_wrap {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 34px;
height: 107px;
box-sizing: border-box;
padding: 13px 36px 13px 20px;
background: #f6f6f6;
border-radius: 16px 16px 0 0;
.left_time {
position: relative;
width: 377px;
height: 61px;
background: url(@/assets/img/operator/time.png) no-repeat;
background-size: 100% 100%;
.time {
font-family: Source Han Sans CN;
font-size: 28px;
font-weight: bold;
line-height: normal;
letter-spacing: 0.1em;
color: #ffffff;
position: absolute;
left: 165px;
top: 12px;
width: 178px;
height: 41px;
text-align: center;
}
}
.left_log_wrap {
display: flex;
align-items: center;
.text {
font-family: Source Han Sans CN;
font-size: 30px;
font-weight: bold;
line-height: normal;
letter-spacing: 0.1em;
color: #06518b;
}
.val {
margin-left: 10px;
font-family: Poppins;
font-size: 32px;
font-weight: bold;
line-height: normal;
letter-spacing: 0.1em;
color: #17f179;
}
}
.btn {
padding: 12px 28px;
white-space: nowrap;
box-sizing: border-box;
width: 140px;
height: 50px;
border-radius: 25px;
background: #06518b;
display: flex;
align-items: center;
justify-content: center;
font-family: Source Han Sans CN;
font-size: 20px;
font-weight: 500;
line-height: normal;
letter-spacing: 0.07em;
color: #ffffff;
}
}
.echarts_wrap {
height: 351px;
display: flex;
box-sizing: border-box;
padding-left: 20px;
align-items: center;
margin-bottom: 19px;
.single_wrap {
flex: 1;
height: 351px;
.title {
margin-left: 28px;
padding: 5px 13px;
margin-bottom: 24px;
font-family: Source Han Sans CN;
font-size: 14px;
font-weight: 500;
line-height: normal;
letter-spacing: 0.1em;
color: #ffffff;
height: 27px;
border-radius: 14px;
opacity: 1;
background: #06518b;
width: 70px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
}
.echarts_box {
width: 380px;
height: 308px;
}
}
}
.detail_wrap {
padding-left: 20px;
display: flex;
align-items: center;
padding-right: 16px;
height: 50px;
.tip_info {
padding: 12px 20px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 550px;
height: 50px;
border-radius: 6px;
opacity: 1;
background: #f6f6f6;
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: bold;
line-height: normal;
letter-spacing: 0.1em;
margin-right: 20px;
color: #fa1c1c;
}
.speed_wrap {
background: url(@/assets/img/operator/speed.png) no-repeat;
background-size: 100% 100%;
position: relative;
width: 335px;
height: 41px;
margin-right: 37px;
.speed {
position: absolute;
font-family: Source Han Sans CN;
font-size: 28px;
font-weight: bold;
line-height: normal;
letter-spacing: 0.02em;
color: #17f179;
left: 194px;
bottom: -2px;
width: 68px;
height: 41px;
white-space: nowrap;
text-align: center;
}
}
}
}
.wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.block {
width: 120px;
height: 120px;
display: flex;
flex-direction: column;
padding: 16px;
align-items: center;
justify-content: center;
.shutdown_text {
margin-top: 24px;
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: normal;
line-height: normal;
letter-spacing: 0.06em;
color: #fff;
white-space: nowrap;
}
}
</style>

2
src/pages/Home.vue

@ -374,7 +374,7 @@ import Audit from 'cpns/Audit'
import SealTest from '@/device/pipeline/TightnessTestPanel'
import LeaveModal from 'cpns/dialogs/LeaveModal'
import DisinfectionSetting from 'cpns/DisinfectionSetting'
import Progress from 'cpns/Progress'
import Progress from '@/device/pipeline/Progress'
import LiquidHandle from '@/device/pipeline/LiquidHandle'
import Setting from 'cpns/Setting'
import Test from 'cpns/Test'

Loading…
Cancel
Save