diff --git a/src/views/ops/pages/dc/device-collect/components/FormDialog.vue b/src/views/ops/pages/dc/device-collect/components/FormDialog.vue index dae7be5..9813909 100644 --- a/src/views/ops/pages/dc/device-collect/components/FormDialog.vue +++ b/src/views/ops/pages/dc/device-collect/components/FormDialog.vue @@ -140,62 +140,11 @@ - - - - - - - + @@ -243,6 +192,7 @@ import { } from '@/api/ops/room-device' import { fetchPolicyOptions, type PolicyOptionItem } from '@/api/ops/alertPolicy' import { fetchRoomOptions, type RoomOptionItem } from '@/api/ops/room' +import SnmpOidEditor from '../../components/SnmpOidEditor.vue' interface Props { visible: boolean @@ -256,22 +206,12 @@ const props = withDefaults(defineProps(), { const emit = defineEmits(['update:visible', 'success']) const formRef = ref() +const snmpOidEditorRef = ref>() +const snmpOidEditorResetKey = ref(0) const confirmLoading = ref(false) const policyOptions = ref([]) const roomOptions = ref([]) -type SnmpOidEditMode = 'table' | 'json' - -interface SnmpOidRow { - oid: string - metric_name: string - metric_unit: string - type: string -} - -const snmpOidEditMode = ref('table') -const snmpOidRows = ref([]) - const isEdit = computed(() => !!props.record?.id) const formData = reactive({ @@ -307,96 +247,6 @@ const rules = { device_category: [{ required: true, message: '请选择设备分类' }], } -const createEmptySnmpOidRow = (): SnmpOidRow => ({ - oid: '', - metric_name: '', - metric_unit: '', - type: '', -}) - -const snmpOidTableFields = ['oid', 'metric_name', 'metric_unit', 'type'] - -const normalizeSnmpOidRows = (rows: SnmpOidRow[]) => - rows - .map((row) => ({ - oid: row.oid.trim(), - metric_name: row.metric_name.trim(), - metric_unit: row.metric_unit.trim(), - type: row.type.trim(), - })) - .filter((row) => row.oid || row.metric_name || row.metric_unit || row.type) - -const findIncompleteSnmpOidRowIndex = (rows: SnmpOidRow[]) => - rows.findIndex((row) => { - const normalizedRow = { - oid: row.oid.trim(), - metric_name: row.metric_name.trim(), - metric_unit: row.metric_unit.trim(), - type: row.type.trim(), - } - const hasAnyValue = - normalizedRow.oid || normalizedRow.metric_name || normalizedRow.metric_unit || normalizedRow.type - return Boolean(hasAnyValue && (!normalizedRow.oid || !normalizedRow.metric_name)) - }) - -const parseSnmpOidJsonArray = (raw: string) => { - const text = raw.trim() - if (!text) { - return [] - } - const parsed = JSON.parse(text) - if (!Array.isArray(parsed)) { - throw new Error('SNMP OID 配置必须是 JSON 数组') - } - return parsed -} - -const hasSnmpOidTableUnsupportedFields = (raw: string) => { - const rows = parseSnmpOidJsonArray(raw) - return rows.some((item) => { - if (!item || typeof item !== 'object' || Array.isArray(item)) { - return true - } - return Object.keys(item).some((key) => !snmpOidTableFields.includes(key)) - }) -} - -const findInvalidSnmpOidJsonRowIndex = (rows: unknown[]) => - rows.findIndex((item) => { - if (!item || typeof item !== 'object' || Array.isArray(item)) { - return true - } - const row = item as Record - return !String(row.oid ?? '').trim() || !String(row.metric_name ?? '').trim() - }) - -const stringifySnmpOidRows = (rows: SnmpOidRow[]) => { - const normalizedRows = normalizeSnmpOidRows(rows) - return normalizedRows.length ? JSON.stringify(normalizedRows, null, 2) : '' -} - -const parseSnmpOidRows = (raw: string): SnmpOidRow[] => { - const text = raw.trim() - if (!text) { - return [] - } - const parsed = parseSnmpOidJsonArray(text) - return parsed.map((item) => ({ - oid: String(item?.oid ?? '').trim(), - metric_name: String(item?.metric_name ?? '').trim(), - metric_unit: String(item?.metric_unit ?? '').trim(), - type: String(item?.type ?? '').trim(), - })) -} - -const syncSnmpOidRowsFromJson = () => { - snmpOidRows.value = parseSnmpOidRows(formData.snmp_oids || '') -} - -const syncSnmpOidJsonFromRows = () => { - formData.snmp_oids = stringifySnmpOidRows(snmpOidRows.value) -} - const loadPolicyOptions = async () => { try { const response: any = await fetchPolicyOptions({ enabled: true }) @@ -460,18 +310,7 @@ watch( collect_interval: props.record.collect_interval || 60, policy_ids: props.record.policy_ids || [], }) - snmpOidEditMode.value = 'table' - try { - if (hasSnmpOidTableUnsupportedFields(formData.snmp_oids || '')) { - snmpOidEditMode.value = 'json' - snmpOidRows.value = [] - } else { - syncSnmpOidRowsFromJson() - } - } catch { - snmpOidEditMode.value = 'json' - snmpOidRows.value = [] - } + snmpOidEditorResetKey.value += 1 } else { Object.assign(formData, { name: '', @@ -499,84 +338,12 @@ watch( collect_interval: 60, policy_ids: [], }) - snmpOidEditMode.value = 'table' - snmpOidRows.value = [] + snmpOidEditorResetKey.value += 1 } } } ) -const addSnmpOidRow = () => { - if (snmpOidEditMode.value !== 'table') { - return - } - snmpOidRows.value.push(createEmptySnmpOidRow()) - syncSnmpOidJsonFromRows() -} - -const removeSnmpOidRow = (index: number) => { - snmpOidRows.value.splice(index, 1) - syncSnmpOidJsonFromRows() -} - -const handleSnmpOidRowChange = () => { - syncSnmpOidJsonFromRows() -} - -const switchSnmpOidEditMode = () => { - if (snmpOidEditMode.value === 'table') { - syncSnmpOidJsonFromRows() - snmpOidEditMode.value = 'json' - return - } - try { - if (hasSnmpOidTableUnsupportedFields(formData.snmp_oids)) { - Message.warning('当前 SNMP OID JSON 包含表格不支持的字段,请在 JSON 模式下编辑') - return - } - syncSnmpOidRowsFromJson() - snmpOidEditMode.value = 'table' - } catch { - Message.warning('SNMP OID 配置必须是合法 JSON 数组,修正后才能切换到表格模式') - } -} - -const validateSnmpOidConfigBeforeSubmit = () => { - if (snmpOidEditMode.value === 'table') { - const invalidIndex = findIncompleteSnmpOidRowIndex(snmpOidRows.value) - if (invalidIndex >= 0) { - Message.warning(`SNMP OID 第 ${invalidIndex + 1} 行请填写 OID 和指标名称`) - return false - } - const rows = normalizeSnmpOidRows(snmpOidRows.value) - formData.snmp_oids = rows.length ? JSON.stringify(rows, null, 2) : '' - return true - } - - if (!formData.snmp_oids?.trim()) { - snmpOidRows.value = [] - formData.snmp_oids = '' - return true - } - - try { - const parsedRows = parseSnmpOidJsonArray(formData.snmp_oids) - const invalidJsonIndex = findInvalidSnmpOidJsonRowIndex(parsedRows) - if (invalidJsonIndex >= 0) { - Message.warning(`SNMP OID 第 ${invalidJsonIndex + 1} 行请填写 OID 和指标名称`) - return false - } - const rows = parseSnmpOidRows(formData.snmp_oids) - const normalizedRows = normalizeSnmpOidRows(rows) - snmpOidRows.value = normalizedRows - formData.snmp_oids = JSON.stringify(parsedRows, null, 2) - return true - } catch { - Message.warning('SNMP OID 配置必须是合法 JSON 数组') - return false - } -} - const handleOk = async () => { try { await formRef.value?.validate() @@ -606,7 +373,7 @@ const handleOk = async () => { Message.warning('SNMP v2c 模式下请填写 community') return } - if (!validateSnmpOidConfigBeforeSubmit()) { + if (!snmpOidEditorRef.value?.validate()) { return } } @@ -705,21 +472,3 @@ onMounted(() => { loadRoomOptions() }) - -