消毒机设备
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

344 lines
8.9 KiB

<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>