Merge branch 'main' of https://git.apinb.com/ops/front
This commit is contained in:
@@ -1,40 +1,31 @@
|
|||||||
import { request } from "@/api/request";
|
import { request } from "@/api/request";
|
||||||
|
|
||||||
/** 获取服务器列表(分页) */
|
/** 获取服务器列表(分页) */
|
||||||
export const fetchServerList = (data?: {
|
export const fetchServerList = (params?: {
|
||||||
page?: number;
|
page?: number;
|
||||||
page_size?: number;
|
size?: number;
|
||||||
keyword?: string;
|
keyword?: string;
|
||||||
datacenter_id?: number;
|
collect_on?: boolean;
|
||||||
rack_id?: number;
|
|
||||||
status?: string;
|
|
||||||
sort?: string;
|
|
||||||
order?: string;
|
|
||||||
}) => {
|
}) => {
|
||||||
return request.post("/Assets/v1/server/list", data || {});
|
return request.get("/DC-Control/v1/servers", { params });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 获取服务器详情 */
|
/** 获取服务器详情 */
|
||||||
export const fetchServerDetail = (id: number) => {
|
export const fetchServerDetail = (id: number) => {
|
||||||
return request.get(`/Assets/v1/server/detail/${id}`);
|
return request.get(`/DC-Control/v1/servers/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 创建服务器 */
|
/** 创建服务器 */
|
||||||
export const createServer = (data: any) => {
|
export const createServer = (data: any) => {
|
||||||
return request.post("/Assets/v1/server/create", data);
|
return request.post("/DC-Control/v1/servers", data);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 更新服务器 */
|
/** 更新服务器 */
|
||||||
export const updateServer = (data: any) => {
|
export const updateServer = (id: number, data: any) => {
|
||||||
return request.put("/Assets/v1/server/update", data);
|
return request.put(`/DC-Control/v1/servers/${id}`, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 删除服务器 */
|
/** 删除服务器 */
|
||||||
export const deleteServer = (id: number) => {
|
export const deleteServer = (id: number) => {
|
||||||
return request.delete(`/Assets/v1/server/delete/${id}`);
|
return request.delete(`/DC-Control/v1/servers/${id}`);
|
||||||
};
|
|
||||||
|
|
||||||
/** 获取机柜列表(用于下拉选择) */
|
|
||||||
export const fetchRackListForSelect = (datacenterId?: number) => {
|
|
||||||
return request.get("/Assets/v1/rack/all", { params: { datacenter_id: datacenterId } });
|
|
||||||
};
|
};
|
||||||
|
|||||||
365
src/views/ops/pages/dc/server/api.md
Normal file
365
src/views/ops/pages/dc/server/api.md
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
# 服务器管理接口文档
|
||||||
|
|
||||||
|
## 基础信息
|
||||||
|
|
||||||
|
- **文档索引**: [README.md](README.md)
|
||||||
|
- **服务前缀**: `/DC-Control/v1/servers`
|
||||||
|
- **认证方式**: JWT认证(所有接口都需要JWT Token)
|
||||||
|
- **Content-Type**: `application/json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 获取服务器列表
|
||||||
|
|
||||||
|
### 接口信息
|
||||||
|
- **路径**: `GET /DC-Control/v1/servers`
|
||||||
|
- **描述**: 分页获取服务器列表,支持关键词搜索、按是否启用采集(`collect_on`)过滤
|
||||||
|
|
||||||
|
### 请求参数
|
||||||
|
|
||||||
|
#### 查询参数 (Query Parameters)
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|
||||||
|
|--------|------|------|--------|------|
|
||||||
|
| page | int | 否 | 1 | 页码(必须为正整数) |
|
||||||
|
| size | int | 否 | 20 | 每页数量(必须为正整数,最大100) |
|
||||||
|
| keyword | string | 否 | - | 搜索关键词(按**名称、主机地址**模糊匹配,实现见 `ListServers`) |
|
||||||
|
| collect_on | bool | 否 | - | 是否启用采集过滤,仅 `true`/`false`;缺省或空串不按该条件过滤,非法值返回 400 |
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /DC-Control/v1/servers?page=1&size=20&keyword=生产&collect_on=true
|
||||||
|
Authorization: Bearer {JWT_TOKEN}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回参数
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"total": 50,
|
||||||
|
"page": 1,
|
||||||
|
"page_size": 20,
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"created_at": "2024-01-01T10:00:00Z",
|
||||||
|
"updated_at": "2024-01-01T10:00:00Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"server_identity": "server-001",
|
||||||
|
"name": "生产服务器-001",
|
||||||
|
"host": "192.168.1.100",
|
||||||
|
"ip_address": "192.168.1.100",
|
||||||
|
"description": "生产环境主服务器",
|
||||||
|
"os": "Linux",
|
||||||
|
"os_version": "22.04",
|
||||||
|
"kernel": "x86",
|
||||||
|
"server_type": "physical",
|
||||||
|
"tags": "production,web",
|
||||||
|
"location": "机房A-机架01",
|
||||||
|
"remote_access": "ssh://user@host",
|
||||||
|
"agent_config": "",
|
||||||
|
"status": "online",
|
||||||
|
"last_check_time": "2024-01-01T10:00:00Z",
|
||||||
|
"collect_on": true,
|
||||||
|
"collect_args": "",
|
||||||
|
"collect_interval": 60,
|
||||||
|
"collect_last_result": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回字段说明
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| total | int64 | 总记录数 |
|
||||||
|
| page | int | 当前页码 |
|
||||||
|
| page_size | int | 每页数量 |
|
||||||
|
| data | array | 服务器列表 |
|
||||||
|
| data[].id | uint | 服务器ID |
|
||||||
|
| data[].created_at | string | 创建时间 |
|
||||||
|
| data[].updated_at | string | 更新时间 |
|
||||||
|
| data[].deleted_at | string\|null | 删除时间(软删除) |
|
||||||
|
| data[].server_identity | string | 服务器唯一标识(唯一索引) |
|
||||||
|
| data[].name | string | 服务器名称 |
|
||||||
|
| data[].host | string | 服务器地址 |
|
||||||
|
| data[].ip_address | string | IP地址 |
|
||||||
|
| data[].description | string | 描述信息 |
|
||||||
|
| data[].os | string | 操作系统:Windows/Linux/Mac/Other 等 |
|
||||||
|
| data[].os_version | string | 操作系统版本 |
|
||||||
|
| data[].kernel | string | 内核类型:x86/arm 等 |
|
||||||
|
| data[].server_type | string | 服务器类型:physical(物理)/virtual(虚拟)/cloud(云) |
|
||||||
|
| data[].tags | string | 标签,逗号分隔的字符串(如 `prod,web`),可为空 |
|
||||||
|
| data[].location | string | 位置/机房信息 |
|
||||||
|
| data[].remote_access | string | 远程访问信息 |
|
||||||
|
| data[].agent_config | string | Agent 配置 |
|
||||||
|
| data[].status | string | 状态:online(在线)/offline(离线)/unknown(未知) |
|
||||||
|
| data[].last_check_time | string | 最后检查时间 |
|
||||||
|
| data[].collect_on | bool | 是否启用采集 |
|
||||||
|
| data[].collect_args | string | 采集参数 |
|
||||||
|
| data[].collect_interval | int | 采集间隔(秒),默认 60 |
|
||||||
|
| data[].collect_last_result | string | 采集最后结果 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 获取服务器详情
|
||||||
|
|
||||||
|
### 接口信息
|
||||||
|
- **路径**: `GET /DC-Control/v1/servers/:id`
|
||||||
|
- **描述**: 根据ID获取单个服务器的详细信息
|
||||||
|
|
||||||
|
### 请求参数
|
||||||
|
|
||||||
|
#### 路径参数 (Path Parameters)
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|--------|
|
||||||
|
| id | uint | 是 | 服务器ID(必须大于0) |
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /DC-Control/v1/servers/1
|
||||||
|
Authorization: Bearer {JWT_TOKEN}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回参数
|
||||||
|
|
||||||
|
返回单体字段与列表项一致(见上一节 `data[]` 字段说明),无嵌套 `collectors` 字段;采集器与服务器通过采集器表 `server_id` 关联,需通过采集器管理接口查询。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 创建服务器
|
||||||
|
|
||||||
|
### 接口信息
|
||||||
|
- **路径**: `POST /DC-Control/v1/servers`
|
||||||
|
- **描述**: 创建新的服务器记录
|
||||||
|
|
||||||
|
### 请求参数
|
||||||
|
|
||||||
|
#### 请求体 (Request Body)
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|--------|
|
||||||
|
| server_identity | string | 否 | 服务器唯一标识;**不传或空串时服务端生成 ULID** |
|
||||||
|
| name | string | 是 | 服务器名称(最大100字符) |
|
||||||
|
| host | string | 是 | 服务器地址(最大255字符) |
|
||||||
|
| ip_address | string | 否 | IP地址(最大50字符) |
|
||||||
|
| description | string | 否 | 描述信息 |
|
||||||
|
| os | string | 否 | 操作系统类型 |
|
||||||
|
| os_version | string | 否 | 操作系统版本 |
|
||||||
|
| kernel | string | 否 | 内核类型 |
|
||||||
|
| server_type | string | 否 | 服务器类型:physical/virtual/cloud(最大50字符) |
|
||||||
|
| tags | string | 否 | 标签,逗号分隔(如 `env,role,tier`),最大约 500 字符,可为空 |
|
||||||
|
| location | string | 否 | 位置/机房信息(最大200字符) |
|
||||||
|
| remote_access | string | 否 | 远程访问 |
|
||||||
|
| agent_config | string | 否 | Agent 配置 |
|
||||||
|
| status | string | 否 | 状态:online/offline/unknown,默认由库表 default 为 unknown |
|
||||||
|
| last_check_time | string (RFC3339) | 否 | 最后检查时间 |
|
||||||
|
| collect_on | bool | 否 | 是否启用采集,默认 true |
|
||||||
|
| collect_args | string | 否 | 采集参数 |
|
||||||
|
| collect_interval | int | 否 | 采集间隔(秒),默认 60 |
|
||||||
|
| collect_last_result | string | 否 | 采集最后结果 |
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
POST /DC-Control/v1/servers
|
||||||
|
Authorization: Bearer {JWT_TOKEN}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"server_identity": "server-001",
|
||||||
|
"name": "生产服务器-001",
|
||||||
|
"host": "192.168.1.100",
|
||||||
|
"ip_address": "192.168.1.100",
|
||||||
|
"description": "生产环境主服务器",
|
||||||
|
"server_type": "physical",
|
||||||
|
"tags": "production,web,tier1",
|
||||||
|
"location": "机房A-机架01",
|
||||||
|
"remote_access": "ssh://ops@192.168.1.100",
|
||||||
|
"status": "online",
|
||||||
|
"collect_on": true,
|
||||||
|
"collect_interval": 60
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回参数
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"id": 1,
|
||||||
|
"created_at": "2024-01-01T10:00:00Z",
|
||||||
|
"updated_at": "2024-01-01T10:00:00Z",
|
||||||
|
"deleted_at": null,
|
||||||
|
"server_identity": "server-001",
|
||||||
|
"name": "生产服务器-001",
|
||||||
|
"host": "192.168.1.100",
|
||||||
|
"ip_address": "192.168.1.100",
|
||||||
|
"description": "生产环境主服务器",
|
||||||
|
"os": "",
|
||||||
|
"os_version": "",
|
||||||
|
"kernel": "",
|
||||||
|
"server_type": "physical",
|
||||||
|
"tags": "production,web,tier1",
|
||||||
|
"location": "机房A-机架01",
|
||||||
|
"remote_access": "ssh://ops@192.168.1.100",
|
||||||
|
"agent_config": "",
|
||||||
|
"status": "online",
|
||||||
|
"last_check_time": "0001-01-01T00:00:00Z",
|
||||||
|
"collect_on": true,
|
||||||
|
"collect_args": "",
|
||||||
|
"collect_interval": 60,
|
||||||
|
"collect_last_result": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 创建接口直接返回内存中的 `server` 对象。采集器与服务器的关联请在**采集器管理**接口中维护(如设置采集器的 `server_id`)。
|
||||||
|
|
||||||
|
### 错误响应
|
||||||
|
|
||||||
|
当达到许可证限制时,会返回以下错误:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 400,
|
||||||
|
"message": "已达到许可证允许的最大服务器数量限制({max_server}),无法创建更多服务器",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 更新服务器
|
||||||
|
|
||||||
|
### 接口信息
|
||||||
|
- **路径**: `PUT /DC-Control/v1/servers/:id`
|
||||||
|
- **描述**: 更新服务器信息
|
||||||
|
|
||||||
|
### 请求参数
|
||||||
|
|
||||||
|
#### 路径参数 (Path Parameters)
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|--------|
|
||||||
|
| id | uint | 是 | 服务器ID(必须大于0) |
|
||||||
|
|
||||||
|
#### 请求体 (Request Body)
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|--------|
|
||||||
|
| server_identity | string | 否 | 服务器唯一标识 |
|
||||||
|
| name | string | 否 | 服务器名称 |
|
||||||
|
| host | string | 否 | 服务器地址 |
|
||||||
|
| ip_address | string | 否 | IP地址 |
|
||||||
|
| description | string | 否 | 描述信息 |
|
||||||
|
| server_type | string | 否 | 服务器类型 |
|
||||||
|
| tags | string | 否 | 标签,逗号分隔 |
|
||||||
|
| location | string | 否 | 位置/机房信息 |
|
||||||
|
| remote_access | string | 否 | 远程访问 |
|
||||||
|
| agent_config | string | 否 | Agent 配置 |
|
||||||
|
| status | string | 否 | 状态 |
|
||||||
|
| last_check_time | string (RFC3339) | 否 | 最后检查时间 |
|
||||||
|
| collect_on | bool | 否 | 是否启用采集(可显式更新为 false) |
|
||||||
|
| collect_args | string | 否 | 采集参数 |
|
||||||
|
| collect_interval | int | 否 | 采集间隔(秒) |
|
||||||
|
| collect_last_result | string | 否 | 采集最后结果 |
|
||||||
|
| os / os_version / kernel | string | 否 | 操作系统与内核字段 |
|
||||||
|
|
||||||
|
**注意**: 只传需要更新的字段;未出现的列不修改。更新使用 `map` 写入,可将 `collect_on`、`collect_interval` 等设为 `false`/`0`。
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
PUT /DC-Control/v1/servers/1
|
||||||
|
Authorization: Bearer {JWT_TOKEN}
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"description": "更新后的描述",
|
||||||
|
"status": "offline",
|
||||||
|
"collect_on": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回参数
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"message": "updated"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 删除服务器
|
||||||
|
|
||||||
|
### 接口信息
|
||||||
|
- **路径**: `DELETE /DC-Control/v1/servers/:id`
|
||||||
|
- **描述**: 删除服务器(软删除)
|
||||||
|
|
||||||
|
### 请求参数
|
||||||
|
|
||||||
|
#### 路径参数 (Path Parameters)
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 必填 | 说明 |
|
||||||
|
|--------|------|------|--------|
|
||||||
|
| id | uint | 是 | 服务器ID(必须大于0) |
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
DELETE /DC-Control/v1/servers/1
|
||||||
|
Authorization: Bearer {JWT_TOKEN}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回参数
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"message": "deleted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 错误码说明
|
||||||
|
|
||||||
|
| 错误码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 200 | 成功 |
|
||||||
|
| 400 | 参数验证失败(如ID为0、page/size无效等) |
|
||||||
|
| 401 | 未授权(JWT Token无效或过期) |
|
||||||
|
| 404 | 资源不存在 |
|
||||||
|
| 500 | 服务器内部错误 |
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 所有接口都需要在请求头中携带JWT Token:`Authorization: Bearer {JWT_TOKEN}`
|
||||||
|
2. 服务器ID必须大于0
|
||||||
|
3. 分页参数page和size必须为正整数,size最大为100
|
||||||
|
4. `server_identity` 在库中必须唯一;若创建时不传则由服务端生成 ULID
|
||||||
|
5. 服务器类型(`server_type`)支持:physical(物理)、virtual(虚拟)、cloud(云)
|
||||||
|
6. 服务器状态:online(在线)、offline(离线)、unknown(未知)
|
||||||
|
7. 删除服务器为软删除,数据不会真正删除
|
||||||
|
8. **tags** 为可选,任意逗号分隔字符串(如 `env,app,tier`),长度受模型 `varchar(500)` 限制
|
||||||
|
9. **许可证限制**:创建服务器时会检查**服务器总条数**是否达到许可证 `MaxServer` 上限,超出则拒绝创建
|
||||||
|
10. 服务器 CRUD **不处理**采集器绑定;关联关系通过**采集器管理**接口(更新采集器 `server_id` 等)维护。列表与详情不内嵌采集器数组。
|
||||||
@@ -121,6 +121,7 @@ import { Message } from '@arco-design/web-vue'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import type { FormInstance } from '@arco-design/web-vue'
|
import type { FormInstance } from '@arco-design/web-vue'
|
||||||
import DatacenterSelector from './DatacenterSelector.vue'
|
import DatacenterSelector from './DatacenterSelector.vue'
|
||||||
|
import { createServer, updateServer } from '@/api/ops/server'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
visible: boolean
|
visible: boolean
|
||||||
@@ -216,17 +217,52 @@ const handleOk = async () => {
|
|||||||
try {
|
try {
|
||||||
await formRef.value?.validate()
|
await formRef.value?.validate()
|
||||||
|
|
||||||
if (!formData.unique_id) {
|
|
||||||
formData.unique_id = uuidv4()
|
|
||||||
}
|
|
||||||
|
|
||||||
confirmLoading.value = true
|
confirmLoading.value = true
|
||||||
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
// 准备提交数据
|
||||||
|
const submitData: any = {
|
||||||
|
name: formData.name,
|
||||||
|
host: formData.ip,
|
||||||
|
ip_address: formData.ip,
|
||||||
|
description: formData.remark,
|
||||||
|
os: formData.os,
|
||||||
|
server_type: formData.server_type,
|
||||||
|
kernel: formData.kernel,
|
||||||
|
tags: formData.tags,
|
||||||
|
remote_access: formData.remote_access,
|
||||||
|
agent_config: formData.agent_config,
|
||||||
|
collect_on: formData.data_collection,
|
||||||
|
collect_interval: formData.collection_interval,
|
||||||
|
}
|
||||||
|
|
||||||
Message.success(isEdit.value ? '更新成功' : '创建成功')
|
// 编辑模式或唯一标识
|
||||||
|
if (isEdit.value && props.record?.id) {
|
||||||
|
// 更新服务器
|
||||||
|
const res: any = await updateServer(props.record.id, submitData)
|
||||||
|
if (res.code === 200 || res.code === 0) {
|
||||||
|
Message.success('更新成功')
|
||||||
emit('success')
|
emit('success')
|
||||||
handleCancel()
|
handleCancel()
|
||||||
|
} else {
|
||||||
|
Message.error(res.message || '更新失败')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 创建服务器
|
||||||
|
if (!formData.unique_id) {
|
||||||
|
submitData.server_identity = uuidv4()
|
||||||
|
} else {
|
||||||
|
submitData.server_identity = formData.unique_id
|
||||||
|
}
|
||||||
|
|
||||||
|
const res: any = await createServer(submitData)
|
||||||
|
if (res.code === 200 || res.code === 0) {
|
||||||
|
Message.success('创建成功')
|
||||||
|
emit('success')
|
||||||
|
handleCancel()
|
||||||
|
} else {
|
||||||
|
Message.error(res.message || '创建失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('验证失败:', error)
|
console.error('验证失败:', error)
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export const columns = [
|
|||||||
slotName: 'id',
|
slotName: 'id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'service_identity',
|
dataIndex: 'server_identity',
|
||||||
title: '唯一标识',
|
title: '唯一标识',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
@@ -15,34 +15,34 @@ export const columns = [
|
|||||||
title: '名称',
|
title: '名称',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'host',
|
||||||
|
title: '主机地址',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'ip_address',
|
||||||
|
title: 'IP 地址',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'os',
|
||||||
|
title: '操作系统',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'os_version',
|
||||||
|
title: '系统版本',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'server_type',
|
dataIndex: 'server_type',
|
||||||
title: '类型',
|
title: '类型',
|
||||||
width: 120,
|
width: 120,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
dataIndex: 'os',
|
|
||||||
title: '操作系统',
|
|
||||||
width: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'kernel',
|
|
||||||
title: '内核类型',
|
|
||||||
width: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'location',
|
|
||||||
title: '位置信息',
|
|
||||||
width: 150,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
dataIndex: 'tags',
|
dataIndex: 'tags',
|
||||||
title: '标签',
|
title: '标签',
|
||||||
width: 120,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'ip',
|
|
||||||
title: 'IP地址',
|
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -54,29 +54,11 @@ export const columns = [
|
|||||||
{
|
{
|
||||||
dataIndex: 'agent_config',
|
dataIndex: 'agent_config',
|
||||||
title: 'Agent 配置',
|
title: 'Agent 配置',
|
||||||
width: 150,
|
width: 100,
|
||||||
slotName: 'agent_config',
|
slotName: 'agent_config',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'cpu',
|
dataIndex: 'collect_on',
|
||||||
title: 'CPU使用率',
|
|
||||||
width: 150,
|
|
||||||
slotName: 'cpu',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'memory',
|
|
||||||
title: '内存使用率',
|
|
||||||
width: 150,
|
|
||||||
slotName: 'memory',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'disk',
|
|
||||||
title: '硬盘使用率',
|
|
||||||
width: 150,
|
|
||||||
slotName: 'disk',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'data_collection',
|
|
||||||
title: '数据采集',
|
title: '数据采集',
|
||||||
width: 100,
|
width: 100,
|
||||||
slotName: 'data_collection',
|
slotName: 'data_collection',
|
||||||
|
|||||||
@@ -5,36 +5,18 @@ export const searchFormConfig: FormItem[] = [
|
|||||||
field: 'keyword',
|
field: 'keyword',
|
||||||
label: '关键词',
|
label: '关键词',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
placeholder: '请输入服务器名称、编码或IP',
|
placeholder: '请输入服务器名称、主机地址',
|
||||||
span: 6,
|
span: 8,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'datacenter_id',
|
field: 'collect_on',
|
||||||
label: '数据中心',
|
label: '数据采集',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
placeholder: '请选择数据中心',
|
placeholder: '请选择采集状态',
|
||||||
options: [], // 需要动态加载
|
|
||||||
span: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'rack_id',
|
|
||||||
label: '机柜',
|
|
||||||
type: 'select',
|
|
||||||
placeholder: '请选择机柜',
|
|
||||||
options: [], // 需要动态加载
|
|
||||||
span: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
label: '状态',
|
|
||||||
type: 'select',
|
|
||||||
placeholder: '请选择状态',
|
|
||||||
options: [
|
options: [
|
||||||
{ label: '在线', value: 'online' },
|
{ label: '启用', value: true },
|
||||||
{ label: '离线', value: 'offline' },
|
{ label: '禁用', value: false },
|
||||||
{ label: '维护中', value: 'maintenance' },
|
|
||||||
{ label: '已退役', value: 'retired' },
|
|
||||||
],
|
],
|
||||||
span: 6,
|
span: 8,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
<template #memory="{ record }">
|
<template #memory="{ record }">
|
||||||
<div class="resource-display">
|
<div class="resource-display">
|
||||||
<div class="resource-info">
|
<div class="resource-info">
|
||||||
<span class="resource-laebl">内存</span>
|
<span class="resource-label">内存</span>
|
||||||
<span class="resource-value">{{ record.memory_info?.value || 0 }}%</span>
|
<span class="resource-value">{{ record.memory_info?.value || 0 }}%</span>
|
||||||
</div>
|
</div>
|
||||||
<a-progress
|
<a-progress
|
||||||
@@ -94,8 +94,8 @@
|
|||||||
|
|
||||||
<!-- 数据采集 -->
|
<!-- 数据采集 -->
|
||||||
<template #data_collection="{ record }">
|
<template #data_collection="{ record }">
|
||||||
<a-tag :color="record.data_collection ? 'green' : 'gray'">
|
<a-tag :color="record.collect_on ? 'green' : 'gray'">
|
||||||
{{ record.data_collection ? '已启用' : '未启用' }}
|
{{ record.collect_on ? '已启用' : '未启用' }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -202,215 +202,10 @@ import {
|
|||||||
fetchServerList,
|
fetchServerList,
|
||||||
deleteServer,
|
deleteServer,
|
||||||
} from '@/api/ops/server'
|
} from '@/api/ops/server'
|
||||||
import { fetchDatacenterAll } from '@/api/ops/datacenter'
|
import axios from 'axios'
|
||||||
import { fetchRackListByDatacenter } from '@/api/ops/rack'
|
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
// Mock 假数据
|
|
||||||
const mockServerData = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
unique_id: 'SRV-2024-0001',
|
|
||||||
name: 'Web服务器-01',
|
|
||||||
type: 'Web服务器',
|
|
||||||
os: 'CentOS 7.9',
|
|
||||||
location: '数据中心A-1楼-机柜01-U1',
|
|
||||||
tags: 'Web,应用',
|
|
||||||
ip: '192.168.1.101',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '8核 Intel Xeon',
|
|
||||||
memory: '32GB',
|
|
||||||
disk: '1TB SSD',
|
|
||||||
cpu_info: { value: 45, total: '8核', used: '3.6核' },
|
|
||||||
memory_info: { value: 62, total: '32GB', used: '19.8GB' },
|
|
||||||
disk_info: { value: 78, total: '1TB', used: '780GB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'online',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
unique_id: 'SRV-2024-0002',
|
|
||||||
name: '数据库服务器-01',
|
|
||||||
type: '数据库服务器',
|
|
||||||
os: 'Ubuntu 22.04',
|
|
||||||
location: '数据中心A-1楼-机柜02-U1',
|
|
||||||
tags: '数据库,MySQL',
|
|
||||||
ip: '192.168.1.102',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '16核 AMD EPYC',
|
|
||||||
memory: '64GB',
|
|
||||||
disk: '2TB NVMe',
|
|
||||||
cpu_info: { value: 78, total: '16核', used: '12.5核' },
|
|
||||||
memory_info: { value: 85, total: '64GB', used: '54.4GB' },
|
|
||||||
disk_info: { value: 92, total: '2TB', used: '1.84TB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'online',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
unique_id: 'SRV-2024-0003',
|
|
||||||
name: '应用服务器-01',
|
|
||||||
type: '应用服务器',
|
|
||||||
os: 'Windows Server 2019',
|
|
||||||
location: '数据中心A-2楼-机柜05-U2',
|
|
||||||
tags: '应用,.NET',
|
|
||||||
ip: '192.168.1.103',
|
|
||||||
remote_access: false,
|
|
||||||
agent_config: false,
|
|
||||||
cpu: '4核 Intel Xeon',
|
|
||||||
memory: '16GB',
|
|
||||||
disk: '500GB SSD',
|
|
||||||
cpu_info: { value: 0, total: '4核', used: '0核' },
|
|
||||||
memory_info: { value: 0, total: '16GB', used: '0GB' },
|
|
||||||
disk_info: { value: 0, total: '500GB', used: '0GB' },
|
|
||||||
data_collection: false,
|
|
||||||
status: 'offline',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
unique_id: 'SRV-2024-0004',
|
|
||||||
name: '缓存服务器-01',
|
|
||||||
type: '缓存服务器',
|
|
||||||
os: 'CentOS 8.5',
|
|
||||||
location: '数据中心A-2楼-机柜06-U1',
|
|
||||||
tags: '缓存,Redis',
|
|
||||||
ip: '192.168.1.104',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '8核 Intel Xeon',
|
|
||||||
memory: '32GB',
|
|
||||||
disk: '1TB SSD',
|
|
||||||
cpu_info: { value: 35, total: '8核', used: '2.8核' },
|
|
||||||
memory_info: { value: 68, total: '32GB', used: '21.8GB' },
|
|
||||||
disk_info: { value: 42, total: '1TB', used: '420GB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'online',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
unique_id: 'SRV-2024-0005',
|
|
||||||
name: '文件服务器-01',
|
|
||||||
type: '文件服务器',
|
|
||||||
os: 'Debian 11',
|
|
||||||
location: '数据中心B-1楼-机柜03-U1',
|
|
||||||
tags: '文件,NFS',
|
|
||||||
ip: '192.168.2.101',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '12核 Intel Xeon',
|
|
||||||
memory: '48GB',
|
|
||||||
disk: '10TB HDD',
|
|
||||||
cpu_info: { value: 28, total: '12核', used: '3.4核' },
|
|
||||||
memory_info: { value: 45, total: '48GB', used: '21.6GB' },
|
|
||||||
disk_info: { value: 88, total: '10TB', used: '8.8TB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'maintenance',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
unique_id: 'SRV-2024-0006',
|
|
||||||
name: '测试服务器-01',
|
|
||||||
type: '测试服务器',
|
|
||||||
os: 'CentOS 7.9',
|
|
||||||
location: '数据中心B-2楼-机柜10-U1',
|
|
||||||
tags: '测试,开发',
|
|
||||||
ip: '192.168.2.102',
|
|
||||||
remote_access: false,
|
|
||||||
agent_config: false,
|
|
||||||
cpu: '4核 Intel Xeon',
|
|
||||||
memory: '8GB',
|
|
||||||
disk: '256GB SSD',
|
|
||||||
cpu_info: { value: 0, total: '4核', used: '0核' },
|
|
||||||
memory_info: { value: 0, total: '8GB', used: '0GB' },
|
|
||||||
disk_info: { value: 0, total: '256GB', used: '0GB' },
|
|
||||||
data_collection: false,
|
|
||||||
status: 'retired',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 7,
|
|
||||||
unique_id: 'SRV-2024-0007',
|
|
||||||
name: '监控服务器-01',
|
|
||||||
type: '监控服务器',
|
|
||||||
os: 'Ubuntu 20.04',
|
|
||||||
location: '数据中心A-1楼-机柜08-U1',
|
|
||||||
tags: '监控,Prometheus',
|
|
||||||
ip: '192.168.1.105',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '8核 Intel Xeon',
|
|
||||||
memory: '32GB',
|
|
||||||
disk: '1TB SSD',
|
|
||||||
cpu_info: { value: 55, total: '8核', used: '4.4核' },
|
|
||||||
memory_info: { value: 72, total: '32GB', used: '23.0GB' },
|
|
||||||
disk_info: { value: 65, total: '1TB', used: '650GB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'online',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 8,
|
|
||||||
unique_id: 'SRV-2024-0008',
|
|
||||||
name: '备份服务器-01',
|
|
||||||
type: '备份服务器',
|
|
||||||
os: 'Rocky Linux 9',
|
|
||||||
location: '数据中心B-1楼-机柜04-U1',
|
|
||||||
tags: '备份,存储',
|
|
||||||
ip: '192.168.2.103',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '16核 AMD EPYC',
|
|
||||||
memory: '64GB',
|
|
||||||
disk: '20TB HDD',
|
|
||||||
cpu_info: { value: 42, total: '16核', used: '6.7核' },
|
|
||||||
memory_info: { value: 38, total: '64GB', used: '24.3GB' },
|
|
||||||
disk_info: { value: 75, total: '20TB', used: '15TB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'online',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 9,
|
|
||||||
unique_id: 'SRV-2024-0009',
|
|
||||||
name: 'CI/CD服务器-01',
|
|
||||||
type: 'CI/CD服务器',
|
|
||||||
os: 'Ubuntu 22.04',
|
|
||||||
location: '数据中心A-2楼-机柜07-U1',
|
|
||||||
tags: 'CI/CD,Jenkins',
|
|
||||||
ip: '192.168.1.106',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '8核 Intel Xeon',
|
|
||||||
memory: '16GB',
|
|
||||||
disk: '500GB SSD',
|
|
||||||
cpu_info: { value: 68, total: '8核', used: '5.4核' },
|
|
||||||
memory_info: { value: 75, total: '16GB', used: '12GB' },
|
|
||||||
disk_info: { value: 55, total: '500GB', used: '275GB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'online',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 10,
|
|
||||||
unique_id: 'SRV-2024-0010',
|
|
||||||
name: '日志服务器-01',
|
|
||||||
type: '日志服务器',
|
|
||||||
os: 'CentOS Stream 9',
|
|
||||||
location: '数据中心B-2楼-机柜12-U1',
|
|
||||||
tags: '日志,ELK',
|
|
||||||
ip: '192.168.2.104',
|
|
||||||
remote_access: true,
|
|
||||||
agent_config: true,
|
|
||||||
cpu: '12核 Intel Xeon',
|
|
||||||
memory: '48GB',
|
|
||||||
disk: '2TB SSD',
|
|
||||||
cpu_info: { value: 0, total: '12核', used: '0核' },
|
|
||||||
memory_info: { value: 0, total: '48GB', used: '0GB' },
|
|
||||||
disk_info: { value: 0, total: '2TB', used: '0TB' },
|
|
||||||
data_collection: true,
|
|
||||||
status: 'offline',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
// 状态管理
|
// 状态管理
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const tableData = ref<any[]>([])
|
const tableData = ref<any[]>([])
|
||||||
@@ -419,9 +214,7 @@ const quickConfigVisible = ref(false)
|
|||||||
const currentRecord = ref<any>(null)
|
const currentRecord = ref<any>(null)
|
||||||
const formModel = ref({
|
const formModel = ref({
|
||||||
keyword: '',
|
keyword: '',
|
||||||
datacenter_id: undefined,
|
collect_on: undefined as boolean | undefined,
|
||||||
rack_id: undefined,
|
|
||||||
status: undefined,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const pagination = reactive({
|
const pagination = reactive({
|
||||||
@@ -430,69 +223,16 @@ const pagination = reactive({
|
|||||||
total: 0,
|
total: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
const datacenterSelectOptions = ref<{ label: string; value: number }[]>([])
|
// 表单项配置
|
||||||
const rackSelectOptions = ref<{ label: string; value: number }[]>([])
|
|
||||||
|
|
||||||
const loadDatacenterOptions = async () => {
|
|
||||||
try {
|
|
||||||
const res: any = await fetchDatacenterAll()
|
|
||||||
if (res.code === 0) {
|
|
||||||
const list = res.details?.data ?? res.data ?? res.details ?? []
|
|
||||||
const rows = Array.isArray(list) ? list : []
|
|
||||||
datacenterSelectOptions.value = rows.map((d: any) => ({
|
|
||||||
label: d.name || d.code || String(d.id),
|
|
||||||
value: d.id,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载数据中心列表失败:', error)
|
|
||||||
Message.error('加载数据中心列表失败')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadRackOptions = async (datacenterId: number) => {
|
|
||||||
try {
|
|
||||||
const res: any = await fetchRackListByDatacenter(datacenterId)
|
|
||||||
if (res.code === 0) {
|
|
||||||
const list = res.details?.data ?? res.data ?? res.details ?? []
|
|
||||||
const rows = Array.isArray(list) ? list : []
|
|
||||||
rackSelectOptions.value = rows.map((r: any) => ({
|
|
||||||
label: r.floor?.name ? `${r.name}(${r.floor.name})` : r.name || r.code || String(r.id),
|
|
||||||
value: r.id,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载机柜列表失败:', error)
|
|
||||||
Message.error('加载机柜列表失败')
|
|
||||||
rackSelectOptions.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => formModel.value.datacenter_id,
|
|
||||||
(newId, oldId) => {
|
|
||||||
if (newId !== oldId) {
|
|
||||||
formModel.value.rack_id = undefined
|
|
||||||
}
|
|
||||||
if (newId) {
|
|
||||||
loadRackOptions(newId)
|
|
||||||
} else {
|
|
||||||
rackSelectOptions.value = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 表单项配置(数据中心:GET /Assets/v1/datacenter/all;机柜:GET /Assets/v1/rack/datacenter/:id)
|
|
||||||
const formItems = computed<FormItem[]>(() =>
|
const formItems = computed<FormItem[]>(() =>
|
||||||
searchFormConfig.map((item) => {
|
searchFormConfig.map((item) => {
|
||||||
if (item.field === 'datacenter_id') {
|
if (item.field === 'collect_on') {
|
||||||
return { ...item, options: datacenterSelectOptions.value }
|
|
||||||
}
|
|
||||||
if (item.field === 'rack_id') {
|
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
options: rackSelectOptions.value,
|
options: [
|
||||||
disabled: !formModel.value.datacenter_id,
|
{ label: '是', value: true },
|
||||||
|
{ label: '否', value: false },
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
@@ -507,8 +247,7 @@ const getStatusColor = (status?: string) => {
|
|||||||
const colorMap: Record<string, string> = {
|
const colorMap: Record<string, string> = {
|
||||||
online: 'green',
|
online: 'green',
|
||||||
offline: 'red',
|
offline: 'red',
|
||||||
maintenance: 'orange',
|
unknown: 'gray',
|
||||||
retired: 'gray',
|
|
||||||
}
|
}
|
||||||
return colorMap[status || ''] || 'gray'
|
return colorMap[status || ''] || 'gray'
|
||||||
}
|
}
|
||||||
@@ -518,8 +257,7 @@ const getStatusText = (status?: string) => {
|
|||||||
const textMap: Record<string, string> = {
|
const textMap: Record<string, string> = {
|
||||||
online: '在线',
|
online: '在线',
|
||||||
offline: '离线',
|
offline: '离线',
|
||||||
maintenance: '维护中',
|
unknown: '未知',
|
||||||
retired: '已退役',
|
|
||||||
}
|
}
|
||||||
return textMap[status || ''] || '-'
|
return textMap[status || ''] || '-'
|
||||||
}
|
}
|
||||||
@@ -532,37 +270,37 @@ const getProgressColor = (value: number) => {
|
|||||||
return '#00B42A' // 绿色
|
return '#00B42A' // 绿色
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取服务器列表(使用 Mock 数据)
|
// 获取服务器列表
|
||||||
const fetchServers = async () => {
|
const fetchServers = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 模拟网络延迟
|
const params: any = {
|
||||||
await new Promise(resolve => setTimeout(resolve, 500))
|
page: pagination.current,
|
||||||
|
size: pagination.pageSize,
|
||||||
// 使用 Mock 数据
|
}
|
||||||
tableData.value = mockServerData
|
|
||||||
pagination.total = mockServerData.length
|
|
||||||
|
|
||||||
// 如果有搜索条件,进行过滤
|
|
||||||
if (formModel.value.keyword || formModel.value.status) {
|
|
||||||
let filteredData = [...mockServerData]
|
|
||||||
|
|
||||||
if (formModel.value.keyword) {
|
if (formModel.value.keyword) {
|
||||||
const keyword = formModel.value.keyword.toLowerCase()
|
params.keyword = formModel.value.keyword
|
||||||
filteredData = filteredData.filter(item =>
|
|
||||||
item.name.toLowerCase().includes(keyword) ||
|
|
||||||
item.unique_id.toLowerCase().includes(keyword) ||
|
|
||||||
item.ip.toLowerCase().includes(keyword)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formModel.value.status) {
|
if (formModel.value.collect_on !== undefined) {
|
||||||
filteredData = filteredData.filter(item => item.status === formModel.value.status)
|
params.collect_on = formModel.value.collect_on
|
||||||
}
|
}
|
||||||
|
|
||||||
tableData.value = filteredData
|
const res: any = await fetchServerList(params)
|
||||||
pagination.total = filteredData.length
|
|
||||||
|
if (res.code === 200 || res.code === 0) {
|
||||||
|
const responseData = res.data || res.details || {}
|
||||||
|
tableData.value = responseData.data || []
|
||||||
|
pagination.total = responseData.total || 0
|
||||||
|
|
||||||
|
// 列表加载成功后,获取监控指标
|
||||||
|
await getAllMetrics()
|
||||||
|
} else {
|
||||||
|
Message.error(res.message || '获取服务器列表失败')
|
||||||
|
tableData.value = []
|
||||||
|
pagination.total = 0
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取服务器列表失败:', error)
|
console.error('获取服务器列表失败:', error)
|
||||||
@@ -589,11 +327,8 @@ const handleFormModelUpdate = (value: any) => {
|
|||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
formModel.value = {
|
formModel.value = {
|
||||||
keyword: '',
|
keyword: '',
|
||||||
datacenter_id: undefined,
|
collect_on: undefined,
|
||||||
rack_id: undefined,
|
|
||||||
status: undefined,
|
|
||||||
}
|
}
|
||||||
rackSelectOptions.value = []
|
|
||||||
pagination.current = 1
|
pagination.current = 1
|
||||||
fetchServers()
|
fetchServers()
|
||||||
}
|
}
|
||||||
@@ -673,31 +408,100 @@ const handleRemoteControl = (record: any) => {
|
|||||||
|
|
||||||
// 删除服务器
|
// 删除服务器
|
||||||
const handleDelete = async (record: any) => {
|
const handleDelete = async (record: any) => {
|
||||||
try {
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '确认删除',
|
title: '确认删除',
|
||||||
content: `确认删除服务器 ${record.name} 吗?`,
|
content: `确认删除服务器 ${record.name} 吗?`,
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
// Mock 删除操作
|
try {
|
||||||
const index = mockServerData.findIndex(item => item.id === record.id)
|
const res: any = await deleteServer(record.id)
|
||||||
if (index > -1) {
|
if (res.code === 200 || res.code === 0) {
|
||||||
mockServerData.splice(index, 1)
|
|
||||||
Message.success('删除成功')
|
Message.success('删除成功')
|
||||||
fetchServers()
|
fetchServers()
|
||||||
} else {
|
} else {
|
||||||
|
Message.error(res.message || '删除失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除服务器失败:', error)
|
||||||
Message.error('删除失败')
|
Message.error('删除失败')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有服务器的监控指标
|
||||||
|
const getAllMetrics = async () => {
|
||||||
|
try {
|
||||||
|
// 遍历每个服务器记录
|
||||||
|
const metricsPromises = tableData.value.map(async (record) => {
|
||||||
|
// 检查是否有 agent_config 配置
|
||||||
|
if (record.agent_config) {
|
||||||
|
try {
|
||||||
|
// 从 agent_config 中解析 URL
|
||||||
|
let metricsUrl = record.agent_config
|
||||||
|
|
||||||
|
// 验证 URL 是否合法
|
||||||
|
try {
|
||||||
|
new URL(metricsUrl)
|
||||||
|
} catch (urlError) {
|
||||||
|
console.warn(`服务器 ${record.name} 的 agent_config 不是合法的 URL:`, metricsUrl)
|
||||||
|
// 设置默认值 0
|
||||||
|
record.cpu_info = { value: 0, total: '', used: '' }
|
||||||
|
record.memory_info = { value: 0, total: '', used: '' }
|
||||||
|
record.disk_info = { value: 0, total: '', used: '' }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送请求获取指标数据
|
||||||
|
const response = await axios.get(metricsUrl, {
|
||||||
|
timeout: 5000, // 5 秒超时
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.data) {
|
||||||
|
// 更新记录的监控数据
|
||||||
|
record.cpu_info = {
|
||||||
|
value: response.data.cpu_usage || 0,
|
||||||
|
total: response.data.cpu?.[0]?.cores ? `${response.data.cpu[0].cores}核` : '',
|
||||||
|
used: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
record.memory_info = {
|
||||||
|
value: response.data.mem_usage?.used_percent || 0,
|
||||||
|
total: response.data.mem_usage?.total ? `${(response.data.mem_usage.total / 1024 / 1024 / 1024).toFixed(1)}GB` : '',
|
||||||
|
used: response.data.mem_usage?.used ? `${(response.data.mem_usage.used / 1024 / 1024 / 1024).toFixed(1)}GB` : '',
|
||||||
|
}
|
||||||
|
|
||||||
|
record.disk_info = {
|
||||||
|
value: response.data.disk_usage?.used_percent || 0,
|
||||||
|
total: response.data.disk_usage?.total ? `${(response.data.disk_usage.total / 1024 / 1024 / 1024).toFixed(0)}GB` : '',
|
||||||
|
used: response.data.disk_usage?.used ? `${(response.data.disk_usage.used / 1024 / 1024 / 1024).toFixed(0)}GB` : '',
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('删除服务器失败:', error)
|
console.warn(`获取服务器 ${record.name} 的监控指标失败:`, error)
|
||||||
|
// 初始化默认值
|
||||||
|
record.cpu_info = { value: 0, total: '', used: '' }
|
||||||
|
record.memory_info = { value: 0, total: '', used: '' }
|
||||||
|
record.disk_info = { value: 0, total: '', used: '' }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 没有配置 agent,设置默认值
|
||||||
|
record.cpu_info = { value: 0, total: '', used: '' }
|
||||||
|
record.memory_info = { value: 0, total: '', used: '' }
|
||||||
|
record.disk_info = { value: 0, total: '', used: '' }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 等待所有请求完成
|
||||||
|
await Promise.all(metricsPromises)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取所有服务器监控指标失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadDatacenterOptions()
|
|
||||||
fetchServers()
|
fetchServers()
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
Reference in New Issue
Block a user