fix: 初验针对修改
This commit is contained in:
@@ -22,6 +22,8 @@ export interface MessageRecord {
|
||||
firstOccurredAt?: string
|
||||
lastOccurredAt?: string
|
||||
lastDeliveryId?: number
|
||||
severity?: string
|
||||
soundEnabled?: boolean
|
||||
}
|
||||
export type MessageListType = MessageRecord[]
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
/** 批次列表 */
|
||||
export const fetchLoanBatch = (data: { page: number; size: number }) => request.post('/factor/v1/fetch/loan_batch', data)
|
||||
|
||||
/** 上报列表 */
|
||||
export const fetchTransferWatch = (data: { page: number; size: number }) => request.post('/factor/v1/fetch/transfer_watch', data)
|
||||
|
||||
/** 回盘列表 */
|
||||
export const fetchTransferDown = (data: { page: number; size: number }) => request.post('/factor/v1/fetch/transfer_down', data)
|
||||
|
||||
/** 放款数据列表 */
|
||||
export const fetchDataFile = (data: { page: number; size: number }) => request.post('/factor/v1/fetch/data_file', data)
|
||||
|
||||
/** 回盘数据列表 */
|
||||
export const fetchDataReply = (data: { page: number; size: number }) => request.post('/factor/v1/fetch/data_reply', data)
|
||||
|
||||
/** 贷款支付数据列表 */
|
||||
export const fetchLoanPayment = (data: { page: number; size: number; status?: number }) =>
|
||||
request.post('/factor/v1/fetch/loan_payment', data)
|
||||
|
||||
/** 获取日报数据 */
|
||||
export const fetchOverviewReports = (data: { page: number; size: number }) => request.post('/factor/v1/reports/overview', data)
|
||||
|
||||
/** 获取日报数据 */
|
||||
export const fetchDailyReports = (data: { page: number; size: number }) => request.post('/factor/v1/reports/days', data)
|
||||
|
||||
/** 获取周报数据 */
|
||||
export const fetchWeeklyReports = (data: { page: number; size: number }) => request.post('/factor/v1/reports/weeks', data)
|
||||
|
||||
/** 获取月报数据 */
|
||||
export const fetchMonthlyReports = (data: { page: number; size: number }) => request.post('/factor/v1/reports/months', data)
|
||||
|
||||
/** 获取批次详情 */
|
||||
export const getLoanBatchDetail = (data: { batch_id: number }) => request.post(`/factor/v1/get/batch`, data)
|
||||
@@ -34,11 +34,3 @@ export const modifyMenu = (data: MenuItem) => request.post('/rbac2/v1/pmn/modify
|
||||
export const deleteMenu = (data: { id: MenuItem['id'] }) => request.post('/rbac2/v1/pmn/del', data, { needWorkspace: true })
|
||||
/** 更新菜单排序 */
|
||||
export const updateMenuOrder = (data: { pmn_id: number; sort_key: number }[]) => request.post('/rbac2/v1/pmn/sort', data)
|
||||
|
||||
/** 用户-给指定用户设置权限 */
|
||||
export const userPmn = (data: { code: string; list: { id: number; pmn_id: number }[] }) =>
|
||||
request.post('/rbac2/v1/pmn/user_pmn', data, { needWorkspace: true })
|
||||
|
||||
/** 用户-给指定用户设置权限 */
|
||||
export const userSetPmn = (data: { list: { id: number; pmn_id: number }[] }) =>
|
||||
request.post('/rbac2/v1/pmn/user/set_pmn', data, { needWorkspace: true })
|
||||
|
||||
@@ -4,7 +4,9 @@ import { LoginRequest, UserItem } from '../types'
|
||||
/** 登录 */
|
||||
export const login = (data: LoginRequest) => request.post('/rbac2/v1/login', data)
|
||||
/** 登出 */
|
||||
export const logout = () => request.post('/rbac2/v1/logout')
|
||||
export const logout = () => request.post('/rbac2/v1/user/logout')
|
||||
/** 更新在线状态 */
|
||||
export const heartbeat = () => request.post('/rbac2/v1/user/heartbeat')
|
||||
/** 获取菜单列表 */
|
||||
export const getMenuList = () => request.post('/rbac2/v1/user/menu')
|
||||
/** 创建用户 */
|
||||
@@ -17,19 +19,14 @@ export const fetchUserList = (data: { page: number; size: number; keyword?: stri
|
||||
export const modifyUser = (data: UserItem) => request.post('/rbac2/v1/user/modify', data)
|
||||
/** 删除用户 */
|
||||
export const deleteUser = (data: { id: UserItem['id'] }) => request.post('/rbac2/v1/user/del', data)
|
||||
/** 获取所有权限【树形】 */
|
||||
export const getUserPmnTree = (data: { id: UserItem['id']; workspace: string }) => request.post('/rbac2/v1/user/pmn_tree', data)
|
||||
|
||||
/** 用户-获取所有权限【平面】 */
|
||||
/** 获取用户通过角色获得的权限 */
|
||||
export const userPmn = (data: { id: UserItem['id']; workspace: string }) =>
|
||||
request.post('/rbac2/v1/user/pmn', data, { needWorkspace: true })
|
||||
/** 用户-给指定用户设置权限 */
|
||||
export const userSetPmn = (data: { list: { id: number; pmn_id: number }[] }) =>
|
||||
request.post('/rbac2/v1/user/set_pmn', data, { needWorkspace: true })
|
||||
|
||||
/** 用户-给指定用户编辑权限 */
|
||||
export const userModifyPmn = (data: { id: UserItem['id']; list: number[] }) =>
|
||||
request.post('/rbac2/v1/user/modify_pmn', data, { needWorkspace: true })
|
||||
/** 在线用户 */
|
||||
export const fetchOnlineUsers = (data: { page: number; size: number; keyword?: string }) => request.post('/rbac2/v1/user/online', data)
|
||||
/** 登录日志 */
|
||||
export const fetchLoginLogs = (data: { page: number; size: number; keyword?: string; result?: string }) =>
|
||||
request.post('/rbac2/v1/user/login-logs', data)
|
||||
|
||||
/** 重置密码(短信) */
|
||||
export const resetUserPassword = (data: {
|
||||
|
||||
@@ -143,5 +143,38 @@ export interface PolicyOptionsParams {
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export type ServicePolicyCategory = 'database' | 'middleware' | 'host' | 'security' | 'storage' | 'room_device'
|
||||
|
||||
export interface ServicePolicyBindingDetails {
|
||||
category: ServicePolicyCategory
|
||||
service_identity: string
|
||||
source_version: number
|
||||
policy_ids: number[]
|
||||
}
|
||||
|
||||
export interface AlertBindingSyncStatus {
|
||||
category: ServicePolicyCategory
|
||||
service_identity: string
|
||||
source_version?: number
|
||||
status: 'none' | 'pending' | 'processing' | 'succeeded' | 'failed'
|
||||
attempt_count?: number
|
||||
last_error?: string
|
||||
last_http_code?: number
|
||||
last_attempt_at?: string
|
||||
next_attempt_at?: string
|
||||
}
|
||||
|
||||
/** 获取告警策略下拉选项(不分页),支持 keyword 模糊搜索与 enabled 过滤 */
|
||||
export const fetchPolicyOptions = (params?: PolicyOptionsParams) => request.get<PolicyOptionItem[]>('/Alert/v1/policy/options', { params })
|
||||
|
||||
/** 获取资源当前绑定的告警策略 */
|
||||
export const fetchServicePolicyBindings = (category: ServicePolicyCategory, serviceIdentity: string) =>
|
||||
request.get<{ code: number; details?: ServicePolicyBindingDetails; message?: string }>('/Alert/v1/service-policy-bindings', {
|
||||
params: { category, service_identity: serviceIdentity },
|
||||
})
|
||||
|
||||
/** 获取告警策略绑定同步状态 */
|
||||
export const fetchAlertBindingSyncStatus = (category: ServicePolicyCategory, serviceIdentity: string) =>
|
||||
request.get<{ code: number; details?: AlertBindingSyncStatus; message?: string }>('/DC-Control/v1/alert-binding-sync/status', {
|
||||
params: { category, service_identity: serviceIdentity },
|
||||
})
|
||||
|
||||
@@ -17,6 +17,8 @@ export const fetchAlertRecords = (data: {
|
||||
resource_category?: string
|
||||
server_identity?: string
|
||||
ip?: string
|
||||
resource_uid?: string
|
||||
mine?: boolean
|
||||
}) => {
|
||||
return request.get('/Alert/v1/record/list', { params: data })
|
||||
}
|
||||
@@ -24,13 +26,21 @@ export const fetchAlertRecords = (data: {
|
||||
/** 获取 告警记录详情 */
|
||||
export const fetchAlertRecordDetail = (id: number) => request.get(`/Alert/v1/record/get/${id}`)
|
||||
|
||||
/** 按统一资源批量获取未恢复告警,供拓扑等视图复用。 */
|
||||
export const fetchActiveAlertsByResources = (resourceUids: string[], limitPerResource = 5) =>
|
||||
request.post('/Alert/v1/record/active/by-resources', {
|
||||
resource_uids: resourceUids,
|
||||
limit_per_resource: limitPerResource,
|
||||
})
|
||||
|
||||
/** 创建处理记录(执行确认/解决/屏蔽等操作) */
|
||||
export const createAlertProcess = (data: {
|
||||
alert_record_id: number
|
||||
action: string // ack / resolve / silence / comment / assign / escalate / close
|
||||
comment?: string
|
||||
assign_to?: string
|
||||
assign_to_id?: string
|
||||
assign_to_id?: number
|
||||
assign_role_id?: number
|
||||
silence_until?: string
|
||||
silence_reason?: string
|
||||
escalate_level?: string
|
||||
@@ -41,6 +51,9 @@ export const createAlertProcess = (data: {
|
||||
metadata?: string
|
||||
}) => request.post('/Alert/v1/process/create', data)
|
||||
|
||||
/** 获取“级别—状态—监控对象”告警分类计数。 */
|
||||
export const fetchAlertTree = (mine = false) => request.get('/Alert/v1/record/tree', { params: { mine } })
|
||||
|
||||
/** 获取 告警处理记录列表 */
|
||||
export const fetchAlertProcessList = (data: {
|
||||
alert_record_id?: number
|
||||
|
||||
74
src/api/ops/alertRouting.ts
Normal file
74
src/api/ops/alertRouting.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
export interface MessageContentTemplate {
|
||||
id?: number
|
||||
code: string
|
||||
name: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
subject_template: string
|
||||
body_template: string
|
||||
recovery_subject_template: string
|
||||
recovery_body_template: string
|
||||
}
|
||||
|
||||
export interface NotificationGroup {
|
||||
id?: number
|
||||
code: string
|
||||
name: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
member_user_ids: number[] | string
|
||||
}
|
||||
|
||||
export interface RoutingScope {
|
||||
priority: number
|
||||
resource_category?: string
|
||||
business_system_id?: number
|
||||
ip_cidr?: string
|
||||
device_level?: string
|
||||
label_matchers?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface ResponsibilityRule extends RoutingScope {
|
||||
id?: number
|
||||
code: string
|
||||
name: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
owner_user_id: number
|
||||
subscriber_group_ids: number[] | string
|
||||
cc_user_ids: number[] | string
|
||||
}
|
||||
|
||||
export interface NotificationPolicy extends RoutingScope {
|
||||
id?: number
|
||||
name: string
|
||||
enabled: boolean
|
||||
severity_filter: string[] | string
|
||||
channel_ids: number[] | string
|
||||
notification_group_ids: number[] | string
|
||||
cc_user_ids: number[] | string
|
||||
}
|
||||
|
||||
type ListParams = { page?: number; page_size?: number; keyword?: string; enabled?: boolean | string }
|
||||
|
||||
export const fetchMessageTemplateList = (params?: ListParams) => request.get('/Alert/v1/message-template/list', { params: params || {} })
|
||||
export const createMessageTemplate = (data: MessageContentTemplate) => request.post('/Alert/v1/message-template/create', data)
|
||||
export const updateMessageTemplate = (data: MessageContentTemplate) => request.post('/Alert/v1/message-template/update', data)
|
||||
export const deleteMessageTemplate = (id: number) => request.delete(`/Alert/v1/message-template/delete/${id}`)
|
||||
|
||||
export const fetchNotificationGroupList = (params?: ListParams) => request.get('/Alert/v1/notification-group/list', { params: params || {} })
|
||||
export const createNotificationGroup = (data: NotificationGroup) => request.post('/Alert/v1/notification-group/create', data)
|
||||
export const updateNotificationGroup = (data: NotificationGroup) => request.post('/Alert/v1/notification-group/update', data)
|
||||
export const deleteNotificationGroup = (id: number) => request.delete(`/Alert/v1/notification-group/delete/${id}`)
|
||||
|
||||
export const fetchResponsibilityList = (params?: ListParams) => request.get('/Alert/v1/responsibility/list', { params: params || {} })
|
||||
export const createResponsibility = (data: ResponsibilityRule) => request.post('/Alert/v1/responsibility/create', data)
|
||||
export const updateResponsibility = (data: ResponsibilityRule) => request.post('/Alert/v1/responsibility/update', data)
|
||||
export const deleteResponsibility = (id: number) => request.delete(`/Alert/v1/responsibility/delete/${id}`)
|
||||
|
||||
export const fetchNotificationPolicyList = (params?: ListParams) => request.get('/Alert/v1/notification-policy/list', { params: params || {} })
|
||||
export const createNotificationPolicy = (data: NotificationPolicy) => request.post('/Alert/v1/notification-policy/create', data)
|
||||
export const updateNotificationPolicy = (data: NotificationPolicy) => request.post('/Alert/v1/notification-policy/update', data)
|
||||
export const deleteNotificationPolicy = (id: number) => request.delete(`/Alert/v1/notification-policy/delete/${id}`)
|
||||
@@ -44,17 +44,33 @@ export interface AssetListParams {
|
||||
status?: string
|
||||
sort?: string
|
||||
order?: string
|
||||
category_code?: string
|
||||
manufacturer_code?: string
|
||||
datacenter_id?: number
|
||||
province_id?: number
|
||||
city_id?: number
|
||||
room_id?: number
|
||||
rack_id?: number
|
||||
department_id?: number
|
||||
department?: string
|
||||
business_system_id?: number
|
||||
device_level?: string
|
||||
projection_status?: string
|
||||
}
|
||||
|
||||
/** 资产表单数据 */
|
||||
export interface AssetForm {
|
||||
id?: number
|
||||
resource_uid?: string
|
||||
asset_name: string
|
||||
asset_code: string
|
||||
category_id?: number
|
||||
model?: string
|
||||
manufacturer?: string
|
||||
manufacturer_id?: number
|
||||
manufacturer_code?: string
|
||||
serial_number?: string
|
||||
management_ip?: string
|
||||
device_level?: 'core' | 'important' | 'normal'
|
||||
source_address?: string
|
||||
purchase_date?: string
|
||||
original_value?: number
|
||||
@@ -62,6 +78,8 @@ export interface AssetForm {
|
||||
warranty_period?: number
|
||||
warranty_expiry?: string
|
||||
department?: string
|
||||
department_id?: number
|
||||
business_system_id?: number
|
||||
user?: string
|
||||
status?: string
|
||||
location?: string
|
||||
@@ -74,48 +92,49 @@ export interface AssetForm {
|
||||
specifications?: string
|
||||
description?: string
|
||||
remarks?: string
|
||||
attachments?: string
|
||||
}
|
||||
|
||||
/** 获取资产列表(分页) */
|
||||
export const fetchAssetList = (data?: AssetListParams) => {
|
||||
return request.post('/Assets/v1/asset/list', data || {})
|
||||
return request.get('/Assets/v1/devices', { params: data || {} })
|
||||
}
|
||||
|
||||
/** 获取资产列表(不分页,下拉) */
|
||||
export const fetchAssetAll = (params?: { keyword?: string }) => {
|
||||
return request.get('/Assets/v1/asset/all', { params })
|
||||
return request.get('/Assets/v1/devices/options', { params })
|
||||
}
|
||||
|
||||
/** 获取资产详情 */
|
||||
export const fetchAssetDetail = (id: number) => {
|
||||
return request.get(`/Assets/v1/asset/detail/${id}`)
|
||||
export const fetchAssetDetail = (resourceUid: string) => {
|
||||
return request.get(`/Assets/v1/devices/${encodeURIComponent(resourceUid)}`)
|
||||
}
|
||||
|
||||
/** 创建资产 */
|
||||
export const createAsset = (data: AssetForm) => {
|
||||
return request.post('/Assets/v1/asset/create', data)
|
||||
return request.post('/Assets/v1/devices', data)
|
||||
}
|
||||
|
||||
/** 批量导入资产 */
|
||||
export const bulkImportAssets = (data: { dry_run?: boolean; items: any[] }) => {
|
||||
return request.post('/Assets/v1/asset/bulk_import', data)
|
||||
return request.post('/Assets/v1/devices/bulk-import', data)
|
||||
}
|
||||
|
||||
/** 更新资产 */
|
||||
export const updateAsset = (data: AssetForm) => {
|
||||
return request.put('/Assets/v1/asset/update', data)
|
||||
export const updateAsset = (resourceUid: string, data: AssetForm) => {
|
||||
return request.put(`/Assets/v1/devices/${encodeURIComponent(resourceUid)}`, data)
|
||||
}
|
||||
|
||||
/** 删除资产 */
|
||||
export const deleteAsset = (id: number) => {
|
||||
return request.delete(`/Assets/v1/asset/delete/${id}`)
|
||||
export const deleteAsset = (resourceUid: string) => {
|
||||
return request.delete(`/Assets/v1/devices/${encodeURIComponent(resourceUid)}`)
|
||||
}
|
||||
|
||||
/** 导出资产 */
|
||||
export const exportAssets = (keyword?: string) => {
|
||||
const params: any = {}
|
||||
if (keyword) params.keyword = keyword
|
||||
return request.get('/Assets/v1/asset/export', { params })
|
||||
return request.get('/Assets/v1/devices/export', { params })
|
||||
}
|
||||
|
||||
/** 获取资产分类列表(下拉) */
|
||||
@@ -128,24 +147,7 @@ export const fetchSupplierOptions = () => {
|
||||
return request.get('/Assets/v1/supplier/all')
|
||||
}
|
||||
|
||||
/** 绑定资产和监控资源 */
|
||||
export const linkAssetResource = (data: {
|
||||
asset_id: number
|
||||
resource_uid: string
|
||||
display_name?: string
|
||||
business_system_id?: number
|
||||
health_status?: string
|
||||
alert_status?: string
|
||||
}) => {
|
||||
return request.post('/Assets/v1/asset/resource/link', data)
|
||||
}
|
||||
|
||||
/** 查询资产绑定的监控资源 */
|
||||
export const fetchAssetResourceBindings = (assetId: number) => {
|
||||
return request.get(`/Assets/v1/asset/resource/${assetId}`)
|
||||
}
|
||||
|
||||
/** 解除资产和监控资源绑定 */
|
||||
export const unlinkAssetResource = (assetId: number, resourceUid: string) => {
|
||||
return request.delete(`/Assets/v1/asset/resource/${assetId}`, { params: { resource_uid: resourceUid } })
|
||||
/** 获取生产厂商列表(下拉) */
|
||||
export const fetchManufacturerOptions = (keyword?: string) => {
|
||||
return request.get('/Assets/v1/manufacturers/options', { params: { keyword } })
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
export interface AutomationScript {
|
||||
id: number
|
||||
name: string
|
||||
resource_category: string
|
||||
command_template: string
|
||||
approval_level: string
|
||||
rollback_command?: string
|
||||
rollback_required: boolean
|
||||
description?: string
|
||||
status: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface AutomationExecution {
|
||||
id: number
|
||||
script_id: number
|
||||
mode: string
|
||||
status: string
|
||||
resource_uid: string
|
||||
rendered_command: string
|
||||
incident_id?: number
|
||||
ticket_id?: number
|
||||
approval_level: string
|
||||
approved_by?: string
|
||||
approved_at?: string
|
||||
operator?: string
|
||||
started_at?: string
|
||||
finished_at?: string
|
||||
timeout_sec?: number
|
||||
stdout?: string
|
||||
stderr?: string
|
||||
exit_code?: number
|
||||
error?: string
|
||||
audit_trail?: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface AutomationRunRequest {
|
||||
resource_uid: string
|
||||
incident_id?: number
|
||||
ticket_id?: number
|
||||
operator?: string
|
||||
approver?: string
|
||||
approved?: boolean
|
||||
mode?: 'execute' | 'rollback'
|
||||
variables?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface PageResponse<T> {
|
||||
total: number
|
||||
page: number
|
||||
page_size: number
|
||||
data: T[]
|
||||
}
|
||||
|
||||
export const fetchAutomationScripts = (params?: Record<string, any>) =>
|
||||
request.get<{ details: PageResponse<AutomationScript> }>('/DC-Control/v1/automation/scripts', { params })
|
||||
|
||||
export const createAutomationScript = (data: Partial<AutomationScript>) =>
|
||||
request.post<{ details: AutomationScript }>('/DC-Control/v1/automation/scripts', data)
|
||||
|
||||
export const updateAutomationScript = (id: number, data: Partial<AutomationScript>) =>
|
||||
request.put(`/DC-Control/v1/automation/scripts/${id}`, data)
|
||||
|
||||
export const deleteAutomationScript = (id: number) => request.delete(`/DC-Control/v1/automation/scripts/${id}`)
|
||||
|
||||
export const dryRunAutomationScript = (id: number, data: AutomationRunRequest) =>
|
||||
request.post<{ details: AutomationExecution }>(`/DC-Control/v1/automation/scripts/${id}/dry-run`, data)
|
||||
|
||||
export const requestAutomationExecution = (id: number, data: AutomationRunRequest) =>
|
||||
request.post<{ details: AutomationExecution }>(`/DC-Control/v1/automation/scripts/${id}/executions`, data)
|
||||
|
||||
export const executeAutomationScript = (id: number, data: AutomationRunRequest) =>
|
||||
request.post<{ details: AutomationExecution }>(`/DC-Control/v1/automation/scripts/${id}/execute`, data)
|
||||
|
||||
export const rollbackAutomationScript = (id: number, data: AutomationRunRequest) =>
|
||||
request.post<{ details: AutomationExecution }>(`/DC-Control/v1/automation/scripts/${id}/rollback`, data)
|
||||
|
||||
export const fetchAutomationExecutions = (params?: Record<string, any>) =>
|
||||
request.get<{ details: PageResponse<AutomationExecution> }>('/DC-Control/v1/automation/executions', { params })
|
||||
|
||||
export const approveAutomationExecution = (id: number, data: { approver: string; operator?: string }) =>
|
||||
request.post<{ details: AutomationExecution }>(`/DC-Control/v1/automation/executions/${id}/approve`, data)
|
||||
@@ -17,8 +17,12 @@ export interface BigScreen {
|
||||
width: number
|
||||
height: number
|
||||
status: number
|
||||
publish_status: 'draft' | 'published' | 'offline' | string
|
||||
is_public?: boolean
|
||||
publish_status: 'draft' | 'published' | string
|
||||
dataset_code: 'network_topology' | 'it_resource_monitor' | 'business_monitor' | string
|
||||
built_in_code?: string
|
||||
is_builtin: boolean
|
||||
carousel_enabled: boolean
|
||||
carousel_order: number
|
||||
creator_name?: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
@@ -45,12 +49,15 @@ export interface BigScreenPublish {
|
||||
|
||||
export interface BigScreenCarousel {
|
||||
id: number
|
||||
name: string
|
||||
screen_ids: Record<string, any>
|
||||
interval_seconds: number
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export interface BigScreenDataset {
|
||||
code: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface BigScreenSnapshot {
|
||||
id: number
|
||||
screen_id: number
|
||||
@@ -79,7 +86,10 @@ export const createBigScreen = (data: Partial<BigScreen>) =>
|
||||
export const updateBigScreen = (id: number, data: Partial<BigScreen>) =>
|
||||
request.put<ApiResponse<BigScreen>>(`/Mgt/v1/screen/${id}`, data)
|
||||
|
||||
export const publishBigScreen = (data: { screen_id: number; publish_type: 1 | 2; change_log?: string }) =>
|
||||
export const beginEditBigScreen = (id: number) =>
|
||||
request.post<ApiResponse<BigScreen>>(`/Mgt/v1/screen/${id}/begin-edit`)
|
||||
|
||||
export const publishBigScreen = (data: { screen_id: number; publish_type: 1; change_log?: string }) =>
|
||||
request.post<ApiResponse<BigScreenPublish>>('/Mgt/v1/publish', data)
|
||||
|
||||
export const fetchBigScreenPublishes = (params: { screen_id: number; page?: number; page_size?: number }) =>
|
||||
@@ -91,11 +101,17 @@ export const fetchBigScreenGroups = () =>
|
||||
export const createBigScreenGroup = (data: Partial<BigScreenGroup>) =>
|
||||
request.post<ApiResponse<BigScreenGroup>>('/Mgt/v1/big-screen/groups', data)
|
||||
|
||||
export const fetchBigScreenCarousels = () =>
|
||||
request.get<ApiResponse<BigScreenCarousel[]>>('/Mgt/v1/big-screen/carousels')
|
||||
export const fetchBigScreenCarousel = () =>
|
||||
request.get<ApiResponse<BigScreenCarousel>>('/Mgt/v1/big-screen/carousel')
|
||||
|
||||
export const createBigScreenCarousel = (data: Partial<BigScreenCarousel>) =>
|
||||
request.post<ApiResponse<BigScreenCarousel>>('/Mgt/v1/big-screen/carousels', data)
|
||||
export const updateBigScreenCarousel = (data: Pick<BigScreenCarousel, 'interval_seconds' | 'enabled'>) =>
|
||||
request.put<ApiResponse<BigScreenCarousel>>('/Mgt/v1/big-screen/carousel', data)
|
||||
|
||||
export const updateBigScreenCarouselItem = (id: number, data: { enabled: boolean; order: number }) =>
|
||||
request.put<ApiResponse<BigScreen>>(`/Mgt/v1/big-screen/screens/${id}/carousel`, data)
|
||||
|
||||
export const fetchBigScreenDatasets = () =>
|
||||
request.get<ApiResponse<BigScreenDataset[]>>('/Mgt/v1/public/big-screens/datasets')
|
||||
|
||||
export const fetchBigScreenSnapshots = (params?: { screen_id?: number }) =>
|
||||
request.get<ApiResponse<BigScreenSnapshot[]>>('/Mgt/v1/big-screen/snapshots', { params })
|
||||
|
||||
@@ -171,6 +171,101 @@ export interface ListResult<T> {
|
||||
count: number
|
||||
}
|
||||
|
||||
/** HTTP/API 检测步骤请求头 */
|
||||
export interface BusinessHTTPHeader {
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
|
||||
/** HTTP/API 检测响应变量提取 */
|
||||
export interface BusinessHTTPExtract {
|
||||
variable: string
|
||||
source: 'json' | 'header' | 'cookie'
|
||||
expression: string
|
||||
}
|
||||
|
||||
/** HTTP/API 检测断言 */
|
||||
export interface BusinessHTTPAssertion {
|
||||
kind: 'status' | 'max_response_time_ms' | 'header_equals' | 'body_contains' | 'json_exists' | 'json_equals'
|
||||
expression?: string
|
||||
expected?: string
|
||||
}
|
||||
|
||||
/** HTTP/API 检测步骤 */
|
||||
export interface BusinessHTTPCheckStep {
|
||||
code: string
|
||||
name: string
|
||||
method: 'GET' | 'HEAD' | 'POST'
|
||||
path: string
|
||||
headers?: Record<string, string>
|
||||
body?: string
|
||||
read_only_confirmed?: boolean
|
||||
extracts?: BusinessHTTPExtract[]
|
||||
assertions?: BusinessHTTPAssertion[]
|
||||
}
|
||||
|
||||
export interface BusinessHTTPCheck {
|
||||
id: number
|
||||
business_system_id: number
|
||||
name: string
|
||||
base_url: string
|
||||
collector_node_id: number
|
||||
credential_id?: number
|
||||
enabled: boolean
|
||||
interval_seconds: number
|
||||
timeout_seconds: number
|
||||
version: number
|
||||
next_run_at?: string
|
||||
last_run_at?: string
|
||||
last_status: string
|
||||
last_duration_ms: number
|
||||
last_error?: string
|
||||
last_trace_id?: string
|
||||
steps: BusinessHTTPCheckStep[]
|
||||
collector_node?: { id: number; name: string; code: string; status: string }
|
||||
credential?: { id: number; name: string; code: string; type: string }
|
||||
}
|
||||
|
||||
export interface BusinessHTTPCheckInput {
|
||||
name: string
|
||||
base_url: string
|
||||
collector_node_id: number
|
||||
credential_id?: number
|
||||
enabled: boolean
|
||||
interval_seconds: number
|
||||
timeout_seconds: number
|
||||
steps: BusinessHTTPCheckStep[]
|
||||
}
|
||||
|
||||
export interface BusinessHTTPCheckStepResult {
|
||||
code: string
|
||||
name: string
|
||||
span_id: string
|
||||
success: boolean
|
||||
status_code: number
|
||||
duration_ms: number
|
||||
message: string
|
||||
method: string
|
||||
request_path: string
|
||||
}
|
||||
|
||||
export interface BusinessHTTPCheckRun {
|
||||
id: number
|
||||
http_check_id: number
|
||||
business_system_id: number
|
||||
collector_node_id: number
|
||||
task_id: string
|
||||
trigger_type: string
|
||||
status: string
|
||||
started_at?: string
|
||||
finished_at?: string
|
||||
duration_ms: number
|
||||
failed_step_code?: string
|
||||
message?: string
|
||||
step_results_json: string
|
||||
trace_id?: string
|
||||
}
|
||||
|
||||
/** 获取业务系统列表 */
|
||||
export const fetchBusinessSystems = (params?: BusinessSystemListParams) =>
|
||||
request.get<{ code?: number; details?: PageResult<BusinessSystemItem>; message?: string }>('/DC-Control/v1/business-systems', { params })
|
||||
@@ -235,3 +330,27 @@ export const fetchBusinessDocumentLinks = (id: number) =>
|
||||
/** 新增业务文档链接 */
|
||||
export const createBusinessDocumentLink = (id: number, data: Partial<BusinessDocumentLink>) =>
|
||||
request.post<{ code?: number; details?: BusinessDocumentLink; message?: string }>(`/DC-Control/v1/business-systems/${id}/documents`, data)
|
||||
|
||||
/** 获取业务系统 HTTP/API 检测 */
|
||||
export const fetchBusinessHTTPChecks = (id: number) =>
|
||||
request.get<{ code?: number; details?: ListResult<BusinessHTTPCheck>; message?: string }>(`/DC-Control/v1/business-systems/${id}/http-checks`)
|
||||
|
||||
export const createBusinessHTTPCheck = (id: number, data: BusinessHTTPCheckInput) =>
|
||||
request.post<{ code?: number; details?: BusinessHTTPCheck; message?: string }>(`/DC-Control/v1/business-systems/${id}/http-checks`, data)
|
||||
|
||||
export const updateBusinessHTTPCheck = (id: number, checkId: number, data: BusinessHTTPCheckInput) =>
|
||||
request.put<{ code?: number; details?: BusinessHTTPCheck; message?: string }>(`/DC-Control/v1/business-systems/${id}/http-checks/${checkId}`, data)
|
||||
|
||||
export const deleteBusinessHTTPCheck = (id: number, checkId: number) =>
|
||||
request.delete(`/DC-Control/v1/business-systems/${id}/http-checks/${checkId}`)
|
||||
|
||||
export const runBusinessHTTPCheck = (id: number, checkId: number) =>
|
||||
request.post<{ code?: number; details?: { task_id: string; status: string }; message?: string }>(
|
||||
`/DC-Control/v1/business-systems/${id}/http-checks/${checkId}/run`
|
||||
)
|
||||
|
||||
export const fetchBusinessHTTPCheckRuns = (id: number, checkId: number, limit = 50) =>
|
||||
request.get<{ code?: number; details?: ListResult<BusinessHTTPCheckRun>; message?: string }>(
|
||||
`/DC-Control/v1/business-systems/${id}/http-checks/${checkId}/runs`,
|
||||
{ params: { limit } }
|
||||
)
|
||||
|
||||
180
src/api/ops/collection.ts
Normal file
180
src/api/ops/collection.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
const PREFIX = '/DC-Control/v1/monitoring'
|
||||
|
||||
export interface PageResult<T> {
|
||||
total: number
|
||||
page: number
|
||||
page_size: number
|
||||
data: T[]
|
||||
}
|
||||
|
||||
export type CredentialType = 'snmp_v1' | 'snmp_v2c' | 'snmp_v3' | 'ssh' | 'database' | 'http_api' | 'redfish' | 'ipmi'
|
||||
|
||||
export interface CollectionCredential {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
type: CredentialType
|
||||
username?: string
|
||||
scope?: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
secret_configured: boolean
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface CredentialInput {
|
||||
code: string
|
||||
name: string
|
||||
type: CredentialType
|
||||
username?: string
|
||||
scope?: string
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
secret?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface CollectionTemplate {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
manufacturer_code: string
|
||||
resource_category: string
|
||||
protocol: string
|
||||
version: number
|
||||
model_matchers: string
|
||||
metric_mappings: string
|
||||
index_discoveries: string
|
||||
inventory_mappings: string
|
||||
read_only_queries: string
|
||||
alert_rule_codes: string
|
||||
content_digest: string
|
||||
description?: string
|
||||
adapter_verified: boolean
|
||||
verification_note?: string
|
||||
verified_at?: string
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export type CollectionTemplateInput = Omit<CollectionTemplate, 'id' | 'version' | 'content_digest' | 'verified_at'>
|
||||
|
||||
export interface CollectorNode {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
node_type: 'center' | 'regional'
|
||||
region_code?: string
|
||||
description?: string
|
||||
enabled: boolean
|
||||
status: string
|
||||
capabilities: string
|
||||
version?: string
|
||||
queue_depth: number
|
||||
last_heartbeat_at?: string
|
||||
last_error?: string
|
||||
enrollment_expires_at?: string
|
||||
}
|
||||
|
||||
export interface CollectorNodeInput {
|
||||
code: string
|
||||
name: string
|
||||
node_type: 'center' | 'regional'
|
||||
region_code?: string
|
||||
description?: string
|
||||
capabilities: string
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export interface CollectionBinding {
|
||||
id: number
|
||||
name: string
|
||||
resource_uid: string
|
||||
collector_node_id: number
|
||||
credential_id: number
|
||||
template_id: number
|
||||
template_version: number
|
||||
protocol: string
|
||||
target: string
|
||||
port: number
|
||||
interval_seconds: number
|
||||
retry_policy: string
|
||||
enabled: boolean
|
||||
state: string
|
||||
last_validation_error?: string
|
||||
collector_node?: CollectorNode
|
||||
credential?: CollectionCredential
|
||||
template?: CollectionTemplate
|
||||
}
|
||||
|
||||
export interface CollectionBindingInput {
|
||||
name: string
|
||||
resource_uid: string
|
||||
collector_node_id: number
|
||||
credential_id: number
|
||||
template_id: number
|
||||
protocol: string
|
||||
target: string
|
||||
port: number
|
||||
interval_seconds: number
|
||||
retry_policy?: string
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export interface HostAgentRegistration {
|
||||
id: number
|
||||
agent_id: string
|
||||
resource_uid: string
|
||||
claimed_resource_uid: string
|
||||
hostname: string
|
||||
version: string
|
||||
status: 'confirmed' | 'pending_confirmation'
|
||||
last_error: string
|
||||
last_seen_at: string
|
||||
}
|
||||
|
||||
export const fetchCredentials = (params?: Record<string, unknown>) =>
|
||||
request.get<{ code: number; details?: PageResult<CollectionCredential>; message?: string }>(`${PREFIX}/credentials`, { params })
|
||||
|
||||
export const createCredential = (data: CredentialInput) => request.post(`${PREFIX}/credentials`, data)
|
||||
export const updateCredential = (id: number, data: CredentialInput) => request.put(`${PREFIX}/credentials/${id}`, data)
|
||||
export const deleteCredential = (id: number) => request.delete(`${PREFIX}/credentials/${id}`)
|
||||
|
||||
export const fetchCollectionTemplates = (params?: Record<string, unknown>) =>
|
||||
request.get<{ code: number; details?: PageResult<CollectionTemplate>; message?: string }>(`${PREFIX}/templates`, { params })
|
||||
|
||||
export const createCollectionTemplate = (data: CollectionTemplateInput) => request.post(`${PREFIX}/templates`, data)
|
||||
export const updateCollectionTemplate = (id: number, data: CollectionTemplateInput) => request.put(`${PREFIX}/templates/${id}`, data)
|
||||
export const deleteCollectionTemplate = (id: number) => request.delete(`${PREFIX}/templates/${id}`)
|
||||
export const exportCollectionTemplate = (id: number) => request.get(`${PREFIX}/templates/${id}/export`)
|
||||
export const importCollectionTemplate = (data: Record<string, unknown>) => request.post(`${PREFIX}/templates/import`, data)
|
||||
|
||||
export const fetchCollectorNodes = (params?: Record<string, unknown>) =>
|
||||
request.get<{ code: number; details?: PageResult<CollectorNode>; message?: string }>(`${PREFIX}/collector-nodes`, { params })
|
||||
|
||||
export const createCollectorNode = (data: CollectorNodeInput) => request.post(`${PREFIX}/collector-nodes`, data)
|
||||
export const updateCollectorNode = (id: number, data: CollectorNodeInput) => request.put(`${PREFIX}/collector-nodes/${id}`, data)
|
||||
export const deleteCollectorNode = (id: number) => request.delete(`${PREFIX}/collector-nodes/${id}`)
|
||||
export const rotateCollectorNodeToken = (id: number) => request.post(`${PREFIX}/collector-nodes/${id}/installation-token`)
|
||||
|
||||
export const fetchHostAgentRegistrations = (params?: Record<string, unknown>) =>
|
||||
request.get<{ code: number; details?: PageResult<HostAgentRegistration>; message?: string }>(`${PREFIX}/host-agents`, { params })
|
||||
|
||||
export const confirmHostAgentRegistration = (id: number, resourceUid: string) =>
|
||||
request.post(`${PREFIX}/host-agents/${id}/confirm`, { resource_uid: resourceUid })
|
||||
|
||||
export const fetchCollectionBindings = (params?: Record<string, unknown>) =>
|
||||
request.get<{ code: number; details?: PageResult<CollectionBinding>; message?: string }>(`${PREFIX}/bindings`, { params })
|
||||
|
||||
export const createCollectionBinding = (data: CollectionBindingInput) => request.post(`${PREFIX}/bindings`, data)
|
||||
export const updateCollectionBinding = (id: number, data: CollectionBindingInput) => request.put(`${PREFIX}/bindings/${id}`, data)
|
||||
export const deleteCollectionBinding = (id: number) => request.delete(`${PREFIX}/bindings/${id}`)
|
||||
|
||||
export const fetchDiscoveryRuns = (params?: Record<string, string | number | boolean | undefined>) =>
|
||||
request.get(`${PREFIX}/discovery-runs`, { params })
|
||||
|
||||
export const collectResourceNow = (resourceUid: string) =>
|
||||
request.post<{ code: number; details?: { task_ids: string[]; count: number }; message?: string }>(
|
||||
`${PREFIX}/resources/${encodeURIComponent(resourceUid)}/collect-now`
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
/** 数据库类型枚举 */
|
||||
export type DatabaseType = 'MySQL' | 'PostgreSQL' | 'Redis' | 'MongoDB' | 'DM' | 'KingBase'
|
||||
export type DatabaseType = 'MySQL' | 'PostgreSQL' | 'Redis' | 'MongoDB' | 'DM' | 'KingBase' | 'Oracle' | 'OracleRAC'
|
||||
|
||||
/** 数据库服务状态 */
|
||||
export type DatabaseStatus = 'online' | 'offline' | 'error'
|
||||
@@ -13,19 +13,16 @@ export interface DatabaseService {
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
service_identity: string
|
||||
server_identity: string
|
||||
name: string
|
||||
category: string
|
||||
type: DatabaseType
|
||||
host: string
|
||||
port: number
|
||||
username: string
|
||||
password: string // 列表接口恒为空字符串,详情接口不返回
|
||||
database: string
|
||||
tls_mode: 'require' | 'verify-ca' | 'verify-full'
|
||||
description: string
|
||||
enabled: boolean
|
||||
interval: number
|
||||
extra: string
|
||||
tags: string
|
||||
status: DatabaseStatus
|
||||
status_code: number
|
||||
@@ -36,10 +33,9 @@ export interface DatabaseService {
|
||||
last_offline_time: string | null
|
||||
continuous_errors: number
|
||||
uptime: number
|
||||
collect_on: boolean
|
||||
collect_interval: number
|
||||
collect_args: string
|
||||
collect_last_result: string
|
||||
product_version: string
|
||||
adapter_status: 'verified' | 'unverified' | 'blocked'
|
||||
last_data_time: string | null
|
||||
}
|
||||
|
||||
/** 列表接口返回的分页数据 */
|
||||
@@ -52,48 +48,32 @@ export interface DatabaseListResponse {
|
||||
|
||||
/** 创建数据库服务请求参数 */
|
||||
export interface CreateDatabaseParams {
|
||||
service_identity?: string
|
||||
server_identity?: string
|
||||
name: string
|
||||
category: string
|
||||
type: DatabaseType
|
||||
host: string
|
||||
port: number
|
||||
username?: string
|
||||
password?: string
|
||||
database?: string
|
||||
tls_mode?: 'require' | 'verify-ca' | 'verify-full'
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
/** 更新数据库服务请求参数 */
|
||||
export interface UpdateDatabaseParams {
|
||||
service_identity?: string
|
||||
server_identity?: string
|
||||
name?: string
|
||||
category?: string
|
||||
type?: DatabaseType
|
||||
host?: string
|
||||
port?: number
|
||||
username?: string
|
||||
password?: string
|
||||
database?: string
|
||||
tls_mode?: 'require' | 'verify-ca' | 'verify-full'
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
/** 列表查询参数 */
|
||||
@@ -107,14 +87,13 @@ export interface DatabaseQueryParams {
|
||||
/** 指标采集请求参数 */
|
||||
export interface CollectMetricsParams {
|
||||
ids: number[]
|
||||
persist?: boolean
|
||||
}
|
||||
|
||||
/** 指标采集结果项 */
|
||||
export interface CollectMetricsResultItem {
|
||||
id: number
|
||||
service_identity: string
|
||||
metrics?: Record<string, any>
|
||||
task_ids?: string[]
|
||||
error?: string
|
||||
}
|
||||
|
||||
@@ -164,7 +143,7 @@ export const fetchDatabaseDetail = (id: number) => request.get<DatabaseService>(
|
||||
* 创建数据库服务
|
||||
* @param data 创建参数
|
||||
*/
|
||||
export const createDatabase = (data: CreateDatabaseParams) => request.post<{ message: string; id: number }>('/DC-Control/v1/database', data)
|
||||
export const createDatabase = (data: CreateDatabaseParams) => request.post<{ message: string; id: number; service_identity: string }>('/DC-Control/v1/database', data)
|
||||
|
||||
/**
|
||||
* 更新数据库服务
|
||||
|
||||
@@ -68,6 +68,10 @@ export interface ControlResource {
|
||||
display_name: string
|
||||
description?: string
|
||||
status: string
|
||||
asset_status?: string
|
||||
manufacturer_code?: string
|
||||
management_ip?: string
|
||||
device_level?: string
|
||||
business_system_id?: number
|
||||
owner_user_id?: number
|
||||
department_id?: number
|
||||
@@ -86,23 +90,33 @@ export interface ControlResource {
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface ControlResourcePayload {
|
||||
resource_category?: string
|
||||
service_identity?: string
|
||||
display_name?: string
|
||||
description?: string
|
||||
status?: string
|
||||
business_system_id?: number | null
|
||||
owner_user_id?: number | null
|
||||
department_id?: number | null
|
||||
asset_id?: number | null
|
||||
datacenter_id?: number | null
|
||||
room_id?: number | null
|
||||
rack_id?: number | null
|
||||
unit_start?: number | null
|
||||
unit_end?: number | null
|
||||
location_ref?: string | null
|
||||
tags?: string
|
||||
export interface ControlResourceRuntimeMetric {
|
||||
name: string
|
||||
value: number
|
||||
unit: string
|
||||
type: string
|
||||
timestamp: string
|
||||
}
|
||||
|
||||
export interface ControlResourceRuntime {
|
||||
resource_uid: string
|
||||
resource_category: string
|
||||
service_identity: string
|
||||
display_name: string
|
||||
status: string
|
||||
metrics_at?: string
|
||||
metrics: ControlResourceRuntimeMetric[]
|
||||
}
|
||||
|
||||
export interface ControlResourceOverview {
|
||||
master: ControlResource
|
||||
runtime: ControlResourceRuntime | null
|
||||
context: {
|
||||
resource_uid: string
|
||||
alert_query: { resource_uid: string }
|
||||
log_query: { resource_uid: string }
|
||||
topology_query: { resource_uid: string }
|
||||
}
|
||||
}
|
||||
|
||||
export interface ControlResourceType {
|
||||
@@ -169,6 +183,15 @@ export interface ControlCollectionStatus {
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface ControlCollectionSummary {
|
||||
enabled: number
|
||||
ok: number
|
||||
failed: number
|
||||
unknown: number
|
||||
overdue: number
|
||||
as_of: string
|
||||
}
|
||||
|
||||
export interface ResourceListParams {
|
||||
page?: number
|
||||
size?: number
|
||||
@@ -192,17 +215,10 @@ export const fetchControlResourceOptions = (params?: { resource_category?: strin
|
||||
params,
|
||||
})
|
||||
|
||||
export const createControlResource = (data: ControlResourcePayload) =>
|
||||
request.post<{ code?: number; details?: ControlResource; message?: string }>('/DC-Control/v1/resources', data)
|
||||
|
||||
export const updateControlResource = (id: number, data: ControlResourcePayload) =>
|
||||
request.put<{ code?: number; details?: ControlResource; message?: string }>(`/DC-Control/v1/resources/${id}`, data)
|
||||
|
||||
export const deleteControlResource = (id: number) =>
|
||||
request.delete<{ code?: number; details?: { message: string }; message?: string }>(`/DC-Control/v1/resources/${id}`)
|
||||
|
||||
export const backfillControlResources = () =>
|
||||
request.post<{ code?: number; details?: { message: string }; message?: string }>('/DC-Control/v1/resources/backfill')
|
||||
export const fetchControlResourceOverview = (resourceUid: string) =>
|
||||
request.get<{ code?: number; details?: ControlResourceOverview; message?: string }>(
|
||||
`/DC-Control/v1/resources/${encodeURIComponent(resourceUid)}/overview`
|
||||
)
|
||||
|
||||
export const fetchControlResourceTypes = (params?: { page?: number; size?: number; keyword?: string }) =>
|
||||
request.get<{ code?: number; details?: PageResult<ControlResourceType>; message?: string }>('/DC-Control/v1/resource-types', { params })
|
||||
@@ -245,3 +261,6 @@ export const fetchCollectionStatus = (params?: {
|
||||
request.get<{ code?: number; details?: PageResult<ControlCollectionStatus>; message?: string }>('/DC-Control/v1/collection/status', {
|
||||
params,
|
||||
})
|
||||
|
||||
export const fetchCollectionStatusSummary = () =>
|
||||
request.get<{ code?: number; details?: ControlCollectionSummary; message?: string }>('/DC-Control/v1/collection/status/summary')
|
||||
|
||||
74
src/api/ops/device-interface.ts
Normal file
74
src/api/ops/device-interface.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
export interface ImportantInterfaceConfig {
|
||||
id: number
|
||||
resource_uid: string
|
||||
interface_identity: string
|
||||
purpose: string
|
||||
expected_peer_resource_uid?: string
|
||||
expected_peer_interface_identity?: string
|
||||
enabled: boolean
|
||||
last_condition: 'unknown' | 'normal' | 'interface_down' | 'neighbor_missing'
|
||||
last_evaluated_at?: string
|
||||
last_transition_at?: string
|
||||
}
|
||||
|
||||
export interface UnifiedDeviceInterface {
|
||||
id: number
|
||||
resource_uid: string
|
||||
interface_identity: string
|
||||
name: string
|
||||
mac?: string
|
||||
admin_state: string
|
||||
oper_state: string
|
||||
speed_bps: number
|
||||
in_bytes: number
|
||||
out_bytes: number
|
||||
in_errors: number
|
||||
out_errors: number
|
||||
last_seen_at: string
|
||||
important?: ImportantInterfaceConfig
|
||||
}
|
||||
|
||||
export interface DeviceConfigVersion {
|
||||
id: number
|
||||
resource_uid: string
|
||||
task_id: string
|
||||
template_code: string
|
||||
template_version: number
|
||||
collected_at: string
|
||||
content_hash: string
|
||||
filename: string
|
||||
size: number
|
||||
previous_version_id?: number
|
||||
}
|
||||
|
||||
const resourcePath = (resourceUid: string) => `/DC-Control/v1/monitoring/resources/${encodeURIComponent(resourceUid)}`
|
||||
|
||||
export const fetchUnifiedDeviceInterfaces = (resourceUid: string) =>
|
||||
request.get(`${resourcePath(resourceUid)}/interfaces`)
|
||||
|
||||
export const saveImportantInterface = (
|
||||
resourceUid: string,
|
||||
interfaceIdentity: string,
|
||||
data: {
|
||||
purpose: string
|
||||
expected_peer_resource_uid?: string
|
||||
expected_peer_interface_identity?: string
|
||||
}
|
||||
) => request.put(`${resourcePath(resourceUid)}/interfaces/${encodeURIComponent(interfaceIdentity)}/importance`, data)
|
||||
|
||||
export const removeImportantInterface = (resourceUid: string, interfaceIdentity: string) =>
|
||||
request.delete(`${resourcePath(resourceUid)}/interfaces/${encodeURIComponent(interfaceIdentity)}/importance`)
|
||||
|
||||
export const triggerDeviceConfigBackup = (resourceUid: string) =>
|
||||
request.post(`${resourcePath(resourceUid)}/config-backups`)
|
||||
|
||||
export const fetchDeviceConfigBackups = (resourceUid: string, params?: { page?: number; size?: number }) =>
|
||||
request.get(`${resourcePath(resourceUid)}/config-backups`, { params })
|
||||
|
||||
export const fetchDeviceConfigDiff = (resourceUid: string, baseId: number, targetId: number) =>
|
||||
request.get(`${resourcePath(resourceUid)}/config-backups/diff`, { params: { base_id: baseId, target_id: targetId } })
|
||||
|
||||
export const downloadDeviceConfig = (resourceUid: string, versionId: number) =>
|
||||
request.get<Blob>(`${resourcePath(resourceUid)}/config-backups/${versionId}/download`, { responseType: 'blob' })
|
||||
@@ -13,10 +13,12 @@ export interface Floor {
|
||||
enabled?: boolean
|
||||
layout_plan?: string
|
||||
layout_plan_file_id?: string
|
||||
layout_plan_name?: string
|
||||
layout_plan_content_type?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export type SaveFloorPayload = Omit<Floor, 'layout_plan'>
|
||||
export type SaveFloorPayload = Omit<Floor, 'layout_plan' | 'layout_plan_name' | 'layout_plan_content_type'>
|
||||
|
||||
interface ApiResponse<T> {
|
||||
code: number
|
||||
|
||||
@@ -2,7 +2,6 @@ import { request } from '@/api/request'
|
||||
|
||||
export interface PendingUpload {
|
||||
file_id: string
|
||||
object_key: string
|
||||
upload: {
|
||||
method: string
|
||||
url: string
|
||||
@@ -17,7 +16,7 @@ interface ApiResponse<T> {
|
||||
details: T
|
||||
}
|
||||
|
||||
/** 初始化楼层布局文件并直传 OSS。 */
|
||||
/** 初始化楼层布局文件并上传到当前全局存储。 */
|
||||
export async function uploadFloorLayout(file: File): Promise<PendingUpload> {
|
||||
const response = await request.post<ApiResponse<PendingUpload>>('/Assets/v1/floor/layout/init', {
|
||||
filename: file.name,
|
||||
|
||||
@@ -41,11 +41,21 @@ export interface CapacityRisk {
|
||||
metric_code: string
|
||||
unit: string
|
||||
current_value: number
|
||||
threshold: number
|
||||
status: '资源不足' | '配置合理' | '资源闲置' | '容量风险' | '数据不足'
|
||||
idle_threshold: number
|
||||
risk_threshold: number
|
||||
shortage_threshold: number
|
||||
slope_per_hour: number
|
||||
risk_level: string
|
||||
predicted_at?: string
|
||||
predicted_value?: number
|
||||
confidence_low?: number
|
||||
confidence_high?: number
|
||||
sample_count: number
|
||||
data_start?: string
|
||||
data_end?: string
|
||||
data_span_hours: number
|
||||
forecast_hours: number
|
||||
}
|
||||
|
||||
export interface SloDashboardBucket {
|
||||
@@ -75,7 +85,7 @@ export const fetchAlertNoise = (params?: { hours?: number }) =>
|
||||
export const fetchRuleSuggestions = (params?: { hours?: number }) =>
|
||||
request.get<RuleSuggestion[]>('/Alert/v1/governance/suggestions', { params })
|
||||
|
||||
export const fetchCapacityRisk = (params?: { resource_uid?: string; metric_code?: string }) =>
|
||||
export const fetchCapacityRisk = (params?: { resource_uid?: string; metric_type?: string; metric_code?: string }) =>
|
||||
request.get<CapacityRisk>('/DC-Control/v1/risk/capacity', { params })
|
||||
|
||||
export const fetchSloDashboard = () => request.get<SloDashboard>('/Feedback/v1/tickets/slo/dashboard')
|
||||
|
||||
@@ -8,12 +8,16 @@ export interface IpScanTask {
|
||||
description?: string
|
||||
target_range: string
|
||||
port_range?: string
|
||||
config?: string
|
||||
timeout?: number
|
||||
concurrency?: number
|
||||
collector_node_id: number
|
||||
candidate_credential_ids: string
|
||||
allowed_protocols: string
|
||||
default_location: string
|
||||
default_resource_category: string
|
||||
auto_onboard: boolean
|
||||
cron_expr?: string
|
||||
status?: string
|
||||
server_id: number
|
||||
last_scan_time?: string
|
||||
next_scan_time?: string
|
||||
last_scan_status?: string
|
||||
@@ -42,7 +46,7 @@ export const fetchIpScanList = (params?: { page?: number; size?: number; keyword
|
||||
export const fetchIpScanDetail = (id: number) =>
|
||||
request.get<{ code: number; details?: IpScanTask; message?: string }>(`/DC-Control/v1/ipscans/${id}`)
|
||||
|
||||
/** 触发一次扫描(会创建 scan_run 并调用 Agent);成功体见文档 { message: "scan triggered" } */
|
||||
/** 触发一次扫描,运行记录进入指定采集节点的等待队列。 */
|
||||
export const triggerIpScan = (id: number) =>
|
||||
request.post<{ code: number; details?: { message?: string }; message?: string }>(`/DC-Control/v1/ipscans/${id}/trigger`)
|
||||
|
||||
|
||||
@@ -21,8 +21,12 @@ export interface LogEvent {
|
||||
normalized_detail: string
|
||||
device_name: string
|
||||
resource_type: string
|
||||
resource_uid: string
|
||||
resource_id: string
|
||||
resource_name: string
|
||||
business_system_id?: number
|
||||
trace_id?: string
|
||||
span_id?: string
|
||||
match_method: string
|
||||
severity_code: string
|
||||
trap_oid: string
|
||||
@@ -38,6 +42,61 @@ export interface LogEntriesParams {
|
||||
resource_id?: string
|
||||
dispatch_status?: string
|
||||
log_event_id?: number
|
||||
trace_id?: string
|
||||
resource_uid?: string
|
||||
business_system_id?: number
|
||||
}
|
||||
|
||||
export interface TraceSummary {
|
||||
trace_id: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
duration_ms: number
|
||||
span_count: number
|
||||
error_count: number
|
||||
services: string
|
||||
business_system_id?: number
|
||||
resource_uid?: string
|
||||
}
|
||||
|
||||
export interface TraceSpan {
|
||||
id: number
|
||||
trace_id: string
|
||||
span_id: string
|
||||
parent_span_id?: string
|
||||
service_name: string
|
||||
operation_name: string
|
||||
span_kind: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
duration_ms: number
|
||||
status_code: string
|
||||
status_message?: string
|
||||
business_system_id?: number
|
||||
resource_uid?: string
|
||||
http_method?: string
|
||||
http_route?: string
|
||||
http_status_code?: number
|
||||
}
|
||||
|
||||
export interface TraceListParams {
|
||||
page?: number
|
||||
page_size?: number
|
||||
trace_id?: string
|
||||
service_name?: string
|
||||
resource_uid?: string
|
||||
business_system_id?: number
|
||||
status?: 'ok' | 'error' | 'unset'
|
||||
start_time?: string
|
||||
end_time?: string
|
||||
}
|
||||
|
||||
export interface ServiceDependency {
|
||||
source_service: string
|
||||
target_service: string
|
||||
call_count: number
|
||||
error_count: number
|
||||
average_ms: number
|
||||
}
|
||||
|
||||
export interface LogEntriesResult {
|
||||
@@ -138,6 +197,7 @@ export interface AuditLog {
|
||||
actor_id: string
|
||||
actor_name: string
|
||||
action: string
|
||||
log_category: 'operation' | 'data'
|
||||
object_type: string
|
||||
object_id: string
|
||||
operation_risk: string
|
||||
@@ -157,6 +217,7 @@ export interface AuditLogParams {
|
||||
source_service?: string
|
||||
actor_id?: string
|
||||
action?: string
|
||||
log_category?: 'operation' | 'data'
|
||||
object_type?: string
|
||||
object_id?: string
|
||||
operation_risk?: string
|
||||
@@ -197,6 +258,18 @@ export function fetchLogEntries(params?: LogEntriesParams) {
|
||||
return request.get(`${BASE}/entries`, { params })
|
||||
}
|
||||
|
||||
export function fetchTraces(params?: TraceListParams) {
|
||||
return request.get(`${BASE}/traces`, { params })
|
||||
}
|
||||
|
||||
export function fetchTraceDetail(traceId: string) {
|
||||
return request.get(`${BASE}/traces/${encodeURIComponent(traceId)}`)
|
||||
}
|
||||
|
||||
export function fetchServiceDependencies(params?: TraceListParams) {
|
||||
return request.get(`${BASE}/service-dependencies`, { params })
|
||||
}
|
||||
|
||||
export function fetchAlertOutbox(params?: AlertOutboxParams) {
|
||||
return request.get(`${BASE}/alert-outbox`, { params })
|
||||
}
|
||||
|
||||
@@ -14,9 +14,11 @@ export interface MiddlewareItem {
|
||||
description: string
|
||||
enabled: boolean
|
||||
interval: number
|
||||
extra: string
|
||||
tags: string
|
||||
status_url: string
|
||||
adapter_mode: 'http_status' | 'json' | 'prometheus' | 'jolokia'
|
||||
product_version: string
|
||||
adapter_status: 'verified' | 'unverified' | 'blocked'
|
||||
last_data_time: string | null
|
||||
status: string
|
||||
status_code: number
|
||||
status_message: string
|
||||
@@ -26,11 +28,6 @@ export interface MiddlewareItem {
|
||||
last_offline_time: string | null
|
||||
continuous_errors: number
|
||||
uptime: number
|
||||
agent_config: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
}
|
||||
|
||||
/** 中间件列表响应 */
|
||||
@@ -51,7 +48,6 @@ export interface MiddlewareListParams {
|
||||
|
||||
/** 创建中间件请求参数 */
|
||||
export interface MiddlewareCreateData {
|
||||
service_identity?: string
|
||||
server_identity?: string
|
||||
name: string
|
||||
category: string
|
||||
@@ -59,19 +55,13 @@ export interface MiddlewareCreateData {
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
adapter_mode?: 'http_status' | 'json' | 'prometheus' | 'jolokia'
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
/** 更新中间件请求参数 */
|
||||
export interface MiddlewareUpdateData {
|
||||
service_identity?: string
|
||||
server_identity?: string
|
||||
name?: string
|
||||
category?: string
|
||||
@@ -79,52 +69,11 @@ export interface MiddlewareUpdateData {
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
status?: string
|
||||
status_code?: number
|
||||
status_message?: string
|
||||
response_time?: number
|
||||
last_check_time?: string
|
||||
last_online_time?: string | null
|
||||
last_offline_time?: string | null
|
||||
continuous_errors?: number
|
||||
uptime?: number
|
||||
adapter_mode?: 'http_status' | 'json' | 'prometheus' | 'jolokia'
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
/** 采集配置更新参数 */
|
||||
export interface MiddlewareCollectData {
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
/** 指标上报项 */
|
||||
export interface MetricItem {
|
||||
service_identity: string
|
||||
timestamp: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/** 指标上报请求参数 */
|
||||
export interface MetricsUploadData {
|
||||
metrics: MetricItem[]
|
||||
}
|
||||
|
||||
/** 指标上报响应 */
|
||||
export interface MetricsUploadResponse {
|
||||
message: string
|
||||
count: number
|
||||
}
|
||||
|
||||
/** 指标项 */
|
||||
export interface MiddlewareMetric {
|
||||
metric_name: string
|
||||
@@ -177,7 +126,7 @@ export const fetchMiddlewareDetail = (id: number) => {
|
||||
|
||||
/** 创建中间件服务 */
|
||||
export const createMiddleware = (data: MiddlewareCreateData) => {
|
||||
return request.post<{ message: string; id: number }>('/DC-Control/v1/middleware', data)
|
||||
return request.post<{ message: string; id: number; service_identity: string }>('/DC-Control/v1/middleware', data)
|
||||
}
|
||||
|
||||
/** 更新中间件服务 */
|
||||
@@ -185,21 +134,11 @@ export const updateMiddleware = (id: number, data: MiddlewareUpdateData) => {
|
||||
return request.put<{ message: string }>(`/DC-Control/v1/middleware/${id}`, data)
|
||||
}
|
||||
|
||||
/** 部分更新采集配置 */
|
||||
export const patchMiddlewareCollect = (id: number, data: MiddlewareCollectData) => {
|
||||
return request.patch<{ message: string }>(`/DC-Control/v1/middleware/${id}/collect`, data)
|
||||
}
|
||||
|
||||
/** 删除中间件服务 */
|
||||
export const deleteMiddleware = (id: number) => {
|
||||
return request.delete<{ message: string }>(`/DC-Control/v1/middleware/${id}`)
|
||||
}
|
||||
|
||||
/** 上报中间件服务指标(匿名接口) */
|
||||
export const uploadMiddlewareMetrics = (data: MetricsUploadData) => {
|
||||
return request.post<MetricsUploadResponse>('/DC-Control/v1/middleware/metrics/upload', data)
|
||||
}
|
||||
|
||||
/** 查询中间件服务指标元数据 */
|
||||
export const fetchMiddlewareMetricsMeta = (params: MetricsMetaParams) => {
|
||||
return request.get<MetricsMetaResponse>('/DC-Control/v1/services/metrics/meta', { params })
|
||||
@@ -217,13 +156,13 @@ export const MIDDLEWARE_TYPE_MAP: Record<string, string> = {
|
||||
nginx: 'Nginx',
|
||||
apache: 'Apache',
|
||||
tomcat: 'Tomcat',
|
||||
redis: 'Redis',
|
||||
kafka: 'Kafka',
|
||||
activemq: 'ActiveMQ',
|
||||
rocketmq: 'RocketMQ',
|
||||
websphere: 'WebSphere',
|
||||
generic: '通用中间件',
|
||||
rabbitmq: 'RabbitMQ',
|
||||
elasticsearch: 'Elasticsearch',
|
||||
mysql: 'MySQL',
|
||||
postgresql: 'PostgreSQL',
|
||||
mongodb: 'MongoDB',
|
||||
other: '其他',
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface Topology {
|
||||
node_count?: number
|
||||
link_count?: number
|
||||
enable?: boolean
|
||||
auto_discovery?: boolean
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
@@ -41,6 +42,12 @@ export interface Link {
|
||||
description?: string
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
discovery_source?: string
|
||||
confirmed?: boolean
|
||||
source_resource_uid?: string
|
||||
source_interface_identity?: string
|
||||
target_resource_uid?: string
|
||||
target_interface_identity?: string
|
||||
}
|
||||
|
||||
/** 拓扑分组 */
|
||||
@@ -133,6 +140,9 @@ export const fetchTopologies = (data: { page: number; size: number; keyword?: st
|
||||
/** 获取拓扑详情 */
|
||||
export const fetchTopologyDetail = (id: number) => request.get(`/DC-Control/v1/topologies/${id}`)
|
||||
|
||||
/** 获取统一资源对应的系统自动拓扑 */
|
||||
export const fetchAutomaticTopology = () => request.get('/DC-Control/v1/topologies/automatic')
|
||||
|
||||
/** 创建拓扑 */
|
||||
export const createTopology = (data: Partial<Topology>) => request.post('/DC-Control/v1/topologies', data)
|
||||
|
||||
@@ -160,6 +170,13 @@ export const fetchImpactAnalysis = (params: { resource_uid: string; topology_id?
|
||||
export const createNode = (topologyId: number, data: Partial<TopologyNode>) =>
|
||||
request.post(`/DC-Control/v1/topologies/${topologyId}/nodes`, data)
|
||||
|
||||
/** 将已有统一设备引用加入手工拓扑 */
|
||||
export const addResourceNodes = (topologyId: number, resource_uids: string[]) =>
|
||||
request.post<{ code: number; details?: { message: string; added: number } }>(
|
||||
`/DC-Control/v1/topologies/${topologyId}/resource-nodes`,
|
||||
{ resource_uids }
|
||||
)
|
||||
|
||||
/** 更新节点 */
|
||||
export const updateNode = (topologyId: number, nodeId: string, data: Partial<TopologyNode>) =>
|
||||
request.put(`/DC-Control/v1/topologies/${topologyId}/nodes/${nodeId}`, data)
|
||||
@@ -171,13 +188,6 @@ export const deleteNode = (topologyId: number, nodeId: string) => request.delete
|
||||
export const updateNodesPositions = (topologyId: number, positions: Array<{ id: string; position: { x: number; y: number } }>) =>
|
||||
request.put(`/DC-Control/v1/topologies/${topologyId}/nodes/positions`, { positions })
|
||||
|
||||
/** 按资产 ID 批量导入节点(后端生成 node_id=asset-{id} 与 ref_type=asset) */
|
||||
export const batchImportAssetNodes = (topologyId: number, asset_ids: number[]) =>
|
||||
request.post<{ code: number; details?: { message: string; imported: number } }>(
|
||||
`/DC-Control/v1/topologies/${topologyId}/nodes/batch-import`,
|
||||
{ asset_ids }
|
||||
)
|
||||
|
||||
// ==================== 链路管理接口 ====================
|
||||
|
||||
/** 获取链路列表 */
|
||||
|
||||
@@ -1,32 +1,24 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
export type NetworkDeviceProtocol = 'snmp' | 'ssh' | 'telnet'
|
||||
export type NetworkDeviceSnmpVersion = 'v1' | 'v2c' | 'v3'
|
||||
export type NetworkDeviceStatus = 'online' | 'offline' | 'error' | 'unknown'
|
||||
|
||||
export interface NetworkDeviceService {
|
||||
id: number
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
service_identity: string
|
||||
server_identity: string
|
||||
name: string
|
||||
category: string
|
||||
type: string
|
||||
host: string
|
||||
port: number
|
||||
protocol: NetworkDeviceProtocol
|
||||
community: string
|
||||
snmp_version: NetworkDeviceSnmpVersion
|
||||
username: string
|
||||
vendor: string
|
||||
model: string
|
||||
location: string
|
||||
description: string
|
||||
enabled: boolean
|
||||
interval: number
|
||||
extra: string
|
||||
tags: string
|
||||
status: NetworkDeviceStatus
|
||||
status_code: number
|
||||
@@ -37,6 +29,40 @@ export interface NetworkDeviceService {
|
||||
last_offline_time: string | null
|
||||
continuous_errors: number
|
||||
uptime: number
|
||||
product_version: string
|
||||
adapter_status: 'verified' | 'unverified'
|
||||
last_data_time: string | null
|
||||
}
|
||||
|
||||
export interface DeviceInterfaceSnapshot {
|
||||
timestamp: string
|
||||
service_identity: string
|
||||
device_host: string
|
||||
if_index: number
|
||||
if_name: string
|
||||
mac_address: string
|
||||
admin_status: string
|
||||
oper_status: string
|
||||
in_octets: number
|
||||
out_octets: number
|
||||
in_errors: number
|
||||
out_errors: number
|
||||
speed_bps: number
|
||||
}
|
||||
|
||||
export interface WirelessAccessPoint {
|
||||
id: number
|
||||
controller_resource_uid: string
|
||||
ap_identity: string
|
||||
name: string
|
||||
mac_address: string
|
||||
ip_address: string
|
||||
serial_number: string
|
||||
model: string
|
||||
status: string
|
||||
radio_count: number
|
||||
client_count: number
|
||||
last_seen_at: string
|
||||
}
|
||||
|
||||
export interface NetworkDeviceListResponse {
|
||||
@@ -54,25 +80,18 @@ export interface NetworkDeviceQueryParams {
|
||||
}
|
||||
|
||||
export interface CreateNetworkDeviceParams {
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
service_identity?: string
|
||||
server_identity?: string
|
||||
name: string
|
||||
category: string
|
||||
type?: string
|
||||
host: string
|
||||
port?: number
|
||||
protocol?: NetworkDeviceProtocol
|
||||
community?: string
|
||||
snmp_version?: NetworkDeviceSnmpVersion
|
||||
username?: string
|
||||
password?: string
|
||||
vendor?: string
|
||||
model?: string
|
||||
location?: string
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
}
|
||||
|
||||
@@ -89,4 +108,8 @@ export const createNetworkDevice = (data: CreateNetworkDeviceParams) =>
|
||||
export const updateNetworkDevice = (id: number, data: UpdateNetworkDeviceParams) =>
|
||||
request.put<{ message: string }>(`/DC-Control/v1/network-device-services/${id}`, data)
|
||||
|
||||
export const deleteNetworkDevice = (id: number) => request.delete<{ message: string }>(`/DC-Control/v1/network-device-services/${id}`)
|
||||
export const fetchNetworkDeviceInterfaces = (id: number) =>
|
||||
request.get<DeviceInterfaceSnapshot[]>(`/DC-Control/v1/network-device-services/${id}/interfaces`)
|
||||
|
||||
export const fetchNetworkDeviceAccessPoints = (id: number) =>
|
||||
request.get<WirelessAccessPoint[]>(`/DC-Control/v1/network-device-services/${id}/access-points`)
|
||||
|
||||
@@ -15,7 +15,8 @@ export const createNoticeChannel = (data: {
|
||||
name: string
|
||||
type: string
|
||||
config: string
|
||||
message_template?: string
|
||||
message_template_id: number
|
||||
in_app_sound_enabled?: boolean
|
||||
rate_limit?: number
|
||||
rate_limit_window?: number
|
||||
severity_filter?: string
|
||||
@@ -51,7 +52,8 @@ export const updateNoticeChannel = (data: {
|
||||
name?: string
|
||||
type?: string
|
||||
config?: string
|
||||
message_template?: string
|
||||
message_template_id?: number
|
||||
in_app_sound_enabled?: boolean
|
||||
rate_limit?: number
|
||||
rate_limit_window?: number
|
||||
severity_filter?: string
|
||||
|
||||
@@ -5,14 +5,6 @@ export interface PCListParams {
|
||||
page?: number
|
||||
size?: number
|
||||
keyword?: string
|
||||
collect_on?: boolean
|
||||
}
|
||||
|
||||
/** 资源使用率信息 */
|
||||
export interface ResourceInfo {
|
||||
value: number // 使用率百分比
|
||||
total?: string // 总量描述
|
||||
used?: string // 已用描述
|
||||
}
|
||||
|
||||
/** PC 数据结构 */
|
||||
@@ -22,6 +14,8 @@ export interface PCItem {
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
pc_identity: string
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
name: string
|
||||
host: string
|
||||
ip_address: string
|
||||
@@ -32,19 +26,8 @@ export interface PCItem {
|
||||
server_type: string
|
||||
tags: string
|
||||
location: string
|
||||
remote_access: string
|
||||
remote_port: number
|
||||
agent_config: string
|
||||
status: string
|
||||
last_check_time: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
// 资源使用率(前端展示用,可能来自采集数据)
|
||||
cpu_info?: ResourceInfo
|
||||
memory_info?: ResourceInfo
|
||||
disk_info?: ResourceInfo
|
||||
}
|
||||
|
||||
/** PC 列表返回数据 */
|
||||
@@ -57,6 +40,8 @@ export interface PCListResult {
|
||||
|
||||
/** PC 创建参数 */
|
||||
export interface PCCreateParams {
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
pc_identity?: string
|
||||
name: string
|
||||
host: string
|
||||
@@ -68,21 +53,11 @@ export interface PCCreateParams {
|
||||
server_type?: string
|
||||
tags?: string
|
||||
location?: string
|
||||
remote_access?: string
|
||||
remote_port?: number
|
||||
agent_config?: string
|
||||
status?: string
|
||||
last_check_time?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
/** PC 更新参数 */
|
||||
export interface PCUpdateParams {
|
||||
id: number
|
||||
pc_identity?: string
|
||||
name?: string
|
||||
host?: string
|
||||
ip_address?: string
|
||||
@@ -93,15 +68,6 @@ export interface PCUpdateParams {
|
||||
server_type?: string
|
||||
tags?: string
|
||||
location?: string
|
||||
remote_access?: string
|
||||
remote_port?: number
|
||||
agent_config?: string
|
||||
status?: string
|
||||
last_check_time?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
/** 获取PC列表(分页) */
|
||||
@@ -123,8 +89,3 @@ export const createPC = (data: PCCreateParams) => {
|
||||
export const updatePC = (id: number, data: Omit<PCUpdateParams, 'id'>) => {
|
||||
return request.put<{ message: string }>(`/DC-Control/v1/pcs/${id}`, data)
|
||||
}
|
||||
|
||||
/** 删除PC */
|
||||
export const deletePC = (id: number) => {
|
||||
return request.delete<{ message: string }>(`/DC-Control/v1/pcs/${id}`)
|
||||
}
|
||||
|
||||
193
src/api/ops/platformRuntime.ts
Normal file
193
src/api/ops/platformRuntime.ts
Normal file
@@ -0,0 +1,193 @@
|
||||
import { isAxiosError } from 'axios'
|
||||
import { request } from '@/api/request'
|
||||
|
||||
export interface RuntimeCheck {
|
||||
name: string
|
||||
required: boolean
|
||||
ready: boolean
|
||||
message?: string
|
||||
}
|
||||
|
||||
export interface RuntimeWorker {
|
||||
name: string
|
||||
running: boolean
|
||||
queue_depth?: number
|
||||
last_error?: string
|
||||
last_error_at?: string
|
||||
last_succeeded_at?: string
|
||||
}
|
||||
|
||||
export interface RuntimeScheduler {
|
||||
running: boolean
|
||||
last_error?: string
|
||||
}
|
||||
|
||||
export interface RuntimeDisk {
|
||||
path: string
|
||||
total_bytes: number
|
||||
used_bytes: number
|
||||
free_bytes: number
|
||||
used_percent: number
|
||||
minimum_free_bytes?: number
|
||||
level: 'normal' | 'warning' | 'critical'
|
||||
}
|
||||
|
||||
export interface RuntimeStorage {
|
||||
provider: 'local' | 'aliyun' | string
|
||||
container: string
|
||||
writable: boolean
|
||||
}
|
||||
|
||||
export interface NotificationQueue {
|
||||
pending: number
|
||||
retry_scheduled: number
|
||||
uncertain: number
|
||||
failed: number
|
||||
backlog: number
|
||||
oldest_pending?: string
|
||||
}
|
||||
|
||||
export interface PlatformServiceStatus {
|
||||
key: string
|
||||
name: string
|
||||
reachable: boolean
|
||||
ready: boolean
|
||||
version: string
|
||||
checked_at?: string
|
||||
checks: RuntimeCheck[]
|
||||
workers: RuntimeWorker[]
|
||||
scheduler?: RuntimeScheduler
|
||||
disk?: RuntimeDisk
|
||||
storage?: RuntimeStorage
|
||||
notification_queue?: NotificationQueue
|
||||
error?: string
|
||||
}
|
||||
|
||||
interface ServiceSpec {
|
||||
key: string
|
||||
name: string
|
||||
path: string
|
||||
}
|
||||
|
||||
const services: ServiceSpec[] = [
|
||||
{ key: 'rbac2', name: '权限中心', path: '/rbac2/v1/runtime/status' },
|
||||
{ key: 'assets', name: '资产管理', path: '/Assets/v1/runtime/status' },
|
||||
{ key: 'dc-control', name: '监控控制中心', path: '/DC-Control/v1/runtime/status' },
|
||||
{ key: 'dc-network', name: '网络采集', path: '/dc-network/v1/runtime/status' },
|
||||
{ key: 'dc-hardware', name: '硬件采集', path: '/DC-Hardware/v1/runtime/status' },
|
||||
{ key: 'alert', name: '告警中心', path: '/Alert/v1/runtime/status' },
|
||||
{ key: 'logs', name: '日志中心', path: '/Logs/v1/runtime/status' },
|
||||
{ key: 'feedback', name: '工单反馈', path: '/Feedback/v1/runtime/status' },
|
||||
{ key: 'kb', name: '知识库', path: '/Kb/v1/runtime/status' },
|
||||
{ key: 'mgt', name: '大屏管理', path: '/Mgt/v1/runtime/status' },
|
||||
{ key: 'visual', name: '可视化服务', path: '/Visual/v1/runtime/status' },
|
||||
{ key: 'files', name: '文件服务', path: '/Files/v1/runtime/status' },
|
||||
]
|
||||
|
||||
const asRecord = (value: unknown): Record<string, any> => (value && typeof value === 'object' ? (value as Record<string, any>) : {})
|
||||
|
||||
const optionalString = (value: unknown): string | undefined => (typeof value === 'string' && value.length > 0 ? value : undefined)
|
||||
|
||||
const normalizeWorker = (value: unknown, fallbackName = ''): RuntimeWorker => {
|
||||
const record = asRecord(value)
|
||||
return {
|
||||
name: optionalString(record.name) || fallbackName,
|
||||
running: record.running === true,
|
||||
queue_depth: typeof record.queue_depth === 'number' ? record.queue_depth : undefined,
|
||||
last_error: optionalString(record.last_error),
|
||||
last_error_at: optionalString(record.last_error_at),
|
||||
last_succeeded_at: optionalString(record.last_succeeded_at) || optionalString(record.last_success),
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeWorkers = (value: unknown): RuntimeWorker[] => {
|
||||
if (Array.isArray(value)) return value.map((item) => normalizeWorker(item))
|
||||
const record = asRecord(value)
|
||||
return Object.entries(record).map(([name, item]) => normalizeWorker(item, name))
|
||||
}
|
||||
|
||||
const normalizeDisk = (value: unknown): RuntimeDisk | undefined => {
|
||||
const record = asRecord(value)
|
||||
const level = record.level
|
||||
if (!['normal', 'warning', 'critical'].includes(level)) return undefined
|
||||
if (typeof record.path !== 'string') return undefined
|
||||
const values = [record.total_bytes, record.used_bytes, record.free_bytes, record.used_percent]
|
||||
if (!values.every((item) => typeof item === 'number' && Number.isFinite(item))) return undefined
|
||||
return record as RuntimeDisk
|
||||
}
|
||||
|
||||
const normalizeStorage = (value: unknown): RuntimeStorage | undefined => {
|
||||
const record = asRecord(value)
|
||||
if (typeof record.provider !== 'string' || typeof record.container !== 'string' || typeof record.writable !== 'boolean') {
|
||||
return undefined
|
||||
}
|
||||
return record as RuntimeStorage
|
||||
}
|
||||
|
||||
const normalizeNotificationQueue = (value: unknown): NotificationQueue | undefined => {
|
||||
const record = asRecord(value)
|
||||
const fields = ['pending', 'retry_scheduled', 'uncertain', 'failed', 'backlog'] as const
|
||||
if (!fields.every((field) => typeof record[field] === 'number' && Number.isFinite(record[field]))) return undefined
|
||||
return {
|
||||
pending: record.pending,
|
||||
retry_scheduled: record.retry_scheduled,
|
||||
uncertain: record.uncertain,
|
||||
failed: record.failed,
|
||||
backlog: record.backlog,
|
||||
oldest_pending: optionalString(record.oldest_pending),
|
||||
}
|
||||
}
|
||||
|
||||
const isRuntimePayload = (payload: unknown): boolean => {
|
||||
const envelope = asRecord(payload)
|
||||
const readiness = asRecord(envelope.readiness || envelope)
|
||||
return typeof readiness.ready === 'boolean'
|
||||
}
|
||||
|
||||
const normalizePayload = (spec: ServiceSpec, payload: unknown): PlatformServiceStatus => {
|
||||
const envelope = asRecord(payload)
|
||||
const readiness = asRecord(envelope.readiness || envelope)
|
||||
const workers = envelope.workers && envelope.readiness ? envelope.workers : readiness.workers
|
||||
return {
|
||||
key: spec.key,
|
||||
name: spec.name,
|
||||
reachable: true,
|
||||
ready: readiness.ready === true,
|
||||
version: typeof readiness.version === 'string' ? readiness.version : 'unknown',
|
||||
checked_at: typeof readiness.checked_at === 'string' ? readiness.checked_at : undefined,
|
||||
checks: Array.isArray(readiness.checks) ? (readiness.checks as RuntimeCheck[]) : [],
|
||||
workers: normalizeWorkers(workers),
|
||||
scheduler: readiness.scheduler ? (readiness.scheduler as RuntimeScheduler) : undefined,
|
||||
disk: normalizeDisk(envelope.disk || readiness.disk),
|
||||
storage: normalizeStorage(envelope.storage || readiness.storage),
|
||||
notification_queue: normalizeNotificationQueue(envelope.notification_queue),
|
||||
}
|
||||
}
|
||||
|
||||
const fetchServiceStatus = async (spec: ServiceSpec): Promise<PlatformServiceStatus> => {
|
||||
try {
|
||||
const payload = await request.get(spec.path)
|
||||
return normalizePayload(spec, payload)
|
||||
} catch (error) {
|
||||
if (isAxiosError(error) && error.response?.data && isRuntimePayload(error.response.data)) {
|
||||
return normalizePayload(spec, error.response.data)
|
||||
}
|
||||
return {
|
||||
key: spec.key,
|
||||
name: spec.name,
|
||||
reachable: false,
|
||||
ready: false,
|
||||
version: 'unknown',
|
||||
checks: [],
|
||||
workers: [],
|
||||
error:
|
||||
isAxiosError(error) && error.response?.status
|
||||
? `网关返回 ${error.response.status}`
|
||||
: error instanceof Error
|
||||
? error.message
|
||||
: '服务无法连接',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchPlatformRuntime = (): Promise<PlatformServiceStatus[]> => Promise.all(services.map(fetchServiceStatus))
|
||||
@@ -9,7 +9,12 @@ export interface UserItem {
|
||||
username?: string
|
||||
email?: string
|
||||
phone?: string
|
||||
status?: string
|
||||
status?: number
|
||||
department_id?: number
|
||||
position_id?: number
|
||||
department?: { id: number; name: string }
|
||||
position?: { id: number; name: string }
|
||||
roles?: { id: number; name: string }[]
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
@@ -30,3 +35,52 @@ export interface UserListResponse {
|
||||
export const fetchUserList = async (data: any) => {
|
||||
return request.post<UserListResponse>('/rbac2/v1/user/list', data, { needWorkspace: true })
|
||||
}
|
||||
|
||||
export interface RoleItem {
|
||||
id: number
|
||||
name: string
|
||||
description?: string
|
||||
data_scope: 'all' | 'department'
|
||||
status?: number
|
||||
users?: UserItem[]
|
||||
}
|
||||
|
||||
export const fetchRoleList = (data: { page?: number; size?: number; keyword?: string; status?: number }) =>
|
||||
request.post('/rbac2/v1/role/fetch', data, { needWorkspace: true })
|
||||
|
||||
export const fetchRoleUsers = (roleId: number) => request.post('/rbac2/v1/role/user', { id: roleId }, { needWorkspace: true })
|
||||
|
||||
export interface DepartmentItem {
|
||||
id: number
|
||||
name: string
|
||||
parent_id?: number
|
||||
leader_id?: number
|
||||
status?: number
|
||||
}
|
||||
|
||||
export interface PositionItem {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
description?: string
|
||||
status?: number
|
||||
}
|
||||
|
||||
export const fetchDepartmentList = (data: { page?: number; size?: number; keyword?: string }) =>
|
||||
request.post('/rbac2/v1/dpt/fetch', data, { needWorkspace: true })
|
||||
export const createDepartment = (data: Partial<DepartmentItem>) => request.post('/rbac2/v1/dpt/create', data, { needWorkspace: true })
|
||||
export const updateDepartment = (data: Partial<DepartmentItem>) => request.post('/rbac2/v1/dpt/modify', data, { needWorkspace: true })
|
||||
export const deleteDepartment = (id: number) => request.post('/rbac2/v1/dpt/del', { id }, { needWorkspace: true })
|
||||
|
||||
export const fetchPositionList = (data: { page?: number; size?: number; keyword?: string }) =>
|
||||
request.post('/rbac2/v1/position/fetch', data, { needWorkspace: true })
|
||||
export const createPosition = (data: Partial<PositionItem>) => request.post('/rbac2/v1/position/create', data, { needWorkspace: true })
|
||||
export const updatePosition = (data: Partial<PositionItem>) => request.post('/rbac2/v1/position/modify', data, { needWorkspace: true })
|
||||
export const deletePosition = (id: number) => request.post('/rbac2/v1/position/del', { id }, { needWorkspace: true })
|
||||
|
||||
export const createRole = (data: Partial<RoleItem>) => request.post('/rbac2/v1/role/create', data, { needWorkspace: true })
|
||||
export const updateRole = (data: Partial<RoleItem>) => request.post('/rbac2/v1/role/modify', data, { needWorkspace: true })
|
||||
export const deleteRole = (id: number) => request.post('/rbac2/v1/role/del', { id }, { needWorkspace: true })
|
||||
export const fetchRolePermissions = (id: number) => request.post('/rbac2/v1/role/pmn', { id }, { needWorkspace: true })
|
||||
export const updateRolePermissions = (id: number, list: number[]) =>
|
||||
request.post('/rbac2/v1/role/modify_pmn', { id, list }, { needWorkspace: true })
|
||||
|
||||
@@ -19,6 +19,7 @@ export enum ReportType {
|
||||
SERVER = 'server',
|
||||
NETWORK_DEVICE = 'network_device',
|
||||
OPERATIONS = 'operations',
|
||||
DESIGNER = 'designer',
|
||||
EVIDENCE = 'evidence',
|
||||
}
|
||||
|
||||
@@ -48,6 +49,92 @@ export interface ReportRecord {
|
||||
finished_at?: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
definition_id?: number
|
||||
definition_version?: number
|
||||
period_type?: 'daily' | 'monthly'
|
||||
}
|
||||
|
||||
export interface ReportDatasetField {
|
||||
code: string
|
||||
name: string
|
||||
type: 'string' | 'number' | 'datetime' | 'boolean'
|
||||
operators: string[]
|
||||
aggregations: string[]
|
||||
}
|
||||
|
||||
export interface ReportDataset {
|
||||
code: string
|
||||
name: string
|
||||
category: string
|
||||
description: string
|
||||
fields: ReportDatasetField[]
|
||||
temporal: boolean
|
||||
enabled: boolean
|
||||
version: number
|
||||
}
|
||||
|
||||
export interface ReportSelectedField {
|
||||
field: string
|
||||
aggregation: string
|
||||
}
|
||||
|
||||
export interface ReportFilter {
|
||||
field: string
|
||||
operator: string
|
||||
value: string | number | boolean | Array<string | number | boolean>
|
||||
}
|
||||
|
||||
export interface ReportLayoutBlock {
|
||||
type: 'table' | 'bar' | 'line' | 'stat'
|
||||
title: string
|
||||
x_field?: string
|
||||
y_fields?: string[]
|
||||
}
|
||||
|
||||
export interface ReportDefinitionInput {
|
||||
code: string
|
||||
name: string
|
||||
description: string
|
||||
dataset_code: string
|
||||
fields: ReportSelectedField[]
|
||||
filters: ReportFilter[]
|
||||
layout: { blocks: ReportLayoutBlock[] }
|
||||
row_limit: number
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export interface ReportDefinition extends ReportDefinitionInput {
|
||||
id: number
|
||||
version: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface ReportSchedule {
|
||||
id: number
|
||||
definition_id: number
|
||||
period_type: 'daily' | 'monthly'
|
||||
timezone: string
|
||||
hour: number
|
||||
minute: number
|
||||
enabled: boolean
|
||||
next_run_at?: string
|
||||
last_run_at?: string
|
||||
definition?: ReportDefinition
|
||||
}
|
||||
|
||||
export interface CapacityThreshold {
|
||||
id: number
|
||||
resource_category: string
|
||||
metric_type: string
|
||||
metric_code: string
|
||||
display_name: string
|
||||
idle_threshold: number
|
||||
risk_threshold: number
|
||||
shortage_threshold: number
|
||||
min_samples: number
|
||||
forecast_hours: number
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export interface ReportListParams {
|
||||
@@ -242,6 +329,41 @@ export const fetchReportMetricsAvailable = (params: {
|
||||
export const fetchReportMetricsRegistry = (params: { data_source: string }) =>
|
||||
request.get<ApiResponse<{ data_source: string; metrics: any[] }>>('/DC-Control/v1/reports/metrics/registry', { params })
|
||||
|
||||
export const fetchReportDatasets = () => request.get<ApiResponse<ReportDataset[]>>('/DC-Control/v1/reports/datasets')
|
||||
|
||||
export const fetchReportDefinitions = () => request.get<ApiResponse<ReportDefinition[]>>('/DC-Control/v1/reports/definitions')
|
||||
|
||||
export const createReportDefinition = (data: ReportDefinitionInput) =>
|
||||
request.post<ApiResponse<ReportDefinition>>('/DC-Control/v1/reports/definitions', data)
|
||||
|
||||
export const updateReportDefinition = (id: number, data: ReportDefinitionInput) =>
|
||||
request.put<ApiResponse<ReportDefinition>>(`/DC-Control/v1/reports/definitions/${id}`, data)
|
||||
|
||||
export const deleteReportDefinition = (id: number) => request.delete(`/DC-Control/v1/reports/definitions/${id}`)
|
||||
|
||||
export const generateReportDefinition = (
|
||||
id: number,
|
||||
data: { period_type: 'daily' | 'monthly'; start_time: string; end_time: string }
|
||||
) => request.post<ApiResponse<ReportRecord>>(`/DC-Control/v1/reports/definitions/${id}/generate`, data)
|
||||
|
||||
export const fetchReportSchedules = () => request.get<ApiResponse<ReportSchedule[]>>('/DC-Control/v1/reports/schedules')
|
||||
|
||||
export const saveReportSchedule = (data: Omit<ReportSchedule, 'id' | 'next_run_at' | 'last_run_at' | 'definition'>) =>
|
||||
request.post<ApiResponse<ReportSchedule>>('/DC-Control/v1/reports/schedules', data)
|
||||
|
||||
export const deleteReportSchedule = (id: number) => request.delete(`/DC-Control/v1/reports/schedules/${id}`)
|
||||
|
||||
export const fetchCapacityThresholds = () =>
|
||||
request.get<ApiResponse<CapacityThreshold[]>>('/DC-Control/v1/reports/capacity-thresholds')
|
||||
|
||||
export const createCapacityThreshold = (data: Omit<CapacityThreshold, 'id'>) =>
|
||||
request.post<ApiResponse<CapacityThreshold>>('/DC-Control/v1/reports/capacity-thresholds', data)
|
||||
|
||||
export const updateCapacityThreshold = (id: number, data: Omit<CapacityThreshold, 'id'>) =>
|
||||
request.put<ApiResponse<CapacityThreshold>>(`/DC-Control/v1/reports/capacity-thresholds/${id}`, data)
|
||||
|
||||
export const deleteCapacityThreshold = (id: number) => request.delete(`/DC-Control/v1/reports/capacity-thresholds/${id}`)
|
||||
|
||||
/** 查看报表内容 */
|
||||
export const fetchReportContent = (id: number) => request.get<ApiResponse<Record<string, any>>>(`/DC-Control/v1/reports/${id}/content`)
|
||||
|
||||
|
||||
@@ -7,33 +7,16 @@ export interface RoomDeviceItem {
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
service_identity: string
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
name: string
|
||||
description: string
|
||||
room_id: number
|
||||
device_code?: string
|
||||
device_category: string
|
||||
type?: string
|
||||
status_url?: string
|
||||
agent_config: string
|
||||
collect_method: 'api' | 'snmp'
|
||||
snmp_target: string
|
||||
snmp_port: number
|
||||
snmp_version: 'v2c' | 'v3'
|
||||
snmp_community: string
|
||||
snmp_v3_security_level: string
|
||||
snmp_v3_security_name: string
|
||||
snmp_v3_auth_protocol: string
|
||||
snmp_v3_auth_password: string
|
||||
snmp_v3_priv_protocol: string
|
||||
snmp_v3_priv_password: string
|
||||
snmp_v3_context_name: string
|
||||
snmp_timeout_ms: number
|
||||
snmp_retries: number
|
||||
snmp_oids: string
|
||||
management_address?: string
|
||||
enabled: boolean
|
||||
collect_on: boolean
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
status?: string
|
||||
status_code?: number
|
||||
status_message?: string
|
||||
@@ -66,82 +49,22 @@ export interface RoomDeviceListParams {
|
||||
|
||||
/** 机房设备创建数据 */
|
||||
export interface RoomDeviceCreateData {
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
service_identity?: string
|
||||
name: string
|
||||
description?: string
|
||||
room_id: number
|
||||
device_code?: string
|
||||
device_category: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
type?: string
|
||||
management_address?: string
|
||||
enabled?: boolean
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
/** 机房设备更新数据 */
|
||||
export interface RoomDeviceUpdateData {
|
||||
name?: string
|
||||
description?: string
|
||||
room_id?: number
|
||||
device_category?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
enabled?: boolean
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
/** 机房设备采集配置数据 */
|
||||
export interface RoomDeviceCollectData {
|
||||
collect_method?: 'api' | 'snmp'
|
||||
agent_config?: string
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
}
|
||||
export type RoomDeviceUpdateData = Partial<RoomDeviceCreateData>
|
||||
|
||||
/** 指标数据项 */
|
||||
export interface MetricItem {
|
||||
@@ -195,16 +118,6 @@ export const updateRoomDevice = (id: number, data: RoomDeviceUpdateData) => {
|
||||
return request.put<{ message: string }>(`/DC-Control/v1/room-devices/${id}`, data)
|
||||
}
|
||||
|
||||
/** 删除机房设备 */
|
||||
export const deleteRoomDevice = (id: number) => {
|
||||
return request.delete<{ message: string }>(`/DC-Control/v1/room-devices/${id}`)
|
||||
}
|
||||
|
||||
/** 更新采集配置 */
|
||||
export const patchRoomDeviceCollect = (id: number, data: RoomDeviceCollectData) => {
|
||||
return request.patch<{ message: string }>(`/DC-Control/v1/room-devices/${id}/collect`, data)
|
||||
}
|
||||
|
||||
/** 查询最新指标 */
|
||||
export const fetchLatestMetrics = (serviceIdentity: string) => {
|
||||
return request.get<RoomDeviceMetricsLatestResponse>('/DC-Control/v1/room-devices/metrics/latest', {
|
||||
|
||||
@@ -1,43 +1,25 @@
|
||||
import { request } from '@/api/request'
|
||||
import type { DeviceInterfaceSnapshot, WirelessAccessPoint } from './network-device'
|
||||
|
||||
/** 安全设备服务项 */
|
||||
export interface SecurityServiceItem {
|
||||
id: number
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
service_identity: string
|
||||
oid: string
|
||||
server_identity: string
|
||||
name: string
|
||||
category: string
|
||||
type: string
|
||||
host: string
|
||||
vendor: string
|
||||
model: string
|
||||
location: string
|
||||
description: string
|
||||
enabled: boolean
|
||||
interval: number
|
||||
extra: string
|
||||
tags: string
|
||||
status_url: string
|
||||
agent_config: string
|
||||
collect_method: 'api' | 'snmp'
|
||||
snmp_target: string
|
||||
snmp_port: number
|
||||
snmp_version: 'v2c' | 'v3'
|
||||
snmp_community: string
|
||||
snmp_v3_security_level: string
|
||||
snmp_v3_security_name: string
|
||||
snmp_v3_auth_protocol: string
|
||||
snmp_v3_auth_password: string
|
||||
snmp_v3_priv_protocol: string
|
||||
snmp_v3_priv_password: string
|
||||
snmp_v3_context_name: string
|
||||
snmp_timeout_ms: number
|
||||
snmp_retries: number
|
||||
snmp_oids: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
status: string
|
||||
status_code: number
|
||||
status_message: string
|
||||
@@ -47,6 +29,9 @@ export interface SecurityServiceItem {
|
||||
last_offline_time: string | null
|
||||
continuous_errors: number
|
||||
uptime: number
|
||||
product_version: string
|
||||
adapter_status: 'verified' | 'unverified'
|
||||
last_data_time: string | null
|
||||
}
|
||||
|
||||
/** 安全设备服务列表数据 */
|
||||
@@ -67,45 +52,32 @@ export interface SecurityServiceListParams {
|
||||
|
||||
/** 创建/更新安全设备服务请求参数 */
|
||||
export interface SecurityServiceFormData {
|
||||
resource_uid?: string
|
||||
asset_id?: number
|
||||
service_identity?: string
|
||||
oid?: string
|
||||
server_identity?: string
|
||||
name?: string
|
||||
category?: string
|
||||
type?: string
|
||||
host?: string
|
||||
vendor?: string
|
||||
model?: string
|
||||
location?: string
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
/** 安全设备指标项 */
|
||||
export interface SecurityMetric {
|
||||
timestamp?: string
|
||||
service_identity?: string
|
||||
type?: string
|
||||
metric_name: string
|
||||
metric_value: number
|
||||
metric_unit: string
|
||||
series_key?: string
|
||||
labels?: string
|
||||
}
|
||||
|
||||
/** 安全设备最新指标数据 */
|
||||
@@ -136,11 +108,6 @@ export const updateSecurityService = (id: number, data: Partial<SecurityServiceF
|
||||
return request.put<{ code: number; message: string; details: { message: string } }>(`/DC-Control/v1/security/${id}`, data)
|
||||
}
|
||||
|
||||
/** 删除安全设备服务 */
|
||||
export const deleteSecurityService = (id: number) => {
|
||||
return request.delete<{ code: number; message: string; details: { message: string } }>(`/DC-Control/v1/security/${id}`)
|
||||
}
|
||||
|
||||
/** 获取最新时序指标 */
|
||||
export const fetchSecurityMetricsLatest = (serviceIdentity: string) => {
|
||||
return request.get<{ code: number; message: string; details: SecurityMetricsLatestData }>('/DC-Control/v1/security/metrics/latest', {
|
||||
@@ -148,33 +115,35 @@ export const fetchSecurityMetricsLatest = (serviceIdentity: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
/** 采集配置补丁参数 */
|
||||
export interface SecurityServicePatchData {
|
||||
collect_method?: 'api' | 'snmp'
|
||||
agent_config?: string
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
export interface SecurityMetricsTimeseriesQuery {
|
||||
start_time?: string
|
||||
end_time?: string
|
||||
metric_name?: string
|
||||
}
|
||||
|
||||
/** 采集配置补丁 */
|
||||
export const patchSecurityServiceCollect = (id: number, data: SecurityServicePatchData) => {
|
||||
return request.patch<{ code: number; message: string; details: { message: string } }>(`/DC-Control/v1/security/${id}/collect`, data)
|
||||
export interface SecurityMetricsTimeseriesData {
|
||||
service_identity: string
|
||||
start_time: string
|
||||
end_time: string
|
||||
count: number
|
||||
metrics: SecurityMetric[]
|
||||
}
|
||||
|
||||
/** 查询安全设备指标原始时序点 */
|
||||
export const fetchSecurityMetricsTimeseries = (serviceIdentity: string, params?: SecurityMetricsTimeseriesQuery) => {
|
||||
const path = encodeURIComponent(serviceIdentity)
|
||||
return request.get<{ code: number; message: string; details: SecurityMetricsTimeseriesData }>(
|
||||
`/DC-Control/v1/security/metrics/timeseries/${path}`,
|
||||
{ params }
|
||||
)
|
||||
}
|
||||
|
||||
export const fetchSecurityInterfaces = (id: number) =>
|
||||
request.get<{ code: number; message: string; details: DeviceInterfaceSnapshot[] }>(`/DC-Control/v1/security/${id}/interfaces`)
|
||||
|
||||
export const fetchSecurityAccessPoints = (id: number) =>
|
||||
request.get<{ code: number; message: string; details: WirelessAccessPoint[] }>(`/DC-Control/v1/security/${id}/access-points`)
|
||||
|
||||
/** 告警聚合查询参数 */
|
||||
export interface SecurityMetricsAggregateParams {
|
||||
service_identity: string
|
||||
@@ -210,6 +179,12 @@ export const SECURITY_TYPE_MAP: Record<string, string> = {
|
||||
ids: 'IDS',
|
||||
ips: 'IPS',
|
||||
vpn: 'VPN',
|
||||
threat_awareness: '态势感知',
|
||||
bastion_host: '堡垒机',
|
||||
log_audit: '日志审计',
|
||||
database_audit: '数据库审计',
|
||||
internet_behavior: '上网行为管理',
|
||||
security_gap: '网闸',
|
||||
other: '其他',
|
||||
}
|
||||
|
||||
@@ -220,6 +195,12 @@ export const SECURITY_TYPE_OPTIONS = [
|
||||
{ label: 'IDS', value: 'ids' },
|
||||
{ label: 'IPS', value: 'ips' },
|
||||
{ label: 'VPN', value: 'vpn' },
|
||||
{ label: '态势感知', value: 'threat_awareness' },
|
||||
{ label: '堡垒机', value: 'bastion_host' },
|
||||
{ label: '日志审计', value: 'log_audit' },
|
||||
{ label: '数据库审计', value: 'database_audit' },
|
||||
{ label: '上网行为管理', value: 'internet_behavior' },
|
||||
{ label: '网闸', value: 'security_gap' },
|
||||
{ label: '其他', value: 'other' },
|
||||
]
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { request } from '@/api/request'
|
||||
/** 服务器类型 */
|
||||
export interface ServerItem {
|
||||
id: number
|
||||
resource_uid: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
@@ -18,17 +19,10 @@ export interface ServerItem {
|
||||
tags: string
|
||||
location: string
|
||||
asset_id?: number
|
||||
remote_access: string
|
||||
remote_port: number
|
||||
agent_config: string
|
||||
monitored_processes: string[]
|
||||
monitored_ports: number[]
|
||||
status: string
|
||||
last_check_time: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
is_ip_scan_server: boolean
|
||||
ip_scan_port: number
|
||||
}
|
||||
|
||||
/** 服务器列表响应 */
|
||||
@@ -44,12 +38,11 @@ export interface ServerListParams {
|
||||
page?: number
|
||||
size?: number
|
||||
keyword?: string
|
||||
collect_on?: boolean
|
||||
is_ip_scan_server?: boolean
|
||||
}
|
||||
|
||||
/** 创建/更新服务器请求参数 */
|
||||
export interface ServerFormData {
|
||||
resource_uid?: string
|
||||
server_identity?: string
|
||||
name?: string
|
||||
host?: string
|
||||
@@ -62,17 +55,8 @@ export interface ServerFormData {
|
||||
tags?: string
|
||||
location?: string
|
||||
asset_id?: number
|
||||
remote_access?: string
|
||||
remote_port?: number
|
||||
agent_config?: string
|
||||
status?: string
|
||||
last_check_time?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
is_ip_scan_server?: boolean
|
||||
ip_scan_port?: number
|
||||
monitored_processes?: string[]
|
||||
monitored_ports?: number[]
|
||||
}
|
||||
|
||||
/** 获取服务器列表(分页) */
|
||||
@@ -95,11 +79,6 @@ export const updateServer = (id: number, data: Partial<ServerFormData>) => {
|
||||
return request.put<{ message: string }>(`/DC-Control/v1/servers/${id}`, data)
|
||||
}
|
||||
|
||||
/** 删除服务器 */
|
||||
export const deleteServer = (id: number) => {
|
||||
return request.delete<{ message: string }>(`/DC-Control/v1/servers/${id}`)
|
||||
}
|
||||
|
||||
/** 主机最新指标摘要(统计卡片,与 dc-control /servers/metrics/summary 一致) */
|
||||
export interface HostMetricsUseStat {
|
||||
total_bytes: number
|
||||
@@ -138,6 +117,33 @@ export interface HostMetricsSummary {
|
||||
cpu?: HostMetricsCpuCard
|
||||
}
|
||||
|
||||
export interface HostMetricRow {
|
||||
timestamp: string
|
||||
server_identity: string
|
||||
type: string
|
||||
sub_type: string
|
||||
metric_name: string
|
||||
metric_value: number
|
||||
metric_unit: string
|
||||
}
|
||||
|
||||
export interface HostLatestMetricsPayload {
|
||||
server_identity: string
|
||||
timestamp?: string
|
||||
has_data: boolean
|
||||
rows: HostMetricRow[]
|
||||
}
|
||||
|
||||
export interface HardwareSnapshotPayload {
|
||||
has_data: boolean
|
||||
protocol?: string
|
||||
collected_at?: string
|
||||
metrics: Array<{ code: string; value: number; unit: string; labels: Record<string, string> }>
|
||||
inventory: Array<{ type: string; identity: string; name: string; status: string; attributes: Record<string, string> }>
|
||||
events: Array<{ code: string; severity: string; summary: string; attributes: Record<string, string> }>
|
||||
diagnostics: Array<{ code: string; level: string; message: string }>
|
||||
}
|
||||
|
||||
export interface HostNetworkTrafficPoint {
|
||||
time: string
|
||||
recv_mbps: number
|
||||
@@ -162,12 +168,15 @@ export const fetchServerMetricsSummary = (serverIdentity: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
/** 立即拉取一次主机指标并返回最新统计卡片 */
|
||||
export const collectServerMetricsNow = (serverIdentity: string) => {
|
||||
return request.post<{ code: number; details?: HostMetricsSummary; message?: string }>('/DC-Control/v1/servers/metrics/collect', {
|
||||
server_identity: serverIdentity,
|
||||
})
|
||||
}
|
||||
export const fetchServerLatestMetrics = (serverIdentity: string) =>
|
||||
request.get<{ code: number; details?: HostLatestMetricsPayload; message?: string }>('/DC-Control/v1/servers/metrics/latest', {
|
||||
params: { server_identity: serverIdentity },
|
||||
})
|
||||
|
||||
export const fetchServerHardwareSnapshot = (serverIdentity: string) =>
|
||||
request.get<{ code: number; details?: HardwareSnapshotPayload; message?: string }>('/DC-Control/v1/servers/metrics/hardware', {
|
||||
params: { server_identity: serverIdentity },
|
||||
})
|
||||
|
||||
/** 近 N 小时网络收/发速率(Mbps,相邻采样字节差分) */
|
||||
export const fetchServerNetworkTraffic = (serverIdentity: string, hours = 6) => {
|
||||
|
||||
@@ -3,41 +3,22 @@ import { request } from '@/api/request'
|
||||
/** 存储设备服务项 */
|
||||
export interface StorageItem {
|
||||
id: number
|
||||
resource_uid: string
|
||||
asset_id: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
service_identity: string
|
||||
oid: string
|
||||
server_identity: string
|
||||
name: string
|
||||
category: string
|
||||
type: string
|
||||
host: string
|
||||
vendor: string
|
||||
model: string
|
||||
location: string
|
||||
description: string
|
||||
enabled: boolean
|
||||
interval: number
|
||||
extra: string
|
||||
tags: string
|
||||
status_url: string
|
||||
agent_config: string
|
||||
collect_method: 'api' | 'snmp'
|
||||
snmp_target: string
|
||||
snmp_port: number
|
||||
snmp_version: 'v2c' | 'v3'
|
||||
snmp_community: string
|
||||
snmp_v3_security_level: string
|
||||
snmp_v3_security_name: string
|
||||
snmp_v3_auth_protocol: string
|
||||
snmp_v3_auth_password: string
|
||||
snmp_v3_priv_protocol: string
|
||||
snmp_v3_priv_password: string
|
||||
snmp_v3_context_name: string
|
||||
snmp_timeout_ms: number
|
||||
snmp_retries: number
|
||||
snmp_oids: string
|
||||
collect_on: boolean
|
||||
collect_args: string
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
status: string
|
||||
status_code: number
|
||||
status_message: string
|
||||
@@ -47,6 +28,9 @@ export interface StorageItem {
|
||||
last_offline_time: string | null
|
||||
continuous_errors: number
|
||||
uptime: number
|
||||
product_version: string
|
||||
adapter_status: 'verified' | 'unverified'
|
||||
last_data_time: string | null
|
||||
}
|
||||
|
||||
/** 存储设备列表响应 */
|
||||
@@ -67,86 +51,53 @@ export interface StorageListParams {
|
||||
|
||||
/** 创建存储设备请求参数 */
|
||||
export interface StorageCreateData {
|
||||
resource_uid?: string
|
||||
asset_id?: number
|
||||
service_identity?: string
|
||||
name: string
|
||||
category?: string
|
||||
type: string
|
||||
oid?: string
|
||||
server_identity?: string
|
||||
host?: string
|
||||
vendor?: string
|
||||
model?: string
|
||||
location?: string
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
/** 更新存储设备请求参数 */
|
||||
export interface StorageUpdateData {
|
||||
resource_uid?: string
|
||||
asset_id?: number
|
||||
service_identity?: string
|
||||
oid?: string
|
||||
server_identity?: string
|
||||
name?: string
|
||||
category?: string
|
||||
type?: string
|
||||
host?: string
|
||||
vendor?: string
|
||||
model?: string
|
||||
location?: string
|
||||
description?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
status_url?: string
|
||||
agent_config?: string
|
||||
collect_method?: 'api' | 'snmp'
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_args?: string
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
status?: string
|
||||
status_code?: number
|
||||
status_message?: string
|
||||
response_time?: number
|
||||
last_check_time?: string
|
||||
last_online_time?: string | null
|
||||
last_offline_time?: string | null
|
||||
continuous_errors?: number
|
||||
uptime?: number
|
||||
policy_ids?: number[]
|
||||
}
|
||||
|
||||
export interface StorageComponent {
|
||||
id: number
|
||||
resource_uid: string
|
||||
component_type: string
|
||||
component_identity: string
|
||||
name: string
|
||||
status: string
|
||||
capacity_bytes: number
|
||||
used_bytes: number
|
||||
attributes: string
|
||||
last_seen_at: string
|
||||
}
|
||||
|
||||
/** 指标项 */
|
||||
export interface StorageMetricItem {
|
||||
metric_name: string
|
||||
@@ -182,10 +133,8 @@ export const updateStorage = (id: number, data: StorageUpdateData) => {
|
||||
return request.put<{ message: string }>(`/DC-Control/v1/storage/${id}`, data)
|
||||
}
|
||||
|
||||
/** 删除存储设备服务 */
|
||||
export const deleteStorage = (id: number) => {
|
||||
return request.delete<{ message: string }>(`/DC-Control/v1/storage/${id}`)
|
||||
}
|
||||
export const fetchStorageComponents = (id: number) =>
|
||||
request.get<StorageComponent[]>(`/DC-Control/v1/storage/${id}/components`)
|
||||
|
||||
/** 查询最新一批时序指标 */
|
||||
export const fetchStorageMetricsLatest = (serviceIdentity: string) => {
|
||||
@@ -199,27 +148,21 @@ export interface StorageMonitorOptionItem {
|
||||
service_identity: string
|
||||
name: string
|
||||
type: string
|
||||
server_identity: string
|
||||
host: string
|
||||
vendor: string
|
||||
model: string
|
||||
status: string
|
||||
}
|
||||
|
||||
/** 监控大屏:汇总 current.host(与后端 storage_monitor 一致) */
|
||||
export interface StorageMonitorSummaryHost {
|
||||
has_data: boolean
|
||||
cpu_usage_percent?: number | null
|
||||
memory_usage_percent?: number | null
|
||||
swap_usage_percent?: number | null
|
||||
disk_root_used_percent?: number | null
|
||||
disk_root_avail_percent?: number | null
|
||||
host_server_identity?: string
|
||||
host_summary_timestamp?: string | null
|
||||
}
|
||||
|
||||
export interface StorageMonitorSummaryCurrent {
|
||||
service_identity: string
|
||||
controller_status: string
|
||||
server_identity: string
|
||||
host?: StorageMonitorSummaryHost | null
|
||||
resource_uid: string
|
||||
status: string
|
||||
adapter_status: string
|
||||
product_version: string
|
||||
last_data_time?: string | null
|
||||
component_count: number
|
||||
abnormal_component_count: number
|
||||
}
|
||||
|
||||
export interface StorageMonitorSummaryPayload {
|
||||
@@ -230,7 +173,7 @@ export interface StorageMonitorSummaryPayload {
|
||||
current?: StorageMonitorSummaryCurrent | null
|
||||
}
|
||||
|
||||
export const fetchStorageMonitorList = (params?: { keyword?: string; limit?: number }) => {
|
||||
export const fetchStorageMonitorList = (params?: { keyword?: string }) => {
|
||||
return request.get<{
|
||||
code: number
|
||||
details?: { data: StorageMonitorOptionItem[]; count: number }
|
||||
@@ -330,30 +273,3 @@ export const fetchStorageMetricsTimeseries = (serviceIdentity: string, params?:
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
/** 采集配置补丁 */
|
||||
export interface StoragePatchData {
|
||||
collect_method?: 'api' | 'snmp'
|
||||
agent_config?: string
|
||||
snmp_target?: string
|
||||
snmp_port?: number
|
||||
snmp_version?: 'v2c' | 'v3'
|
||||
snmp_community?: string
|
||||
snmp_v3_security_level?: string
|
||||
snmp_v3_security_name?: string
|
||||
snmp_v3_auth_protocol?: string
|
||||
snmp_v3_auth_password?: string
|
||||
snmp_v3_priv_protocol?: string
|
||||
snmp_v3_priv_password?: string
|
||||
snmp_v3_context_name?: string
|
||||
snmp_timeout_ms?: number
|
||||
snmp_retries?: number
|
||||
snmp_oids?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
}
|
||||
|
||||
/** 采集配置补丁更新 */
|
||||
export const patchStorage = (id: number, data: StoragePatchData) => {
|
||||
return request.patch<{ message: string }>(`/DC-Control/v1/storage/${id}/collect`, data)
|
||||
}
|
||||
|
||||
67
src/api/ops/systemSettings.ts
Normal file
67
src/api/ops/systemSettings.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
const BASE = '/Mgt/v1/settings'
|
||||
|
||||
export interface DataDictionaryItem {
|
||||
id?: number
|
||||
category_code: string
|
||||
item_code: string
|
||||
label: string
|
||||
value: string
|
||||
sort: number
|
||||
enabled: boolean
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface SystemParameter {
|
||||
id: number
|
||||
code: string
|
||||
name: string
|
||||
value: number
|
||||
unit: string
|
||||
minimum: number
|
||||
maximum: number
|
||||
description: string
|
||||
}
|
||||
|
||||
export interface CommonPhrase {
|
||||
id?: number
|
||||
category_code: string
|
||||
content: string
|
||||
sort: number
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export type PublicSystemParameters = Record<string, number>
|
||||
|
||||
export const fetchDictionaries = (params?: { category_code?: string; enabled?: boolean }) =>
|
||||
request.get(`${BASE}/dictionaries`, { params })
|
||||
export const createDictionary = (data: DataDictionaryItem) => request.post(`${BASE}/dictionaries`, data)
|
||||
export const updateDictionary = (id: number, data: DataDictionaryItem) => request.put(`${BASE}/dictionaries/${id}`, data)
|
||||
export const deleteDictionary = (id: number) => request.delete(`${BASE}/dictionaries/${id}`)
|
||||
|
||||
export const fetchSystemParameters = () => request.get(`${BASE}/parameters`)
|
||||
export const fetchPublicSystemParameters = () => request.get<unknown>('/Mgt/v1/settings/parameters/public')
|
||||
export const updateSystemParameter = (code: string, value: number) => request.put(`${BASE}/parameters/${code}`, { value })
|
||||
|
||||
export const fetchCommonPhrases = (params?: { page?: number; page_size?: number; keyword?: string; category_code?: string }) =>
|
||||
request.get(`${BASE}/phrases`, { params })
|
||||
export const createCommonPhrase = (data: CommonPhrase) => request.post(`${BASE}/phrases`, data)
|
||||
export const updateCommonPhrase = (id: number, data: CommonPhrase) => request.put(`${BASE}/phrases/${id}`, data)
|
||||
export const deleteCommonPhrase = (id: number) => request.delete(`${BASE}/phrases/${id}`)
|
||||
|
||||
export function unwrapSystemSettings<T>(response: any): T {
|
||||
return (response?.details ?? response?.data) as T
|
||||
}
|
||||
|
||||
export async function fetchDictionaryOptions(categoryCode: string): Promise<Array<{ label: string; value: string }>> {
|
||||
const response = await fetchDictionaries({ category_code: categoryCode, enabled: true })
|
||||
const rows = unwrapSystemSettings<DataDictionaryItem[]>(response) || []
|
||||
return rows.map((item) => ({ label: item.label, value: item.value }))
|
||||
}
|
||||
|
||||
export async function fetchEnabledCommonPhrases(categoryCode: string): Promise<CommonPhrase[]> {
|
||||
const response = await fetchCommonPhrases({ page: 1, page_size: 100, category_code: categoryCode })
|
||||
const payload = unwrapSystemSettings<{ data?: CommonPhrase[] }>(response) || {}
|
||||
return (payload.data || []).filter((item) => item.enabled)
|
||||
}
|
||||
@@ -33,8 +33,8 @@ export interface ThreeMachineRoomSize {
|
||||
depth: number
|
||||
}
|
||||
|
||||
/** 设备绑定的监控资源。 */
|
||||
export interface ThreeMachineRoomBinding {
|
||||
/** 统一监控资源身份。 */
|
||||
export interface ThreeMachineRoomResourceIdentity {
|
||||
resource_uid: string
|
||||
resource_category?: string
|
||||
service_identity?: string
|
||||
@@ -52,7 +52,7 @@ export interface ThreeMachineRoomMetric {
|
||||
}
|
||||
|
||||
/** 设备资源运行数据。 */
|
||||
export interface ThreeMachineRoomResource extends ThreeMachineRoomBinding {
|
||||
export interface ThreeMachineRoomResource extends ThreeMachineRoomResourceIdentity {
|
||||
status?: string
|
||||
metrics_at?: string
|
||||
metrics?: ThreeMachineRoomMetric[]
|
||||
@@ -89,6 +89,7 @@ export interface ThreeMachineRoomUnit {
|
||||
/** 机柜中的资产设备。 */
|
||||
export interface ThreeMachineRoomDevice {
|
||||
asset_id: number
|
||||
resource_uid: string
|
||||
asset_code?: string
|
||||
asset_name?: string
|
||||
category_id?: number | null
|
||||
@@ -102,7 +103,6 @@ export interface ThreeMachineRoomDevice {
|
||||
power_consumption?: number
|
||||
transform?: ThreeMachineRoomTransform
|
||||
size?: ThreeMachineRoomSize
|
||||
bindings?: ThreeMachineRoomBinding[]
|
||||
}
|
||||
|
||||
/** 3D 场景机柜。 */
|
||||
|
||||
@@ -84,6 +84,35 @@ export interface TrafficDashboardResponse {
|
||||
}>
|
||||
}
|
||||
|
||||
export interface NetworkObservation {
|
||||
id: number
|
||||
created_at: string
|
||||
probe_id: string
|
||||
source_kind: string
|
||||
sensor_interface?: string
|
||||
window_start: string
|
||||
window_end: string
|
||||
source_ip: string
|
||||
destination_ip: string
|
||||
source_port?: number
|
||||
destination_port?: number
|
||||
transport: string
|
||||
application?: string
|
||||
bytes: number
|
||||
packets: number
|
||||
connections: number
|
||||
latency_ms?: number
|
||||
http_method?: string
|
||||
http_host?: string
|
||||
http_path?: string
|
||||
http_status_code?: number
|
||||
tls_version?: string
|
||||
tls_server_name?: string
|
||||
tls_cert_subject?: string
|
||||
tls_cert_issuer?: string
|
||||
tls_cert_not_after?: string
|
||||
}
|
||||
|
||||
export const fetchTrafficList = (params?: Record<string, any>) =>
|
||||
request.get<{ code: number; details?: TrafficListResponse; message?: string }>('/DC-Control/v1/traffic', {
|
||||
params,
|
||||
@@ -106,3 +135,9 @@ export const fetchRealtimeTraffic = (params?: Record<string, any>) =>
|
||||
|
||||
export const fetchTrafficDashboard = (params?: Record<string, any>) =>
|
||||
request.get<{ code: number; details?: TrafficDashboardResponse; message?: string }>('/DC-Control/v1/traffic/dashboard', { params })
|
||||
|
||||
export const fetchNetworkObservations = (params?: Record<string, any>) =>
|
||||
request.get<{ code: number; details?: { total: number; page: number; page_size: number; data: NetworkObservation[] }; message?: string }>(
|
||||
'/DC-Control/v1/traffic/network-observations',
|
||||
{ params }
|
||||
)
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
import { request } from '@/api/request'
|
||||
|
||||
export interface UrlDeviceItem {
|
||||
id: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
service_identity: string
|
||||
name: string
|
||||
description: string
|
||||
target_url: string
|
||||
method: string
|
||||
enabled: boolean
|
||||
interval: number
|
||||
extra: string
|
||||
tags: string
|
||||
collect_on: boolean
|
||||
collect_interval: number
|
||||
collect_last_result: string
|
||||
status: string
|
||||
status_code: number
|
||||
response_time: number
|
||||
last_check_time: string
|
||||
last_online_time: string | null
|
||||
last_offline_time: string | null
|
||||
continuous_errors: number
|
||||
}
|
||||
|
||||
export interface UrlDeviceListResponse {
|
||||
total: number
|
||||
page: number
|
||||
page_size: number
|
||||
data: UrlDeviceItem[]
|
||||
}
|
||||
|
||||
export interface UrlDeviceListParams {
|
||||
page?: number
|
||||
size?: number
|
||||
keyword?: string
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export interface UrlDeviceCreateData {
|
||||
service_identity?: string
|
||||
name: string
|
||||
description?: string
|
||||
target_url: string
|
||||
method?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
export interface UrlDeviceUpdateData {
|
||||
name?: string
|
||||
description?: string
|
||||
target_url?: string
|
||||
method?: string
|
||||
enabled?: boolean
|
||||
interval?: number
|
||||
extra?: string
|
||||
tags?: string
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
status?: string
|
||||
status_code?: number
|
||||
response_time?: number
|
||||
last_check_time?: string
|
||||
last_online_time?: string | null
|
||||
last_offline_time?: string | null
|
||||
continuous_errors?: number
|
||||
}
|
||||
|
||||
export interface UrlDeviceCollectData {
|
||||
collect_on?: boolean
|
||||
collect_interval?: number
|
||||
collect_last_result?: string
|
||||
}
|
||||
|
||||
export const fetchUrlDeviceList = (params?: UrlDeviceListParams) => {
|
||||
return request.get<UrlDeviceListResponse>('/DC-Control/v1/url-devices', { params })
|
||||
}
|
||||
|
||||
export const fetchUrlDeviceDetail = (id: number) => {
|
||||
return request.get<UrlDeviceItem>(`/DC-Control/v1/url-devices/${id}`)
|
||||
}
|
||||
|
||||
export const createUrlDevice = (data: UrlDeviceCreateData) => {
|
||||
return request.post<{ message: string; id: number }>('/DC-Control/v1/url-devices', data)
|
||||
}
|
||||
|
||||
export const updateUrlDevice = (id: number, data: UrlDeviceUpdateData) => {
|
||||
return request.put<{ message: string }>(`/DC-Control/v1/url-devices/${id}`, data)
|
||||
}
|
||||
|
||||
export const patchUrlDeviceCollect = (id: number, data: UrlDeviceCollectData) => {
|
||||
return request.patch<{ message: string }>(`/DC-Control/v1/url-devices/${id}/collect`, data)
|
||||
}
|
||||
|
||||
export const deleteUrlDevice = (id: number) => {
|
||||
return request.delete<{ message: string }>(`/DC-Control/v1/url-devices/${id}`)
|
||||
}
|
||||
|
||||
export interface UrlDeviceStatsOverview {
|
||||
total: number
|
||||
online: number
|
||||
today_alert_count: number
|
||||
avg_response_time_ms: number
|
||||
}
|
||||
|
||||
export interface ResponseTimePoint {
|
||||
hour: string
|
||||
avg_response_time_ms: number
|
||||
}
|
||||
|
||||
export interface UrlDeviceResponseTimeTrend {
|
||||
points: ResponseTimePoint[]
|
||||
}
|
||||
|
||||
export interface StatusDistributionItem {
|
||||
status: string
|
||||
count: number
|
||||
}
|
||||
|
||||
export interface UrlDeviceStatusDistribution {
|
||||
total: number
|
||||
by_status: StatusDistributionItem[]
|
||||
}
|
||||
|
||||
export const fetchUrlDeviceStatsOverview = () => {
|
||||
return request.get<UrlDeviceStatsOverview>('/DC-Control/v1/url-devices/stats/overview')
|
||||
}
|
||||
|
||||
export const fetchUrlDeviceResponseTimeTrend = () => {
|
||||
return request.get<UrlDeviceResponseTimeTrend>('/DC-Control/v1/url-devices/stats/response-time-trend')
|
||||
}
|
||||
|
||||
export const fetchUrlDeviceStatusDistribution = () => {
|
||||
return request.get<UrlDeviceStatusDistribution>('/DC-Control/v1/url-devices/stats/status-distribution')
|
||||
}
|
||||
@@ -28,6 +28,12 @@ export interface UserItem {
|
||||
status?: number
|
||||
role_id?: number
|
||||
role_name?: string
|
||||
department_id?: number
|
||||
position_id?: number
|
||||
role_ids?: number[]
|
||||
department?: { id: number; name: string }
|
||||
position?: { id: number; name: string }
|
||||
roles?: { id: number; name: string }[]
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user