|
|
<script lang="ts" setup> import { sendCmd, syncSendCmd } from 'apis/system' import homeFinish from 'assets/images/home/home-finish.svg' import homeStart from 'assets/images/home/home-start.svg' import SealInstrumentSvg from 'assets/images/seal/seal-instrument.svg' import SoftKeyboard from 'components/common/SoftKeyboard/index.vue' import DashboardChart from 'components/seal/DashboardChart.vue' import { roundNumber } from 'libs/utils' import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { getDeviceStatus } from '@/libs/deviceComm' import { FtMessage } from '@/libs/message' import { FtMessageBox } from '@/libs/messageBox' import { useSealStore } from '@/stores/sealStore'
defineOptions({ name: 'Seal' })
const sealStore = useSealStore()
const initialPressure = ref<string>('0') const sealInfo = computed(() => sealStore.sealInfo) const leakRemainingTime = computed(() => sealStore.leakRemainingTime) const currentPressure = computed(() => sealStore.currentPressure) const diffPressure = computed<number>(() => { if (sealInfo.value.workState === 'leakTesting') { return Math.abs(Number(currentPressure.value) - Number(initialPressure.value)) } return 0 }) const inputValue = ref('') const keyboardVisible = ref(false) const keyboardType = ref<'text' | 'number'>('number') const softKeyboardRef = ref() const inflationTime = ref<number>() const loading = ref(false)
watch( () => sealInfo.value.workState, (newState, oldState) => { if (oldState === 'stabilizingPressure' && newState === 'leakTesting') { initialPressure.value = sealInfo.value.pressure } }, )
onMounted(async () => { const res = await sendCmd({ className: 'AirLeakDetectTest', fnName: 'getServiceConfig', params: { inflationTimeMs: 0.3 }, }) inflationTime.value = res.inflationTimeMs poll = setInterval(() => { if (sealInfo.value.workState === 'leakTesting') { sealStore.startLeakTimer() clearInterval(poll) } }, 100) }) onUnmounted(() => { clearInterval(poll) })
const stopText = computed(() => (sealInfo.value.workState === 'stopping' ? '停止中...' : '停止测试')) const stopDisabled = computed(() => sealInfo.value.workState === 'stopping' || sealInfo.value.workState === 'idle')
let poll: any = 0 function onStartTest() { const statusName = getDeviceStatus() if (statusName) { FtMessageBox.error(statusName) return } loading.value = true syncSendCmd({ className: 'AirLeakDetectTest', fnName: 'start', params: { inflationTimeMs: 0 } }) .then((res) => { if (res.ackcode === 0) { poll = setInterval(() => { if (sealInfo.value.workState === 'leakTesting') { sealStore.startLeakTimer() clearInterval(poll) } }, 100) FtMessage.success('开始执行密封测试') } else { FtMessage.error('指令发送失败,请稍候再试') } }) .finally(() => { loading.value = false }) }
function onFinishTest() { loading.value = true syncSendCmd({ className: 'AirLeakDetectTest', fnName: 'stop', params: {} }) .then((res) => { if (res.ackcode === 0) { sealStore.stopLeakTimer() FtMessage.success('测试已停止') } }) .finally(() => { loading.value = false }) }
function handleConfirm(value: string) { console.log('确认输入:', value) } </script>
<template> <div class="dashboard-container"> <main class="main-content"> <div class="seal-left"> <!-- 仪表盘 --> <div class="seal-chart"> <div class="chart-ml"> <DashboardChart /> </div> <div class="seal-opt"> <div class="seal-status"> <div class="seal-time-text"> 测试时间: </div> <div v-if="sealInfo.workState !== 'leakTesting'" class="seal-time-statue seal-time-text"> 未开始 </div> <div v-else class="seal-test-time"> {{ leakRemainingTime }} </div> </div> <div class="seal-status"> <div class="seal-diff-text"> 测试前气压: </div> <div v-if="sealInfo.workState === 'inflating'" class="seal-diff-statue seal-diff-text"> 打压中 </div> <div v-else-if="sealInfo.workState === 'stabilizingPressure'" class="seal-diff-statue seal-diff-text"> 稳压中 </div> <div v-else-if="sealInfo.workState === 'stopping'" class="seal-diff-statue seal-diff-text"> 停止中 </div> <!-- 捡漏中 --> <div v-else-if="sealInfo.workState === 'leakTesting'" class="seal-test-time"> {{ initialPressure }}Kpa </div> <div v-else class="seal-diff-statue seal-diff-text"> 未开始 </div> </div> </div> </div> </div> <div class="seal-right"> <div class="title-text-test"> <img :src="SealInstrumentSvg" alt="仪表盘"> <div class="title-text"> 气压差值 </div> <div class="title-text title-text-kpa"> <span>{{ roundNumber(diffPressure, 2) }}</span> <span class="title-kpa-pl">Kpa</span> </div> </div> <bt-button button-text="启动测试" bg-color="#31CB7A" text-color="#FFFFFF" width="27vw" height="7vh" text-size="24px" border-radius="12px" :disabled="sealInfo.workState !== 'idle'" min-height="4rem" @click="onStartTest" > <template #icon> <img :src="homeStart" alt=""> </template> </bt-button> <bt-button style="margin: 0" :button-text="stopText" bg-color="#FF6767" text-color="#FFFFFF" width="27vw" height="7vh" text-size="24px" border-radius="12px" :disabled="stopDisabled" min-height="4rem" @click="onFinishTest" > <template #icon> <img :src="homeFinish" alt=""> </template> </bt-button> </div> </main> <SoftKeyboard ref="softKeyboardRef" v-model="inputValue" :is-visible="keyboardVisible" :keyboard-type="keyboardType" @update-keyboard-visible="(visible: boolean) => (keyboardVisible = visible)" @confirm="handleConfirm" @close="keyboardVisible = false" /> </div> </template>
<style lang="scss" scoped> .main-content { display: grid; grid-template-columns: repeat(3, 1fr); height: $main-container-height; gap: 10px; .seal-left { background: #ffffff; grid-column: 1 / 3; box-shadow: 0px 1px 5px 0px rgba(9, 39, 62, 0.15); background: $gradient-color; .seal-chart { } .chart-ml { margin: 2rem; height: 32rem; } } } .seal-opt { display: flex; gap: 2rem; margin-left: 9rem; margin-top: -2rem; .seal-status { display: flex; justify-content: center; align-items: center; background: #f6fafe; //width: 16rem;
height: 5rem; border-radius: 15px; padding: 0 20px; } .seal-time-text { font-size: 1.5rem; font-weight: 500; padding-left: 0.5rem; } .seal-test-time { font-size: 24px; color: #2892f3; } .seal-time-statue { height: 3rem; width: 5rem; display: flex; justify-content: center; align-items: center; font-weight: 600; } .seal-diff-text { font-size: 1.5rem; font-weight: 500; padding-left: 0.5rem; } .seal-diff-statue { height: 3rem; width: 5rem; display: flex; justify-content: center; align-items: center; font-weight: 600; } }
.seal-right { background: $gradient-color; display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 30px; .title-text-test { display: flex; justify-content: center; align-items: center; gap: 5px; height: 50px; img { height: 50%; } .title-text { font-size: 20px; } .title-text-kpa { color: #409eff; } .title-kpa-pl { padding-left: 5px; font-weight: bold; } } .seal-right-btn { //height: 30vh;
grid-row: 2 / 4; margin-top: -6rem; display: flex; justify-content: center; .seal-input { padding-left: 2rem; height: 8rem; font-size: 2.143vw; font-weight: 400; .inflation-time { height: 4rem; } .seal-diff-text { height: 4rem; } .input { width: 25vw; } } .seal-add-btn { width: 25vw; height: 12vh; border-radius: 12px; color: #ffffff; display: flex; align-items: center; justify-content: center; font-size: 24px; gap: 10px; } } } </style>
|