deving
This commit is contained in:
92
src/views/ops/pages/dc/database/config/columns.ts
Normal file
92
src/views/ops/pages/dc/database/config/columns.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
export const columns = [
|
||||||
|
{
|
||||||
|
dataIndex: 'id',
|
||||||
|
title: 'ID',
|
||||||
|
width: 80,
|
||||||
|
slotName: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'unique_id',
|
||||||
|
title: '唯一标识',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
title: '名称',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'os',
|
||||||
|
title: '操作系统',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'location',
|
||||||
|
title: '位置信息',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'tags',
|
||||||
|
title: '标签',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'ip',
|
||||||
|
title: 'IP地址',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'remote_access',
|
||||||
|
title: '远程访问',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'remote_access',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'agent_config',
|
||||||
|
title: 'Agent配置',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'agent_config',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'cpu',
|
||||||
|
title: 'CPU使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'cpu',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'memory',
|
||||||
|
title: '内存使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'memory',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'disk',
|
||||||
|
title: '硬盘使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'disk',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'data_collection',
|
||||||
|
title: '数据采集',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'data_collection',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'status',
|
||||||
|
title: '状态',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'actions',
|
||||||
|
title: '操作',
|
||||||
|
width: 180,
|
||||||
|
fixed: 'right' as const,
|
||||||
|
slotName: 'actions',
|
||||||
|
},
|
||||||
|
]
|
||||||
40
src/views/ops/pages/dc/database/config/search-form.ts
Normal file
40
src/views/ops/pages/dc/database/config/search-form.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { FormItem } from '@/components/search-form/types'
|
||||||
|
|
||||||
|
export const searchFormConfig: FormItem[] = [
|
||||||
|
{
|
||||||
|
field: 'keyword',
|
||||||
|
label: '关键词',
|
||||||
|
type: 'input',
|
||||||
|
placeholder: '请输入服务器名称、编码或IP',
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'datacenter_id',
|
||||||
|
label: '数据中心',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择数据中心',
|
||||||
|
options: [], // 需要动态加载
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'rack_id',
|
||||||
|
label: '机柜',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择机柜',
|
||||||
|
options: [], // 需要动态加载
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择状态',
|
||||||
|
options: [
|
||||||
|
{ label: '在线', value: 'online' },
|
||||||
|
{ label: '离线', value: 'offline' },
|
||||||
|
{ label: '维护中', value: 'maintenance' },
|
||||||
|
{ label: '已退役', value: 'retired' },
|
||||||
|
],
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
]
|
||||||
676
src/views/ops/pages/dc/database/index.vue
Normal file
676
src/views/ops/pages/dc/database/index.vue
Normal file
@@ -0,0 +1,676 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<search-table
|
||||||
|
:form-model="formModel"
|
||||||
|
:form-items="formItems"
|
||||||
|
:data="tableData"
|
||||||
|
:columns="columns"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination"
|
||||||
|
title="数据库管理"
|
||||||
|
search-button-text="查询"
|
||||||
|
reset-button-text="重置"
|
||||||
|
@update:form-model="handleFormModelUpdate"
|
||||||
|
@search="handleSearch"
|
||||||
|
@reset="handleReset"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
@refresh="handleRefresh"
|
||||||
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<a-button type="primary" @click="handleAdd">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus />
|
||||||
|
</template>
|
||||||
|
新增数据库
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- ID -->
|
||||||
|
<template #id="{ record }">
|
||||||
|
{{ record.id }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 远程访问 -->
|
||||||
|
<template #remote_access="{ record }">
|
||||||
|
<a-tag :color="record.remote_access ? 'green' : 'gray'">
|
||||||
|
{{ record.remote_access ? '已开启' : '未开启' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Agent配置 -->
|
||||||
|
<template #agent_config="{ record }">
|
||||||
|
<a-tag :color="record.agent_config ? 'green' : 'gray'">
|
||||||
|
{{ record.agent_config ? '已配置' : '未配置' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- CPU -->
|
||||||
|
<template #cpu="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-label">CPU</span>
|
||||||
|
<span class="resource-value">{{ record.cpu_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.cpu_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.cpu_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 内存 -->
|
||||||
|
<template #memory="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-laebl">内存</span>
|
||||||
|
<span class="resource-value">{{ record.memory_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.memory_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.memory_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 硬盘 -->
|
||||||
|
<template #disk="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-label">硬盘</span>
|
||||||
|
<span class="resource-value">{{ record.disk_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.disk_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.disk_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 数据采集 -->
|
||||||
|
<template #data_collection="{ record }">
|
||||||
|
<a-tag :color="record.data_collection ? 'green' : 'gray'">
|
||||||
|
{{ record.data_collection ? '已启用' : '未启用' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 状态 -->
|
||||||
|
<template #status="{ record }">
|
||||||
|
<a-tag :color="getStatusColor(record.status)">
|
||||||
|
{{ getStatusText(record.status) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 操作栏 - 下拉菜单 -->
|
||||||
|
<template #actions="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
v-if="!record.agent_config"
|
||||||
|
type="outline"
|
||||||
|
size="small"
|
||||||
|
@click="handleQuickConfig(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon-settings />
|
||||||
|
</template>
|
||||||
|
快捷配置
|
||||||
|
</a-button>
|
||||||
|
<a-dropdown trigger="hover">
|
||||||
|
<a-button type="primary" size="small">
|
||||||
|
管理
|
||||||
|
<icon-down />
|
||||||
|
</a-button>
|
||||||
|
<template #content>
|
||||||
|
<a-doption @click="handleRestart(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-refresh />
|
||||||
|
</template>
|
||||||
|
重启
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleDetail(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-eye />
|
||||||
|
</template>
|
||||||
|
详情
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleEdit(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-edit />
|
||||||
|
</template>
|
||||||
|
编辑
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleRemoteControl(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-desktop />
|
||||||
|
</template>
|
||||||
|
远程控制
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleDelete(record)" style="color: rgb(var(--danger-6))">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
|
删除
|
||||||
|
</a-doption>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</search-table>
|
||||||
|
|
||||||
|
<!-- 新增/编辑对话框 -->
|
||||||
|
<ServerFormDialog
|
||||||
|
v-model:visible="formDialogVisible"
|
||||||
|
:record="currentRecord"
|
||||||
|
@success="handleFormSuccess"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 快捷配置对话框 -->
|
||||||
|
<QuickConfigDialog
|
||||||
|
v-model:visible="quickConfigVisible"
|
||||||
|
:record="currentRecord"
|
||||||
|
@success="handleFormSuccess"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, computed } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { Message, Modal } from '@arco-design/web-vue'
|
||||||
|
import {
|
||||||
|
IconPlus,
|
||||||
|
IconDown,
|
||||||
|
IconEdit,
|
||||||
|
IconDesktop,
|
||||||
|
IconDelete,
|
||||||
|
IconRefresh,
|
||||||
|
IconEye,
|
||||||
|
IconSettings
|
||||||
|
} from '@arco-design/web-vue/es/icon'
|
||||||
|
import type { FormItem } from '@/components/search-form/types'
|
||||||
|
import SearchTable from '@/components/search-table/index.vue'
|
||||||
|
import { searchFormConfig } from './config/search-form'
|
||||||
|
import ServerFormDialog from '../pc/components/ServerFormDialog.vue'
|
||||||
|
import QuickConfigDialog from '../pc/components/QuickConfigDialog.vue'
|
||||||
|
import { columns as columnsConfig } from './config/columns'
|
||||||
|
import {
|
||||||
|
fetchServerList,
|
||||||
|
deleteServer,
|
||||||
|
} from '@/api/ops/server'
|
||||||
|
|
||||||
|
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 tableData = ref<any[]>([])
|
||||||
|
const formDialogVisible = ref(false)
|
||||||
|
const quickConfigVisible = ref(false)
|
||||||
|
const currentRecord = ref<any>(null)
|
||||||
|
const formModel = ref({
|
||||||
|
keyword: '',
|
||||||
|
datacenter_id: undefined,
|
||||||
|
rack_id: undefined,
|
||||||
|
status: undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单项配置
|
||||||
|
const formItems = computed<FormItem[]>(() => searchFormConfig)
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = computed(() => columnsConfig)
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
online: 'green',
|
||||||
|
offline: 'red',
|
||||||
|
maintenance: 'orange',
|
||||||
|
retired: 'gray',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'gray'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
online: '在线',
|
||||||
|
offline: '离线',
|
||||||
|
maintenance: '维护中',
|
||||||
|
retired: '已退役',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取进度条颜色
|
||||||
|
const getProgressColor = (value: number) => {
|
||||||
|
if (value >= 90) return '#F53F3F' // 红色
|
||||||
|
if (value >= 70) return '#FF7D00' // 橙色
|
||||||
|
if (value >= 50) return '#FFD00B' // 黄色
|
||||||
|
return '#00B42A' // 绿色
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据库列表(使用 Mock 数据)
|
||||||
|
const fetchServers = async () => {
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 模拟网络延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
// 使用 Mock 数据
|
||||||
|
tableData.value = mockServerData
|
||||||
|
pagination.total = mockServerData.length
|
||||||
|
|
||||||
|
// 如果有搜索条件,进行过滤
|
||||||
|
if (formModel.value.keyword || formModel.value.status) {
|
||||||
|
let filteredData = [...mockServerData]
|
||||||
|
|
||||||
|
if (formModel.value.keyword) {
|
||||||
|
const keyword = formModel.value.keyword.toLowerCase()
|
||||||
|
filteredData = filteredData.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(keyword) ||
|
||||||
|
item.unique_id.toLowerCase().includes(keyword) ||
|
||||||
|
item.ip.toLowerCase().includes(keyword)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formModel.value.status) {
|
||||||
|
filteredData = filteredData.filter(item => item.status === formModel.value.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
tableData.value = filteredData
|
||||||
|
pagination.total = filteredData.length
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取数据库列表失败:', error)
|
||||||
|
Message.error('获取数据库列表失败')
|
||||||
|
tableData.value = []
|
||||||
|
pagination.total = 0
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const handleSearch = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理表单模型更新
|
||||||
|
const handleFormModelUpdate = (value: any) => {
|
||||||
|
formModel.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const handleReset = () => {
|
||||||
|
formModel.value = {
|
||||||
|
keyword: '',
|
||||||
|
datacenter_id: undefined,
|
||||||
|
rack_id: undefined,
|
||||||
|
status: undefined,
|
||||||
|
}
|
||||||
|
pagination.current = 1
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页变化
|
||||||
|
const handlePageChange = (current: number) => {
|
||||||
|
pagination.current = current
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
const handleRefresh = () => {
|
||||||
|
fetchServers()
|
||||||
|
Message.success('数据已刷新')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增数据库
|
||||||
|
const handleAdd = () => {
|
||||||
|
currentRecord.value = null
|
||||||
|
formDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快捷配置
|
||||||
|
const handleQuickConfig = (record: any) => {
|
||||||
|
currentRecord.value = record
|
||||||
|
quickConfigVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑数据库
|
||||||
|
const handleEdit = (record: any) => {
|
||||||
|
currentRecord.value = record
|
||||||
|
formDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单提交成功
|
||||||
|
const handleFormSuccess = () => {
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重启数据库
|
||||||
|
const handleRestart = (record: any) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认重启',
|
||||||
|
content: `确认重启数据库 ${record.name} 吗?`,
|
||||||
|
onOk: () => {
|
||||||
|
Message.info('正在发送重启指令...')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情 - 在当前窗口打开
|
||||||
|
const handleDetail = (record: any) => {
|
||||||
|
router.push({
|
||||||
|
path: '/dc/detail',
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
ip: record.ip,
|
||||||
|
status: record.status,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 远程控制 - 在新窗口打开
|
||||||
|
const handleRemoteControl = (record: any) => {
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/dc/remote',
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
ip: record.ip,
|
||||||
|
status: record.status,
|
||||||
|
},
|
||||||
|
}).href
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除数据库
|
||||||
|
const handleDelete = async (record: any) => {
|
||||||
|
try {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: `确认删除数据库 ${record.name} 吗?`,
|
||||||
|
onOk: async () => {
|
||||||
|
// Mock 删除操作
|
||||||
|
const index = mockServerData.findIndex(item => item.id === record.id)
|
||||||
|
if (index > -1) {
|
||||||
|
mockServerData.splice(index, 1)
|
||||||
|
Message.success('删除成功')
|
||||||
|
fetchServers()
|
||||||
|
} else {
|
||||||
|
Message.error('删除失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除数据库失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化加载数据
|
||||||
|
fetchServers()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DataCenterServer',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource-display {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 4px 0;
|
||||||
|
|
||||||
|
.resource-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
> div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.resource-value {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: rgb(var(--text-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-progress) {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.arco-progress-bar-bg {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-progress-bar {
|
||||||
|
border-radius: 2px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
92
src/views/ops/pages/dc/middleware/config/columns.ts
Normal file
92
src/views/ops/pages/dc/middleware/config/columns.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
export const columns = [
|
||||||
|
{
|
||||||
|
dataIndex: 'id',
|
||||||
|
title: 'ID',
|
||||||
|
width: 80,
|
||||||
|
slotName: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'unique_id',
|
||||||
|
title: '唯一标识',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
title: '名称',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'os',
|
||||||
|
title: '操作系统',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'location',
|
||||||
|
title: '位置信息',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'tags',
|
||||||
|
title: '标签',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'ip',
|
||||||
|
title: 'IP地址',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'remote_access',
|
||||||
|
title: '远程访问',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'remote_access',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'agent_config',
|
||||||
|
title: 'Agent配置',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'agent_config',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'cpu',
|
||||||
|
title: 'CPU使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'cpu',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'memory',
|
||||||
|
title: '内存使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'memory',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'disk',
|
||||||
|
title: '硬盘使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'disk',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'data_collection',
|
||||||
|
title: '数据采集',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'data_collection',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'status',
|
||||||
|
title: '状态',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'actions',
|
||||||
|
title: '操作',
|
||||||
|
width: 180,
|
||||||
|
fixed: 'right' as const,
|
||||||
|
slotName: 'actions',
|
||||||
|
},
|
||||||
|
]
|
||||||
40
src/views/ops/pages/dc/middleware/config/search-form.ts
Normal file
40
src/views/ops/pages/dc/middleware/config/search-form.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { FormItem } from '@/components/search-form/types'
|
||||||
|
|
||||||
|
export const searchFormConfig: FormItem[] = [
|
||||||
|
{
|
||||||
|
field: 'keyword',
|
||||||
|
label: '关键词',
|
||||||
|
type: 'input',
|
||||||
|
placeholder: '请输入服务器名称、编码或IP',
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'datacenter_id',
|
||||||
|
label: '数据中心',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择数据中心',
|
||||||
|
options: [], // 需要动态加载
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'rack_id',
|
||||||
|
label: '机柜',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择机柜',
|
||||||
|
options: [], // 需要动态加载
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择状态',
|
||||||
|
options: [
|
||||||
|
{ label: '在线', value: 'online' },
|
||||||
|
{ label: '离线', value: 'offline' },
|
||||||
|
{ label: '维护中', value: 'maintenance' },
|
||||||
|
{ label: '已退役', value: 'retired' },
|
||||||
|
],
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
]
|
||||||
676
src/views/ops/pages/dc/middleware/index.vue
Normal file
676
src/views/ops/pages/dc/middleware/index.vue
Normal file
@@ -0,0 +1,676 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<search-table
|
||||||
|
:form-model="formModel"
|
||||||
|
:form-items="formItems"
|
||||||
|
:data="tableData"
|
||||||
|
:columns="columns"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination"
|
||||||
|
title="中间件管理"
|
||||||
|
search-button-text="查询"
|
||||||
|
reset-button-text="重置"
|
||||||
|
@update:form-model="handleFormModelUpdate"
|
||||||
|
@search="handleSearch"
|
||||||
|
@reset="handleReset"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
@refresh="handleRefresh"
|
||||||
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<a-button type="primary" @click="handleAdd">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus />
|
||||||
|
</template>
|
||||||
|
新增中间件
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- ID -->
|
||||||
|
<template #id="{ record }">
|
||||||
|
{{ record.id }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 远程访问 -->
|
||||||
|
<template #remote_access="{ record }">
|
||||||
|
<a-tag :color="record.remote_access ? 'green' : 'gray'">
|
||||||
|
{{ record.remote_access ? '已开启' : '未开启' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Agent配置 -->
|
||||||
|
<template #agent_config="{ record }">
|
||||||
|
<a-tag :color="record.agent_config ? 'green' : 'gray'">
|
||||||
|
{{ record.agent_config ? '已配置' : '未配置' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- CPU -->
|
||||||
|
<template #cpu="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-label">CPU</span>
|
||||||
|
<span class="resource-value">{{ record.cpu_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.cpu_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.cpu_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 内存 -->
|
||||||
|
<template #memory="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-laebl">内存</span>
|
||||||
|
<span class="resource-value">{{ record.memory_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.memory_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.memory_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 硬盘 -->
|
||||||
|
<template #disk="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-label">硬盘</span>
|
||||||
|
<span class="resource-value">{{ record.disk_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.disk_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.disk_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 数据采集 -->
|
||||||
|
<template #data_collection="{ record }">
|
||||||
|
<a-tag :color="record.data_collection ? 'green' : 'gray'">
|
||||||
|
{{ record.data_collection ? '已启用' : '未启用' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 状态 -->
|
||||||
|
<template #status="{ record }">
|
||||||
|
<a-tag :color="getStatusColor(record.status)">
|
||||||
|
{{ getStatusText(record.status) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 操作栏 - 下拉菜单 -->
|
||||||
|
<template #actions="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
v-if="!record.agent_config"
|
||||||
|
type="outline"
|
||||||
|
size="small"
|
||||||
|
@click="handleQuickConfig(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon-settings />
|
||||||
|
</template>
|
||||||
|
快捷配置
|
||||||
|
</a-button>
|
||||||
|
<a-dropdown trigger="hover">
|
||||||
|
<a-button type="primary" size="small">
|
||||||
|
管理
|
||||||
|
<icon-down />
|
||||||
|
</a-button>
|
||||||
|
<template #content>
|
||||||
|
<a-doption @click="handleRestart(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-refresh />
|
||||||
|
</template>
|
||||||
|
重启
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleDetail(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-eye />
|
||||||
|
</template>
|
||||||
|
详情
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleEdit(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-edit />
|
||||||
|
</template>
|
||||||
|
编辑
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleRemoteControl(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-desktop />
|
||||||
|
</template>
|
||||||
|
远程控制
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleDelete(record)" style="color: rgb(var(--danger-6))">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
|
删除
|
||||||
|
</a-doption>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</search-table>
|
||||||
|
|
||||||
|
<!-- 新增/编辑对话框 -->
|
||||||
|
<ServerFormDialog
|
||||||
|
v-model:visible="formDialogVisible"
|
||||||
|
:record="currentRecord"
|
||||||
|
@success="handleFormSuccess"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 快捷配置对话框 -->
|
||||||
|
<QuickConfigDialog
|
||||||
|
v-model:visible="quickConfigVisible"
|
||||||
|
:record="currentRecord"
|
||||||
|
@success="handleFormSuccess"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, computed } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { Message, Modal } from '@arco-design/web-vue'
|
||||||
|
import {
|
||||||
|
IconPlus,
|
||||||
|
IconDown,
|
||||||
|
IconEdit,
|
||||||
|
IconDesktop,
|
||||||
|
IconDelete,
|
||||||
|
IconRefresh,
|
||||||
|
IconEye,
|
||||||
|
IconSettings
|
||||||
|
} from '@arco-design/web-vue/es/icon'
|
||||||
|
import type { FormItem } from '@/components/search-form/types'
|
||||||
|
import SearchTable from '@/components/search-table/index.vue'
|
||||||
|
import { searchFormConfig } from './config/search-form'
|
||||||
|
import ServerFormDialog from '../pc/components/ServerFormDialog.vue'
|
||||||
|
import QuickConfigDialog from '../pc/components/QuickConfigDialog.vue'
|
||||||
|
import { columns as columnsConfig } from './config/columns'
|
||||||
|
import {
|
||||||
|
fetchServerList,
|
||||||
|
deleteServer,
|
||||||
|
} from '@/api/ops/server'
|
||||||
|
|
||||||
|
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 tableData = ref<any[]>([])
|
||||||
|
const formDialogVisible = ref(false)
|
||||||
|
const quickConfigVisible = ref(false)
|
||||||
|
const currentRecord = ref<any>(null)
|
||||||
|
const formModel = ref({
|
||||||
|
keyword: '',
|
||||||
|
datacenter_id: undefined,
|
||||||
|
rack_id: undefined,
|
||||||
|
status: undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单项配置
|
||||||
|
const formItems = computed<FormItem[]>(() => searchFormConfig)
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = computed(() => columnsConfig)
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
online: 'green',
|
||||||
|
offline: 'red',
|
||||||
|
maintenance: 'orange',
|
||||||
|
retired: 'gray',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'gray'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
online: '在线',
|
||||||
|
offline: '离线',
|
||||||
|
maintenance: '维护中',
|
||||||
|
retired: '已退役',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取进度条颜色
|
||||||
|
const getProgressColor = (value: number) => {
|
||||||
|
if (value >= 90) return '#F53F3F' // 红色
|
||||||
|
if (value >= 70) return '#FF7D00' // 橙色
|
||||||
|
if (value >= 50) return '#FFD00B' // 黄色
|
||||||
|
return '#00B42A' // 绿色
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取中间件列表(使用 Mock 数据)
|
||||||
|
const fetchServers = async () => {
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 模拟网络延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
// 使用 Mock 数据
|
||||||
|
tableData.value = mockServerData
|
||||||
|
pagination.total = mockServerData.length
|
||||||
|
|
||||||
|
// 如果有搜索条件,进行过滤
|
||||||
|
if (formModel.value.keyword || formModel.value.status) {
|
||||||
|
let filteredData = [...mockServerData]
|
||||||
|
|
||||||
|
if (formModel.value.keyword) {
|
||||||
|
const keyword = formModel.value.keyword.toLowerCase()
|
||||||
|
filteredData = filteredData.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(keyword) ||
|
||||||
|
item.unique_id.toLowerCase().includes(keyword) ||
|
||||||
|
item.ip.toLowerCase().includes(keyword)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formModel.value.status) {
|
||||||
|
filteredData = filteredData.filter(item => item.status === formModel.value.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
tableData.value = filteredData
|
||||||
|
pagination.total = filteredData.length
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取中间件列表失败:', error)
|
||||||
|
Message.error('获取中间件列表失败')
|
||||||
|
tableData.value = []
|
||||||
|
pagination.total = 0
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const handleSearch = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理表单模型更新
|
||||||
|
const handleFormModelUpdate = (value: any) => {
|
||||||
|
formModel.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const handleReset = () => {
|
||||||
|
formModel.value = {
|
||||||
|
keyword: '',
|
||||||
|
datacenter_id: undefined,
|
||||||
|
rack_id: undefined,
|
||||||
|
status: undefined,
|
||||||
|
}
|
||||||
|
pagination.current = 1
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页变化
|
||||||
|
const handlePageChange = (current: number) => {
|
||||||
|
pagination.current = current
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
const handleRefresh = () => {
|
||||||
|
fetchServers()
|
||||||
|
Message.success('数据已刷新')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增中间件
|
||||||
|
const handleAdd = () => {
|
||||||
|
currentRecord.value = null
|
||||||
|
formDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快捷配置
|
||||||
|
const handleQuickConfig = (record: any) => {
|
||||||
|
currentRecord.value = record
|
||||||
|
quickConfigVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑中间件
|
||||||
|
const handleEdit = (record: any) => {
|
||||||
|
currentRecord.value = record
|
||||||
|
formDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单提交成功
|
||||||
|
const handleFormSuccess = () => {
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重启中间件
|
||||||
|
const handleRestart = (record: any) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认重启',
|
||||||
|
content: `确认重启中间件 ${record.name} 吗?`,
|
||||||
|
onOk: () => {
|
||||||
|
Message.info('正在发送重启指令...')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情 - 在当前窗口打开
|
||||||
|
const handleDetail = (record: any) => {
|
||||||
|
router.push({
|
||||||
|
path: '/dc/detail',
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
ip: record.ip,
|
||||||
|
status: record.status,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 远程控制 - 在新窗口打开
|
||||||
|
const handleRemoteControl = (record: any) => {
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/dc/remote',
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
ip: record.ip,
|
||||||
|
status: record.status,
|
||||||
|
},
|
||||||
|
}).href
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除中间件
|
||||||
|
const handleDelete = async (record: any) => {
|
||||||
|
try {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: `确认删除中间件 ${record.name} 吗?`,
|
||||||
|
onOk: async () => {
|
||||||
|
// Mock 删除操作
|
||||||
|
const index = mockServerData.findIndex(item => item.id === record.id)
|
||||||
|
if (index > -1) {
|
||||||
|
mockServerData.splice(index, 1)
|
||||||
|
Message.success('删除成功')
|
||||||
|
fetchServers()
|
||||||
|
} else {
|
||||||
|
Message.error('删除失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除中间件失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化加载数据
|
||||||
|
fetchServers()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DataCenterServer',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource-display {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 4px 0;
|
||||||
|
|
||||||
|
.resource-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
> div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.resource-value {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: rgb(var(--text-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-progress) {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.arco-progress-bar-bg {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-progress-bar {
|
||||||
|
border-radius: 2px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
92
src/views/ops/pages/dc/network/config/columns.ts
Normal file
92
src/views/ops/pages/dc/network/config/columns.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
export const columns = [
|
||||||
|
{
|
||||||
|
dataIndex: 'id',
|
||||||
|
title: 'ID',
|
||||||
|
width: 80,
|
||||||
|
slotName: 'id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'unique_id',
|
||||||
|
title: '唯一标识',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'name',
|
||||||
|
title: '名称',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'os',
|
||||||
|
title: '操作系统',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'location',
|
||||||
|
title: '位置信息',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'tags',
|
||||||
|
title: '标签',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'ip',
|
||||||
|
title: 'IP地址',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'remote_access',
|
||||||
|
title: '远程访问',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'remote_access',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'agent_config',
|
||||||
|
title: 'Agent配置',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'agent_config',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'cpu',
|
||||||
|
title: 'CPU使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'cpu',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'memory',
|
||||||
|
title: '内存使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'memory',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'disk',
|
||||||
|
title: '硬盘使用率',
|
||||||
|
width: 150,
|
||||||
|
slotName: 'disk',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'data_collection',
|
||||||
|
title: '数据采集',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'data_collection',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'status',
|
||||||
|
title: '状态',
|
||||||
|
width: 100,
|
||||||
|
slotName: 'status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'actions',
|
||||||
|
title: '操作',
|
||||||
|
width: 180,
|
||||||
|
fixed: 'right' as const,
|
||||||
|
slotName: 'actions',
|
||||||
|
},
|
||||||
|
]
|
||||||
40
src/views/ops/pages/dc/network/config/search-form.ts
Normal file
40
src/views/ops/pages/dc/network/config/search-form.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import type { FormItem } from '@/components/search-form/types'
|
||||||
|
|
||||||
|
export const searchFormConfig: FormItem[] = [
|
||||||
|
{
|
||||||
|
field: 'keyword',
|
||||||
|
label: '关键词',
|
||||||
|
type: 'input',
|
||||||
|
placeholder: '请输入服务器名称、编码或IP',
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'datacenter_id',
|
||||||
|
label: '数据中心',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择数据中心',
|
||||||
|
options: [], // 需要动态加载
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'rack_id',
|
||||||
|
label: '机柜',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择机柜',
|
||||||
|
options: [], // 需要动态加载
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: '状态',
|
||||||
|
type: 'select',
|
||||||
|
placeholder: '请选择状态',
|
||||||
|
options: [
|
||||||
|
{ label: '在线', value: 'online' },
|
||||||
|
{ label: '离线', value: 'offline' },
|
||||||
|
{ label: '维护中', value: 'maintenance' },
|
||||||
|
{ label: '已退役', value: 'retired' },
|
||||||
|
],
|
||||||
|
span: 6,
|
||||||
|
},
|
||||||
|
]
|
||||||
676
src/views/ops/pages/dc/network/index.vue
Normal file
676
src/views/ops/pages/dc/network/index.vue
Normal file
@@ -0,0 +1,676 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<search-table
|
||||||
|
:form-model="formModel"
|
||||||
|
:form-items="formItems"
|
||||||
|
:data="tableData"
|
||||||
|
:columns="columns"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination"
|
||||||
|
title="网络设备管理"
|
||||||
|
search-button-text="查询"
|
||||||
|
reset-button-text="重置"
|
||||||
|
@update:form-model="handleFormModelUpdate"
|
||||||
|
@search="handleSearch"
|
||||||
|
@reset="handleReset"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
@refresh="handleRefresh"
|
||||||
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<a-button type="primary" @click="handleAdd">
|
||||||
|
<template #icon>
|
||||||
|
<icon-plus />
|
||||||
|
</template>
|
||||||
|
新增网络设备
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- ID -->
|
||||||
|
<template #id="{ record }">
|
||||||
|
{{ record.id }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 远程访问 -->
|
||||||
|
<template #remote_access="{ record }">
|
||||||
|
<a-tag :color="record.remote_access ? 'green' : 'gray'">
|
||||||
|
{{ record.remote_access ? '已开启' : '未开启' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Agent配置 -->
|
||||||
|
<template #agent_config="{ record }">
|
||||||
|
<a-tag :color="record.agent_config ? 'green' : 'gray'">
|
||||||
|
{{ record.agent_config ? '已配置' : '未配置' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- CPU -->
|
||||||
|
<template #cpu="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-label">CPU</span>
|
||||||
|
<span class="resource-value">{{ record.cpu_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.cpu_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.cpu_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 内存 -->
|
||||||
|
<template #memory="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-laebl">内存</span>
|
||||||
|
<span class="resource-value">{{ record.memory_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.memory_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.memory_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 硬盘 -->
|
||||||
|
<template #disk="{ record }">
|
||||||
|
<div class="resource-display">
|
||||||
|
<div class="resource-info">
|
||||||
|
<span class="resource-label">硬盘</span>
|
||||||
|
<span class="resource-value">{{ record.disk_info?.value || 0 }}%</span>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
:percent="(record.disk_info?.value || 0) / 100"
|
||||||
|
:color="getProgressColor(record.disk_info?.value || 0)"
|
||||||
|
size="small"
|
||||||
|
:show-text="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 数据采集 -->
|
||||||
|
<template #data_collection="{ record }">
|
||||||
|
<a-tag :color="record.data_collection ? 'green' : 'gray'">
|
||||||
|
{{ record.data_collection ? '已启用' : '未启用' }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 状态 -->
|
||||||
|
<template #status="{ record }">
|
||||||
|
<a-tag :color="getStatusColor(record.status)">
|
||||||
|
{{ getStatusText(record.status) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 操作栏 - 下拉菜单 -->
|
||||||
|
<template #actions="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button
|
||||||
|
v-if="!record.agent_config"
|
||||||
|
type="outline"
|
||||||
|
size="small"
|
||||||
|
@click="handleQuickConfig(record)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon-settings />
|
||||||
|
</template>
|
||||||
|
快捷配置
|
||||||
|
</a-button>
|
||||||
|
<a-dropdown trigger="hover">
|
||||||
|
<a-button type="primary" size="small">
|
||||||
|
管理
|
||||||
|
<icon-down />
|
||||||
|
</a-button>
|
||||||
|
<template #content>
|
||||||
|
<a-doption @click="handleRestart(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-refresh />
|
||||||
|
</template>
|
||||||
|
重启
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleDetail(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-eye />
|
||||||
|
</template>
|
||||||
|
详情
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleEdit(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-edit />
|
||||||
|
</template>
|
||||||
|
编辑
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleRemoteControl(record)">
|
||||||
|
<template #icon>
|
||||||
|
<icon-desktop />
|
||||||
|
</template>
|
||||||
|
远程控制
|
||||||
|
</a-doption>
|
||||||
|
<a-doption @click="handleDelete(record)" style="color: rgb(var(--danger-6))">
|
||||||
|
<template #icon>
|
||||||
|
<icon-delete />
|
||||||
|
</template>
|
||||||
|
删除
|
||||||
|
</a-doption>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</search-table>
|
||||||
|
|
||||||
|
<!-- 新增/编辑对话框 -->
|
||||||
|
<ServerFormDialog
|
||||||
|
v-model:visible="formDialogVisible"
|
||||||
|
:record="currentRecord"
|
||||||
|
@success="handleFormSuccess"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 快捷配置对话框 -->
|
||||||
|
<QuickConfigDialog
|
||||||
|
v-model:visible="quickConfigVisible"
|
||||||
|
:record="currentRecord"
|
||||||
|
@success="handleFormSuccess"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, computed } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { Message, Modal } from '@arco-design/web-vue'
|
||||||
|
import {
|
||||||
|
IconPlus,
|
||||||
|
IconDown,
|
||||||
|
IconEdit,
|
||||||
|
IconDesktop,
|
||||||
|
IconDelete,
|
||||||
|
IconRefresh,
|
||||||
|
IconEye,
|
||||||
|
IconSettings
|
||||||
|
} from '@arco-design/web-vue/es/icon'
|
||||||
|
import type { FormItem } from '@/components/search-form/types'
|
||||||
|
import SearchTable from '@/components/search-table/index.vue'
|
||||||
|
import { searchFormConfig } from './config/search-form'
|
||||||
|
import ServerFormDialog from '../pc/components/ServerFormDialog.vue'
|
||||||
|
import QuickConfigDialog from '../pc/components/QuickConfigDialog.vue'
|
||||||
|
import { columns as columnsConfig } from './config/columns'
|
||||||
|
import {
|
||||||
|
fetchServerList,
|
||||||
|
deleteServer,
|
||||||
|
} from '@/api/ops/server'
|
||||||
|
|
||||||
|
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 tableData = ref<any[]>([])
|
||||||
|
const formDialogVisible = ref(false)
|
||||||
|
const quickConfigVisible = ref(false)
|
||||||
|
const currentRecord = ref<any>(null)
|
||||||
|
const formModel = ref({
|
||||||
|
keyword: '',
|
||||||
|
datacenter_id: undefined,
|
||||||
|
rack_id: undefined,
|
||||||
|
status: undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单项配置
|
||||||
|
const formItems = computed<FormItem[]>(() => searchFormConfig)
|
||||||
|
|
||||||
|
// 表格列配置
|
||||||
|
const columns = computed(() => columnsConfig)
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
online: 'green',
|
||||||
|
offline: 'red',
|
||||||
|
maintenance: 'orange',
|
||||||
|
retired: 'gray',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'gray'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
online: '在线',
|
||||||
|
offline: '离线',
|
||||||
|
maintenance: '维护中',
|
||||||
|
retired: '已退役',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取进度条颜色
|
||||||
|
const getProgressColor = (value: number) => {
|
||||||
|
if (value >= 90) return '#F53F3F' // 红色
|
||||||
|
if (value >= 70) return '#FF7D00' // 橙色
|
||||||
|
if (value >= 50) return '#FFD00B' // 黄色
|
||||||
|
return '#00B42A' // 绿色
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取网络设备列表(使用 Mock 数据)
|
||||||
|
const fetchServers = async () => {
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 模拟网络延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
// 使用 Mock 数据
|
||||||
|
tableData.value = mockServerData
|
||||||
|
pagination.total = mockServerData.length
|
||||||
|
|
||||||
|
// 如果有搜索条件,进行过滤
|
||||||
|
if (formModel.value.keyword || formModel.value.status) {
|
||||||
|
let filteredData = [...mockServerData]
|
||||||
|
|
||||||
|
if (formModel.value.keyword) {
|
||||||
|
const keyword = formModel.value.keyword.toLowerCase()
|
||||||
|
filteredData = filteredData.filter(item =>
|
||||||
|
item.name.toLowerCase().includes(keyword) ||
|
||||||
|
item.unique_id.toLowerCase().includes(keyword) ||
|
||||||
|
item.ip.toLowerCase().includes(keyword)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formModel.value.status) {
|
||||||
|
filteredData = filteredData.filter(item => item.status === formModel.value.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
tableData.value = filteredData
|
||||||
|
pagination.total = filteredData.length
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取网络设备列表失败:', error)
|
||||||
|
Message.error('获取网络设备列表失败')
|
||||||
|
tableData.value = []
|
||||||
|
pagination.total = 0
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const handleSearch = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理表单模型更新
|
||||||
|
const handleFormModelUpdate = (value: any) => {
|
||||||
|
formModel.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const handleReset = () => {
|
||||||
|
formModel.value = {
|
||||||
|
keyword: '',
|
||||||
|
datacenter_id: undefined,
|
||||||
|
rack_id: undefined,
|
||||||
|
status: undefined,
|
||||||
|
}
|
||||||
|
pagination.current = 1
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页变化
|
||||||
|
const handlePageChange = (current: number) => {
|
||||||
|
pagination.current = current
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
const handleRefresh = () => {
|
||||||
|
fetchServers()
|
||||||
|
Message.success('数据已刷新')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增网络设备
|
||||||
|
const handleAdd = () => {
|
||||||
|
currentRecord.value = null
|
||||||
|
formDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快捷配置
|
||||||
|
const handleQuickConfig = (record: any) => {
|
||||||
|
currentRecord.value = record
|
||||||
|
quickConfigVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑网络设备
|
||||||
|
const handleEdit = (record: any) => {
|
||||||
|
currentRecord.value = record
|
||||||
|
formDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单提交成功
|
||||||
|
const handleFormSuccess = () => {
|
||||||
|
fetchServers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重启网络设备
|
||||||
|
const handleRestart = (record: any) => {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认重启',
|
||||||
|
content: `确认重启网络设备 ${record.name} 吗?`,
|
||||||
|
onOk: () => {
|
||||||
|
Message.info('正在发送重启指令...')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情 - 在当前窗口打开
|
||||||
|
const handleDetail = (record: any) => {
|
||||||
|
router.push({
|
||||||
|
path: '/dc/detail',
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
ip: record.ip,
|
||||||
|
status: record.status,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 远程控制 - 在新窗口打开
|
||||||
|
const handleRemoteControl = (record: any) => {
|
||||||
|
const url = router.resolve({
|
||||||
|
path: '/dc/remote',
|
||||||
|
query: {
|
||||||
|
id: record.id,
|
||||||
|
name: record.name,
|
||||||
|
ip: record.ip,
|
||||||
|
status: record.status,
|
||||||
|
},
|
||||||
|
}).href
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除网络设备
|
||||||
|
const handleDelete = async (record: any) => {
|
||||||
|
try {
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认删除',
|
||||||
|
content: `确认删除网络设备 ${record.name} 吗?`,
|
||||||
|
onOk: async () => {
|
||||||
|
// Mock 删除操作
|
||||||
|
const index = mockServerData.findIndex(item => item.id === record.id)
|
||||||
|
if (index > -1) {
|
||||||
|
mockServerData.splice(index, 1)
|
||||||
|
Message.success('删除成功')
|
||||||
|
fetchServers()
|
||||||
|
} else {
|
||||||
|
Message.error('删除失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除网络设备失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化加载数据
|
||||||
|
fetchServers()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DataCenterServer',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.container {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource-display {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 4px 0;
|
||||||
|
|
||||||
|
.resource-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
> div {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.resource-value {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: rgb(var(--text-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-progress) {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.arco-progress-bar-bg {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-progress-bar {
|
||||||
|
border-radius: 2px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
:columns="columns"
|
:columns="columns"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
title="服务器及PC管理"
|
title="办公PC管理"
|
||||||
search-button-text="查询"
|
search-button-text="查询"
|
||||||
reset-button-text="重置"
|
reset-button-text="重置"
|
||||||
@update:form-model="handleFormModelUpdate"
|
@update:form-model="handleFormModelUpdate"
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-plus />
|
<icon-plus />
|
||||||
</template>
|
</template>
|
||||||
新增
|
新增办公PC
|
||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -492,7 +492,7 @@ const handleDetail = (record: any) => {
|
|||||||
const handleRestart = (record: any) => {
|
const handleRestart = (record: any) => {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: '确认重启',
|
title: '确认重启',
|
||||||
content: `确认重启服务器/PC ${record.name} 吗?`,
|
content: `确认重启办公PC ${record.name} 吗?`,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
Message.info('正在发送重启指令...')
|
Message.info('正在发送重启指令...')
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user