修改页面弹窗全屏
This commit is contained in:
17
web-vue/packages/biz/api/biz/resourceMonitor.ts
Normal file
17
web-vue/packages/biz/api/biz/resourceMonitor.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { defHttp } from '@jeesite/core/utils/http/axios';
|
||||
import { useGlobSetting } from '@jeesite/core/hooks/setting';
|
||||
import { BasicModel, Page, TreeDataModel, TreeModel } from '@jeesite/core/api/model/baseModel';
|
||||
const { adminPath } = useGlobSetting();
|
||||
|
||||
export interface BizResourceMonitor extends BasicModel<BizResourceMonitor> {
|
||||
createTime: string; // 记录时间
|
||||
hostName: string; // 服务器主机名
|
||||
cpuUsage: number; // CPU使用率
|
||||
memoryUsage: number; // 内存使用率
|
||||
memoryTotal: number; // 服务器总内存大小
|
||||
hourTime: string; // 时间
|
||||
hostId: string; // 服务器主机编号
|
||||
}
|
||||
|
||||
export const bizResourceMonitorListAll = (params?: BizResourceMonitor | any) =>
|
||||
defHttp.get<BizResourceMonitor[]>({ url: adminPath + '/biz/resourceMonitor/listAll', params });
|
||||
@@ -5,148 +5,127 @@
|
||||
title="主机详情"
|
||||
:showOkBtn="false"
|
||||
:showCancelBtn="false"
|
||||
width="60%"
|
||||
class="server-detail-modal"
|
||||
defaultFullscreen="true"
|
||||
width="70%"
|
||||
>
|
||||
<!-- 整体容器 - 淡蓝色背景 -->
|
||||
<div class="server-detail-container">
|
||||
<!-- 左侧基础信息(30%宽度) -->
|
||||
<div class="server-info-left">
|
||||
<div class="info-card base-info-card">
|
||||
<h3 class="card-title">基础信息</h3>
|
||||
<div class="card-grid base-info-content">
|
||||
<!-- 主机名称 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">主机名称:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.sysHostname || '--'">
|
||||
{{ serverInfo?.sysHostname || '--' }}
|
||||
<!-- 基础信息+磁盘信息 -->
|
||||
<div class="server-info-top">
|
||||
<div class="server-info-left">
|
||||
<div class="info-card base-info-card">
|
||||
<h3 class="card-title">基础信息</h3>
|
||||
<div class="card-grid base-info-content">
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">主机名称:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.sysHostname || '--'">
|
||||
{{ serverInfo?.sysHostname || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">🖥️</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">IP 地址:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.ipAddress || '--'">
|
||||
{{ serverInfo?.ipAddress || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">🌐</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">CPU 型号:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.cpuModel || '--'">
|
||||
{{ serverInfo?.cpuModel || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">⚙️</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">内存大小:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.memoryTotal || '--'">
|
||||
{{ serverInfo?.memoryTotal || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">🧠</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">系统版本:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.kernelVersion || '--'">
|
||||
{{ serverInfo?.kernelVersion || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">🖨️</div>
|
||||
</div>
|
||||
<div class="metric-icon">🖥️</div>
|
||||
</div>
|
||||
|
||||
<!-- IP地址 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">IP 地址:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.ipAddress || '--'">
|
||||
{{ serverInfo?.ipAddress || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="server-info-right">
|
||||
<div class="info-card disk-info-card">
|
||||
<h3 class="card-title">磁盘信息</h3>
|
||||
<div class="disk-table-container disk-info-content">
|
||||
<div class="custom-table-wrapper">
|
||||
<div class="table-header">
|
||||
<div class="table-th" style="width: 200px"><div class="ellipsis-text">挂载路径</div></div>
|
||||
<div class="table-th" style="width: 180px"><div class="ellipsis-text">设备名称</div></div>
|
||||
<div class="table-th" style="width: 100px"><div class="ellipsis-text">总容量</div></div>
|
||||
<div class="table-th" style="width: 100px"><div class="ellipsis-text">已用容量</div></div>
|
||||
<div class="table-th flex-1"><div class="ellipsis-text">磁盘使用率</div></div>
|
||||
</div>
|
||||
<div class="table-body-wrapper">
|
||||
<div class="table-body">
|
||||
<div v-if="diskList.length === 0" class="empty-tip">
|
||||
<div class="empty-icon">📁</div>
|
||||
<div class="empty-text">暂无磁盘信息</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(disk, index) in diskList"
|
||||
:key="index"
|
||||
class="table-tr"
|
||||
:class="{ 'table-tr-stripe': index % 2 === 1 }"
|
||||
@mouseenter="hoveredRow = index"
|
||||
@mouseleave="hoveredRow = -1"
|
||||
>
|
||||
<div class="table-td" style="width: 200px">
|
||||
<span class="path-icon">📂</span>
|
||||
<div class="ellipsis-text" :title="disk.mountPoint || '--'">
|
||||
{{ disk.mountPoint || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td" style="width: 180px">
|
||||
<div class="ellipsis-text" :title="disk.device || '--'">
|
||||
{{ disk.device || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td" style="width: 100px">
|
||||
<div class="ellipsis-text" :title="`${disk.totalSize || '--'}`">
|
||||
{{ disk.totalSize || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td" style="width: 100px">
|
||||
<div class="ellipsis-text" :title="`${disk.usedSize || '--'}`">
|
||||
{{ disk.usedSize || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td flex-1">
|
||||
<div class="custom-progress-container">
|
||||
<div
|
||||
class="custom-progress-bar"
|
||||
:style="{
|
||||
width: `${disk.usageRate || 0}%`,
|
||||
backgroundColor: getProgressColor(disk.usageRate)
|
||||
}"
|
||||
:class="{ 'progress-hover': hoveredRow === index }"
|
||||
></div>
|
||||
<span class="custom-progress-text">{{ disk.usageRate || 0 }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-icon">🌐</div>
|
||||
</div>
|
||||
|
||||
<!-- CPU型号 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">CPU 型号:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.cpuModel || '--'">
|
||||
{{ serverInfo?.cpuModel || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">⚙️</div>
|
||||
</div>
|
||||
|
||||
<!-- 内存大小 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">内存大小:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.memoryTotal || '--'">
|
||||
{{ serverInfo?.memoryTotal || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">🧠</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统版本 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">系统版本:</div>
|
||||
<div class="metric-value ellipsis-text" :title="serverInfo?.kernelVersion || '--'">
|
||||
{{ serverInfo?.kernelVersion || '--' }}
|
||||
</div>
|
||||
<div class="metric-icon">🖨️</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧磁盘信息(70%宽度) -->
|
||||
<div class="server-info-right">
|
||||
<div class="info-card disk-info-card">
|
||||
<h3 class="card-title">磁盘信息</h3>
|
||||
<div class="disk-table-container disk-info-content">
|
||||
<!-- 自定义表格(固定表头) -->
|
||||
<div class="custom-table-wrapper">
|
||||
<!-- 表格头部 -->
|
||||
<div class="table-header">
|
||||
<div class="table-th" style="width: 200px">
|
||||
<div class="ellipsis-text">挂载路径</div>
|
||||
</div>
|
||||
<div class="table-th" style="width: 180px">
|
||||
<div class="ellipsis-text">设备名称</div>
|
||||
</div>
|
||||
<div class="table-th" style="width: 100px">
|
||||
<div class="ellipsis-text">总容量</div>
|
||||
</div>
|
||||
<div class="table-th" style="width: 100px">
|
||||
<div class="ellipsis-text">已用容量</div>
|
||||
</div>
|
||||
<div class="table-th flex-1">
|
||||
<div class="ellipsis-text">磁盘使用率</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格内容(可滚动) -->
|
||||
<div class="table-body-wrapper">
|
||||
<div class="table-body">
|
||||
<!-- 空数据提示 -->
|
||||
<div v-if="diskList.length === 0" class="empty-tip">
|
||||
<div class="empty-icon">📁</div>
|
||||
<div class="empty-text">暂无磁盘信息</div>
|
||||
</div>
|
||||
|
||||
<!-- 磁盘数据行 -->
|
||||
<div
|
||||
v-for="(disk, index) in diskList"
|
||||
:key="index"
|
||||
class="table-tr"
|
||||
:class="{ 'table-tr-stripe': index % 2 === 1 }"
|
||||
@mouseenter="hoveredRow = index"
|
||||
@mouseleave="hoveredRow = -1"
|
||||
>
|
||||
<div class="table-td" style="width: 200px">
|
||||
<span class="path-icon">📂</span>
|
||||
<div class="ellipsis-text" :title="disk.mountPoint || '--'">
|
||||
{{ disk.mountPoint || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td" style="width: 180px">
|
||||
<div class="ellipsis-text" :title="disk.device || '--'">
|
||||
{{ disk.device || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td" style="width: 100px">
|
||||
<div class="ellipsis-text" :title="`${disk.totalSize || '--'}`">
|
||||
{{ disk.totalSize || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td" style="width: 100px">
|
||||
<div class="ellipsis-text" :title="`${disk.usedSize || '--'}`">
|
||||
{{ disk.usedSize || '--' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-td flex-1">
|
||||
<!-- 自定义进度条(调整为更细) -->
|
||||
<div class="custom-progress-container">
|
||||
<div
|
||||
class="custom-progress-bar"
|
||||
:style="{
|
||||
width: `${disk.usageRate || 0}%`,
|
||||
backgroundColor: getProgressColor(disk.usageRate)
|
||||
}"
|
||||
:class="{ 'progress-hover': hoveredRow === index }"
|
||||
></div>
|
||||
<span class="custom-progress-text">{{ disk.usageRate || 0 }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 监控信息 -->
|
||||
<div class="server-info-bottom">
|
||||
<div class="info-card monitor-card">
|
||||
<h3 class="card-title">监控信息</h3>
|
||||
<div ref="chartDom" class="monitor-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,47 +133,56 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { defineComponent, ref, onMounted, onUnmounted, watch, computed, nextTick } from 'vue';
|
||||
import { BasicModal, useModalInner } from '@jeesite/core/components/Modal';
|
||||
import { useMessage } from '@jeesite/core/hooks/web/useMessage';
|
||||
import { BizDeviceInfo, bizDeviceInfoListAll } from '@jeesite/biz/api/biz/deviceInfo';
|
||||
import { BizResourceMonitor, bizResourceMonitorListAll } from '@jeesite/biz/api/biz/resourceMonitor';
|
||||
|
||||
import * as echarts from 'echarts';
|
||||
import type { ECharts, EChartsOption, LineSeriesOption } from 'echarts';
|
||||
|
||||
export default defineComponent({
|
||||
components: { BasicModal },
|
||||
setup() {
|
||||
// 状态定义
|
||||
const serverInfo = ref();
|
||||
// 基础状态
|
||||
const serverInfo = ref<any>({});
|
||||
const diskList = ref<BizDeviceInfo[]>([]);
|
||||
const hoveredRow = ref(-1);
|
||||
const hostId = ref<string | number>('');
|
||||
const isLoadingMonitor = ref(false);
|
||||
|
||||
// 模态框注册
|
||||
// 图表核心状态
|
||||
const chartDom = ref<HTMLDivElement | null>(null);
|
||||
const monitorData = ref<BizResourceMonitor[]>([]);
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
|
||||
// 模态框初始化
|
||||
const [register, { closeModal }] = useModalInner(async (data: any) => {
|
||||
if (!data) return;
|
||||
const { status, ...restData } = data;
|
||||
serverInfo.value = { ...restData };
|
||||
// 获取磁盘列表
|
||||
if (data.hostId) {
|
||||
await getDiskList({ hostId: data.hostId });
|
||||
}
|
||||
});
|
||||
if (!data || !data.hostId) return;
|
||||
serverInfo.value = { ...data };
|
||||
diskList.value = [];
|
||||
monitorData.value = [];
|
||||
hostId.value = data.hostId;
|
||||
isLoadingMonitor.value = true;
|
||||
|
||||
// 获取磁盘列表数据
|
||||
const getDiskList = async (params: { hostId: any }) => {
|
||||
try {
|
||||
const result = await bizDeviceInfoListAll(params);
|
||||
diskList.value = result;
|
||||
diskList.value = await bizDeviceInfoListAll({ hostId: data.hostId });
|
||||
// monitorData.value = await bizResourceMonitorListAll({ hostId: data.hostId });
|
||||
} catch (error) {
|
||||
console.error('获取磁盘信息失败:', error);
|
||||
diskList.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 根据使用率获取进度条颜色
|
||||
const getProgressColor = (rate?: number) => {
|
||||
const usageRate = typeof rate === 'number' ? rate : 0;
|
||||
if (usageRate >= 80) return '#f56c6c'; // 红色
|
||||
if (usageRate >= 60) return '#e6a23c'; // 黄色
|
||||
return '#409eff'; // 蓝色(默认)
|
||||
};
|
||||
console.error('主机数据加载失败:', error);
|
||||
monitorData.value = [];
|
||||
}
|
||||
});
|
||||
|
||||
// 根据使用率获取进度条颜色
|
||||
const getProgressColor = (rate?: number) => {
|
||||
const usageRate = typeof rate === 'number' ? rate : 0;
|
||||
if (usageRate >= 80) return '#f56c6c'; // 红色
|
||||
if (usageRate >= 60) return '#e6a23c'; // 黄色
|
||||
return '#409eff'; // 蓝色(默认)
|
||||
};
|
||||
|
||||
return {
|
||||
register,
|
||||
@@ -202,34 +190,54 @@ export default defineComponent({
|
||||
serverInfo,
|
||||
diskList,
|
||||
hoveredRow,
|
||||
getProgressColor
|
||||
chartDom,
|
||||
monitorData,
|
||||
isLoadingMonitor,
|
||||
getProgressColor
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 整体容器样式 - 淡蓝色背景 */
|
||||
/* 整体容器样式 - 上下布局 */
|
||||
.server-detail-container {
|
||||
display: flex;
|
||||
flex-direction: column; /* 核心:改为垂直方向布局 */
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
background-color: #f0f8ff;
|
||||
border-radius: 8px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden; /* 防止整体溢出 */
|
||||
}
|
||||
|
||||
/* 上半部分:左右分栏容器 */
|
||||
.server-info-top {
|
||||
display: flex; /* 保持左右布局 */
|
||||
gap: 20px;
|
||||
flex: 0 0 auto; /* 高度自适应内容,不拉伸 */
|
||||
min-height: 300px; /* 保证基础高度 */
|
||||
}
|
||||
|
||||
/* 下半部分:Monitor组件容器 */
|
||||
.server-info-bottom {
|
||||
flex: 1; /* 占满剩余高度 */
|
||||
min-height: 200px; /* 保证最小高度 */
|
||||
}
|
||||
|
||||
/* 左侧基础信息容器 (30%) */
|
||||
.server-info-left {
|
||||
width: 30%;
|
||||
flex-shrink: 0;
|
||||
height: 100%; /* 撑满上半部分高度 */
|
||||
}
|
||||
|
||||
/* 右侧磁盘信息容器 (70%) */
|
||||
.server-info-right {
|
||||
width: 70%;
|
||||
flex-grow: 1;
|
||||
height: 100%; /* 撑满上半部分高度 */
|
||||
}
|
||||
|
||||
/* 卡片通用样式 */
|
||||
@@ -238,8 +246,10 @@ export default defineComponent({
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
||||
padding: 16px;
|
||||
height: 100%;
|
||||
height: 100%; /* 撑满父容器高度 */
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column; /* 卡片内部垂直布局,标题+内容 */
|
||||
}
|
||||
|
||||
.card-title {
|
||||
@@ -249,6 +259,7 @@ export default defineComponent({
|
||||
color: #303133;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
padding-bottom: 8px;
|
||||
flex: 0 0 auto; /* 标题不拉伸 */
|
||||
}
|
||||
|
||||
/* 基础信息网格布局 */
|
||||
@@ -256,6 +267,8 @@ export default defineComponent({
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
flex: 1; /* 撑满卡片剩余高度 */
|
||||
overflow-y: auto; /* 内容过多时滚动 */
|
||||
}
|
||||
|
||||
/* 核心修复:基础信息卡片布局约束 */
|
||||
@@ -309,6 +322,9 @@ export default defineComponent({
|
||||
border: 1px solid #e6e6e6;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
@@ -316,6 +332,7 @@ export default defineComponent({
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
font-weight: 600;
|
||||
flex: 0 0 auto; /* 表头不拉伸 */
|
||||
}
|
||||
|
||||
.table-th {
|
||||
@@ -327,7 +344,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.table-body-wrapper {
|
||||
max-height: 400px;
|
||||
flex: 1; /* 表格内容占满剩余高度 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -384,6 +401,7 @@ export default defineComponent({
|
||||
justify-content: center;
|
||||
padding: 40px 0;
|
||||
color: #909399;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
@@ -432,29 +450,27 @@ export default defineComponent({
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 卡片动画 */
|
||||
.animate-in {
|
||||
animation: fadeInUp 0.5s ease forwards;
|
||||
/* Monitor组件容器样式 */
|
||||
.monitor-card {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
.monitor-content {
|
||||
flex: 1; /* 撑满卡片剩余高度 */
|
||||
height: 100%;
|
||||
overflow: hidden; /* 防止Monitor组件溢出 */
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
/* 响应式适配 - 优化60%宽度下的显示 */
|
||||
/* 响应式适配 */
|
||||
@media (max-width: 1024px) {
|
||||
.server-detail-container {
|
||||
flex-direction: column;
|
||||
.server-info-top {
|
||||
flex-direction: column; /* 小屏上半部分改为垂直布局 */
|
||||
min-height: auto;
|
||||
}
|
||||
.server-info-left, .server-info-right {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.server-info-left {
|
||||
margin-bottom: 20px;
|
||||
|
||||
Reference in New Issue
Block a user