fix
This commit is contained in:
@@ -12,6 +12,13 @@ export interface RoomDeviceItem {
|
||||
room_id: string
|
||||
device_category: string
|
||||
agent_config: string
|
||||
collect_method: 'api' | 'snmp'
|
||||
snmp_target: string
|
||||
snmp_port: number
|
||||
snmp_community: string
|
||||
snmp_timeout_ms: number
|
||||
snmp_retries: number
|
||||
snmp_oids: string
|
||||
enabled: boolean
|
||||
collect_on: boolean
|
||||
collect_interval: number
|
||||
@@ -45,6 +52,13 @@ export interface RoomDeviceCreateData {
|
||||
room_id: string
|
||||
device_category: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
enabled?: boolean
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
@@ -58,6 +72,13 @@ export interface RoomDeviceUpdateData {
|
||||
room_id?: string
|
||||
device_category?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
enabled?: boolean
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
@@ -66,9 +87,16 @@ export interface RoomDeviceUpdateData {
|
||||
|
||||
/** 机房设备采集配置数据 */
|
||||
export interface RoomDeviceCollectData {
|
||||
collect_method?: 'api' | 'snmp'
|
||||
agent_config?: string
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
agent_config?: string
|
||||
}
|
||||
|
||||
/** 指标数据项 */
|
||||
|
||||
@@ -19,6 +19,13 @@ export interface SecurityServiceItem {
|
||||
tags: string
|
||||
status_url: string
|
||||
agent_config: string
|
||||
collect_method: 'api' | 'snmp'
|
||||
snmp_target: string
|
||||
snmp_port: number
|
||||
snmp_community: string
|
||||
snmp_timeout_ms: number
|
||||
snmp_retries: number
|
||||
snmp_oids: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
@@ -65,6 +72,13 @@ export interface SecurityServiceFormData {
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
@@ -120,6 +134,14 @@ export const fetchSecurityMetricsLatest = (serviceIdentity: string) => {
|
||||
|
||||
/** 采集配置补丁参数 */
|
||||
export interface SecurityServicePatchData {
|
||||
collect_method?: 'api' | 'snmp'
|
||||
agent_config?: string
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
}
|
||||
|
||||
@@ -19,6 +19,13 @@ export interface StorageItem {
|
||||
tags: string
|
||||
status_url: string
|
||||
agent_config: string
|
||||
collect_method: 'api' | 'snmp'
|
||||
snmp_target: string
|
||||
snmp_port: number
|
||||
snmp_community: string
|
||||
snmp_timeout_ms: number
|
||||
snmp_retries: number
|
||||
snmp_oids: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
@@ -65,6 +72,13 @@ export interface StorageCreateData {
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
@@ -86,6 +100,13 @@ export interface StorageUpdateData {
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
@@ -151,6 +172,14 @@ export const fetchStorageMetricsLatest = (serviceIdentity: string) => {
|
||||
|
||||
/** 采集配置补丁 */
|
||||
export interface StoragePatchData {
|
||||
collect_method?: 'api' | 'snmp'
|
||||
agent_config?: string
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_community?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
}
|
||||
|
||||
@@ -10,10 +10,22 @@
|
||||
<a-descriptions-item label="机房ID">{{ record.room_id }}</a-descriptions-item>
|
||||
<a-descriptions-item label="描述信息" :span="2">{{ record.description || '-' }}</a-descriptions-item>
|
||||
|
||||
<a-descriptions-item label="采集地址" :span="2">
|
||||
<a-link v-if="record.agent_config" :href="record.agent_config" target="_blank">{{ record.agent_config }}</a-link>
|
||||
<a-descriptions-item label="采集方式">
|
||||
<a-tag :color="record.collect_method === 'snmp' ? 'purple' : 'arcoblue'">
|
||||
{{ record.collect_method === 'snmp' ? 'SNMP' : 'API' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="采集地址/目标" :span="2">
|
||||
<a-link v-if="record.collect_method !== 'snmp' && record.agent_config" :href="record.agent_config" target="_blank">{{ record.agent_config }}</a-link>
|
||||
<span v-else-if="record.collect_method === 'snmp'">{{ record.snmp_target || '-' }}</span>
|
||||
<span v-else>-</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.collect_method === 'snmp'" label="SNMP连接">
|
||||
{{ (record.snmp_community || '-') + ' @ ' + (record.snmp_port || 161) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.collect_method === 'snmp'" label="SNMP超时/重试">
|
||||
{{ (record.snmp_timeout_ms || 3000) + 'ms / ' + (record.snmp_retries ?? 1) }}
|
||||
</a-descriptions-item>
|
||||
|
||||
<a-descriptions-item label="启用状态">
|
||||
<a-tag :color="record.enabled ? 'green' : 'gray'">
|
||||
|
||||
@@ -38,9 +38,57 @@
|
||||
<a-textarea v-model="formData.description" placeholder="请输入描述信息" :rows="2" />
|
||||
</a-form-item>
|
||||
|
||||
<a-divider orientation="left">采集协议与连接</a-divider>
|
||||
<a-form-item field="collect_method" label="采集方式">
|
||||
<a-radio-group v-model="formData.collect_method" type="button">
|
||||
<a-radio value="api">API</a-radio>
|
||||
<a-radio value="snmp">SNMP</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<template v-if="formData.collect_method === 'api'">
|
||||
<a-form-item field="agent_config" label="采集地址(HTTP/HTTPS GET)">
|
||||
<a-input v-model="formData.agent_config" placeholder="周期采集地址,返回 JSON 格式指标数组" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="snmp_target" label="SNMP目标地址">
|
||||
<a-input v-model="formData.snmp_target" placeholder="例如 192.168.1.10" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="snmp_port" label="SNMP端口">
|
||||
<a-input-number v-model="formData.snmp_port" :min="1" :max="65535" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="snmp_community" label="Community">
|
||||
<a-input v-model="formData.snmp_community" placeholder="SNMP v2c community" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item field="snmp_timeout_ms" label="超时(ms)">
|
||||
<a-input-number v-model="formData.snmp_timeout_ms" :min="1" :max="60000" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item field="snmp_retries" label="重试次数">
|
||||
<a-input-number v-model="formData.snmp_retries" :min="0" :max="10" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item field="snmp_oids" label="SNMP OID配置(JSON数组)">
|
||||
<a-textarea
|
||||
v-model="formData.snmp_oids"
|
||||
:rows="3"
|
||||
placeholder='可留空使用默认模板,或填写如 [{"oid":"1.3.6.1.2.1.1.3.0","metric_name":"sys_uptime"}]'
|
||||
/>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
@@ -110,6 +158,13 @@ const formData = reactive({
|
||||
room_id: '',
|
||||
device_category: '',
|
||||
agent_config: '',
|
||||
collect_method: 'api' as 'api' | 'snmp',
|
||||
snmp_target: '',
|
||||
snmp_port: 161,
|
||||
snmp_community: '',
|
||||
snmp_timeout_ms: 3000,
|
||||
snmp_retries: 1,
|
||||
snmp_oids: '',
|
||||
enabled: true,
|
||||
collect_on: true,
|
||||
collect_interval: 60,
|
||||
@@ -149,6 +204,13 @@ watch(
|
||||
room_id: props.record.room_id || '',
|
||||
device_category: props.record.device_category || '',
|
||||
agent_config: props.record.agent_config || '',
|
||||
collect_method: props.record.collect_method || 'api',
|
||||
snmp_target: props.record.snmp_target || '',
|
||||
snmp_port: props.record.snmp_port || 161,
|
||||
snmp_community: props.record.snmp_community || '',
|
||||
snmp_timeout_ms: props.record.snmp_timeout_ms || 3000,
|
||||
snmp_retries: props.record.snmp_retries ?? 1,
|
||||
snmp_oids: props.record.snmp_oids || '',
|
||||
enabled: props.record.enabled ?? true,
|
||||
collect_on: props.record.collect_on ?? true,
|
||||
collect_interval: props.record.collect_interval || 60,
|
||||
@@ -161,6 +223,13 @@ watch(
|
||||
room_id: '',
|
||||
device_category: '',
|
||||
agent_config: '',
|
||||
collect_method: 'api',
|
||||
snmp_target: '',
|
||||
snmp_port: 161,
|
||||
snmp_community: '',
|
||||
snmp_timeout_ms: 3000,
|
||||
snmp_retries: 1,
|
||||
snmp_oids: '',
|
||||
enabled: true,
|
||||
collect_on: true,
|
||||
collect_interval: 60,
|
||||
@@ -174,6 +243,24 @@ watch(
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
if (formData.collect_method === 'api' && !formData.agent_config?.trim()) {
|
||||
Message.warning('API 模式下请填写采集地址')
|
||||
return
|
||||
}
|
||||
if (formData.collect_method === 'snmp') {
|
||||
if (!formData.snmp_target?.trim() || !formData.snmp_community?.trim()) {
|
||||
Message.warning('SNMP 模式下请填写目标地址和 community')
|
||||
return
|
||||
}
|
||||
if (formData.snmp_oids?.trim()) {
|
||||
try {
|
||||
JSON.parse(formData.snmp_oids)
|
||||
} catch {
|
||||
Message.warning('SNMP OID 配置必须是合法 JSON')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
confirmLoading.value = true
|
||||
|
||||
@@ -184,6 +271,13 @@ const handleOk = async () => {
|
||||
room_id: formData.room_id,
|
||||
device_category: formData.device_category,
|
||||
agent_config: formData.agent_config,
|
||||
collect_method: formData.collect_method,
|
||||
snmp_target: formData.snmp_target,
|
||||
snmp_port: formData.snmp_port,
|
||||
snmp_community: formData.snmp_community,
|
||||
snmp_timeout_ms: formData.snmp_timeout_ms,
|
||||
snmp_retries: formData.snmp_retries,
|
||||
snmp_oids: formData.snmp_oids,
|
||||
enabled: formData.enabled,
|
||||
collect_on: formData.collect_on,
|
||||
collect_interval: formData.collect_interval,
|
||||
@@ -198,6 +292,13 @@ const handleOk = async () => {
|
||||
room_id: formData.room_id,
|
||||
device_category: formData.device_category,
|
||||
agent_config: formData.agent_config,
|
||||
collect_method: formData.collect_method,
|
||||
snmp_target: formData.snmp_target,
|
||||
snmp_port: formData.snmp_port,
|
||||
snmp_community: formData.snmp_community,
|
||||
snmp_timeout_ms: formData.snmp_timeout_ms,
|
||||
snmp_retries: formData.snmp_retries,
|
||||
snmp_oids: formData.snmp_oids,
|
||||
enabled: formData.enabled,
|
||||
collect_on: formData.collect_on,
|
||||
collect_interval: formData.collect_interval,
|
||||
|
||||
@@ -1,6 +1,30 @@
|
||||
<template>
|
||||
<a-modal :visible="visible" title="采集配置" :mask-closable="false" :ok-loading="loading" @ok="handleSubmit" @cancel="handleCancel">
|
||||
<a-form :model="form" layout="vertical">
|
||||
<a-form-item label="采集方式">
|
||||
<a-radio-group v-model="form.collect_method" type="button">
|
||||
<a-radio value="api">API</a-radio>
|
||||
<a-radio value="snmp">SNMP</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<template v-if="form.collect_method === 'api'">
|
||||
<a-form-item label="采集地址(HTTP/HTTPS GET)">
|
||||
<a-input v-model="form.agent_config" placeholder="周期采集地址,返回 JSON 格式指标数组" />
|
||||
<template #extra>
|
||||
<span style="color: #86909c">采集地址应返回 JSON 格式的指标数据,支持 {"metrics":[...]} 或数组形式</span>
|
||||
</template>
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-form-item label="SNMP目标地址">
|
||||
<a-input v-model="form.snmp_target" placeholder="例如 192.168.1.10" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Community">
|
||||
<a-input v-model="form.snmp_community" placeholder="SNMP v2c community" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-form-item label="参与周期采集">
|
||||
<a-switch v-model="form.collect_on" />
|
||||
</a-form-item>
|
||||
@@ -12,12 +36,6 @@
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="采集地址(HTTP/HTTPS GET)">
|
||||
<a-input v-model="form.agent_config" placeholder="周期采集地址,返回 JSON 格式指标数组" />
|
||||
<template #extra>
|
||||
<span style="color: #86909c">采集地址应返回 JSON 格式的指标数据,支持 {"metrics":[...]} 或数组形式</span>
|
||||
</template>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
@@ -38,18 +56,24 @@ const emit = defineEmits(['update:visible', 'success'])
|
||||
const loading = ref(false)
|
||||
|
||||
const form = ref({
|
||||
collect_method: 'api' as 'api' | 'snmp',
|
||||
collect_on: true,
|
||||
collect_interval: 60,
|
||||
agent_config: '',
|
||||
snmp_target: '',
|
||||
snmp_community: '',
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
(val) => {
|
||||
if (val && props.record) {
|
||||
form.value.collect_method = props.record.collect_method || 'api'
|
||||
form.value.collect_on = props.record.collect_on ?? true
|
||||
form.value.collect_interval = props.record.collect_interval || 60
|
||||
form.value.agent_config = props.record.agent_config || ''
|
||||
form.value.snmp_target = props.record.snmp_target || ''
|
||||
form.value.snmp_community = props.record.snmp_community || ''
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -58,9 +82,12 @@ const handleSubmit = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data: RoomDeviceCollectData = {
|
||||
collect_method: form.value.collect_method,
|
||||
collect_on: form.value.collect_on,
|
||||
collect_interval: form.value.collect_interval,
|
||||
agent_config: form.value.agent_config,
|
||||
agent_config: form.value.collect_method === 'api' ? form.value.agent_config : undefined,
|
||||
snmp_target: form.value.collect_method === 'snmp' ? form.value.snmp_target : undefined,
|
||||
snmp_community: form.value.collect_method === 'snmp' ? form.value.snmp_community : undefined,
|
||||
}
|
||||
|
||||
await patchRoomDeviceCollect(props.record.id, data)
|
||||
|
||||
@@ -38,6 +38,12 @@ export const columns = [
|
||||
width: 100,
|
||||
slotName: 'enabled',
|
||||
},
|
||||
{
|
||||
dataIndex: 'collect_method',
|
||||
title: '采集方式',
|
||||
width: 100,
|
||||
slotName: 'collect_method',
|
||||
},
|
||||
{
|
||||
dataIndex: 'collect_on',
|
||||
title: '数据采集',
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
{{ record.collect_on ? '已启用' : '未启用' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #collect_method="{ record }">
|
||||
<a-tag :color="record.collect_method === 'snmp' ? 'purple' : 'arcoblue'">
|
||||
{{ record.collect_method === 'snmp' ? 'SNMP' : 'API' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template #actions="{ record }">
|
||||
<a-space>
|
||||
|
||||
@@ -17,16 +17,28 @@
|
||||
|
||||
<a-divider orientation="left">采集配置</a-divider>
|
||||
<a-descriptions :column="2" bordered>
|
||||
<a-descriptions-item label="采集方式">
|
||||
<a-tag :color="record.collect_method === 'snmp' ? 'purple' : 'arcoblue'">
|
||||
{{ record.collect_method === 'snmp' ? 'SNMP' : 'API' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="采集间隔">{{ record.collect_interval }}秒</a-descriptions-item>
|
||||
<a-descriptions-item label="采集地址" :span="2">
|
||||
<a-link v-if="record.agent_config" :href="record.agent_config" target="_blank">{{ record.agent_config }}</a-link>
|
||||
<a-link v-if="record.collect_method !== 'snmp' && record.agent_config" :href="record.agent_config" target="_blank">{{ record.agent_config }}</a-link>
|
||||
<span v-else-if="record.collect_method === 'snmp'">{{ record.snmp_target || '-' }}</span>
|
||||
<span v-else>-</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.collect_method === 'snmp'" label="SNMP连接">
|
||||
{{ (record.snmp_community || '-') + ' @ ' + (record.snmp_port || 161) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="record.collect_method === 'snmp'" label="SNMP超时/重试">
|
||||
{{ (record.snmp_timeout_ms || 3000) + 'ms / ' + (record.snmp_retries ?? 1) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="启用周期采集">
|
||||
<a-tag :color="record.collect_on ? 'green' : 'gray'">
|
||||
{{ record.collect_on ? '已启用' : '未启用' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="采集间隔">{{ record.collect_interval }}秒</a-descriptions-item>
|
||||
<a-descriptions-item label="采集参数" :span="2">{{ record.collect_args || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="采集结果" :span="2">{{ record.collect_last_result || '-' }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
||||
@@ -55,9 +55,61 @@
|
||||
<a-textarea v-model="formData.description" placeholder="请输入描述信息" :rows="2" />
|
||||
</a-form-item>
|
||||
|
||||
<a-divider orientation="left">采集协议与连接</a-divider>
|
||||
<a-form-item field="collect_method" label="采集方式">
|
||||
<a-radio-group v-model="formData.collect_method" type="button">
|
||||
<a-radio value="api">API</a-radio>
|
||||
<a-radio value="snmp">SNMP</a-radio>
|
||||
</a-radio-group>
|
||||
<template #extra>
|
||||
<span class="form-extra">推荐优先 API;设备无 API 时可切到 SNMP v2c</span>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<template v-if="formData.collect_method === 'api'">
|
||||
<a-form-item field="agent_config" label="采集地址(HTTP/HTTPS GET)">
|
||||
<a-input v-model="formData.agent_config" placeholder="周期采集地址,返回 JSON 格式指标数组" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="snmp_target" label="SNMP目标地址">
|
||||
<a-input v-model="formData.snmp_target" placeholder="例如 192.168.1.10" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="snmp_port" label="SNMP端口">
|
||||
<a-input-number v-model="formData.snmp_port" :min="1" :max="65535" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="snmp_community" label="Community">
|
||||
<a-input v-model="formData.snmp_community" placeholder="SNMP v2c community" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item field="snmp_timeout_ms" label="超时(ms)">
|
||||
<a-input-number v-model="formData.snmp_timeout_ms" :min="1" :max="60000" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item field="snmp_retries" label="重试次数">
|
||||
<a-input-number v-model="formData.snmp_retries" :min="0" :max="10" style="width: 100%" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-form-item field="snmp_oids" label="SNMP OID配置(JSON数组)">
|
||||
<a-textarea
|
||||
v-model="formData.snmp_oids"
|
||||
:rows="3"
|
||||
placeholder='可留空使用默认模板,或填写如 [{"oid":"1.3.6.1.2.1.1.3.0","metric_name":"sys_uptime","metric_unit":"timeticks"}]'
|
||||
/>
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-row :gutter="20">
|
||||
<a-col :span="12">
|
||||
@@ -135,6 +187,13 @@ const formData = reactive({
|
||||
interval: 60,
|
||||
description: '',
|
||||
agent_config: '',
|
||||
collect_method: 'api' as 'api' | 'snmp',
|
||||
snmp_target: '',
|
||||
snmp_port: 161,
|
||||
snmp_community: '',
|
||||
snmp_timeout_ms: 3000,
|
||||
snmp_retries: 1,
|
||||
snmp_oids: '',
|
||||
enabled: true,
|
||||
collect_on: true,
|
||||
collect_interval: 60,
|
||||
@@ -192,6 +251,13 @@ watch(
|
||||
interval: props.record.interval || 60,
|
||||
description: props.record.description || '',
|
||||
agent_config: props.record.agent_config || '',
|
||||
collect_method: props.record.collect_method || 'api',
|
||||
snmp_target: props.record.snmp_target || '',
|
||||
snmp_port: props.record.snmp_port || 161,
|
||||
snmp_community: props.record.snmp_community || '',
|
||||
snmp_timeout_ms: props.record.snmp_timeout_ms || 3000,
|
||||
snmp_retries: props.record.snmp_retries ?? 1,
|
||||
snmp_oids: props.record.snmp_oids || '',
|
||||
enabled: props.record.enabled ?? true,
|
||||
collect_on: props.record.collect_on ?? true,
|
||||
collect_interval: props.record.collect_interval || 60,
|
||||
@@ -209,6 +275,13 @@ watch(
|
||||
interval: 60,
|
||||
description: '',
|
||||
agent_config: '',
|
||||
collect_method: 'api',
|
||||
snmp_target: '',
|
||||
snmp_port: 161,
|
||||
snmp_community: '',
|
||||
snmp_timeout_ms: 3000,
|
||||
snmp_retries: 1,
|
||||
snmp_oids: '',
|
||||
enabled: true,
|
||||
collect_on: true,
|
||||
collect_interval: 60,
|
||||
@@ -224,6 +297,28 @@ watch(
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
if (formData.collect_method === 'api' && !formData.agent_config?.trim()) {
|
||||
Message.warning('API 模式下请填写采集地址')
|
||||
return
|
||||
}
|
||||
if (formData.collect_method === 'snmp') {
|
||||
if (!formData.snmp_target?.trim()) {
|
||||
Message.warning('SNMP 模式下请填写目标地址')
|
||||
return
|
||||
}
|
||||
if (!formData.snmp_community?.trim()) {
|
||||
Message.warning('SNMP 模式下请填写 community')
|
||||
return
|
||||
}
|
||||
if (formData.snmp_oids?.trim()) {
|
||||
try {
|
||||
JSON.parse(formData.snmp_oids)
|
||||
} catch {
|
||||
Message.warning('SNMP OID配置必须是合法 JSON')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
confirmLoading.value = true
|
||||
|
||||
@@ -236,6 +331,13 @@ const handleOk = async () => {
|
||||
interval: formData.interval,
|
||||
description: formData.description,
|
||||
agent_config: formData.agent_config,
|
||||
collect_method: formData.collect_method,
|
||||
snmp_target: formData.snmp_target,
|
||||
snmp_port: formData.snmp_port,
|
||||
snmp_community: formData.snmp_community,
|
||||
snmp_timeout_ms: formData.snmp_timeout_ms,
|
||||
snmp_retries: formData.snmp_retries,
|
||||
snmp_oids: formData.snmp_oids,
|
||||
enabled: formData.enabled,
|
||||
collect_on: formData.collect_on,
|
||||
collect_interval: formData.collect_interval,
|
||||
@@ -276,3 +378,10 @@ onMounted(() => {
|
||||
loadServerOptions()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.form-extra {
|
||||
color: var(--color-text-3);
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,6 +9,27 @@
|
||||
width="500px"
|
||||
>
|
||||
<a-form ref="formRef" :model="formData" layout="vertical">
|
||||
<a-form-item field="collect_method" label="采集方式">
|
||||
<a-radio-group v-model="formData.collect_method" type="button">
|
||||
<a-radio value="api">API</a-radio>
|
||||
<a-radio value="snmp">SNMP</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<template v-if="formData.collect_method === 'api'">
|
||||
<a-form-item field="agent_config" label="采集地址(HTTP/HTTPS GET)">
|
||||
<a-input v-model="formData.agent_config" placeholder="周期采集地址,返回 JSON 格式指标数组" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-form-item field="snmp_target" label="SNMP目标地址">
|
||||
<a-input v-model="formData.snmp_target" placeholder="例如 192.168.1.10" />
|
||||
</a-form-item>
|
||||
<a-form-item field="snmp_community" label="Community">
|
||||
<a-input v-model="formData.snmp_community" placeholder="SNMP v2c community" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
|
||||
<a-form-item field="collect_on" label="启用周期采集">
|
||||
<a-switch v-model="formData.collect_on" />
|
||||
</a-form-item>
|
||||
@@ -43,6 +64,10 @@ const formRef = ref<FormInstance>()
|
||||
const confirmLoading = ref(false)
|
||||
|
||||
const formData = reactive({
|
||||
collect_method: 'api' as 'api' | 'snmp',
|
||||
agent_config: '',
|
||||
snmp_target: '',
|
||||
snmp_community: '',
|
||||
collect_on: true,
|
||||
collect_interval: 60,
|
||||
})
|
||||
@@ -51,6 +76,10 @@ watch(
|
||||
() => props.visible,
|
||||
(val) => {
|
||||
if (val && props.record) {
|
||||
formData.collect_method = props.record.collect_method || 'api'
|
||||
formData.agent_config = props.record.agent_config || ''
|
||||
formData.snmp_target = props.record.snmp_target || ''
|
||||
formData.snmp_community = props.record.snmp_community || ''
|
||||
formData.collect_on = props.record.collect_on ?? true
|
||||
formData.collect_interval = props.record.collect_interval || 60
|
||||
}
|
||||
@@ -62,6 +91,10 @@ const handleOk = async () => {
|
||||
confirmLoading.value = true
|
||||
|
||||
const patchData: SecurityServicePatchData = {
|
||||
collect_method: formData.collect_method,
|
||||
agent_config: formData.collect_method === 'api' ? formData.agent_config : undefined,
|
||||
snmp_target: formData.collect_method === 'snmp' ? formData.snmp_target : undefined,
|
||||
snmp_community: formData.collect_method === 'snmp' ? formData.snmp_community : undefined,
|
||||
collect_on: formData.collect_on,
|
||||
collect_interval: formData.collect_interval,
|
||||
}
|
||||
|
||||
@@ -40,6 +40,12 @@ export const columns = [
|
||||
width: 100,
|
||||
slotName: 'enabled',
|
||||
},
|
||||
{
|
||||
dataIndex: 'collect_method',
|
||||
title: '采集方式',
|
||||
width: 100,
|
||||
slotName: 'collectMethod',
|
||||
},
|
||||
{
|
||||
dataIndex: 'collect_on',
|
||||
title: '采集状态',
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
{{ record.collect_on ? '已启用' : '未启用' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #collectMethod="{ record }">
|
||||
<a-tag :color="record.collect_method === 'snmp' ? 'purple' : 'arcoblue'">
|
||||
{{ record.collect_method === 'snmp' ? 'SNMP' : 'API' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="getStatusColor(record.status)">
|
||||
|
||||
@@ -22,7 +22,21 @@
|
||||
</a-descriptions>
|
||||
|
||||
<a-descriptions title="采集配置" :column="2" bordered style="margin-top: 20px">
|
||||
<a-descriptions-item label="Agent配置">{{ detailData?.agent_config || '-' }}</a-descriptions-item>
|
||||
<a-descriptions-item label="采集方式">
|
||||
<a-tag :color="detailData?.collect_method === 'snmp' ? 'purple' : 'arcoblue'">
|
||||
{{ detailData?.collect_method === 'snmp' ? 'SNMP' : 'API' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="连接配置">
|
||||
<span v-if="detailData?.collect_method === 'snmp'">{{ detailData?.snmp_target || '-' }}</span>
|
||||
<span v-else>{{ detailData?.agent_config || '-' }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="detailData?.collect_method === 'snmp'" label="SNMP连接">
|
||||
{{ (detailData?.snmp_community || '-') + ' @ ' + (detailData?.snmp_port || 161) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-if="detailData?.collect_method === 'snmp'" label="SNMP超时/重试">
|
||||
{{ (detailData?.snmp_timeout_ms || 3000) + 'ms / ' + (detailData?.snmp_retries ?? 1) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="启用采集">
|
||||
<a-tag :color="detailData?.collect_on ? 'green' : 'gray'">
|
||||
{{ detailData?.collect_on ? '已启用' : '未启用' }}
|
||||
|
||||
@@ -68,7 +68,39 @@
|
||||
</a-row>
|
||||
|
||||
<a-form-item field="agent_config" label="Agent配置URL">
|
||||
<a-radio-group v-model="formData.collect_method" type="button" style="margin-bottom: 12px">
|
||||
<a-radio value="api">API</a-radio>
|
||||
<a-radio value="snmp">SNMP</a-radio>
|
||||
</a-radio-group>
|
||||
<template v-if="formData.collect_method === 'api'">
|
||||
<a-input v-model="formData.agent_config" placeholder="请输入Agent配置地址" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-row :gutter="12">
|
||||
<a-col :span="12">
|
||||
<a-input v-model="formData.snmp_target" placeholder="SNMP目标地址" />
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input-number v-model="formData.snmp_port" :min="1" :max="65535" placeholder="SNMP端口" style="width: 100%" />
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-input v-model="formData.snmp_community" placeholder="SNMP community" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-input-number v-model="formData.snmp_timeout_ms" :min="1" :max="60000" placeholder="超时(ms)" style="width: 100%" />
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-input-number v-model="formData.snmp_retries" :min="0" :max="10" placeholder="重试次数" style="width: 100%" />
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-textarea
|
||||
v-model="formData.snmp_oids"
|
||||
:rows="3"
|
||||
placeholder='可留空用默认模板,或填写 JSON 数组如 [{"oid":"1.3.6.1.2.1.1.3.0","metric_name":"sys_uptime"}]'
|
||||
/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="collect_args" label="采集参数">
|
||||
@@ -124,6 +156,13 @@ const formData = reactive<StorageCreateData>({
|
||||
extra: '',
|
||||
tags: '',
|
||||
agent_config: '',
|
||||
collect_method: 'api' as 'api' | 'snmp',
|
||||
snmp_target: '',
|
||||
snmp_port: 161,
|
||||
snmp_community: '',
|
||||
snmp_timeout_ms: 3000,
|
||||
snmp_retries: 1,
|
||||
snmp_oids: '',
|
||||
collect_on: true,
|
||||
collect_args: '',
|
||||
collect_interval: 60,
|
||||
@@ -150,6 +189,13 @@ watch(
|
||||
extra: props.record.extra || '',
|
||||
tags: props.record.tags || '',
|
||||
agent_config: props.record.agent_config || '',
|
||||
collect_method: props.record.collect_method || 'api',
|
||||
snmp_target: props.record.snmp_target || '',
|
||||
snmp_port: props.record.snmp_port || 161,
|
||||
snmp_community: props.record.snmp_community || '',
|
||||
snmp_timeout_ms: props.record.snmp_timeout_ms || 3000,
|
||||
snmp_retries: props.record.snmp_retries ?? 1,
|
||||
snmp_oids: props.record.snmp_oids || '',
|
||||
collect_on: props.record.collect_on ?? true,
|
||||
collect_args: props.record.collect_args || '',
|
||||
collect_interval: props.record.collect_interval || 60,
|
||||
@@ -166,6 +212,13 @@ watch(
|
||||
extra: '',
|
||||
tags: '',
|
||||
agent_config: '',
|
||||
collect_method: 'api',
|
||||
snmp_target: '',
|
||||
snmp_port: 161,
|
||||
snmp_community: '',
|
||||
snmp_timeout_ms: 3000,
|
||||
snmp_retries: 1,
|
||||
snmp_oids: '',
|
||||
collect_on: true,
|
||||
collect_args: '',
|
||||
collect_interval: 60,
|
||||
@@ -178,6 +231,24 @@ watch(
|
||||
const handleOk = async () => {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
if (formData.collect_method === 'api' && !formData.agent_config?.trim()) {
|
||||
Message.warning('API 模式下请填写 Agent 配置 URL')
|
||||
return
|
||||
}
|
||||
if (formData.collect_method === 'snmp') {
|
||||
if (!formData.snmp_target?.trim() || !formData.snmp_community?.trim()) {
|
||||
Message.warning('SNMP 模式下请填写目标地址和 community')
|
||||
return
|
||||
}
|
||||
if (formData.snmp_oids?.trim()) {
|
||||
try {
|
||||
JSON.parse(formData.snmp_oids)
|
||||
} catch {
|
||||
Message.warning('SNMP OID 配置必须是合法 JSON')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
confirmLoading.value = true
|
||||
|
||||
@@ -192,6 +263,13 @@ const handleOk = async () => {
|
||||
extra: formData.extra,
|
||||
tags: formData.tags,
|
||||
agent_config: formData.agent_config,
|
||||
collect_method: formData.collect_method,
|
||||
snmp_target: formData.snmp_target,
|
||||
snmp_port: formData.snmp_port,
|
||||
snmp_community: formData.snmp_community,
|
||||
snmp_timeout_ms: formData.snmp_timeout_ms,
|
||||
snmp_retries: formData.snmp_retries,
|
||||
snmp_oids: formData.snmp_oids,
|
||||
collect_on: formData.collect_on,
|
||||
collect_args: formData.collect_args,
|
||||
collect_interval: formData.collect_interval,
|
||||
|
||||
@@ -31,6 +31,12 @@ export const columns = [
|
||||
width: 100,
|
||||
slotName: 'enabled',
|
||||
},
|
||||
{
|
||||
dataIndex: 'collect_method',
|
||||
title: '采集方式',
|
||||
width: 100,
|
||||
slotName: 'collect_method',
|
||||
},
|
||||
{
|
||||
dataIndex: 'collect_on',
|
||||
title: '数据采集',
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
{{ record.collect_on ? '已启用' : '未启用' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template #collect_method="{ record }">
|
||||
<a-tag :color="record.collect_method === 'snmp' ? 'purple' : 'arcoblue'">
|
||||
{{ record.collect_method === 'snmp' ? 'SNMP' : 'API' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template #status="{ record }">
|
||||
<a-tag :color="getStatusColor(record.status)">
|
||||
|
||||
@@ -97,9 +97,10 @@ const getStatusText = (status?: string) => {
|
||||
return textMap[status || ''] || '-'
|
||||
}
|
||||
|
||||
const formatTime = (time?: string) => {
|
||||
if (!time) return '-'
|
||||
const formatTime = (time?: string | null) => {
|
||||
if (!time || time.startsWith('0001-01-01')) return '-'
|
||||
const date = new Date(time)
|
||||
if (Number.isNaN(date.getTime()) || date.getFullYear() <= 1) return '-'
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
|
||||
@@ -156,9 +156,10 @@ const getStatusText = (status?: string) => {
|
||||
return textMap[status || ''] || '-'
|
||||
}
|
||||
|
||||
const formatTime = (time?: string) => {
|
||||
if (!time) return '-'
|
||||
const formatTime = (time?: string | null) => {
|
||||
if (!time || time.startsWith('0001-01-01')) return '-'
|
||||
const date = new Date(time)
|
||||
if (Number.isNaN(date.getTime()) || date.getFullYear() <= 1) return '-'
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
|
||||
Reference in New Issue
Block a user