<!-- 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>