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

353 lines
9.9 KiB

<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { formulaNameMap } from 'libs/constant'
import { cloneDeep } from 'lodash'
import { useHomeStore } from 'stores/homeStore'
import { computed, inject, nextTick, onMounted, ref, watch, watchEffect } from 'vue'
import { FtMessage } from '@/libs/message'
import { convertValuesToString } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore'
const homeStore = useHomeStore()
const formulaStore = useFormulaStore()
const isFlip = ref(true)
/**
* 当前表单数据
*/
const formData = ref<Record<string, any>>({})
/**
* 软键盘当前输入值
*/
const inputValue = ref<string>('')
/**
* 当前聚焦的输入字段名称
*/
const focusedInput = ref<string | null>(null)
/**
* 注册孙子组件方法的注入函数
*/
const registerGrandsonMethods = inject<(methods: any) => void>('registerGrandsonMethods', () => {})
/**
* 配方配置列表
*/
const formulaConfigList = ref(formulaStore.formulaConfigList)
/**
* 标签单位映射表,用于显示各参数的单位
*/
const labelUnitMap: Record<string, any> = formulaStore.labelUnitMap
onMounted(() => {
formulaStore.getFormualDefaultData() // 获取表单的配置信息
registerGrandsonMethods && registerGrandsonMethods({ getFormData })
formulaStore.initFormulaList() // 更新列表数据
})
/**
* 组件挂载时注册方法供父组件调用
*/
watchEffect(() => {
if (formulaStore.currentSelectedIndex === null) {
formData.value = cloneDeep(formulaStore.defaultFormulaInfo || {})
}
else {
formData.value = cloneDeep(formulaStore.currentSelectedFormulaInfo || {})
}
isFlip.value = formulaStore.flip
// 后端给的数据类型是字符串型,前端需要的是int型,后端开发说(赵贺)后端不好转换,由前端进行转换.
formData.value = convertValuesToString(formData.value, 'name')
})
const disinfectionState = ref(homeStore.disinfectionState) // 消毒状态
/**
* 获取当前表单数据,将值转换为字符串格式
* @returns {Record<string, string>} 转换后的表单数据
*/
const getFormData = () => {
return convertValuesToString(formData.value, 'name')
}
/**
* 监听表单数据变化,同步更新软键盘输入值
* @param {Record<string, any>} newValue - 新的表单数据
*/
watch(
formData,
(newValue) => {
if (focusedInput.value) {
inputValue.value = newValue[focusedInput.value].toString()
}
},
{ deep: true },
)
watch(
() => formulaStore.currentSelectedIndex,
() => {
formRef.value?.clearValidate()
},
)
const formRef = ref()
/**
* 处理表单提交
* 根据不同的type属性值执行不同的保存逻辑
*/
const handleSubmit = async () => {
// 表单验证
try {
const valid = await formRef.value.validate()
if (!valid) {
return
}
if (formData.value.formula_id) {
// 修改配方
// 判断消毒是否正在执行 且正在执行配方是当前修改配方
if (!deviceState.value && formulaStore.selectedFormulaInfo?.formula_id === formData.value.formula_id) {
ElMessage.warning('禁止修改正在执行的配方信息!')
return
}
const formulaForm: Record<string, any> = convertValuesToString(formData.value, 'name')
formulaStore
.editFormula(formulaForm.formula_id, formulaForm as Formula.FormulaItem)
.then(() => {
FtMessage.success('操作成功')
formulaStore.initFormulaList('edit')
if (formData.value.formula_id === formulaStore.selectedFormulaInfo?.formula_id) {
formulaStore.selectedFormulaInfo = formulaForm as Formula.FormulaItem
}
})
.catch((e) => {
console.log(e)
})
}
else {
// 新增配方
formulaStore.onAddFormula().then((res) => {
if (res.ackcode === 0) {
const item = res.rely
const formulaForm: Record<string, any> = convertValuesToString(formData.value, 'name')
formulaForm.formula_id = item.formula_id
formulaStore
.editFormula(item.formula_id, formulaForm as Formula.FormulaItem)
.then(() => {
FtMessage.success('操作成功')
formulaStore.initFormulaList('add')
})
.catch((e) => {
console.log(e)
})
}
})
}
}
catch (e) {
console.log(e)
}
}
/**
* @computed 计算属性 - 设备状态判断
* @returns {boolean} - 设备是否处于空闲或已完成状态
* @desc 控制按钮可用状态
*/
const deviceState = computed(() => {
return disinfectionState.value.state === 'idle' || disinfectionState.value.state === 'finished'
})
const size = 'default'
// 新增配方方法
const addFormula = async () => {
formData.value = cloneDeep(formulaStore.defaultFormulaInfo)
// formData.value = convertValuesToInt(formulaInfo)
await nextTick() // 等待DOM更新
formData.value.name = ''
formData.value.formula_id = null
}
// 暴露方法给父组件
defineExpose({
addFormula,
})
const validatePass = (rule: any, value: any, callback: any, config: Formula.FormulaConfig) => {
if (!value && value !== 0 && value !== '0') {
callback(new Error('此为必填项'))
}
else if (value.substring(0, 1) === '.' || value.split('.').length > 2) {
callback(new Error('输入数值项'))
}
else if (config.val_type === 'int' || config.val_type === 'float') {
const temp = Number(value)
if (temp < config.val_lower_limit || temp > config.val_upper_limit) {
callback(new Error(`输入范围为${config.val_lower_limit}-${config.val_upper_limit}`))
}
}
callback()
}
const validateName = (rule: any, value: any, callback: any) => {
if (!value && value !== 0 && value !== '0') {
callback(new Error('配方名称不能为空'))
}
else if (value.length > 20) {
callback(new Error('配方名称1-20个字符'))
}
callback()
}
</script>
<template>
<transition name="slide-right">
<div v-if="isFlip" class="formula-form">
<el-form
ref="formRef"
:model="formData"
class="form-box"
label-width="auto"
label-position="right"
:size="size"
inline
>
<el-form-item
label="配方名称"
style="width: 93%"
prop="name"
:rules="[
{
required: true,
validator: (rule, value, callback) => validateName(rule, value, callback),
trigger: 'blur',
},
]"
>
<ft-input v-model="formData.name" name="name" placeholder="配方名称" />
</el-form-item>
<el-form-item
v-for="item in formulaConfigList.filter(data => data.is_visible_in_formula_page)"
:key="item.setting_id"
:label="formulaNameMap[item.setting_id]"
style="width: 50%"
:prop="item.setting_id"
:rules="[
{
required: true,
validator: (rule, value, callback) => validatePass(rule, value, callback, item),
trigger: 'blur',
},
]"
>
<template v-if="item.val_type === 'int'">
<ft-input v-model="formData[item.setting_id]" style="width: 80%" layout-name="number">
<template v-if="labelUnitMap[item.setting_id]" #append>
{{ labelUnitMap[item.setting_id] }}
</template>
</ft-input>
</template>
<template v-if="item.val_type === 'float'">
<ft-input v-model="formData[item.setting_id]" layout-name="number" style="width: 80%">
<template v-if="labelUnitMap[item.setting_id]" #append>
{{ labelUnitMap[item.setting_id] }}
</template>
</ft-input>
</template>
<template v-else-if="item.val_type === 'enum'">
<el-select v-model="formData[item.setting_id]" style="width: 80%" placeholder="请选择" readonly>
<el-option v-for="log in item.enums" :key="log" :label="log" :value="log" />
</el-select>
</template>
<template v-else-if="item.val_type === 'boolean'">
<el-radio-group v-model="formData[item.setting_id]">
<el-radio :label="true">
</el-radio>
<el-radio :label="false">
</el-radio>
</el-radio-group>
</template>
</el-form-item>
</el-form>
<div class="default-btn">
<el-button type="primary" class="config-btn" @click="handleSubmit">
确定
</el-button>
</div>
</div>
</transition>
</template>
<style lang="scss" scoped>
.formula-form {
font-size: 20px !important;
align-items: center;
height: 100%;
.form-box {
height: calc(100% - 50px);
overflow: auto;
}
.default-btn {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
.el-button {
width: 100px;
}
}
}
.formula-form-item {
display: grid;
grid-template-columns: 1fr 1fr;
}
.formData-input-config {
width: 10vw;
}
:deep(.el-input__inner) {
text-align: left;
height: 40px;
}
:deep(.el-select) {
height: 42px;
}
:deep(.el-select__wrapper) {
height: 42px;
}
:deep(.el-form-item) {
margin-right: 0;
align-items: center;
}
:deep(.el-input-group__append) {
font-size: 12px;
padding: 0 1vw;
}
/* 进入动画的初始状态 */
.slide-right-enter-from {
transform: translateX(100%);
}
/* 进入动画的结束状态(也可以理解为激活状态) */
.slide-right-enter-to {
transform: translateX(0);
}
/* 进入动画的过渡曲线等 */
.slide-right-enter-active {
transition: transform 0.3s ease-in-out;
}
/* 离开动画的初始状态(激活状态) */
.slide-right-leave-from {
transform: translateX(0);
}
/* 离开动画的结束状态 */
.slide-right-leave-to {
transform: translateX(100%);
}
/* 离开动画的过渡曲线等 */
.slide-right-leave-active {
transition: transform 0.3s ease-in-out;
}
</style>