mirror of https://github.com/halo-dev/halo-admin
feat: add actuator view page (#832)
#### What type of PR is this? /kind feature #### What this PR does / why we need it: 添加 Actuator 信息查看页面。适配 https://github.com/halo-dev/halo/pull/3182 todo: - [x] 页面入口 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/3055 #### Screenshots:  #### Special notes for your reviewer: 测试方式: 1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/3182 分支。 2. Console 需要 `pnpm build:packages` 3. 访问 http://localhost:8090/console#/actuator #### Does this PR introduce a user-facing change? ```release-note Console 端添加系统信息查看页面 ```pull/833/head
parent
6c7b48b086
commit
21530d309e
|
@ -56,6 +56,8 @@ import IconSendPlaneFill from "~icons/ri/send-plane-fill";
|
|||
import IconRocketLine from "~icons/ri/rocket-line";
|
||||
import IconArrowUpCircleLine from "~icons/ri/arrow-up-circle-line";
|
||||
import IconArrowDownCircleLine from "~icons/ri/arrow-down-circle-line";
|
||||
import IconTerminalBoxLine from "~icons/ri/terminal-box-line";
|
||||
import IconClipboardLine from "~icons/ri/clipboard-line";
|
||||
|
||||
export {
|
||||
IconDashboard,
|
||||
|
@ -116,4 +118,6 @@ export {
|
|||
IconRocketLine,
|
||||
IconArrowUpCircleLine,
|
||||
IconArrowDownCircleLine,
|
||||
IconTerminalBoxLine,
|
||||
IconClipboardLine,
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import pluginModule from "./system/plugins/module";
|
|||
import userModule from "./system/users/module";
|
||||
import roleModule from "./system/roles/module";
|
||||
import settingModule from "./system/settings/module";
|
||||
import actuatorModule from "./system/actuator/module";
|
||||
|
||||
// const coreModules = [
|
||||
// dashboardModule,
|
||||
|
@ -28,6 +29,7 @@ const coreModules = [
|
|||
postModule,
|
||||
pluginModule,
|
||||
settingModule,
|
||||
actuatorModule,
|
||||
dashboardModule,
|
||||
menuModule,
|
||||
commentModule,
|
||||
|
|
|
@ -0,0 +1,241 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
IconTerminalBoxLine,
|
||||
IconClipboardLine,
|
||||
VAlert,
|
||||
VPageHeader,
|
||||
VCard,
|
||||
VButton,
|
||||
Toast,
|
||||
} from "@halo-dev/components";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import type { Info, GlobalInfo, Startup } from "./types";
|
||||
import axios from "axios";
|
||||
import { formatDatetime } from "@/utils/date";
|
||||
import { useClipboard } from "@vueuse/core";
|
||||
|
||||
const info = ref<Info>();
|
||||
const globalInfo = ref<GlobalInfo>();
|
||||
const startup = ref<Startup>();
|
||||
|
||||
const handleFetchActuatorInfo = async () => {
|
||||
const { data } = await axios.get(
|
||||
`${import.meta.env.VITE_API_URL}/actuator/info`,
|
||||
{
|
||||
withCredentials: true,
|
||||
}
|
||||
);
|
||||
info.value = data;
|
||||
};
|
||||
|
||||
const handleFetchActuatorGlobalInfo = async () => {
|
||||
const { data } = await axios.get(
|
||||
`${import.meta.env.VITE_API_URL}/actuator/globalinfo`,
|
||||
{
|
||||
withCredentials: true,
|
||||
}
|
||||
);
|
||||
globalInfo.value = data;
|
||||
};
|
||||
|
||||
const handleFetchActuatorStartup = async () => {
|
||||
const { data } = await axios.get(
|
||||
`${import.meta.env.VITE_API_URL}/actuator/startup`,
|
||||
{
|
||||
withCredentials: true,
|
||||
}
|
||||
);
|
||||
startup.value = data;
|
||||
};
|
||||
|
||||
const isExternalUrlValid = computed(() => {
|
||||
if (!globalInfo.value?.externalUrl) {
|
||||
return false;
|
||||
}
|
||||
const url = new URL(globalInfo.value.externalUrl);
|
||||
const { host: currentHost, protocol: currentProtocol } = window.location;
|
||||
return url.host === currentHost && url.protocol === currentProtocol;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
handleFetchActuatorInfo();
|
||||
handleFetchActuatorGlobalInfo();
|
||||
handleFetchActuatorStartup();
|
||||
});
|
||||
|
||||
// copy system information to clipboard
|
||||
const { copy, isSupported } = useClipboard();
|
||||
|
||||
const handleCopy = () => {
|
||||
if (!isSupported.value) {
|
||||
Toast.warning("当前浏览器不支持复制");
|
||||
}
|
||||
|
||||
const text = `
|
||||
- 外部访问地址:${globalInfo.value?.externalUrl}
|
||||
- 启动时间:${formatDatetime(startup.value?.timeline.startTime)}
|
||||
- Halo 版本:${info.value?.build?.version}
|
||||
- 构建时间:${formatDatetime(info.value?.build?.time)}
|
||||
- Git Commit:${info.value?.git?.commit.id}
|
||||
- Java:${info.value?.java.runtime.name} / ${info.value?.java.runtime.version}
|
||||
- 操作系统:${info.value?.os.name} / ${info.value?.os.version}
|
||||
`;
|
||||
|
||||
copy(text);
|
||||
|
||||
Toast.success("复制成功");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPageHeader title="系统概览">
|
||||
<template #icon>
|
||||
<IconTerminalBoxLine class="mr-2 self-center" />
|
||||
</template>
|
||||
<template #actions>
|
||||
<VButton size="sm" @click="handleCopy">
|
||||
<template #icon>
|
||||
<IconClipboardLine class="h-full w-full" />
|
||||
</template>
|
||||
复制
|
||||
</VButton>
|
||||
</template>
|
||||
</VPageHeader>
|
||||
|
||||
<div class="m-0 flex flex-col gap-4 md:m-4">
|
||||
<VCard :body-class="['!p-0']">
|
||||
<div class="bg-white">
|
||||
<div
|
||||
class="flex items-center justify-between bg-white px-4 py-4 sm:px-6"
|
||||
>
|
||||
<div>
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">
|
||||
基本信息
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<dl class="divide-y divide-gray-100">
|
||||
<div
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">外部访问地址</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
<span>
|
||||
{{ globalInfo?.externalUrl }}
|
||||
</span>
|
||||
<VAlert
|
||||
v-if="!isExternalUrlValid"
|
||||
class="mt-3"
|
||||
type="warning"
|
||||
title="警告"
|
||||
:closable="false"
|
||||
>
|
||||
<template #description>
|
||||
检测到外部访问地址与当前访问地址不一致,可能会导致部分链接无法正常跳转,请检查外部访问地址设置。
|
||||
</template>
|
||||
</VAlert>
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">启动时间</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
{{ formatDatetime(startup?.timeline.startTime) }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">时区</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
{{ globalInfo?.timeZone }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">语言</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
{{ globalInfo?.locale }}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</VCard>
|
||||
<VCard v-if="info" :body-class="['!p-0']">
|
||||
<div class="bg-white">
|
||||
<div
|
||||
class="flex items-center justify-between bg-white px-4 py-4 sm:px-6"
|
||||
>
|
||||
<div>
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">
|
||||
环境信息
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<dl class="divide-y divide-gray-100">
|
||||
<div
|
||||
v-if="info.build"
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">版本</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
<a
|
||||
:href="`https://github.com/halo-dev/halo/releases/tag/v${info.build.version}`"
|
||||
class="hover:text-gray-600"
|
||||
target="_blank"
|
||||
>
|
||||
{{ info.build.version }}
|
||||
</a>
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
v-if="info.build"
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">构建时间</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
{{ formatDatetime(info.build.time) }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
v-if="info.git"
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">Git Commit</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
<a
|
||||
:href="`https://github.com/halo-dev/halo/commit/${info.git.commit.id}`"
|
||||
class="hover:text-gray-600"
|
||||
target="_blank"
|
||||
>
|
||||
{{ info.git.commit.id }}
|
||||
</a>
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">Java</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
{{ info.java.runtime.name }} / {{ info.java.runtime.version }}
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white px-4 py-5 hover:bg-gray-50 sm:grid sm:grid-cols-6 sm:gap-4 sm:px-6"
|
||||
>
|
||||
<dt class="text-sm font-medium text-gray-900">操作系统</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||
{{ info.os.name }} {{ info.os.version }} / {{ info.os.arch }}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</VCard>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,32 @@
|
|||
import { definePlugin } from "@halo-dev/console-shared";
|
||||
import { IconTerminalBoxLine } from "@halo-dev/components";
|
||||
import BasicLayout from "@/layouts/BasicLayout.vue";
|
||||
import Actuator from "./Actuator.vue";
|
||||
import { markRaw } from "vue";
|
||||
|
||||
export default definePlugin({
|
||||
components: {},
|
||||
routes: [
|
||||
{
|
||||
path: "/actuator",
|
||||
component: BasicLayout,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
component: Actuator,
|
||||
meta: {
|
||||
title: "系统概览",
|
||||
searchable: true,
|
||||
menu: {
|
||||
name: "概览",
|
||||
group: "system",
|
||||
icon: markRaw(IconTerminalBoxLine),
|
||||
priority: 3,
|
||||
mobile: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,91 @@
|
|||
export interface GlobalInfo {
|
||||
externalUrl: string;
|
||||
timeZone: string;
|
||||
locale: string;
|
||||
allowComments: boolean;
|
||||
allowAnonymousComments: boolean;
|
||||
allowRegistration: boolean;
|
||||
}
|
||||
|
||||
export interface Info {
|
||||
git?: Git;
|
||||
build?: Build;
|
||||
java: Java;
|
||||
os: Os;
|
||||
}
|
||||
|
||||
export interface Commit {
|
||||
id: string;
|
||||
time: Date;
|
||||
}
|
||||
|
||||
export interface Git {
|
||||
branch: string;
|
||||
commit: Commit;
|
||||
}
|
||||
|
||||
export interface Build {
|
||||
artifact: string;
|
||||
name: string;
|
||||
time: Date;
|
||||
version: string;
|
||||
group: string;
|
||||
}
|
||||
|
||||
export interface Vendor {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface Runtime {
|
||||
name: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface Jvm {
|
||||
name: string;
|
||||
vendor: string;
|
||||
version: string;
|
||||
}
|
||||
|
||||
export interface Java {
|
||||
version: string;
|
||||
vendor: Vendor;
|
||||
runtime: Runtime;
|
||||
jvm: Jvm;
|
||||
}
|
||||
|
||||
export interface Os {
|
||||
name: string;
|
||||
version: string;
|
||||
arch: string;
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface StartupStep {
|
||||
name: string;
|
||||
id: number;
|
||||
tags: Tag[];
|
||||
parentId?: number;
|
||||
}
|
||||
|
||||
export interface Event {
|
||||
endTime: Date;
|
||||
duration: string;
|
||||
startTime: Date;
|
||||
startupStep: StartupStep;
|
||||
}
|
||||
|
||||
export interface Timeline {
|
||||
startTime: Date;
|
||||
events: Event[];
|
||||
}
|
||||
|
||||
export interface Startup {
|
||||
springBootVersion: string;
|
||||
timeline: Timeline;
|
||||
}
|
Loading…
Reference in New Issue