Newer
Older
video-monitor-front / src / views / device / editDevice.vue
<!--
  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>