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"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
title="服务器及PC管理"
|
||||
title="办公PC管理"
|
||||
search-button-text="查询"
|
||||
reset-button-text="重置"
|
||||
@update:form-model="handleFormModelUpdate"
|
||||
@@ -21,7 +21,7 @@
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
新增
|
||||
新增办公PC
|
||||
</a-button>
|
||||
</template>
|
||||
|
||||
@@ -492,7 +492,7 @@ const handleDetail = (record: any) => {
|
||||
const handleRestart = (record: any) => {
|
||||
Modal.confirm({
|
||||
title: '确认重启',
|
||||
content: `确认重启服务器/PC ${record.name} 吗?`,
|
||||
content: `确认重启办公PC ${record.name} 吗?`,
|
||||
onOk: () => {
|
||||
Message.info('正在发送重启指令...')
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user