消毒机设备
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.
 
 
 
 
 

304 lines
8.1 KiB

<script lang="ts" setup>
import { syncSendCmd } from 'apis/system'
import BtButton from 'components/common/BTButton/index.vue'
import CascadingSelectModal from 'components/common/CascadingSelectModal/index.vue'
import RunFormulaConfig from 'components/formula/RunFormulaConfig.vue'
import Config from 'components/home/config.vue'
import { compareJSON } from 'libs/utils'
import { cloneDeep } from 'lodash'
import { computed, onMounted, provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'
import { FtMessage } from '@/libs/message'
import { useDeviceStore } from '@/stores/deviceStore'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
/**
* 主页操作控制组件
* @description 负责处理压力控制、消毒设置、图表导航等功能,协调组件间通信
*/
// 依赖注入
const runtimeRef = ref()
provide<(methods: Home.GrandsonMethods) => void>('registerGrandsonMethods', (methods) => {
runtimeRef.value = methods
})
// 状态管理
const router = useRouter()
const formulaStore = useFormulaStore()
const deviceStore = useDeviceStore()
const homeStore = useHomeStore()
// 组件状态
const isModalOpen = ref(false) // 级联选择模态框是否打开
const optionsLeft = ref<System.Option[]>([]) // 压力类型选项(左列)
const optionsRight = ref<System.Option[]>([]) // 压力强度选项(右列)
const selectedValue = ref() // 选中的压力配置值
const disinfectionState = ref(homeStore.disinfectionState) // 消毒状态
const disinfectConfigVisible = ref(false) // 消毒设置对话框是否显示
const disinfectRuntimeVisible = ref(false)
const selectedByFormulas = ref(cloneDeep(formulaStore.selectedFormulaInfo)) // 当前选中的配方信息
const pressureConfig = ref(homeStore.pressureConfig)
const defaultIntensityValue = ref()
/**
* @hook 响应式依赖监听
* @description 监听消毒状态和配方变化,同步更新组件状态
*/
watchEffect(() => {
disinfectionState.value = homeStore.disinfectionState
selectedByFormulas.value = formulaStore.selectedFormulaInfo
pressureConfig.value = homeStore.pressureConfig
})
/**
* @hook 生命周期钩子 - 组件挂载完成时执行
* @description 初始化压力配置
*/
onMounted(async () => {
if (__DEVICE_TYPE__ !== useDeviceStore().deviceTypeMap.LargeSpaceDM_B) {
await getPressureConfig() // 获取压力配置
}
})
/**
* @function getPressureConfig
* @desc 获取当前压力配置信息
*/
const getPressureConfig = async () => {
const pressureParams = {
className: 'PipelinePressureControl',
fnName: 'getConfig',
}
const res = await syncSendCmd(pressureParams)
if (res.ackcode === 0) {
homeStore.updatePressureConfig(res.rely)
}
}
/**
* @computed 计算属性 - 设备状态判断
* @returns {boolean} - 设备是否处于空闲或已完成状态
* @desc 控制按钮可用状态
*/
const deviceState = computed(() => {
return disinfectionState.value.state === 'idle' || disinfectionState.value.state === 'finished'
})
/**
* @function 打开消毒设置对话框
* @desc 根据当前选中配方或默认配方初始化设置
*/
const onDisinfectConfig = () => {
formulaStore.updateSelectedFormula(selectedByFormulas.value || cloneDeep(formulaStore.defaultFormulaInfo))
disinfectConfigVisible.value = true
}
const onDisinfectRuntime = () => {
disinfectRuntimeVisible.value = true
}
/**
* @function 导航到图表页面
* @desc 路由跳转至消毒图表页面
*/
const onShowChart = () => {
router.push('/home/chart')
}
/**
* @function 保存消毒运行参数
* @desc 处理表单数据保存逻辑,区分消毒中与非消毒状态
*/
const onSave = async () => {
const formData = await runtimeRef.value?.saveFormData()
if (!formData) {
return
}
// 消毒中更新实时配置
const res = await formulaStore.getRealtimeConfig()
const diff = compareJSON(res.rely, formData)
const diffKeys = Object.keys(diff)
if (diffKeys.length) {
await Promise.all(
diffKeys.map(async (key) => {
await formulaStore.setRealtimeConfig(key, diff[key].newVal)
}),
)
FtMessage.success('设定成功')
homeStore.setRate(formData.injection_pump_speed)
}
}
/**
* @function 确认压力选择
* @param {string|number[]} value - 选中的压力配置值([类型, 强度])
* @desc 关闭模态框并更新压力配置
*/
const handleConfirm = (value: string | number[]) => {
isModalOpen.value = false
homeStore.updatePressure(value)
}
/**
* @function 取消压力选择
* @desc 关闭模态框
*/
const handleCancel = () => {
isModalOpen.value = false
}
/**
* @function 关闭消毒设置对话框
* @desc 重置对话框状态
*/
const onCloseConfig = () => {
disinfectConfigVisible.value = false
}
const onCloseRuntime = () => {
disinfectRuntimeVisible.value = false
}
const settingWidth = computed(() => {
if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.LargeSpaceDM_B) {
return '12rem'
}
return '7.5rem'
})
</script>
<template>
<div class="home-start-opt">
<div class="home-opt-flex">
<div class="home-opt-ml">
<BtButton
button-text="查看图表"
text-size="1.3rem"
border-radius="5px"
:width="settingWidth"
height="3rem"
text-color="#1989fa"
:disabled="deviceState"
@click="onShowChart"
/>
</div>
<div class="home-opt-ml">
<BtButton
v-if="deviceState"
button-text="消毒设置"
text-size="1.3rem"
border-radius="5px"
:width="settingWidth"
text-color="#1989fa"
height="3rem"
@click="onDisinfectConfig()"
/>
<BtButton
v-else
button-text="运行参数"
text-size="1.3rem"
border-radius="5px"
:width="settingWidth"
text-color="#1989fa"
height="3rem"
@click="onDisinfectRuntime()"
/>
</div>
</div>
</div>
<!-- 消毒设置 -->
<ft-dialog v-model="disinfectConfigVisible" title="消毒设置" width="80vw">
<div style="height: 80vh; overflow: auto">
<Config />
</div>
<template #footer>
<div class="config-btn">
<BtButton
button-text="关闭"
border-radius="5px"
width="7rem"
text-size="1.5rem"
text-color="#1989fa"
height="3rem"
@click="onCloseConfig"
/>
</div>
</template>
</ft-dialog>
<!-- 运行参数 -->
<ft-dialog v-model="disinfectRuntimeVisible" title="运行参数" width="80vw">
<div class="main-content">
<div class="formula-config">
<RunFormulaConfig ref="runtimeRef" />
</div>
</div>
<template #footer>
<div class="config-btn">
<BtButton
button-text="关闭"
border-radius="5px"
width="7rem"
text-size="1.5rem"
text-color="#1989fa"
height="3rem"
@click="onCloseRuntime"
/>
<BtButton
v-if="!deviceState"
bg-color="#1989fa"
button-text="确认"
border-radius="5px"
width="7rem"
text-size="1.5rem"
text-color="#ffffff"
height="3rem"
@click="onSave"
/>
</div>
</template>
</ft-dialog>
<CascadingSelectModal
v-if="isModalOpen"
:options-left="optionsLeft"
:options="optionsRight"
:selected-value="selectedValue"
:default-value="defaultIntensityValue"
placeholder="请选择"
@confirm="handleConfirm"
@cancel="handleCancel"
/>
</template>
<style lang="scss" scoped>
.main-content {
overflow: hidden;
//height: auto;
//background: $gradient-color;
padding: 15px;
.formula-config {
display: grid;
padding: 10px;
width: 100%;
}
.formula-config-form {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5px;
}
.formdata-input {
width: 10vw;
}
}
.home-start-opt {
margin: 0.5rem;
}
.home-opt-flex {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
}
.home-opt-ml {
margin-left: 0;
}
.config {
border: 1px solid red;
}
</style>