From ba2494f5b34af7bf4d8bb8f0bdd5f0c4531742bb Mon Sep 17 00:00:00 2001 From: ygx Date: Tue, 17 Mar 2026 23:31:21 +0800 Subject: [PATCH] feat --- src/api/ops/alertLevel.ts | 50 ++ src/api/ops/noticeChannel.ts | 58 ++ src/api/ops/rack.ts | 51 ++ src/api/ops/unit.ts | 64 ++ .../level/components/LevelDetailDialog.vue | 147 ++++ .../level/components/LevelFormDialog.vue | 248 ++++++ .../ops/pages/alert/level/config/columns.ts | 47 ++ .../pages/alert/level/config/search-form.ts | 20 + src/views/ops/pages/alert/level/index.vue | 262 ++++++ .../notice/components/ChannelDetailDialog.vue | 256 ++++++ .../notice/components/ChannelFormDialog.vue | 423 ++++++++++ .../ops/pages/alert/notice/config/columns.ts | 38 + .../pages/alert/notice/config/search-form.ts | 25 + src/views/ops/pages/alert/notice/index.vue | 298 +++++++ .../rack/components/RackDetailDialog.vue | 386 +++++++++ .../rack/components/RackFormDialog.vue | 779 ++++++++++++++++++ .../pages/datacenter/rack/config/columns.ts | 77 ++ .../datacenter/rack/config/search-form.ts | 55 ++ src/views/ops/pages/datacenter/rack/index.vue | 333 ++++++++ .../components/AllocateUnitDialog.vue | 205 +++++ .../components/ReserveUnitDialog.vue | 163 ++++ .../pages/datacenter/u-position/detail.vue | 557 +++++++++++++ .../ops/pages/datacenter/u-position/index.vue | 490 +++++++++++ 23 files changed, 5032 insertions(+) create mode 100644 src/api/ops/alertLevel.ts create mode 100644 src/api/ops/noticeChannel.ts create mode 100644 src/api/ops/rack.ts create mode 100644 src/api/ops/unit.ts create mode 100644 src/views/ops/pages/alert/level/components/LevelDetailDialog.vue create mode 100644 src/views/ops/pages/alert/level/components/LevelFormDialog.vue create mode 100644 src/views/ops/pages/alert/level/config/columns.ts create mode 100644 src/views/ops/pages/alert/level/config/search-form.ts create mode 100644 src/views/ops/pages/alert/level/index.vue create mode 100644 src/views/ops/pages/alert/notice/components/ChannelDetailDialog.vue create mode 100644 src/views/ops/pages/alert/notice/components/ChannelFormDialog.vue create mode 100644 src/views/ops/pages/alert/notice/config/columns.ts create mode 100644 src/views/ops/pages/alert/notice/config/search-form.ts create mode 100644 src/views/ops/pages/alert/notice/index.vue create mode 100644 src/views/ops/pages/datacenter/rack/components/RackDetailDialog.vue create mode 100644 src/views/ops/pages/datacenter/rack/components/RackFormDialog.vue create mode 100644 src/views/ops/pages/datacenter/rack/config/columns.ts create mode 100644 src/views/ops/pages/datacenter/rack/config/search-form.ts create mode 100644 src/views/ops/pages/datacenter/rack/index.vue create mode 100644 src/views/ops/pages/datacenter/u-position/components/AllocateUnitDialog.vue create mode 100644 src/views/ops/pages/datacenter/u-position/components/ReserveUnitDialog.vue create mode 100644 src/views/ops/pages/datacenter/u-position/detail.vue create mode 100644 src/views/ops/pages/datacenter/u-position/index.vue diff --git a/src/api/ops/alertLevel.ts b/src/api/ops/alertLevel.ts new file mode 100644 index 0000000..2d0ea58 --- /dev/null +++ b/src/api/ops/alertLevel.ts @@ -0,0 +1,50 @@ +import { request } from "@/api/request"; + +/** 获取告警级别列表(分页) */ +export const fetchAlertLevelList = (data?: { + page?: number; + page_size?: number; + keyword?: string; + enabled?: string; +}) => { + return request.get("/Alert/v1/severity/list", data || {}); +}; + +/** 获取告警级别详情 */ +export const fetchAlertLevelDetail = (id: number) => { + return request.get(`/Alert/v1/severity/get/${id}`); +}; + +/** 创建告警级别 */ +export const createAlertLevel = (data: { + name: string; + code: string; + description?: string; + color: string; + icon?: string; + priority?: number; + enabled?: boolean; + config?: string; +}) => { + return request.post("/Alert/v1/severity/create", data); +}; + +/** 更新告警级别 */ +export const updateAlertLevel = (data: { + id: number; + name?: string; + code?: string; + description?: string; + color?: string; + icon?: string; + priority?: number; + enabled?: boolean; + config?: string; +}) => { + return request.post("/Alert/v1/severity/update", data); +}; + +/** 删除告警级别 */ +export const deleteAlertLevel = (id: number) => { + return request.delete(`/Alert/v1/severity/delete/${id}`); +}; diff --git a/src/api/ops/noticeChannel.ts b/src/api/ops/noticeChannel.ts new file mode 100644 index 0000000..54860dc --- /dev/null +++ b/src/api/ops/noticeChannel.ts @@ -0,0 +1,58 @@ +import { request } from "@/api/request"; + +/** 获取通知渠道列表(分页) */ +export const fetchNoticeChannelList = (data?: { + page?: number; + page_size?: number; + keyword?: string; + type?: string; +}) => { + return request.get("/Alert/v1/channel/list", { params: data || {} }); +}; + +/** 获取通知渠道详情 */ +export const fetchNoticeChannelDetail = (id: number) => { + return request.get(`/Alert/v1/channel/get/${id}`); +}; + +/** 创建通知渠道 */ +export const createNoticeChannel = (data: { + name: string; + type: string; + config: string; + message_template?: string; + rate_limit?: number; + rate_limit_window?: number; + severity_filter?: string; + quiet_hours?: string; + retry_times?: number; + retry_interval?: number; + enabled?: boolean; + description?: string; +}) => { + return request.post("/Alert/v1/channel/create", data); +}; + +/** 更新通知渠道 */ +export const updateNoticeChannel = (data: { + id: number; + name?: string; + type?: string; + config?: string; + message_template?: string; + rate_limit?: number; + rate_limit_window?: number; + severity_filter?: string; + quiet_hours?: string; + retry_times?: number; + retry_interval?: number; + enabled?: boolean; + description?: string; +}) => { + return request.post("/Alert/v1/channel/update", data); +}; + +/** 删除通知渠道 */ +export const deleteNoticeChannel = (id: number) => { + return request.delete(`/Alert/v1/channel/delete/${id}`); +}; diff --git a/src/api/ops/rack.ts b/src/api/ops/rack.ts new file mode 100644 index 0000000..757131c --- /dev/null +++ b/src/api/ops/rack.ts @@ -0,0 +1,51 @@ +import { request } from "@/api/request"; + +/** 获取机柜列表(分页) */ +export const fetchRackList = (data?: { + page?: number; + page_size?: number; + keyword?: string; + datacenter_id?: number; + floor_id?: number; + rack_type?: string; + status?: string; + sort?: string; + order?: string; +}) => { + return request.post("/Assets/v1/rack/list", data || {}); +}; + +/** 获取机柜详情 */ +export const fetchRackDetail = (id: number) => { + return request.get(`/Assets/v1/rack/detail/${id}`); +}; + +/** 创建机柜 */ +export const createRack = (data: any) => { + return request.post("/Assets/v1/rack/create", data); +}; + +/** 更新机柜 */ +export const updateRack = (data: any) => { + return request.put("/Assets/v1/rack/update", data); +}; + +/** 删除机柜 */ +export const deleteRack = (id: number) => { + return request.delete(`/Assets/v1/rack/delete/${id}`); +}; + +/** 获取供应商列表(用于下拉选择) */ +export const fetchSupplierList = () => { + return request.get("/Assets/v1/supplier/all"); +}; + +/** 获取数据中心列表(用于下拉选择) */ +export const fetchDatacenterList = () => { + return request.get("/Assets/v1/datacenter/all"); +}; + +/** 获取楼层列表(用于下拉选择) */ +export const fetchFloorListForSelect = (datacenterId?: number) => { + return request.get("/Assets/v1/floor/all", { params: { datacenter_id: datacenterId } }); +}; diff --git a/src/api/ops/unit.ts b/src/api/ops/unit.ts new file mode 100644 index 0000000..137bf26 --- /dev/null +++ b/src/api/ops/unit.ts @@ -0,0 +1,64 @@ +import { request } from "@/api/request"; + +/** 获取机柜U位状态 */ +export const fetchRackUnits = (rackId: number) => { + return request.get(`/Assets/v1/unit/rack/${rackId}`); +}; + +/** 获取U位列表(别名) */ +export const fetchUnitList = fetchRackUnits; + +/** 分配U位 */ +export const allocateUnit = (data: { + rack_id: number; + start_unit: number; + occupied_units: number; + asset_id?: number; + asset_code?: string; + asset_name: string; + asset_type: string; + power_consumption?: number; + description?: string; +}) => { + return request.post("/Assets/v1/unit/allocate", data); +}; + +/** 释放U位 */ +export const releaseUnit = (data: { + rack_id: number; + start_unit: number; + end_unit: number; +}) => { + return request.post("/Assets/v1/unit/release", data); +}; + +/** 预留U位 */ +export const reserveUnit = (data: { + rack_id: number; + start_unit: number; + occupied_units: number; + reserved_for: string; + reserved_until: string; + description?: string; +}) => { + return request.post("/Assets/v1/unit/reserve", data); +}; + +/** 取消预留 */ +export const cancelReservation = (data: { + rack_id: number; + start_unit: number; + end_unit: number; +}) => { + return request.post("/Assets/v1/unit/cancel_reservation", data); +}; + +/** 更新U位状态 */ +export const updateUnitStatus = (data: { + rack_id: number; + start_unit: number; + end_unit: number; + status: "available" | "disabled"; +}) => { + return request.put("/Assets/v1/unit/status", data); +}; diff --git a/src/views/ops/pages/alert/level/components/LevelDetailDialog.vue b/src/views/ops/pages/alert/level/components/LevelDetailDialog.vue new file mode 100644 index 0000000..5cb8f3b --- /dev/null +++ b/src/views/ops/pages/alert/level/components/LevelDetailDialog.vue @@ -0,0 +1,147 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/level/components/LevelFormDialog.vue b/src/views/ops/pages/alert/level/components/LevelFormDialog.vue new file mode 100644 index 0000000..5ab446d --- /dev/null +++ b/src/views/ops/pages/alert/level/components/LevelFormDialog.vue @@ -0,0 +1,248 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/level/config/columns.ts b/src/views/ops/pages/alert/level/config/columns.ts new file mode 100644 index 0000000..5cd67af --- /dev/null +++ b/src/views/ops/pages/alert/level/config/columns.ts @@ -0,0 +1,47 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface' + +export const columns: TableColumnData[] = [ + { + title: '序号', + dataIndex: 'index', + slotName: 'index', + width: 80, + }, + { + title: '级别名称', + dataIndex: 'name', + width: 150, + }, + { + title: '图标', + dataIndex: 'icon', + slotName: 'icon', + width: 100, + }, + { + title: '颜色标识', + dataIndex: 'color', + slotName: 'color', + width: 120, + }, + { + title: '描述', + dataIndex: 'description', + ellipsis: true, + tooltip: true, + width: 200, + }, + { + title: '状态', + dataIndex: 'enabled', + slotName: 'enabled', + width: 120, + }, + { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + width: 240, + fixed: 'right' as const, + }, +] diff --git a/src/views/ops/pages/alert/level/config/search-form.ts b/src/views/ops/pages/alert/level/config/search-form.ts new file mode 100644 index 0000000..6dc0431 --- /dev/null +++ b/src/views/ops/pages/alert/level/config/search-form.ts @@ -0,0 +1,20 @@ +import type { FormItem } from '@/components/search-form/types' + +export const searchFormConfig: FormItem[] = [ + { + field: 'keyword', + label: '关键词', + type: 'input', + placeholder: '请输入级别名称、代码或描述', + }, + { + field: 'enabled', + label: '状态', + type: 'select', + placeholder: '请选择状态', + options: [ + { label: '启用', value: 'true' }, + { label: '禁用', value: 'false' }, + ], + }, +] diff --git a/src/views/ops/pages/alert/level/index.vue b/src/views/ops/pages/alert/level/index.vue new file mode 100644 index 0000000..ed47095 --- /dev/null +++ b/src/views/ops/pages/alert/level/index.vue @@ -0,0 +1,262 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/notice/components/ChannelDetailDialog.vue b/src/views/ops/pages/alert/notice/components/ChannelDetailDialog.vue new file mode 100644 index 0000000..4981598 --- /dev/null +++ b/src/views/ops/pages/alert/notice/components/ChannelDetailDialog.vue @@ -0,0 +1,256 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/notice/components/ChannelFormDialog.vue b/src/views/ops/pages/alert/notice/components/ChannelFormDialog.vue new file mode 100644 index 0000000..e14f335 --- /dev/null +++ b/src/views/ops/pages/alert/notice/components/ChannelFormDialog.vue @@ -0,0 +1,423 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/notice/config/columns.ts b/src/views/ops/pages/alert/notice/config/columns.ts new file mode 100644 index 0000000..5053934 --- /dev/null +++ b/src/views/ops/pages/alert/notice/config/columns.ts @@ -0,0 +1,38 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface' + +export const columns: TableColumnData[] = [ + { + title: '序号', + dataIndex: 'index', + slotName: 'index', + width: 80, + }, + { + title: '渠道名称', + dataIndex: 'name', + width: 180, + }, + { + title: '渠道类型', + dataIndex: 'type', + slotName: 'type', + width: 120, + }, + { + title: '限流次数', + dataIndex: 'rate_limit', + width: 120, + }, + { + title: '限流窗口(秒)', + dataIndex: 'rate_limit_window', + width: 140, + }, + { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + width: 240, + fixed: 'right' as const, + }, +] diff --git a/src/views/ops/pages/alert/notice/config/search-form.ts b/src/views/ops/pages/alert/notice/config/search-form.ts new file mode 100644 index 0000000..d91339d --- /dev/null +++ b/src/views/ops/pages/alert/notice/config/search-form.ts @@ -0,0 +1,25 @@ +import type { FormItem } from '@/components/search-form/types' + +export const searchFormConfig: FormItem[] = [ + { + field: 'keyword', + label: '关键词', + type: 'input', + placeholder: '请输入渠道名称或描述', + }, + { + field: 'type', + label: '渠道类型', + type: 'select', + placeholder: '请选择渠道类型', + options: [ + { label: '邮件', value: 'email' }, + { label: '短信', value: 'sms' }, + { label: 'Webhook', value: 'webhook' }, + { label: '钉钉', value: 'dingtalk' }, + { label: '企业微信', value: 'wechat' }, + { label: '飞书', value: 'feishu' }, + { label: 'Slack', value: 'slack' }, + ], + }, +] diff --git a/src/views/ops/pages/alert/notice/index.vue b/src/views/ops/pages/alert/notice/index.vue new file mode 100644 index 0000000..8fb9ad1 --- /dev/null +++ b/src/views/ops/pages/alert/notice/index.vue @@ -0,0 +1,298 @@ + + + + + + + diff --git a/src/views/ops/pages/datacenter/rack/components/RackDetailDialog.vue b/src/views/ops/pages/datacenter/rack/components/RackDetailDialog.vue new file mode 100644 index 0000000..af1e451 --- /dev/null +++ b/src/views/ops/pages/datacenter/rack/components/RackDetailDialog.vue @@ -0,0 +1,386 @@ + + + + + + + diff --git a/src/views/ops/pages/datacenter/rack/components/RackFormDialog.vue b/src/views/ops/pages/datacenter/rack/components/RackFormDialog.vue new file mode 100644 index 0000000..b125160 --- /dev/null +++ b/src/views/ops/pages/datacenter/rack/components/RackFormDialog.vue @@ -0,0 +1,779 @@ + + + + + + + diff --git a/src/views/ops/pages/datacenter/rack/config/columns.ts b/src/views/ops/pages/datacenter/rack/config/columns.ts new file mode 100644 index 0000000..c0757ad --- /dev/null +++ b/src/views/ops/pages/datacenter/rack/config/columns.ts @@ -0,0 +1,77 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface' + +export const columns: TableColumnData[] = [ + { + title: '序号', + dataIndex: 'index', + slotName: 'index', + width: 80, + }, + { + title: '机柜名称', + dataIndex: 'name', + width: 150, + }, + { + title: '机柜编码', + dataIndex: 'code', + width: 200, + }, + { + title: '所属中心', + dataIndex: 'datacenter', + slotName: 'datacenter', + width: 180, + }, + { + title: '所属楼层', + dataIndex: 'floor', + slotName: 'floor', + width: 120, + }, + { + title: '机柜类型', + dataIndex: 'rack_type', + slotName: 'rack_type', + width: 120, + }, + { + title: '高度(U)', + dataIndex: 'height', + width: 100, + }, + { + title: '总U位', + dataIndex: 'total_units', + width: 100, + }, + { + title: '已用U位', + dataIndex: 'used_units', + width: 100, + }, + { + title: '可用U位', + dataIndex: 'available_units', + width: 100, + }, + { + title: '使用率', + dataIndex: 'utilization_rate', + slotName: 'utilization_rate', + width: 100, + }, + { + title: '状态', + dataIndex: 'status', + slotName: 'status', + width: 120, + }, + { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + width: 320, + fixed: 'right' as const, + }, +] diff --git a/src/views/ops/pages/datacenter/rack/config/search-form.ts b/src/views/ops/pages/datacenter/rack/config/search-form.ts new file mode 100644 index 0000000..4495830 --- /dev/null +++ b/src/views/ops/pages/datacenter/rack/config/search-form.ts @@ -0,0 +1,55 @@ +import type { FormItem } from '@/components/search-form/types' + +export const searchFormConfig: FormItem[] = [ + { + field: 'keyword', + label: '关键词', + type: 'input', + placeholder: '请输入机柜名称或编码', + span: 6, + }, + { + field: 'datacenter_id', + label: '数据中心', + type: 'select', + placeholder: '请选择数据中心', + options: [], // 需要动态加载 + span: 6, + }, + { + field: 'floor_id', + label: '楼层', + type: 'select', + placeholder: '请选择楼层', + options: [], // 需要动态加载 + span: 6, + }, + { + field: 'rack_type', + label: '机柜类型', + type: 'select', + placeholder: '请选择机柜类型', + options: [ + { label: '标准机柜', value: 'standard' }, + { label: '刀片机柜', value: 'blade' }, + { label: '网络机柜', value: 'network' }, + { label: '存储机柜', value: 'storage' }, + { label: '定制机柜', value: 'custom' }, + ], + span: 6, + }, + { + field: 'status', + label: '状态', + type: 'select', + placeholder: '请选择状态', + options: [ + { label: '空闲', value: 'idle' }, + { label: '使用中', value: 'in_use' }, + { label: '已预留', value: 'reserved' }, + { label: '维护中', value: 'maintenance' }, + { label: '已下线', value: 'offline' }, + ], + span: 6, + }, +] diff --git a/src/views/ops/pages/datacenter/rack/index.vue b/src/views/ops/pages/datacenter/rack/index.vue new file mode 100644 index 0000000..eef0551 --- /dev/null +++ b/src/views/ops/pages/datacenter/rack/index.vue @@ -0,0 +1,333 @@ + + + + + + + diff --git a/src/views/ops/pages/datacenter/u-position/components/AllocateUnitDialog.vue b/src/views/ops/pages/datacenter/u-position/components/AllocateUnitDialog.vue new file mode 100644 index 0000000..558cb0c --- /dev/null +++ b/src/views/ops/pages/datacenter/u-position/components/AllocateUnitDialog.vue @@ -0,0 +1,205 @@ + + + + + diff --git a/src/views/ops/pages/datacenter/u-position/components/ReserveUnitDialog.vue b/src/views/ops/pages/datacenter/u-position/components/ReserveUnitDialog.vue new file mode 100644 index 0000000..6b67141 --- /dev/null +++ b/src/views/ops/pages/datacenter/u-position/components/ReserveUnitDialog.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/src/views/ops/pages/datacenter/u-position/detail.vue b/src/views/ops/pages/datacenter/u-position/detail.vue new file mode 100644 index 0000000..539c9c2 --- /dev/null +++ b/src/views/ops/pages/datacenter/u-position/detail.vue @@ -0,0 +1,557 @@ + + + + + + + diff --git a/src/views/ops/pages/datacenter/u-position/index.vue b/src/views/ops/pages/datacenter/u-position/index.vue new file mode 100644 index 0000000..d4264cb --- /dev/null +++ b/src/views/ops/pages/datacenter/u-position/index.vue @@ -0,0 +1,490 @@ + + + + + + +