Newer
Older
sensorHubPlusFront / src / views / basic / device / batchconfig.vue
liyaguang 2 days ago 11 KB 设备配置
<!--
  Description: 批量下发配置
  Author: 李亚光
  Date: 2025-06-12
 -->
<script name="BatchConfigDialog" lang="ts" setup>
import { ElMessage, ElMessageBox, dayjs } from 'element-plus'
import { getDictByCode } from '@/api/system/dict'
import { getDeviceListPage, batchConfig } from '@/api/basic/device'
import $bus from '@/utils/eventBus'
const emit = defineEmits(['refresh'])
const $props = defineProps({
  deviceType: {
    type: String,
    default: ''
  },
})
const { proxy } = getCurrentInstance() as any
const formRef = ref()
const showDialog = ref(false)
const configInfo = ref<{ [key: string]: string }>({
  deviceId: '',
  deviceCode: '',
  percent: '', // 报警阈值
  installHeight: '', // 安装高度
  attemptsMax: '3', // 做大尝试次数
  retryTimes: '3', // 重传次数
  ip: '',
  port: '',
  deviceType: '',
  collectInterval: '', // 采集间隔
  uploadPeriod: '', // 上传周期
  configType: '', // 配置类型
  collectTime: '',  // 3/5
  sleepStartTime: '', // 5
  threshold: '',   // 5
})
const validateCollectInterval = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('采集间隔不能为空'))
  }
  else {
    if (Number(value) >= 5 && Number(value) <= 1440) {
      callback()
    }
    else {
      callback(new Error('采集间隔需在5-1440之间'))
    }
  }
}
const configInfoRules = ref({
  deviceCode: [{ required: true, message: '设备编号不能为空', trigger: 'blur' }],
  installHeight: [{ required: true, message: '安装高度不能为空', trigger: ['blur', 'change'] }],
  percent: [{ required: true, message: '报警阈值不能为空', trigger: ['blur', 'change'] }],
  deviceType: [{ required: true, message: '设备类型不能为空', trigger: ['blur', 'change'] }],
  uploadPeriod: [{ required: true, message: '上传周期不能为空', trigger: ['blur', 'change'] }],
  configType: [{ required: true, message: '配置类型不能为空', trigger: ['blur', 'change'] }],
  collectTime: [{ required: true, message: '采集时间不能为空', trigger: ['blur', 'change'] }],  // 18:03   3/5
  sleepStartTime: [{ required: true, message: '睡眠时间不能为空', trigger: ['blur', 'change'] }],  // 18:03   5
  threshold: [{ required: true, message: '报警阈值不能为空', trigger: ['blur', 'change'] }],  // 18:03   5
  collectInterval: [{ required: true, validator: validateCollectInterval, trigger: ['blur', 'change'] }],
}) // 表单验证规则
const isDisabled = ref(false)
const initDialog = (config: any) => {
  showDialog.value = true
  if (config.devcode) {
    isDisabled.value = true
    setTimeout(() => {
      formRef.value?.resetFields()
      configInfo.value.deviceCode = [config.devcode]
      configInfo.value.deviceType = `${config.deviceType}`
    }, 100);
  }
  else {
    isDisabled.value = false
    // 清空表单
    configInfo.value = {
      deviceId: '',
      deviceCode: '',
      percent: '', // 报警阈值
      installHeight: '', // 安装高度
      attemptsMax: '3', // 做大尝试次数
      retryTimes: '3', // 重传次数
      ip: '',
      port: '',
      deviceType: '',
      collectInterval: '', // 采集间隔
      uploadPeriod: '', // 上传周期
      configType: '', // 配置类型
      collectTime: '',  // 3/5
      sleepStartTime: '', // 5
      threshold: '',   // 5
    }
    formRef.value?.resetFields()
  }
}
const close = () => {
  showDialog.value = false
}


const loadingBtn = ref(false)
const jsonDict = {
  '4': ['uploadPeriod', 'collectInterval', 'attemptsMax', 'retryTimes', 'ip', 'port'],
  '32': ['uploadPeriod', 'collectInterval', 'attemptsMax', 'retryTimes', 'ip', 'port'],
  '1': ['percent', 'installHeight', 'attemptsMax', 'retryTimes', 'ip', 'port'],
  '2': ['attemptsMax', 'retryTimes', 'ip', 'port'],
  '3': ['uploadPeriod', 'collectInterval', 'attemptsMax', 'retryTimes', 'ip', 'port', 'collectTime'],
  '5': ['uploadPeriod', 'collectInterval', 'attemptsMax', 'retryTimes', 'ip', 'port', 'collectTime', 'sleepStartTime', 'threshold'],
} as { [key: string]: string[] }
// 保存
const saveForm = async () => {
  if (!formRef.value) { return }
  formRef.value?.validate((valid: boolean) => {
    if (valid) {
      // 生成json对象
      let obj = {} as { [key: string]: string }
      for (const i in jsonDict[configInfo.value.deviceType]) {
        obj[jsonDict[configInfo.value.deviceType][i]] = configInfo.value[jsonDict[configInfo.value.deviceType][i]]
      }
      const data = {
        configJson: JSON.stringify(obj),
        configType: configInfo.value.configType, // 配置类型
        devcodeList: configInfo.value.deviceCode
      }
      loadingBtn.value = true
      batchConfig(data).then(res => {
        showDialog.value = false
        loadingBtn.value = false
        ElMessage.success(`操作成功`)
        emit('refresh')
      }).catch(() => {
        loadingBtn.value = false
      })
    }
  })

}


const deviceList = ref([])
const configTypeList = ref([])
const deviceAllList = ref([])
const deviceTypeList = ref([])

const fetchDict = () => {
  // 设备类型列表
  getDictByCode('deviceType').then((res: any) => {
    if (res.code === 200) {
      deviceTypeList.value = res.data.filter((item: any) => proxy.support.includes(item.value))
    }
  })
  // 设备列表
  getDeviceListPage({ offset: 1, limit: 999999 }).then(res => {
    deviceList.value = JSON.parse(JSON.stringify(res.data.rows))
    deviceAllList.value = JSON.parse(JSON.stringify(res.data.rows))
  })
  // 配置类型
  getDictByCode('configType').then((res: any) => {
    if (res.code === 200) {
      configTypeList.value = res.data
    }
  })
}
fetchDict()
defineExpose({
  initDialog,
  fetchDict
})
$bus.on('refresh-devicelist', () => {
  // 设备列表
  getDeviceListPage({ offset: 1, limit: 999999 }).then(res => {
    deviceList.value = JSON.parse(JSON.stringify(res.data.rows))
    deviceAllList.value = JSON.parse(JSON.stringify(res.data.rows))
  })
})
const computeOptions = (val: any[]) => {
  return val.map((item: any) => ({ label: `${item.devcode}`, value: item.devcode }))
}

watch(() => configInfo.value.deviceType, (newValue) => {
  if (isDisabled.value) {
    return
  }
  configInfo.value.deviceId = ''
  configInfo.value.deviceCode = ''
  if (newValue) {
    deviceList.value = deviceAllList.value.filter((item: any) => item.deviceType === newValue)
  }
  else {
    deviceList.value = deviceAllList.value
  }
})
// 是否展示重传次数
const showRetryTimes = computed(() => {
  return (type: string) => {
    return proxy.retryTimes.includes(type)
  }
})
// 是否展示最大尝试次数
const showAttemptsMax = computed(() => {
  return (type: string) => {
    return proxy.attemptsMax.includes(type)
  }
})
// 是否展示采集间隔
const showCollectInterva = computed(() => {
  return (type: string) => {
    return proxy.collectInterval.includes(type)
  }
})
// 是否展示上传周期
const showUploadPeriod = computed(() => {
  return (type: string) => {
    return proxy.uploadPeriod.includes(type)
  }
})
</script>

<template>

  <el-dialog v-model="showDialog" title="批量下发配置" :append-to-body="true" :close-on-click-modal="false" :modal="true">
    <el-form ref="formRef" :rules="configInfoRules" :model="configInfo" label-width="110px">
      <el-row :gutter="24">
        <el-col :span="12">
          <el-form-item label="设备类型" prop="deviceType">
            <el-select v-model="configInfo.deviceType" placeholder="选择设备类型" :disabled="isDisabled" style="width: 100%;" clearable filterable>
              <el-option v-for="item in deviceTypeList" :key="item.id" :label="item.name" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="设备编号" prop="deviceCode">
            <el-select-v2 v-model="configInfo.deviceCode" :disabled="isDisabled" multiple collapse-tags :options="computeOptions(deviceList)"
              style="width: 100%;" clearable filterable>
            </el-select-v2>
          </el-form-item>
        </el-col>
        <el-col v-if="showRetryTimes(configInfo.deviceType)" :span="12">
          <el-form-item label="重传次数" prop="retryTimes">
            <el-input v-model="configInfo.retryTimes" type="number" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="showAttemptsMax(configInfo.deviceType)" :span="12">
          <el-form-item label="最大尝试次数" prop="attemptsMax">
            <el-input v-model="configInfo.attemptsMax" type="number" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="showCollectInterva(configInfo.deviceType)" :span="12">
          <el-form-item label="采集间隔(分)" prop="collectInterval">
            <el-input v-model="configInfo.collectInterval" type="number" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="showUploadPeriod(configInfo.deviceType)" :span="12">
          <el-form-item label="上传周期(分)" prop="uploadPeriod">
            <el-input v-model="configInfo.uploadPeriod" type="number" style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="configInfo.deviceType === '1'" :span="12">
          <el-form-item label="报警阈值(%)" prop="percent">
            <el-input v-model="configInfo.percent" type="number" clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="configInfo.deviceType === '1'" :span="12">
          <el-form-item label="安装高度(m)" prop="installHeight">
            <el-input v-model="configInfo.installHeight" type="number" clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <!-- <el-col v-if="configInfo.deviceType === '1'" :span="12">
          <el-form-item label="报警阈值(%)" prop="percent">
            <el-input v-model="configInfo.percent" type="number" clearable style="width: 100%;" />
          </el-form-item>
        </el-col> -->
        <el-col v-if="configInfo.deviceType === '5'" :span="12">
          <el-form-item label="报警阈值" prop="threshold">
            <el-input v-model="configInfo.threshold" type="number" clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="configInfo.deviceType === '5' || configInfo.deviceType === '3'" :span="12">
          <el-form-item label="采集时间" prop="collectTime">
            <el-time-picker v-model="configInfo.collectTime" format="HH:mm" value-format="HH:mm" placeholder="选择采集时间"
              clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col v-if="configInfo.deviceType === '5'" :span="12">
          <el-form-item label="睡眠时间" prop="sleepStartTime">
            <el-time-picker v-model="configInfo.sleepStartTime" format="HH:mm" value-format="HH:mm" placeholder="选择睡眠时间"
              clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="IP" prop="ip">
            <el-input v-model="configInfo.ip" clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="端口" prop="port">
            <el-input v-model="configInfo.port" clearable style="width: 100%;" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="配置类型" prop="configType">
            <el-select v-model="configInfo.configType" placeholder="选择配置类型" style="width: 100%;" clearable filterable>
              <el-option v-for="item in configTypeList" :key="item.id" :label="item.name" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="saveForm" :disabled="loadingBtn" :loading="loadingBtn">
          保存
        </el-button>
        <el-button @click="close">取消</el-button>
      </span>
    </template>
  </el-dialog>
</template>