From 58365870ef1e07cbee21a3823b5b7dcb2400ca27 Mon Sep 17 00:00:00 2001
From: zxr <271055687@qq.com>
Date: Sun, 5 Jul 2026 23:02:09 +0800
Subject: [PATCH] refactor: reuse snmp oid editor in device collect form
---
.../device-collect/components/FormDialog.vue | 273 +-----------------
1 file changed, 11 insertions(+), 262 deletions(-)
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 @@
-
-
-
-
SNMP OID配置
-
-
- {{ snmpOidEditMode === 'table' ? 'JSON' : '表格' }}
-
-
- 添加
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 删除
-
-
-
-
-
-
-
-
-
+
@@ -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()
})
-
-