This commit is contained in:
2026-04-16 22:18:26 +08:00
parent 01139f2874
commit ba933457d4
5 changed files with 129 additions and 46 deletions

View File

@@ -35,6 +35,24 @@ export interface RoomListParams {
status?: string status?: string
} }
/** 机房下拉选项参数 */
export interface RoomOptionsParams {
datacenter_id?: number
floor_id?: number
keyword?: string
}
/** 机房下拉选项项 */
export interface RoomOptionItem {
id: number
name: string
code: string
datacenter_id: number
floor_id: number
enabled: boolean
sort: number
}
/** 机房创建数据 */ /** 机房创建数据 */
export interface RoomCreateData { export interface RoomCreateData {
name: string name: string
@@ -66,6 +84,11 @@ export const fetchRoomDetail = (id: number) => {
return request.get<RoomItem>(`/Assets/v1/room/detail/${id}`) return request.get<RoomItem>(`/Assets/v1/room/detail/${id}`)
} }
/** 获取机房列表(下拉,不分页) */
export const fetchRoomOptions = (params?: RoomOptionsParams) => {
return request.get<RoomOptionItem[]>('/Assets/v1/room/all', { params })
}
/** 根据楼层获取机房列表(下拉,不分页) */ /** 根据楼层获取机房列表(下拉,不分页) */
export const fetchRoomListByFloor = (floorId: number, params?: { name?: string }) => { export const fetchRoomListByFloor = (floorId: number, params?: { name?: string }) => {
return request.get<RoomItem[]>(`/Assets/v1/room/floor/${floorId}`, { params }) return request.get<RoomItem[]>(`/Assets/v1/room/floor/${floorId}`, { params })

View File

@@ -16,8 +16,12 @@
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item field="room_id" label="机房ID"> <a-form-item field="room_id" label="机房">
<a-input v-model="formData.room_id" placeholder="请输入机房ID" /> <a-select v-model="formData.room_id" placeholder="请选择机房" allow-search allow-clear>
<a-option v-for="item in roomOptions" :key="item.id" :value="item.id" :label="item.name">
{{ item.name }} ({{ item.code }})
</a-option>
</a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
@@ -134,6 +138,7 @@ import {
type RoomDeviceUpdateData, type RoomDeviceUpdateData,
} from '@/api/ops/room-device' } from '@/api/ops/room-device'
import { fetchPolicyOptions, type PolicyOptionItem } from '@/api/ops/alertPolicy' import { fetchPolicyOptions, type PolicyOptionItem } from '@/api/ops/alertPolicy'
import { fetchRoomOptions, type RoomOptionItem } from '@/api/ops/room'
interface Props { interface Props {
visible: boolean visible: boolean
@@ -149,13 +154,14 @@ const emit = defineEmits(['update:visible', 'success'])
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const confirmLoading = ref(false) const confirmLoading = ref(false)
const policyOptions = ref<PolicyOptionItem[]>([]) const policyOptions = ref<PolicyOptionItem[]>([])
const roomOptions = ref<RoomOptionItem[]>([])
const isEdit = computed(() => !!props.record?.id) const isEdit = computed(() => !!props.record?.id)
const formData = reactive({ const formData = reactive({
name: '', name: '',
description: '', description: '',
room_id: '', room_id: undefined as number | undefined,
device_category: '', device_category: '',
agent_config: '', agent_config: '',
collect_method: 'api' as 'api' | 'snmp', collect_method: 'api' as 'api' | 'snmp',
@@ -173,7 +179,7 @@ const formData = reactive({
const rules = { const rules = {
name: [{ required: true, message: '请输入服务名称' }], name: [{ required: true, message: '请输入服务名称' }],
room_id: [{ required: true, message: '请输入机房ID' }], room_id: [{ required: true, message: '请选择机房' }],
device_category: [{ required: true, message: '请选择设备分类' }], device_category: [{ required: true, message: '请选择设备分类' }],
} }
@@ -193,6 +199,22 @@ const loadPolicyOptions = async () => {
} }
} }
const loadRoomOptions = async () => {
try {
const response: any = await fetchRoomOptions({ enabled: true })
if (Array.isArray(response)) {
roomOptions.value = response
} else if (response && response.details) {
roomOptions.value = Array.isArray(response.details) ? response.details : response.details.data || []
} else {
roomOptions.value = []
}
} catch (error) {
console.error('加载机房列表失败:', error)
roomOptions.value = []
}
}
watch( watch(
() => props.visible, () => props.visible,
(val) => { (val) => {
@@ -201,7 +223,7 @@ watch(
Object.assign(formData, { Object.assign(formData, {
name: props.record.name || '', name: props.record.name || '',
description: props.record.description || '', description: props.record.description || '',
room_id: props.record.room_id || '', room_id: props.record.room_id ?? undefined,
device_category: props.record.device_category || '', device_category: props.record.device_category || '',
agent_config: props.record.agent_config || '', agent_config: props.record.agent_config || '',
collect_method: props.record.collect_method || 'api', collect_method: props.record.collect_method || 'api',
@@ -220,7 +242,7 @@ watch(
Object.assign(formData, { Object.assign(formData, {
name: '', name: '',
description: '', description: '',
room_id: '', room_id: undefined,
device_category: '', device_category: '',
agent_config: '', agent_config: '',
collect_method: 'api', collect_method: 'api',
@@ -283,8 +305,12 @@ const handleOk = async () => {
collect_interval: formData.collect_interval, collect_interval: formData.collect_interval,
policy_ids: formData.policy_ids, policy_ids: formData.policy_ids,
} }
await updateRoomDevice(props.record.id, updateData) const res: any = await updateRoomDevice(props.record.id, updateData)
if (res.code === 0) {
Message.success('更新成功') Message.success('更新成功')
} else {
Message.error(res.message || '更新失败')
}
} else { } else {
const createData: RoomDeviceCreateData = { const createData: RoomDeviceCreateData = {
name: formData.name, name: formData.name,
@@ -304,8 +330,12 @@ const handleOk = async () => {
collect_interval: formData.collect_interval, collect_interval: formData.collect_interval,
policy_ids: formData.policy_ids, policy_ids: formData.policy_ids,
} }
await createRoomDevice(createData) const res: any = await createRoomDevice(createData)
if (res.code === 0) {
Message.success('创建成功') Message.success('创建成功')
} else {
Message.error(res.message || '创建失败')
}
} }
emit('success') emit('success')
@@ -329,5 +359,6 @@ const handleCancel = () => {
onMounted(() => { onMounted(() => {
loadPolicyOptions() loadPolicyOptions()
loadRoomOptions()
}) })
</script> </script>

View File

@@ -347,11 +347,20 @@ const handleOk = async () => {
} }
if (isEdit.value) { if (isEdit.value) {
await updateSecurityService(props.record.id, submitData) const res = await updateSecurityService(props.record.id, submitData)
if (res.code === 0) {
Message.success('更新成功') Message.success('更新成功')
} else { } else {
await createSecurityService(submitData) Message.success(res.message || '更新失败')
}
} else {
const res = await createSecurityService(submitData)
if (res.code === 0) {
Message.success('创建成功') Message.success('创建成功')
} else {
Message.success(res.message || '创建失败')
}
} }
emit('success') emit('success')

View File

@@ -67,41 +67,61 @@
</a-col> </a-col>
</a-row> </a-row>
<a-form-item field="agent_config" label="Agent配置URL"> <a-divider orientation="left">采集配置</a-divider>
<a-radio-group v-model="formData.collect_method" type="button" style="margin-bottom: 12px">
<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="api">API</a-radio>
<a-radio value="snmp">SNMP</a-radio> <a-radio value="snmp">SNMP</a-radio>
</a-radio-group> </a-radio-group>
</a-form-item>
<template v-if="formData.collect_method === 'api'"> <template v-if="formData.collect_method === 'api'">
<a-form-item field="agent_config" label="Agent配置URL">
<a-input v-model="formData.agent_config" placeholder="请输入Agent配置地址" /> <a-input v-model="formData.agent_config" placeholder="请输入Agent配置地址" />
</a-form-item>
</template> </template>
<template v-else> <template v-else>
<a-row :gutter="12"> <a-row :gutter="20">
<a-col :span="12"> <a-col :span="12">
<a-input v-model="formData.snmp_target" placeholder="SNMP目标地址" /> <a-form-item field="snmp_target" label="SNMP目标地址">
<a-input v-model="formData.snmp_target" placeholder="请输入SNMP目标地址" />
</a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-input-number v-model="formData.snmp_port" :min="1" :max="65535" placeholder="SNMP端口" style="width: 100%" /> <a-form-item field="snmp_port" label="SNMP端口">
<a-input-number v-model="formData.snmp_port" :min="1" :max="65535" placeholder="默认161" style="width: 100%" />
</a-form-item>
</a-col> </a-col>
</a-row>
<a-row :gutter="20">
<a-col :span="12"> <a-col :span="12">
<a-input v-model="formData.snmp_community" placeholder="SNMP community" /> <a-form-item field="snmp_community" label="SNMP Community">
<a-input v-model="formData.snmp_community" placeholder="请输入SNMP community" />
</a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-input-number v-model="formData.snmp_timeout_ms" :min="1" :max="60000" placeholder="超时(ms)" style="width: 100%" /> <a-form-item field="snmp_timeout_ms" label="超时(毫秒)">
<a-input-number v-model="formData.snmp_timeout_ms" :min="1" :max="60000" placeholder="默认3000" style="width: 100%" />
</a-form-item>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-input-number v-model="formData.snmp_retries" :min="0" :max="10" placeholder="重试次数" style="width: 100%" /> <a-form-item field="snmp_retries" label="重试次数">
<a-input-number v-model="formData.snmp_retries" :min="0" :max="10" placeholder="默认1" style="width: 100%" />
</a-form-item>
</a-col> </a-col>
<a-col :span="24"> </a-row>
<a-form-item field="snmp_oids" label="SNMP OID配置">
<a-textarea <a-textarea
v-model="formData.snmp_oids" v-model="formData.snmp_oids"
:rows="3" :rows="3"
placeholder='可留空用默认模板,或填写 JSON 数组如 [{"oid":"1.3.6.1.2.1.1.3.0","metric_name":"sys_uptime"}]' 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>
</template>
<a-form-item field="collect_args" label="采集参数"> <a-form-item field="collect_args" label="采集参数">
<a-textarea v-model="formData.collect_args" placeholder="请输入采集参数(JSON格式)" :rows="3" /> <a-textarea v-model="formData.collect_args" placeholder="请输入采集参数(JSON格式)" :rows="3" />

File diff suppressed because one or more lines are too long