mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-01 19:38:09 +08:00
feat 资产总览统计
This commit is contained in:
parent
f787c17f31
commit
7994b3b5b9
@ -2,6 +2,10 @@
|
||||
|
||||
### 2.11.0.12-beta
|
||||
|
||||
### 🐣 新增功能
|
||||
|
||||
1. 【server】新增 资产总览统计
|
||||
|
||||
### 🐞 解决BUG、优化功能
|
||||
|
||||
1. 【server】修复 mysql 存储使用游标查询报错(不使用游标)(感谢@🇩)
|
||||
|
@ -340,9 +340,11 @@ public class JpomApplicationEvent implements ApplicationListener<ApplicationEven
|
||||
//
|
||||
File file = FileUtil.file(JpomApplication.getInstance().getDataPath(), Const.REMOTE_VERSION);
|
||||
SystemUtil.set("JPOM_REMOTE_VERSION_CACHE_FILE", file.getAbsolutePath());
|
||||
SystemUtil.set("JPOM_IS_DEBUG", String.valueOf(JpomManifest.getInstance().isDebug()));
|
||||
SystemUtil.set("JPOM_TYPE", JpomManifest.getInstance().getType().name());
|
||||
SystemUtil.set("JPOM_VERSION", JpomManifest.getInstance().getVersion());
|
||||
JpomManifest jpomManifest = JpomManifest.getInstance();
|
||||
SystemUtil.set("JPOM_IS_DEBUG", String.valueOf(jpomManifest.isDebug()));
|
||||
SystemUtil.set("JPOM_TYPE", jpomManifest.getType().name());
|
||||
SystemUtil.set("JPOM_VERSION", jpomManifest.getVersion());
|
||||
SystemUtil.set("JPOM_INSTALL_ID", jpomManifest.getInstallId());
|
||||
// 检查目录权限
|
||||
this.checkPath();
|
||||
this.install();
|
||||
|
@ -22,12 +22,19 @@
|
||||
*/
|
||||
package org.dromara.jpom.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.db.Entity;
|
||||
import cn.keepbx.jpom.IJsonMessage;
|
||||
import cn.keepbx.jpom.model.JsonMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.jpom.func.assets.server.MachineDockerServer;
|
||||
import org.dromara.jpom.func.assets.server.MachineNodeServer;
|
||||
import org.dromara.jpom.func.assets.server.MachineSshServer;
|
||||
import org.dromara.jpom.func.files.service.FileStorageService;
|
||||
import org.dromara.jpom.func.files.service.StaticFileStorageService;
|
||||
import org.dromara.jpom.func.system.service.ClusterInfoService;
|
||||
import org.dromara.jpom.model.user.UserModel;
|
||||
import org.dromara.jpom.permission.SystemPermission;
|
||||
import org.dromara.jpom.service.docker.DockerInfoService;
|
||||
import org.dromara.jpom.service.docker.DockerSwarmInfoService;
|
||||
import org.dromara.jpom.service.node.NodeService;
|
||||
@ -37,6 +44,8 @@ import org.dromara.jpom.service.node.ssh.SshCommandService;
|
||||
import org.dromara.jpom.service.node.ssh.SshService;
|
||||
import org.dromara.jpom.service.outgiving.OutGivingServer;
|
||||
import org.dromara.jpom.service.script.ScriptServer;
|
||||
import org.dromara.jpom.service.system.WorkspaceService;
|
||||
import org.dromara.jpom.service.user.UserService;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@ -44,6 +53,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -66,6 +76,12 @@ public class DataStatController {
|
||||
private final FileStorageService fileStorageService;
|
||||
private final StaticFileStorageService staticFileStorageService;
|
||||
private final DockerSwarmInfoService dockerSwarmInfoService;
|
||||
private final UserService userService;
|
||||
private final WorkspaceService workspaceService;
|
||||
private final ClusterInfoService clusterInfoService;
|
||||
private final MachineNodeServer machineNodeServer;
|
||||
private final MachineSshServer machineSshServer;
|
||||
private final MachineDockerServer machineDockerServer;
|
||||
|
||||
public DataStatController(NodeService nodeService,
|
||||
ProjectInfoCacheService projectInfoCacheService,
|
||||
@ -77,7 +93,13 @@ public class DataStatController {
|
||||
DockerInfoService dockerInfoService,
|
||||
FileStorageService fileStorageService,
|
||||
StaticFileStorageService staticFileStorageService,
|
||||
DockerSwarmInfoService dockerSwarmInfoService) {
|
||||
DockerSwarmInfoService dockerSwarmInfoService,
|
||||
UserService userService,
|
||||
WorkspaceService workspaceService,
|
||||
ClusterInfoService clusterInfoService,
|
||||
MachineNodeServer machineNodeServer,
|
||||
MachineSshServer machineSshServer,
|
||||
MachineDockerServer machineDockerServer) {
|
||||
this.nodeService = nodeService;
|
||||
this.projectInfoCacheService = projectInfoCacheService;
|
||||
this.nodeScriptServer = nodeScriptServer;
|
||||
@ -89,6 +111,12 @@ public class DataStatController {
|
||||
this.fileStorageService = fileStorageService;
|
||||
this.staticFileStorageService = staticFileStorageService;
|
||||
this.dockerSwarmInfoService = dockerSwarmInfoService;
|
||||
this.userService = userService;
|
||||
this.workspaceService = workspaceService;
|
||||
this.clusterInfoService = clusterInfoService;
|
||||
this.machineNodeServer = machineNodeServer;
|
||||
this.machineSshServer = machineSshServer;
|
||||
this.machineDockerServer = machineDockerServer;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "workspace", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ -110,4 +138,51 @@ public class DataStatController {
|
||||
//map.put("staticFileCount", staticFileStorageService.count(entity));
|
||||
return JsonMessage.success("", map);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "system", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@SystemPermission
|
||||
public IJsonMessage<Map<String, Object>> system(HttpServletRequest request) {
|
||||
Map<String, Object> map = new HashMap<>(10);
|
||||
{
|
||||
long count = userService.count();
|
||||
map.put("userCount", count);
|
||||
{
|
||||
UserModel userModel = new UserModel();
|
||||
userModel.setSystemUser(1);
|
||||
long systemUserCount = userService.count(userModel);
|
||||
map.put("systemUserCount", systemUserCount);
|
||||
}
|
||||
{
|
||||
UserModel userModel = new UserModel();
|
||||
userModel.setStatus(0);
|
||||
long disableUserCount = userService.count(userModel);
|
||||
map.put("disableUserCount", disableUserCount);
|
||||
}
|
||||
String sql = "select count(1) from " + userService.getTableName() + " where twoFactorAuthKey is null or twoFactorAuthKey=''";
|
||||
Number closeTwoFactorAuth = ObjectUtil.defaultIfNull(userService.queryNumber(sql), 0);
|
||||
map.put("openTwoFactorAuth", count - closeTwoFactorAuth.intValue());
|
||||
}
|
||||
{
|
||||
long workspaceCount = workspaceService.count();
|
||||
long clusterCount = clusterInfoService.count();
|
||||
map.put("workspaceCount", workspaceCount);
|
||||
map.put("clusterCount", clusterCount);
|
||||
}
|
||||
{
|
||||
String sql = "select status,count(1) as count from " + machineDockerServer.getTableName() + " group by status";
|
||||
List<Entity> query = machineDockerServer.query(sql);
|
||||
map.put("dockerStat", query);
|
||||
}
|
||||
{
|
||||
String sql = "select status,count(1) as count from " + machineSshServer.getTableName() + " group by status";
|
||||
List<Entity> query = machineSshServer.query(sql);
|
||||
map.put("sshStat", query);
|
||||
}
|
||||
{
|
||||
String sql = "select status,count(1) as count from " + machineNodeServer.getTableName() + " group by status";
|
||||
List<Entity> query = machineNodeServer.query(sql);
|
||||
map.put("nodeStat", query);
|
||||
}
|
||||
return JsonMessage.success("", map);
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,8 @@ public class CacheManageController extends BaseServerController implements ICach
|
||||
map.put("timeZoneId", TimeZone.getDefault().getID());
|
||||
map.put("errorWorkspace", dataInitEvent.getErrorWorkspaceTable());
|
||||
map.put("clusterId", clusterConfig.getId());
|
||||
map.put("installId", JpomManifest.getInstance().getInstallId());
|
||||
JpomManifest jpomManifest = JpomManifest.getInstance();
|
||||
map.put("installId", jpomManifest.getInstallId());
|
||||
//
|
||||
return JsonMessage.success("", map);
|
||||
}
|
||||
|
@ -1,4 +1,9 @@
|
||||
[
|
||||
{
|
||||
"title": "资产总览",
|
||||
"icon_v3": "laptop",
|
||||
"id": "system-overview"
|
||||
},
|
||||
{
|
||||
"title": "资产管理",
|
||||
"icon_v3": "hdd",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import axios from "@/api/config";
|
||||
import axios from '@/api/config'
|
||||
|
||||
/**
|
||||
* 容器列表
|
||||
@ -6,30 +6,30 @@ import axios from "@/api/config";
|
||||
*/
|
||||
export function dockerList(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/list-data",
|
||||
method: "post",
|
||||
data: params,
|
||||
});
|
||||
url: '/system/assets/docker/list-data',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
export function dockerImportTls(formData) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/import-tls",
|
||||
url: '/system/assets/docker/import-tls',
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data;charset=UTF-8",
|
||||
'Content-Type': 'multipart/form-data;charset=UTF-8'
|
||||
},
|
||||
method: "post",
|
||||
method: 'post',
|
||||
timeout: 0,
|
||||
data: formData,
|
||||
});
|
||||
data: formData
|
||||
})
|
||||
}
|
||||
|
||||
export function editDocker(data) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/edit",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
url: '/system/assets/docker/edit',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,10 +40,10 @@ export function editDocker(data) {
|
||||
*/
|
||||
export function tryLocalDocker(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/try-local-docker",
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
url: '/system/assets/docker/try-local-docker',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,42 +54,42 @@ export function tryLocalDocker(params) {
|
||||
*/
|
||||
export function deleteDcoker(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/del",
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
url: '/system/assets/docker/del',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function dockerListGroup(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/list-group",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
url: '/system/assets/docker/list-group',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
export function initDockerSwarm(data) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/init",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
url: '/system/assets/docker/init',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function joinDockerSwarm(data) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/join",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
url: '/system/assets/docker/join',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function dockerSwarmListAll(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/swarm/list-all",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
url: '/system/assets/docker/swarm/list-all',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,10 +100,10 @@ export function dockerSwarmListAll(params) {
|
||||
*/
|
||||
export function dcokerSwarmLeaveForce(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/leave-force",
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
url: '/system/assets/docker/leave-force',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,24 +112,29 @@ export function dcokerSwarmLeaveForce(params) {
|
||||
*/
|
||||
export function dockerSwarmNodeLeave(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/leave-node",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
url: '/system/assets/docker/leave-node',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
export function machineDockerDistribute(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/distribute",
|
||||
method: "post",
|
||||
data: params,
|
||||
});
|
||||
url: '/system/assets/docker/distribute',
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
export function dockerListWorkspace(params) {
|
||||
return axios({
|
||||
url: "/system/assets/docker/list-workspace-docker",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
url: '/system/assets/docker/list-workspace-docker',
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
|
||||
export const statusMap = {
|
||||
0: { desc: '无法连接', color: 'red' },
|
||||
1: { desc: '正常连接', color: 'green' }
|
||||
}
|
||||
|
@ -251,6 +251,14 @@ export function statWorkspace() {
|
||||
})
|
||||
}
|
||||
|
||||
export function statSystemOverview() {
|
||||
return axios({
|
||||
url: '/stat/system',
|
||||
method: 'get',
|
||||
params: {}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 我的集群
|
||||
*
|
||||
|
1
web-vue/src/d.ts/components.d.ts
vendored
1
web-vue/src/d.ts/components.d.ts
vendored
@ -11,6 +11,7 @@ declare module 'vue' {
|
||||
AAlert: typeof import('ant-design-vue/es')['Alert']
|
||||
AAutoComplete: typeof import('ant-design-vue/es')['AutoComplete']
|
||||
ABackTop: typeof import('ant-design-vue/es')['BackTop']
|
||||
ABadge: typeof import('ant-design-vue/es')['Badge']
|
||||
AButton: typeof import('ant-design-vue/es')['Button']
|
||||
AButtonGroup: typeof import('ant-design-vue/es')['ButtonGroup']
|
||||
ACard: typeof import('ant-design-vue/es')['Card']
|
||||
|
@ -117,7 +117,7 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.mangerMenuOpenkeys = []
|
||||
this.$router.push({
|
||||
path: this.mode == 'normal' ? '/system/management' : '/overview'
|
||||
path: this.mode == 'normal' ? '/system/overview' : '/overview'
|
||||
})
|
||||
})
|
||||
},
|
||||
|
@ -128,9 +128,8 @@
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.dataIndex === 'status'">
|
||||
<a-tag color="green" v-if="record.status === 1">正常</a-tag>
|
||||
<a-tooltip v-else :title="record.failureMsg">
|
||||
<a-tag color="red">无法连接</a-tag>
|
||||
<a-tooltip :title="record.failureMsg">
|
||||
<a-tag :color="statusMap[record.status].color">{{ statusMap[record.status].desc || '未知' }}</a-tag>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'operation'">
|
||||
@ -556,7 +555,8 @@ import {
|
||||
dcokerSwarmLeaveForce,
|
||||
machineDockerDistribute,
|
||||
dockerListWorkspace,
|
||||
dockerListGroup
|
||||
dockerListGroup,
|
||||
statusMap
|
||||
} from '@/api/system/assets-docker'
|
||||
import { machineSshListData } from '@/api/system/assets-ssh'
|
||||
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, parseTime } from '@/utils/const'
|
||||
@ -579,6 +579,7 @@ export default {
|
||||
return {
|
||||
loading: false,
|
||||
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
|
||||
statusMap,
|
||||
list: [],
|
||||
groupList: [],
|
||||
temp: {},
|
||||
|
219
web-vue/src/pages/system/overview.vue
Normal file
219
web-vue/src/pages/system/overview.vue
Normal file
@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-page-header :backIcon="false">
|
||||
<template #title> 欢迎【{{ getUserInfo.name }}】您来到系统管理中心</template>
|
||||
<template #subTitle>当前区域为系统管理、资产管理中心 </template>
|
||||
<template v-slot:tags>
|
||||
<a-tag color="blue">
|
||||
<template v-if="getUserInfo.demoUser">演示账号</template>
|
||||
<template v-else-if="getUserInfo.superSystemUser">超级管理员</template>
|
||||
<template v-else-if="getUserInfo.systemUser">管理员</template>
|
||||
<template v-else>普通用户</template>
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-slot:extra>
|
||||
<a-button @click="init" :loading="loading">
|
||||
<template #icon><ReloadOutlined /></template>
|
||||
</a-button>
|
||||
</template>
|
||||
<a-space>
|
||||
<span> 工作空间总数: <a-badge color="blue" :count="statData['workspaceCount'] || '0'" showZero /> </span>
|
||||
<span>集群数:<a-badge color="cyan" :count="statData['clusterCount'] || '0'" showZero /></span>
|
||||
</a-space>
|
||||
</a-page-header>
|
||||
<a-divider dashed />
|
||||
|
||||
<a-row :gutter="[16, 16]">
|
||||
<a-col :span="6">
|
||||
<a-card size="small">
|
||||
<template #title> 机器节点 </template>
|
||||
|
||||
<a-list :data-source="['all', ...Object.keys(nodeStatusMap)]">
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item v-if="item === 'all'">
|
||||
总数:<a-badge
|
||||
:color="item.color"
|
||||
:count="
|
||||
(statData.nodeStat &&
|
||||
statData.nodeStat.reduce(function (sum, item2) {
|
||||
return sum + Number(item2.count)
|
||||
}, 0)) ||
|
||||
'0'
|
||||
"
|
||||
showZero
|
||||
/>
|
||||
</a-list-item>
|
||||
<a-list-item v-else>
|
||||
{{ nodeStatusMap[item] }}:<a-badge
|
||||
:color="Number(item) === 1 ? 'green' : ''"
|
||||
:count="
|
||||
(statData.nodeStat &&
|
||||
statData.nodeStat.find((item2) => {
|
||||
return item2.status === Number(item)
|
||||
}) &&
|
||||
statData.nodeStat.find((item2) => {
|
||||
return item2.status === Number(item)
|
||||
}).count) ||
|
||||
'0'
|
||||
"
|
||||
showZero
|
||||
/>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-card size="small">
|
||||
<template #title> 机器SSH </template>
|
||||
|
||||
<a-list :data-source="['all', ...Object.keys(sshStatusMap)]">
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item v-if="item === 'all'">
|
||||
总数:<a-badge
|
||||
:color="item.color"
|
||||
:count="
|
||||
(statData.sshStat &&
|
||||
statData.sshStat.reduce(function (sum, item2) {
|
||||
return sum + Number(item2.count)
|
||||
}, 0)) ||
|
||||
'0'
|
||||
"
|
||||
showZero
|
||||
/>
|
||||
</a-list-item>
|
||||
<a-list-item v-else>
|
||||
{{ sshStatusMap[item].desc }}:<a-badge
|
||||
:color="sshStatusMap[item].color"
|
||||
:count="
|
||||
(statData.sshStat &&
|
||||
statData.sshStat.find((item2) => {
|
||||
return item2.status === Number(item)
|
||||
}) &&
|
||||
statData.sshStat.find((item2) => {
|
||||
return item2.status === Number(item)
|
||||
}).count) ||
|
||||
'0'
|
||||
"
|
||||
showZero
|
||||
/>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-card size="small">
|
||||
<template #title> 机器DOCKER </template>
|
||||
|
||||
<a-list :data-source="['all', ...Object.keys(dockerStatusMap)]">
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item v-if="item === 'all'">
|
||||
总数:<a-badge
|
||||
:color="item.color"
|
||||
:count="
|
||||
(statData.dockerStat &&
|
||||
statData.dockerStat.reduce(function (sum, item2) {
|
||||
return sum + Number(item2.count)
|
||||
}, 0)) ||
|
||||
'0'
|
||||
"
|
||||
showZero
|
||||
/>
|
||||
</a-list-item>
|
||||
<a-list-item v-else>
|
||||
{{ dockerStatusMap[item].desc }}:<a-badge
|
||||
:color="dockerStatusMap[item].color"
|
||||
:count="
|
||||
(statData.dockerStat &&
|
||||
statData.dockerStat.find((item2) => {
|
||||
return item2.status === Number(item)
|
||||
}) &&
|
||||
statData.dockerStat.find((item2) => {
|
||||
return item2.status === Number(item)
|
||||
}).count) ||
|
||||
'0'
|
||||
"
|
||||
showZero
|
||||
/>
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-card size="small">
|
||||
<template #title> 用户数据 </template>
|
||||
|
||||
<a-list
|
||||
:data-source="[
|
||||
{ name: '用户总数', field: 'userCount', color: 'red' },
|
||||
{ name: '管理员数', field: 'systemUserCount', color: 'pink' },
|
||||
{ name: '开启MFA数', field: 'openTwoFactorAuth', color: 'green' },
|
||||
{ name: '禁用数量', field: 'disableUserCount', color: 'yellow' }
|
||||
]"
|
||||
>
|
||||
<template #renderItem="{ item }">
|
||||
<a-list-item>
|
||||
{{ item.name }}:<a-badge :color="item.color" :count="statData[item.field] || '0'" showZero />
|
||||
</a-list-item>
|
||||
</template>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { statSystemOverview } from '@/api/user/user'
|
||||
|
||||
import { statusMap as nodeStatusMap } from '@/api/system/assets-machine'
|
||||
import { statusMap as sshStatusMap } from '@/api/system/assets-ssh'
|
||||
import { statusMap as dockerStatusMap } from '@/api/system/assets-docker'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { mapState } from 'pinia'
|
||||
|
||||
import { Empty } from 'ant-design-vue'
|
||||
export default {
|
||||
components: {},
|
||||
computed: {},
|
||||
data() {
|
||||
return {
|
||||
Empty,
|
||||
dockerStatusMap,
|
||||
nodeStatusMap,
|
||||
sshStatusMap,
|
||||
loading: true,
|
||||
statData: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useUserStore, ['getUserInfo'])
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// 数据
|
||||
this.loading = true
|
||||
statSystemOverview()
|
||||
.then((res) => {
|
||||
if (res.code == 200 && res.data) {
|
||||
this.statData = res.data || {}
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.ant-divider-horizontal) {
|
||||
margin: 5px 0;
|
||||
}
|
||||
</style>
|
@ -147,6 +147,11 @@ const children = [
|
||||
]
|
||||
|
||||
const management = [
|
||||
{
|
||||
path: '/system/overview',
|
||||
name: 'system-overview',
|
||||
component: () => import('../pages/system/overview.vue')
|
||||
},
|
||||
{
|
||||
path: '/system/assets/machine-list',
|
||||
name: 'system-machine-list',
|
||||
@ -302,7 +307,7 @@ const router = createRouter({
|
||||
path: '/system/management',
|
||||
name: 'sys-management',
|
||||
component: () => import('../pages/layout/management.vue'),
|
||||
redirect: '/system/workspace',
|
||||
redirect: '/system/overview',
|
||||
children: management.map((item: any) => {
|
||||
const props = item.props || {}
|
||||
props.routerUrl = item.path
|
||||
|
@ -55,7 +55,8 @@ const routeMenuMap: Record<string, string> = {
|
||||
fileReleaseTask: '/file-manager/release-task',
|
||||
certificate: '/certificate/list',
|
||||
authConfig: '/system/oauth-config',
|
||||
overview: '/overview'
|
||||
overview: '/overview',
|
||||
'system-overview': '/system/overview'
|
||||
}
|
||||
|
||||
export default routeMenuMap
|
||||
|
Loading…
Reference in New Issue
Block a user