forked from halo-dev/halo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add actuator view page (halo-dev/console#832)
#### What type of PR is this? /kind feature #### What this PR does / why we need it: 添加 Actuator 信息查看页面。适配 halo-dev#3182 todo: - [x] 页面入口 #### Which issue(s) this PR fixes: Fixes halo-dev#3055 #### Screenshots:  #### Special notes for your reviewer: 测试方式: 1. Halo 需要切换到 halo-dev#3182 分支。 2. Console 需要 `pnpm build:packages` 3. 访问 http://localhost:8090/console#/actuator #### Does this PR introduce a user-facing change? ```release-note Console 端添加系统信息查看页面 ```
- Loading branch information
Showing
5 changed files
with
370 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |