|
|
<script lang="ts" setup> import { sendCmd } from 'apis/system' import homeFinish from 'assets/images/home/home-finish.svg' import homeStart from 'assets/images/home/home-start.svg' import { ElLoading } from 'element-plus' import { startTimer, stopTimer } from 'libs/countdownTimer' import { deviceStateMap } from 'libs/utils' import { computed, ref, watchEffect } from 'vue'
import { getDeviceStatus } from '@/libs/deviceComm' import { FtMessage } from '@/libs/message' import { FtMessageBox } from '@/libs/messageBox' import { useFormulaStore } from '@/stores/formulaStore' import { useHomeStore } from '@/stores/homeStore'
/** * 消毒操作控制组件 * @description 负责处理消毒流程控制(开始/结束)、状态监听及倒计时逻辑 */
// 状态管理
const homeStore = useHomeStore() const formulaStore = useFormulaStore()
// 组件状态
const curStateRemainTimeS = ref<string>('') // 当前状态剩余时间(字符串格式)
const disinfectionState = ref(homeStore.disinfectionState) // 消毒状态
const btnStyle = { width: '25vw', height: '7vh', textSize: '24px', borderRadius: '12px', textColor: '#FFFFFF', } let isDisinfection = false // 是否处于消毒中状态
/** * @hook 响应式依赖监听 * @description 监听消毒状态变化,处理倒计时逻辑 */ watchEffect(() => { disinfectionState.value = homeStore.disinfectionState const time = disinfectionState.value.curStateRemainTimeS
// 进入消毒状态且未启动倒计时时开始计时
if (disinfectionState.value.state === 'disinfection' && !isDisinfection && time > 0) { isDisinfection = true startTimer(time * 1000, (times: string) => { homeStore.updateHomeRemainTime(times) curStateRemainTimeS.value = times }) } })
/** * @function 开始消毒操作 * @desc 校验设备状态并发起消毒请求 */ const onStartDisinfect = () => { // 校验日志等级
if (!formulaStore.loglevel) { FtMessage.warning('请选择消毒等级') return }
FtMessageBox.warning('请确认是否开始消毒').then(() => { doStartDisinfect() }) }
const doStartDisinfect = async () => { // 校验设备状态
const statusName = getDeviceStatus() if (statusName) { FtMessageBox.error(statusName) return }
const loading = ElLoading.service({ lock: true, text: '准备开始消毒', background: 'rgba(255, 255, 255, 0.8)', }) try { // 使用选中配方或默认配置启动消毒
if (formulaStore.selectedFormulaInfo && formulaStore.selectedFormulaInfo.formula_id) { await formulaStore.startDisinfectFormula(formulaStore.selectedFormulaInfo) const poll = setInterval(() => { if (!operationState.value) { loading.close() clearInterval(poll) } }, 100) } else { const startParams = { className: 'DisinfectionCtrlServiceExt', fnName: 'start', params: { loglevel: formulaStore.loglevel }, } await sendCmd(startParams).catch((res) => { FtMessageBox.error(`错误码: ${res.ackcode}, 信息: ${res.message}`) }) const poll = setInterval(() => { if (!operationState.value) { loading.close() clearInterval(poll) } }, 100) } } catch (e) { console.log(e) loading.close() } }
/** * @function 结束消毒操作 * @desc 停止倒计时并发起结束消毒请求 */ const onFinishDisinfect = () => { FtMessageBox.warning('请确认是否结束消毒').then(() => { homeStore.setRate(undefined) homeStore.setLog(undefined) doStopDisinfect() }) }
const doStopDisinfect = async () => { stopTimer() // 停止倒计时
const loading = ElLoading.service({ lock: true, text: '正在停止消毒', background: 'rgba(255, 255, 255, 0.8)', }) try { const stopParams = { className: 'DisinfectionCtrlServiceExt', fnName: 'stop', params: { loglevel: formulaStore.loglevel }, } await sendCmd(stopParams) const poll = setInterval(() => { if (operationState.value) { loading.close() clearInterval(poll) } }, 100) } catch (e) { console.log(e) loading.close() } }
/** * @computed 计算属性 - 操作状态判断 * @returns {boolean} - 是否处于空闲或已完成状态 * @desc 控制开始/结束按钮的显示逻辑 */ const operationState = computed(() => { return disinfectionState.value.state === 'idle' || disinfectionState.value.state === 'finished' })
const startInjection = async () => { const stopParams = { className: 'DisinfectionCtrlServiceExt', fnName: 'handleStartPumpInjection', params: {}, } await sendCmd(stopParams) FtMessage.success('操作成功') }
const stopInjection = async () => { const stopParams = { className: 'DisinfectionCtrlServiceExt', fnName: 'handleStopPumpInjection', params: {}, } await sendCmd(stopParams) FtMessage.success('操作成功') }
const formatSeconds = (seconds: number) => { const hours = Math.floor(seconds / 3600) const minutes = Math.floor((seconds % 3600) / 60) const remainingSeconds = seconds % 60
// 补零函数
const padZero = (num: number) => num.toString().padStart(2, '0')
return `${padZero(hours)}:${padZero(minutes)}:${padZero(remainingSeconds)}` } </script>
<template> <div class="home-disinfect"> <bt-button v-if="operationState" button-text="开始消毒" bg-color="#31CB7A" :text-color="btnStyle.textColor" :width="btnStyle.width" :height="btnStyle.height" :text-size="btnStyle.textSize" :border-radius="btnStyle.borderRadius" min-height="4rem" @click="onStartDisinfect" > <template #icon> <img :src="homeStart" alt=""> </template> </bt-button> <bt-button v-else button-text="结束消毒" bg-color="#FF6767" :text-color="btnStyle.textColor" :width="btnStyle.width" :height="btnStyle.height" :text-size="btnStyle.textSize" :border-radius="btnStyle.borderRadius" min-height="4rem" @click="onFinishDisinfect" > <template #icon> <img :src="homeFinish" alt=""> </template> </bt-button> </div> <div v-if="!operationState" style="width: 100%; display: flex; align-items: center; justify-content: center; margin-top: 10px" > <!-- <div style="margin-right: 10px"> --> <!-- <span v-if="homeStore.disinfectionState.handlePumpStopFlag">已开启</span> --> <!-- <span v-else>已关闭</span> --> <!-- </div> --> <el-button type="primary" @click="startInjection"> 开启喷液 </el-button> <el-button type="danger" @click="stopInjection"> 关闭喷液 </el-button> </div>
<!-- 开始消毒时显示剩余时间或状态 --> <div v-if="!operationState" class="home-remain-time"> <div class="home-remaini-label"> <span v-if="disinfectionState.state === 'disinfection'"> 预计剩余时间: </span> <span v-else> 消毒状态: </span> </div> <div v-if="disinfectionState.state === 'disinfection'" class="home-remaini-value"> {{ formatSeconds(homeStore.disinfectionState.curStateRemainTimeS) }} </div> <div v-else> {{ deviceStateMap[disinfectionState.state] }} </div> </div> </template>
<style lang="scss" scoped> .home-disinfect { display: flex; justify-content: center; margin-top: 20px; } .home-start { background: #31cb7a; } .home-end { background: #ff6767; } .home-remain-time { background: #fff; margin: 10px; height: 40px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 20px; gap: 10px; .home-remaini-value { color: #2892f3; } } </style>
|