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 IconRocketLine from "~icons/ri/rocket-line";
|
||||||
import IconArrowUpCircleLine from "~icons/ri/arrow-up-circle-line";
|
import IconArrowUpCircleLine from "~icons/ri/arrow-up-circle-line";
|
||||||
import IconArrowDownCircleLine from "~icons/ri/arrow-down-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 {
|
export {
|
||||||
IconDashboard,
|
IconDashboard,
|
||||||
|
@ -116,4 +118,6 @@ export {
|
||||||
IconRocketLine,
|
IconRocketLine,
|
||||||
IconArrowUpCircleLine,
|
IconArrowUpCircleLine,
|
||||||
IconArrowDownCircleLine,
|
IconArrowDownCircleLine,
|
||||||
|
IconTerminalBoxLine,
|
||||||
|
IconClipboardLine,
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@ import pluginModule from "./system/plugins/module";
|
||||||
import userModule from "./system/users/module";
|
import userModule from "./system/users/module";
|
||||||
import roleModule from "./system/roles/module";
|
import roleModule from "./system/roles/module";
|
||||||
import settingModule from "./system/settings/module";
|
import settingModule from "./system/settings/module";
|
||||||
|
import actuatorModule from "./system/actuator/module";
|
||||||
|
|
||||||
// const coreModules = [
|
// const coreModules = [
|
||||||
// dashboardModule,
|
// dashboardModule,
|
||||||
|
@ -28,6 +29,7 @@ const coreModules = [
|
||||||
postModule,
|
postModule,
|
||||||
pluginModule,
|
pluginModule,
|
||||||
settingModule,
|
settingModule,
|
||||||
|
actuatorModule,
|
||||||
dashboardModule,
|
dashboardModule,
|
||||||
menuModule,
|
menuModule,
|
||||||
commentModule,
|
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