修改页面弹窗全屏

This commit is contained in:
2026-02-09 00:34:37 +08:00
parent 0f3df16c89
commit 8c42524330
2 changed files with 214 additions and 181 deletions

View 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 });

View File

@@ -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;