Skip to content

Commit

Permalink
feat: add actuator view page (halo-dev/console#832)
Browse files Browse the repository at this point in the history
#### 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:

![image](https://user-images.githubusercontent.com/21301288/215386617-e3aafc6d-777d-49e8-93c9-b9432623e98e.png)


#### 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
ruibaby authored Jan 31, 2023
1 parent 4c816dc commit c2e967c
Show file tree
Hide file tree
Showing 5 changed files with 370 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/components/src/icons/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -116,4 +118,6 @@ export {
IconRocketLine,
IconArrowUpCircleLine,
IconArrowDownCircleLine,
IconTerminalBoxLine,
IconClipboardLine,
};
2 changes: 2 additions & 0 deletions src/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -28,6 +29,7 @@ const coreModules = [
postModule,
pluginModule,
settingModule,
actuatorModule,
dashboardModule,
menuModule,
commentModule,
Expand Down
241 changes: 241 additions & 0 deletions src/modules/system/actuator/Actuator.vue
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>
32 changes: 32 additions & 0 deletions src/modules/system/actuator/module.ts
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,
},
},
},
],
},
],
});
91 changes: 91 additions & 0 deletions src/modules/system/actuator/types/index.ts
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;
}

0 comments on commit c2e967c

Please sign in to comment.