<template> <div class="details"> <n-button type="primary" @click="handleClick('back')" style="margin-bottom: 10px" ><template #icon> <n-icon> <ReturnDownBackSharp /> </n-icon> </template >返回</n-button > <n-tabs type="line" animated @update:value="handleUpdate"> <n-tab-pane name="0" tab="基本信息"> <div class="info"> <div class="slInfo common"> <h3>实例信息</h3> <ul> <li> <span>实例名称:</span><span>{{ info.intranet }}</span> </li> <li> <span>实例ID:</span><span>{{ info.serverName }}</span> </li> <li> <span>实例规格:</span><span>{{ info.type }}</span> </li> <li> <span>所属项目</span><span>{{ info.project }}</span> </li> </ul> </div> <div class="wlInfo common"> <h3>网络信息</h3> <ul> <li> <span>所属网络</span><span>{{ info.internet }}</span> </li> <li> <span>主IPv4公网IP</span><span>{{ info.extranet }}</span> </li> <li> <span>主IPv4内网IP</span><span>{{ info.intranet }}</span> </li> </ul> </div> <div class="pzInfo common"> <h3>配置信息</h3> <ul> <li> <span>操作系统名称</span><span>{{ info.systemName }}</span> </li> <li> <span>cpu</span><span>{{ info.cpu }}</span> </li> <li> <span>内存</span><span>{{ info.ram }}</span> </li> <li> <span>公网宽带</span><span>{{ info.bandwidth }}</span> </li> </ul> </div> </div> </n-tab-pane> <n-tab-pane name="1 " tab="服务应用"> <div class="search" style="margin-bottom: 10px"> <n-space> <span>服务名称</span> <n-input v-model:value="searchValue1" clearable placeholder="请输入端口或服务名称" /> <n-button type="primary" @click="handleClick('search')" >查询</n-button > </n-space> </div> <div class="table"> <n-data-table ref="tableRef" :bordered="false" :max-height="700" striped :columns="columns" :data="data" :remote="true" :pagination="pagination" ></n-data-table> </div> </n-tab-pane> </n-tabs> </div> <n-modal v-model:show="showModal" :show-icon="false" preset="card" :title="modelTitle" :style="{ width: '800px' }" > <n-space> <n-date-picker v-model:value="timestamp1" type="datetime" clearable /> <n-date-picker v-model:value="timestamp2" type="datetime" clearable /> <n-button type="primary" @click="() => handleClick('searchDatils')" >查询</n-button > </n-space> <div class="chartBox"> <div class="chart" v-for="(item, i) in applyChartInfo" :key="i"> <div class="title"> {{ item.chartName }} </div> <div class="box"> <LineChart :data="item.chartData" :xData="xList" /> </div> </div> </div> <template #action> <n-space> <n-button @click="() => (showModal = false)">关闭</n-button> </n-space> </template> </n-modal> </template> <script> import { ReturnDownBackSharp } from "@vicons/ionicons5"; import { reactive, toRefs, h, onMounted, nextTick } from "vue"; import { NButton, NTag } from "naive-ui"; import { getServerManagerList, detailsInfoList, queryDetail } from "@/services"; import { formatDate } from "../../../utils/util"; import { useRouter, useRoute } from "vue-router"; import LineChart from "./component/LineChart.vue"; export default { name: "serverDatils", components: { ReturnDownBackSharp, LineChart, }, setup() { const router = useRouter(); const route = useRoute(); const state = reactive({ exeName: null, serverIp: null, //基本信息 info: {}, // 服务应用 //搜索 searchValue1: null, //表格 columns: [ { title: "应用名称", key: "exeName", align: "center", ellipsis: { tooltip: true, }, }, { title: "服务器IP", key: "serverIp", align: "center", width: "150", }, { title: "路径", key: "homePath", align: "center", ellipsis: { tooltip: true, }, }, { title: "进程号", key: "pid", align: "center", width: "100", }, { title: "端口", key: "port", align: "center", width: "100", render(row) { return row.port == "" ? "-" : row.port; }, }, { title: "状态", key: "status", align: "center", width: "100", render(row) { return h( NTag, { bordered: false, color: { color: "transparent", textColor: row.status === 0 ? "#36ad6a" : "#d03050", }, }, { default: row.status === 0 ? "正常" : "不正常", } ); }, }, { title: "更新时间", key: "updateTime", align: "center", width: "180", }, { title: "操作", key: "actions", align: "center", width: "120", render(row) { return h( NButton, { text: true, size: "small", style: { margin: "10px", }, type: "primary", onClick: () => handleClick("chakan", row), }, { default: () => "查看详情" } ); }, }, ], data: [], // 弹窗 showModal: false, modelTitle: null, timestamp1: Date.now() - 3600 * 1000, timestamp2: Date.now(), applyChartInfo: [], xList: [], }); //分页 const paginationReactive = reactive({ page: 1, pageSize: 10, showSizePicker: true, pageSizes: [10, 20, 50], showQuickJumper: true, pageCount: 0, itemCount: 0, onChange: (page) => { paginationReactive.page = page; getTableData(); }, onPageSizeChange: (pageSize) => { paginationReactive.pageSize = pageSize; paginationReactive.page = 1; getTableData(); }, }); // 获取基本信息数据 const getInfoList = async () => { let pramas = { id: route.query.id, }; let res = await getServerManagerList(pramas); if (res.code == 200) { state.info = res.data[0]; } }; // 获取服务应用表格数据 const getTableData = async () => { let pramas = { current: paginationReactive.page, size: paginationReactive.pageSize, searchStr: state.searchValue1, serverIp: route.query.ip, }; let res = await detailsInfoList(pramas); if (res.code == 200) { state.data = res.data.list; paginationReactive.pageCount = res.data.pages; paginationReactive.itemCount = res.data.total; } }; //按钮点击事件 const handleClick = (type, row) => { switch (type) { case "back": console.log(router); router.back(); break; case "chakan": state.showModal = true; state.modelTitle = `${row.exeName} 应用详情`; state.exeName = row.exeName; state.serverIp = row.serverIp; getdetails(); break; case "searchDatils": getdetails(); break; } }; // 查询服务应用详情 const getdetails = async () => { state.applyChartInfo = []; state.xList = []; let pramas = { endDate: formatDate(state.timestamp2), exeName: state.exeName, serverIp: state.serverIp, startDate: formatDate(state.timestamp1), }; let res = await queryDetail(pramas); if (res.code == 200) { if (res.data.length) { res.data.forEach((item) => { if (item.name !== "time") { state.applyChartInfo.push({ chartName: item.name, chartData: { nameList: [item.name], dataList: [item.data], }, }); console.log(state.applyChartInfo, "yyyyyyyyyyyy"); } else { state.xList = item.data; } }); } } }; //切换tabs const handleUpdate = (value) => { if (value == 0) { getInfoList(); } else { getTableData(); } }; onMounted(() => { nextTick(() => { getInfoList(); }); }); return { ...toRefs(state), pagination: paginationReactive, handleUpdate, getTableData, handleClick, getdetails, }; }, }; </script> <style lang="less" scoped> .search { span { line-height: 36px; } } .info { margin-top: 10px; display: flex; .common { flex: 1; padding: 10px; margin-right: 20px; border: 1px solid #fff; &:last-child { margin-right: 0; } h3 { font-size: 16px; } ul { li { display: flex; line-height: 50px; display: flex; span { margin-right: 60px; &:nth-child(1) { width: 100px; } } } } } } .chartBox { margin-top: 20px; width: 100%; .chart { width: 100%; display: flex; height: 100px; align-items: center; border-bottom: 1px solid #666; .title { width: 50px; text-align: center; } .box { width: calc(100% - 100px); height: 100%; } } } </style>