|
|
<template> <div class="operator_main_content"> <div class="left_contaienr"> <div class="info_cards"> <div class="card"> <DisinfectantLiquidInfo /> </div> <div class="card"> <EnvironmentInfo :cardType="1" /> </div> <div class="card"> <EnvironmentInfo :cardType="2" /> </div> <div class="card"> <EnvironmentInfo :cardType="3" /> </div> </div> <div class="warn_wrap"> <p class="warn_text">警报信息</p> <div class="detail_btn" v-if=" operatorStore.disinfectStatus != 0 && operatorStore.disinfectStatus != 3 " @click="toDetail" > 详情 </div> </div> </div> <div class="right_container"> <div class="setting_title"> <p>消毒设置</p> <p>SET</p> </div> <div class="set_form"> <input type="number" :disabled="[1, 2].includes(operatorStore.disinfectStatus)" v-model="roomSize" class="room_size" id="room_size" @focus="handleShowKeyBoard" /> <div class="log" @click="showLogPicker">{{ logVal }}</div> </div> <div :class=" [1, 2].includes(operatorStore.disinfectStatus) ? 'start cant' : 'start' " @click="startDisinfect" > 开始消毒 </div> <div class="progress"> <p class="title">预计剩余时间</p> <!-- <div class="tube"> <div class="pro" :style="{ '--width': '50px', }" ></div> </div> <div class="num">000/100</div> --> <div class="time"> {{ operatorStore.estimatedRemainingTimeS == 0 ? '已结束' : `${operatorStore.estimatedRemainingTimeS} S` }} </div> </div> </div> <!-- <WarnModal /> --> <LogPicker v-if="logVisible" :changeLogVal="changeLogVal" :logVal="logVal" /> </div> </template>
<script setup> import LogPicker from 'cpns/dialogs/LogPicker' import WarnModal from 'cpns/dialogs/WarnModal' import DisinfectantLiquidInfo from 'cpns/info/DisinfectantLiquidInfo' import EnvironmentInfo from 'cpns/info/EnvironmentInfo' import { ref, watch, onMounted, onUnmounted } from 'vue' import { useOperatorStore, useWebSocketStore } from '@/store' import { startDisinfectionJSON, getStateJSON } from '@/mock/command' import { showSuccessToast, showFailToast } from 'vant'
const operatorStore = useOperatorStore() const webSocketStore = useWebSocketStore()
const props = defineProps({ changeShowOperator: { type: Function, }, handleShowKeyBoard: { type: Function, }, hideKeyBoard: { type: Function, }, input: { type: String, }, })
const toDetail = () => { // 判断当前消毒任务是否开始,如果开始时才生效 否则点击不生效
if (operatorStore.disinfectStatus != 0) { props.changeShowOperator(false) } }
const logVisible = ref(false) const logVal = ref(1) const roomSize = ref(0)
watch(() => { roomSize.value = props.input.match(/\d+/g)[0] })
const changeLogVal = val => { logVal.value = val logVisible.value = false }
const startDisinfect = () => { // 改变开始消毒状态 如果已经开始则不可点击
if (![1, 2].includes(operatorStore.disinfectStatus)) { if (roomSize.value == 0) { showFailToast('请调整房间大小设置,不能为0') } else { localStorage.removeItem('bin') localStorage.removeItem('envir1') localStorage.removeItem('envir2') localStorage.clear() webSocketStore.sendCommandMsg( startDisinfectionJSON(logVal.value, roomSize.value), ) props.changeShowOperator(false) } } }
const showLogPicker = () => { if (![1, 2].includes(operatorStore.disinfectStatus)) { logVisible.value = true } }
const timer = ref(null) onMounted(() => { timer.value = setInterval(() => { webSocketStore.sendCommandMsg(getStateJSON) }, 1000) }) onUnmounted(() => { timer.value = null }) </script>
<style lang="scss" scoped> .operator_main_content { margin-bottom: 30px; height: 580px; box-sizing: border-box; display: flex; align-items: center; .left_contaienr { margin-right: 30px; width: 766px; height: 580px; box-sizing: border-box; border-radius: 16px; background: #ffffff; padding: 20px; .info_cards { width: 726px; height: 470px; box-sizing: border-box; display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(2, 1fr); column-gap: 20px; row-gap: 20px; margin-bottom: 20px; .card { width: 353px; height: 225px; border-radius: 17.5px; background: #06518b; } } .warn_wrap { display: flex; align-items: center; justify-content: space-between; box-sizing: border-box; padding: 0 20px; width: 726px; height: 50px; border-radius: 6px; background: #f6f6f6; .warn_text { font-family: Source Han Sans CN; font-size: 12px; font-weight: 500; letter-spacing: 0.1em; color: #fa1c1c; } .detail_btn { width: 105px; height: 31px; border-radius: 16px; background: #06518b; display: flex; align-items: center; justify-content: center; font-family: Source Han Sans CN; font-size: 12px; font-weight: normal; letter-spacing: 0.1em; color: #ffffff; } } } .right_container { height: 580px; box-sizing: border-box; border-radius: 16px; background: #ffffff; flex: 1; padding: 42px; padding-top: 32px; .setting_title { width: 340px; height: 45px; border-radius: 23px; background: #06518b; padding: 0 24px; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; font-family: Source Han Sans CN; font-size: 14px; font-weight: normal; letter-spacing: 0.1em; color: #ffffff; margin-bottom: 41px; } .set_form { width: 340px; height: 190px; box-sizing: border-box; margin-bottom: 41px; overflow: hidden; background: url(../assets/img/operator/form.png) no-repeat; background-size: 100% 100%; position: relative; .room_size { position: absolute; top: 45px; left: 23px; width: 189px; height: 20px; text-align: center; border: none; outline: none; } .log { position: absolute; top: 145px; left: 0px; width: 240px; height: 42px; text-align: center; display: flex; align-items: center; justify-content: center; font-family: Source Han Sans CN; font-size: 14px; font-weight: 500; letter-spacing: 0.06em; color: #0e0e0e; } } .start { margin-bottom: 30px; width: 340px; height: 45px; border-radius: 23px; background: #06518b; display: flex; align-items: center; justify-content: center; font-family: Source Han Sans CN; font-size: 14px; font-weight: normal; letter-spacing: 0.1em; color: #ffffff; } .cant { background: #f4f4f4; } .progress { width: 340px; height: 114px; border-radius: 16px; opacity: 1; background: #f6f6f6; box-sizing: border-box; padding: 27px 24px 18px 27px; .title { font-family: Source Han Sans CN; font-size: 12px; font-weight: 350; letter-spacing: 0.06em; color: #9e9e9e; margin-bottom: 13px; } .time { text-align: center; padding: 10px; } .tube { width: 292px; height: 14px; border-radius: 7px; background: #ffffff; margin-bottom: 11px; position: relative; overflow: hidden; .pro { position: absolute; left: 0; top: 0; height: 14px; width: var(--width); border-radius: 7px; background: #06518b; } } .num { display: flex; justify-content: flex-end; font-family: Source Han Sans CN; font-size: 10px; font-weight: normal; letter-spacing: 0.06em; color: #9e9e9e; } } } } </style>
|