| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <template>
- <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>
- </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>
- import { getDashboard } from '@/api/devops'
- import { getAuthedUser } from '@/utils/auth'
- export default {
- name: 'Dashboard',
- data() {
- return {
- roles: [],
- machineStatList: [],
- sysInfo: null
- }
- },
- created() {
- const { roles } = getAuthedUser()
- this.roles = roles
- document.title = 'Dashboard'
- this.getData()
- },
- methods: {
- getData() {
- this.getDevopsDashboard()
- },
- getDevopsDashboard() {
- getDashboard().then(resp => {
- if (resp.code === 0) {
- this.sysInfo = resp.data.sysInfo
- this.machineStatList = resp.data.machineStatList
- } else {
- this.$message.error(resp.msg)
- }
- }).catch(error => {
- this.$message.error(error.message)
- })
- },
- goToRole(data) {
- this.$message.info('当前操作角色: ' + data)
- },
- // 其余逻辑保持不变...
- 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 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>
|