|
|
@@ -1,135 +1,110 @@
|
|
|
<template>
|
|
|
- <el-container>
|
|
|
- <el-main class="movie-list">
|
|
|
- <div>
|
|
|
- <h3>我的角色</h3>
|
|
|
- <el-button
|
|
|
- v-for="(item, index) in roles"
|
|
|
- :key="index"
|
|
|
- icon="el-icon-user-solid"
|
|
|
- style="padding: 5px"
|
|
|
- @click="goToRole(item)"
|
|
|
- >
|
|
|
- {{ item }}
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <h3>Dashboard</h3>
|
|
|
- <el-row style="padding: 5px">
|
|
|
- <el-card>
|
|
|
- <div slot="header" class="clearfix">
|
|
|
- <span>CI/CD 流程</span>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <el-steps :active="0" finish-status="success" simple style="margin-top: 20px">
|
|
|
- <el-step title="更新代码" icon="el-icon-loading" />
|
|
|
- <el-step title="编译代码" icon="el-icon-loading" />
|
|
|
- <el-step title="应用打包" icon="el-icon-loading" />
|
|
|
- <el-step title="推送应用" icon="el-icon-upload" />
|
|
|
- <el-step title="拉取应用" icon="el-icon-download" />
|
|
|
- <el-step title="部署应用" icon="el-icon-loading" />
|
|
|
- </el-steps>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
- </el-row>
|
|
|
- <el-row style="padding: 5px">
|
|
|
- <el-col :md="12" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
- <el-card class="box-card">
|
|
|
- <div slot="header" class="clearfix">
|
|
|
- <span>机器节点</span>
|
|
|
- </div>
|
|
|
- <div class="text item">
|
|
|
- <el-table
|
|
|
- :data="machineStatList"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- <el-table-column
|
|
|
- prop="env"
|
|
|
- label="环境"
|
|
|
- />
|
|
|
- <el-table-column
|
|
|
- prop="total"
|
|
|
- label="总数"
|
|
|
- />
|
|
|
- <el-table-column
|
|
|
- prop="onlineCount"
|
|
|
- label="在线"
|
|
|
- >
|
|
|
- <template slot-scope="scope">
|
|
|
- <span style="color: green">{{ scope.row.onlineCount }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column
|
|
|
- prop="offlineCount"
|
|
|
- label="离线"
|
|
|
- >
|
|
|
- <template slot-scope="scope">
|
|
|
- <span style="color: red">{{ scope.row.offlineCount }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- <el-col :md="12" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
|
|
|
- <el-card class="box-card">
|
|
|
- <div slot="header" class="clearfix">
|
|
|
- <span>系统信息</span>
|
|
|
- </div>
|
|
|
- <div class="text item">
|
|
|
- <el-descriptions v-if="sysInfo !== null" class="margin-top" :column="1" border>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-user" />
|
|
|
- 应用版本
|
|
|
- </template>
|
|
|
- <a target="_blank" :href="`https://git.reghao.cn/reghao/devops/commit/${sysInfo.commitId}`" style="text-decoration-line: none">
|
|
|
- {{ sysInfo.commitId }}
|
|
|
- </a>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-mobile-phone" />
|
|
|
- 机器地址
|
|
|
- </template>
|
|
|
- {{ sysInfo.ipv4 }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-location-outline" />
|
|
|
- 操作系统
|
|
|
- </template>
|
|
|
- {{ sysInfo.osInfo }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-tickets" />
|
|
|
- JVM
|
|
|
- </template>
|
|
|
- {{ sysInfo.jvmInfo }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-office-building" />
|
|
|
- 启动时间
|
|
|
- </template>
|
|
|
- {{ sysInfo.startAt }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-office-building" />
|
|
|
- PID
|
|
|
- </template>
|
|
|
- {{ sysInfo.pid }}
|
|
|
- </el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </div>
|
|
|
- </el-main>
|
|
|
- </el-container>
|
|
|
+ <div class="dashboard-wrapper">
|
|
|
+ <el-row :gutter="20" class="stat-row">
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-card shadow="never" class="role-card">
|
|
|
+ <div class="role-container">
|
|
|
+ <span class="role-label"><i class="el-icon-medal"></i> 当前权限角色:</span>
|
|
|
+ <el-tag
|
|
|
+ v-for="(item, index) in roles"
|
|
|
+ :key="index"
|
|
|
+ effect="dark"
|
|
|
+ size="medium"
|
|
|
+ class="role-tag"
|
|
|
+ @click="goToRole(item)"
|
|
|
+ >
|
|
|
+ {{ item }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20" class="process-row">
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <div slot="header" class="card-header">
|
|
|
+ <span><i class="el-icon-refresh"></i> CI/CD 流水线</span>
|
|
|
+ </div>
|
|
|
+ <div class="steps-wrapper">
|
|
|
+ <el-steps :active="1" finish-status="success" align-center>
|
|
|
+ <el-step title="更新代码" icon="el-icon-edit-outline" />
|
|
|
+ <el-step title="编译代码" icon="el-icon-set-up" />
|
|
|
+ <el-step title="应用打包" icon="el-icon-box" />
|
|
|
+ <el-step title="推送应用" icon="el-icon-upload" />
|
|
|
+ <el-step title="拉取应用" icon="el-icon-download" />
|
|
|
+ <el-step title="部署应用" icon="el-icon-monitor" />
|
|
|
+ </el-steps>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :md="12" :sm="24">
|
|
|
+ <el-card shadow="hover" class="data-card">
|
|
|
+ <div slot="header" class="card-header">
|
|
|
+ <span><i class="el-icon-cpu"></i> 机器节点状态</span>
|
|
|
+ <el-tag size="mini" type="info">实时更新</el-tag>
|
|
|
+ </div>
|
|
|
+ <el-table :data="machineStatList" border stripe size="small">
|
|
|
+ <el-table-column prop="env" label="运行环境">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag size="mini" effect="plain">{{ scope.row.env }}</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="total" label="资产总数" align="center" />
|
|
|
+ <el-table-column label="健康状况" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <div class="status-cell">
|
|
|
+ <span class="status-dot online"></span>
|
|
|
+ <span class="status-count">{{ scope.row.onlineCount }}</span>
|
|
|
+ <span class="status-divider">/</span>
|
|
|
+ <span class="status-dot offline"></span>
|
|
|
+ <span class="status-count">{{ scope.row.offlineCount }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :md="12" :sm="24">
|
|
|
+ <el-card shadow="hover" class="data-card">
|
|
|
+ <div slot="header" class="card-header">
|
|
|
+ <span><i class="el-icon-info"></i> 系统核心信息</span>
|
|
|
+ </div>
|
|
|
+ <el-descriptions v-if="sysInfo !== null" :column="1" border size="small">
|
|
|
+ <el-descriptions-item label="应用版本">
|
|
|
+ <el-link
|
|
|
+ type="primary"
|
|
|
+ target="_blank"
|
|
|
+ :href="`https://git.reghao.cn/reghao/devops/commit/${sysInfo.commitId}`"
|
|
|
+ icon="el-icon-link"
|
|
|
+ >
|
|
|
+ {{ sysInfo.commitId.substring(0, 8) }}
|
|
|
+ </el-link>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="机器地址">
|
|
|
+ <code>{{ sysInfo.ipv4 }}</code>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="操作系统">
|
|
|
+ <i class="el-icon-monitor"></i> {{ sysInfo.osInfo }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="JVM 环境">
|
|
|
+ <el-tooltip effect="dark" :content="sysInfo.jvmInfo" placement="top">
|
|
|
+ <span class="text-truncate">{{ sysInfo.jvmInfo }}</span>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="启动/PID">
|
|
|
+ <el-tag size="mini" type="success">{{ sysInfo.startAt }}</el-tag>
|
|
|
+ <el-tag size="mini" type="warning" style="margin-left:5px">PID: {{ sysInfo.pid }}</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
@@ -148,7 +123,7 @@ export default {
|
|
|
created() {
|
|
|
const { roles } = getAuthedUser()
|
|
|
this.roles = roles
|
|
|
- document.title = 'Dashboard'
|
|
|
+ document.title = '运维概览'
|
|
|
this.getData()
|
|
|
},
|
|
|
methods: {
|
|
|
@@ -168,35 +143,127 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
goToRole(data) {
|
|
|
- this.$message.info('role -> ' + data)
|
|
|
- },
|
|
|
- goToDisk() {
|
|
|
- const path = '/disk'
|
|
|
- if (this.$route.path === path) {
|
|
|
- this.$router.go(0)
|
|
|
- return
|
|
|
- }
|
|
|
- this.$router.push(path)
|
|
|
- },
|
|
|
- goToVod() {
|
|
|
- const path = '/vod'
|
|
|
- if (this.$route.path === path) {
|
|
|
- this.$router.go(0)
|
|
|
- return
|
|
|
- }
|
|
|
- this.$router.push(path)
|
|
|
+ this.$message.info('当前操作角色: ' + data)
|
|
|
},
|
|
|
- goToBlog() {
|
|
|
- const path = '/blog'
|
|
|
- if (this.$route.path === path) {
|
|
|
- this.$router.go(0)
|
|
|
- return
|
|
|
- }
|
|
|
+ // 其余逻辑保持不变...
|
|
|
+ goToDisk() { const path = '/disk'; this.handleRoute(path) },
|
|
|
+ goToVod() { const path = '/vod'; this.handleRoute(path) },
|
|
|
+ goToBlog() { const path = '/blog'; this.handleRoute(path) },
|
|
|
+ handleRoute(path) {
|
|
|
+ if (this.$route.path === path) { this.$router.go(0); return }
|
|
|
this.$router.push(path)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style>
|
|
|
+<style scoped>
|
|
|
+.dashboard-wrapper {
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.stat-row {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.role-card {
|
|
|
+ background: #fcfcfc;
|
|
|
+ border-left: 4px solid #409EFF;
|
|
|
+}
|
|
|
+
|
|
|
+.role-container {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.role-label {
|
|
|
+ font-weight: bold;
|
|
|
+ color: #606266;
|
|
|
+ margin-right: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.role-tag {
|
|
|
+ margin-right: 10px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.role-tag:hover {
|
|
|
+ opacity: 0.8;
|
|
|
+ transform: translateY(-1px);
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.process-row {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.steps-wrapper {
|
|
|
+ padding: 20px 0;
|
|
|
+}
|
|
|
+
|
|
|
+.data-card {
|
|
|
+ min-height: 380px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 状态点样式 */
|
|
|
+.status-cell {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.status-dot {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ border-radius: 50%;
|
|
|
+ margin: 0 5px;
|
|
|
+}
|
|
|
+
|
|
|
+.online {
|
|
|
+ background-color: #67C23A;
|
|
|
+ box-shadow: 0 0 5px #67C23A;
|
|
|
+}
|
|
|
+
|
|
|
+.offline {
|
|
|
+ background-color: #F56C6C;
|
|
|
+ box-shadow: 0 0 5px #F56C6C;
|
|
|
+}
|
|
|
+
|
|
|
+.status-count {
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.status-divider {
|
|
|
+ margin: 0 8px;
|
|
|
+ color: #DCDFE6;
|
|
|
+}
|
|
|
+
|
|
|
+.text-truncate {
|
|
|
+ display: inline-block;
|
|
|
+ max-width: 250px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ vertical-align: middle;
|
|
|
+}
|
|
|
+
|
|
|
+code {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ padding: 2px 4px;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #e6a23c;
|
|
|
+ font-family: monospace;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep .el-descriptions-item__label {
|
|
|
+ width: 120px;
|
|
|
+ background-color: #fafafa !important;
|
|
|
+}
|
|
|
</style>
|