<!-- Description: 设备编辑/新建/详情页面 Author: 李亚光 Date: 2023-05-29 --> <script lang="ts" setup name="DeviceEdit"> import type { Ref } from 'vue' import { nextTick, reactive } from 'vue' import { ElButton, ElCol, ElDialog, ElForm, ElFormItem, ElInput, ElInputNumber, ElMessage, ElMessageBox, ElOption, ElRow, ElSelect } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus' import { addDevice, updatDevice } from '@/api/device' import { getDictByCode } from '@/api/system/dict' // ----------------------- 以下是字段定义 emits props --------------------- const emits = defineEmits(['closeRefresh']) // 对话框类型:create,update const dialogStatus = ref('create') const dialogVisible = ref(false) // 显示标题 const textMap: { [key: string]: string } = { update: '编辑', create: '新增', detail: '详情', } const defaultFormData = { alarmGroup: '', channelNum: '', connectType: '', deviceName: '', id: '', ip: '', location: '', password: '', port: '', status: '', userName: '', } // 表单数据对象 const formData = reactive({ ...defaultFormData }) // 保存按钮加载状态 const btnLoading = ref(false) // ---------------表单提交-------------------------------- // 表单对象 const dataFormRef = ref<FormInstance>() // 校验规则 const rules: FormRules = reactive({ deviceName: [{ required: true, message: '设备名称不可为空', trigger: ['blur', 'change'] }], connectType: [{ required: true, message: '设备连接类型不可为空', trigger: ['blur', 'change'] }], ip: [{ required: true, message: '设备ip不可为空', trigger: ['blur', 'change'] }], port: [{ required: true, message: '端口号不可为空', trigger: ['blur', 'change'] }], userName: [{ required: true, message: '用户名不可为空', trigger: ['blur', 'change'] }], password: [{ required: true, message: '密码不可为空', trigger: ['blur', 'change'] }], status: [{ required: true, message: '设备状态不可为空', trigger: ['blur', 'change'] }], location: [{ required: true, message: '设备安装位置不可为空', trigger: ['blur', 'change'] }], }) // 获取设备状态 const deviceStatusList = ref<any[]>() const fetchDeviceStatus = () => { getDictByCode('deviceStatus').then((res) => { deviceStatusList.value = res.data }) } fetchDeviceStatus() // 获取连接类型 const connectTypeList = ref<any[]>() const fetchConnectType = () => { getDictByCode('connectType').then((res) => { connectTypeList.value = res.data }) } fetchConnectType() const submitForm = async (formEl: FormInstance | undefined) => { if (!formEl) { return } await formEl.validate((valid, fields) => { if (valid) { if (valid) { if (dialogStatus.value === 'create') { createData() } else if (dialogStatus.value === 'update') { updateData() } } } }) } // 新增数据 function createData() { btnLoading.value = true addDevice(formData).then((res) => { ElMessage.success('添加') btnLoading.value = false closeRefresh() }).catch((_) => { btnLoading.value = false }) } // 更新数据 function updateData() { updatDevice(formData).then((res) => { ElMessage.success('修改成功') btnLoading.value = false closeRefresh() }).catch((_) => { // 异常情况,loading置为false btnLoading.value = false }) } // 重置表单 function resetForm() { const form = formData const keys = Object.keys(formData) keys.forEach((key) => { form[key] = defaultFormData[key] }) Object.assign(formData, form) nextTick(() => { dataFormRef.value?.clearValidate() }) } // const deptTypeList: Ref<DeptTypeInfo[]> = ref([]) // // 获取所有组织类型 // function getDeptType() { // getDeptTypeList().then((res) => { // deptTypeList.value = res.data // }) // } // getDeptType() // ----------初始化、关闭对话框相关----------------- function initDialog(dialogstatus: string, row: any) { dialogStatus.value = dialogstatus dialogVisible.value = true btnLoading.value = false if (dialogstatus === 'create') { resetForm() nextTick(() => { dataFormRef.value?.clearValidate() }) } else if (dialogstatus === 'update' || dialogstatus === 'detail') { formData.id = row.id formData.alarmGroup = row.alarmGroup formData.channelNum = row.channelNum formData.connectType = row.connectType formData.deviceName = row.deviceName formData.location = row.location formData.password = row.password formData.status = row.status formData.userName = row.userName formData.ip = row.ip formData.port = row.port } } // 关闭并刷新 function closeRefresh() { dialogVisible.value = false resetForm() emits('closeRefresh') } // 关闭弹窗 function dialogClose() { resetForm() dialogVisible.value = false } // ----------------------- 以下是暴露的方法内容 ---------------------------- defineExpose({ initDialog }) </script> <template> <el-dialog v-model="dialogVisible" :title="textMap[dialogStatus]" width="50%" :before-close="dialogClose" append-to-body :open-delay="0" :close-on-click-modal="false"> <el-form ref="dataFormRef" :model="formData" :rules="rules" label-position="left" label-width="100px" class="form-container" :class="{ 'none-required': dialogStatus === 'detail' ? true : false }" size="default" @submit.prevent> <el-row :gutter="10"> <el-col :span="12" class="grid-cell"> <el-form-item label="设备名称" prop="deviceName" class="required"> <el-input v-model.trim="formData.deviceName" type="text" :placeholder="dialogStatus === 'detail' ? '' : '请输入设备名称'" :disabled="dialogStatus === 'detail' ? true : false" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="连接类型" prop="connectType" class="required"> <el-select v-model="formData.connectType" class="full-width-input" clearable :placeholder="dialogStatus === 'detail' ? '' : '请选择设备连接类型'" :disabled="dialogStatus === 'detail' ? true : false"> <el-option v-for="(item, index) in connectTypeList" :key="index" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="位置" prop="location" class="required"> <el-input v-model.trim="formData.location" type="text" :placeholder="dialogStatus === 'detail' ? '' : '请输入设备安装位置'" :disabled="dialogStatus === 'detail' ? true : false" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="设备状态" prop="status" class="required"> <el-select v-model="formData.status" class="full-width-input" clearable :placeholder="dialogStatus === 'detail' ? '' : '请选择设备状态'" :disabled="dialogStatus === 'detail' ? true : false"> <el-option v-for="(item, index) in deviceStatusList" :key="index" :label="item.name" :value="item.value" /> </el-select> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="用户名" prop="userName" class="required"> <el-input v-model.trim="formData.userName" type="text" :placeholder="dialogStatus === 'detail' ? '' : '请输入用户名'" :disabled="dialogStatus === 'detail' ? true : false" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="密码" prop="password"> <el-input v-model.trim="formData.password" type="text" :placeholder="dialogStatus === 'detail' ? '' : '请输入设备密码'" :disabled="dialogStatus === 'detail' ? true : false" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="IP" prop="ip"> <el-input v-model.trim="formData.ip" type="text" :placeholder="dialogStatus === 'detail' ? '' : '请输入设备ip'" :disabled="dialogStatus === 'detail' ? true : false" clearable /> </el-form-item> </el-col> <el-col :span="12" class="grid-cell"> <el-form-item label="端口" prop="port"> <el-input v-model.trim="formData.port" type="text" :placeholder="dialogStatus === 'detail' ? '' : '请输入端口号'" :disabled="dialogStatus === 'detail' ? true : false" clearable /> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div v-if="dialogStatus !== 'detail'" class="dialog-footer"> <el-button :loading="btnLoading" type="primary" @click="submitForm(dataFormRef)"> 保存 </el-button> <el-button @click="dialogClose"> 取消 </el-button> </div> <div v-else class="dialog-footer"> <el-button type="primary" @click="dialogClose"> 确认 </el-button> </div> </template> </el-dialog> </template> <style lang="scss" scoped> .form-container { width: 100%; .full-width-input { width: 100%; } } .none-required { ::v-deep { .el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label::before, .el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label::before { content: ""; display: none; } } }</style>