소스 검색

feat: display the version and backend service status on the page (#848)

### What problem does this PR solve?

#643 feat: display the version and backend service status on the page

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
tags/v0.6.0
balibabu 1 년 전
부모
커밋
93b35f4e58
No account linked to committer's email address

+ 24
- 0
web/src/assets/svg/es.svg 파일 보기

@@ -0,0 +1,24 @@
<svg t="1716195941333" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7780"
width="200" height="200">
<path
d="M1024 534.4c0-85.76-53.12-160.96-133.44-190.08 3.52-17.92 5.44-36.16 5.44-55.04C896 129.92 766.4 0 606.72 0c-93.12 0-179.84 44.8-234.24 120A153.632 153.632 0 0 0 278.4 87.68a153.632 153.632 0 0 0-144 207.04c-79.68 28.8-134.4 105.6-134.4 190.72 0 86.4 53.44 161.6 133.76 190.72-3.52 17.92-5.12 36.48-5.12 55.04 0 159.04 129.6 288.64 288.64 288.64 93.44 0 180.16-44.8 234.24-120.64a152 152 0 0 0 94.08 32.64 153.632 153.632 0 0 0 144-207.04c79.68-28.48 134.4-105.28 134.4-190.4"
fill="#FFFFFF" p-id="7781"></path>
<path
d="M402.56 439.36l224 102.08 225.92-198.08c3.2-16.32 4.8-32.64 4.8-49.6 0-139.52-113.28-252.8-252.8-252.8-83.52 0-161.28 40.96-208.32 109.76l-37.76 195.2 44.16 93.44z"
fill="#FFD00A" p-id="7782"></path>
<path
d="M170.56 676.48c-3.2 16.32-4.8 33.28-4.8 50.56 0 139.84 113.6 253.44 253.44 253.44 84.16 0 162.24-41.28 209.28-111.04l37.44-194.56-49.92-95.04-224.96-102.4-220.48 199.04z"
fill="#20B9AF" p-id="7783"></path>
<path
d="M169.28 288.96l153.6 36.16 33.6-174.72c-21.12-16-47.04-24.96-73.6-24.96-66.88 0-120.96 54.4-120.96 120.96 0 15.04 2.56 29.12 7.36 42.56"
fill="#EE5096" p-id="7784"></path>
<path
d="M155.84 325.44c-68.48 22.72-116.16 88.64-116.16 160.96 0 70.4 43.52 133.44 108.8 158.08l215.36-194.88-39.68-84.48-168.32-39.68z"
fill="#12A5DF" p-id="7785"></path>
<path
d="M667.84 869.44c21.12 16.32 46.72 24.96 73.28 24.96 66.88 0 120.96-54.4 120.96-120.96 0-14.72-2.56-28.8-7.36-42.24l-153.28-35.84-33.6 174.08z"
fill="#90C640" p-id="7786"></path>
<path
d="M699.2 655.36l168.96 39.36c68.48-22.72 116.48-88.32 116.48-160.96 0-70.4-43.52-133.12-109.12-158.08l-220.8 193.6 44.48 86.08z"
fill="#05799F" p-id="7787"></path>
</svg>

+ 10
- 0
web/src/assets/svg/minio.svg 파일 보기

@@ -0,0 +1,10 @@
<svg t="1716195854453" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5857"
width="200" height="200">
<path
d="M638.855218 56.525807s99.268136 159.838523 132.357514 216.623262a2.523766 2.523766 0 0 1 0 2.944394 2.383557 2.383557 0 0 1-3.50523 0L596.231612 97.326693l42.623606-40.800886z"
fill="#dd113c" p-id="5858"></path>
<path
d="M346.518971 639.655999a588.878771 588.878771 0 0 1 116.654081-165.446893 597.291325 597.291325 0 0 1 58.32704-51.176369v126.188308L346.518971 639.655999zM245.568325 756.590498l275.931767-140.209231v321.079139l62.112689 80.760517v-434.648616l37.716283-19.489084a187.179324 187.179324 0 0 0 51.456788-296.121896L530.753901 119.479752a31.547077 31.547077 0 0 1 1.542302-44.446327 31.687286 31.687286 0 0 1 44.586535 1.542302l19.909711 20.750966 42.062769-40.941095c-50.335114-65.337502-112.167385-57.065157-147.64032-24.396407a90.575163 90.575163 0 0 0-3.925859 127.870819l143.574253 149.60325a128.151237 128.151237 0 0 1-28.041846 197.414597l-19.489083 10.095065V314.090164A649.589368 649.589368 0 0 0 245.568325 755.889452v0.701046z"
fill="#dd113c" p-id="5859"></path>
<path d="M583.612781 583.432097v65.617921l-62.112689 31.547077v-65.197293z" fill="#dd113c" p-id="5860"></path>
</svg>

+ 9
- 0
web/src/assets/svg/mysql.svg 파일 보기

@@ -0,0 +1,9 @@
<svg t="1716195691568" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4834"
width="200" height="200">
<path
d="M1001.632 793.792c-7.84-13.856-26.016-37.536-93.12-83.2a1096.224 1096.224 0 0 0-125.152-74.144c-30.592-82.784-89.824-190.112-176.256-319.36-93.056-139.168-201.12-197.792-321.888-174.56a756.608 756.608 0 0 0-40.928-37.696C213.824 78.688 139.2 56.48 96.32 60.736c-19.424 1.952-34.016 9.056-43.36 21.088-21.664 27.904-14.432 68.064 85.504 198.912 19.008 55.616 23.072 84.672 23.072 99.296 0 30.912 15.968 66.368 49.984 110.752l-32 109.504c-28.544 97.792 23.328 224.288 71.616 268.384 25.76 23.552 47.456 20.032 58.176 15.84 21.504-8.448 38.848-29.472 50.048-89.504 5.728 14.112 11.808 29.312 18.208 45.6 34.56 87.744 68.352 136.288 106.336 152.736a32.032 32.032 0 0 0 25.44-58.688c-9.408-4.096-35.328-23.712-72.288-117.504-31.168-79.136-53.856-132.064-69.376-161.856a32.224 32.224 0 0 0-35.328-16.48 32.032 32.032 0 0 0-25.024 29.92c-3.872 91.04-13.056 130.4-19.2 147.008-26.496-30.464-68.128-125.984-47.232-197.536 20.768-71.232 32.992-112.928 36.64-125.248a31.936 31.936 0 0 0-5.888-29.28c-41.664-51.168-46.176-75.584-46.176-83.712 0-29.472-9.248-70.4-28.288-125.152a31.104 31.104 0 0 0-4.768-8.896c-53.824-70.112-73.6-105.216-80.832-121.888 25.632 1.216 74.336 15.04 91.008 29.376a660.8 660.8 0 0 1 49.024 46.304c8 8.448 19.968 11.872 31.232 8.928 100.192-25.92 188.928 21.152 271.072 144 87.808 131.328 146.144 238.048 173.408 317.216a32 32 0 0 0 16.384 18.432 1004.544 1004.544 0 0 1 128.8 75.264c7.392 5.024 14.048 9.696 20.064 14.016h-98.848a32.032 32.032 0 0 0-24.352 52.736 3098.752 3098.752 0 0 0 97.856 110.464 32 32 0 1 0 46.56-43.872 2237.6 2237.6 0 0 1-50.08-55.328h110.08a32.032 32.032 0 0 0 27.84-47.776z"
p-id="4835"></path>
<path
d="M320 289.472c12.672 21.76 22.464 37.344 29.344 46.784 8.288 16.256 21.184 29.248 29.44 45.536l2.016-1.984c14.528-9.952 25.92-49.504 2.752-75.488-12.032-18.176-51.04-17.664-63.552-14.848z"
p-id="4836"></path>
</svg>

+ 6
- 0
web/src/assets/svg/redis.svg 파일 보기

@@ -0,0 +1,6 @@
<svg t="1716195575286" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3818"
width="200" height="200">
<path
d="M959.744 602.16l0.256 0.064v101.952c0 10.24-10.752 21.44-35.072 35.84-22.976 13.696-91.968 47.616-163.328 82.624l-35.712 17.536c-65.088 32-126.016 62.208-149.184 76.032-52.8 31.36-82.048 31.104-123.712 8.32-41.6-22.72-305.28-144.256-352.704-170.176-23.744-12.992-36.224-23.936-36.224-34.24v-103.424c0.384 10.368 12.48 21.248 36.224 34.24C147.776 676.8 411.328 798.4 452.992 821.12c41.664 22.784 70.912 23.04 123.712-8.32 52.672-31.36 300.416-147.712 348.224-176.128 23.232-13.824 34.56-24.768 34.88-34.56l-0.064 0.064z m0-168.576h0.192v101.952c0 10.24-10.752 21.44-35.072 35.968-47.808 28.416-295.552 144.768-348.224 176.128-52.8 31.36-82.048 31.04-123.712 8.32-41.6-22.72-305.28-144.32-352.704-170.24C76.48 572.8 64 561.92 64 551.536v-103.424c0.384 10.24 12.48 21.248 36.224 34.176 47.488 25.92 311.04 147.52 352.704 170.24 41.664 22.72 70.912 23.04 123.712-8.32 52.672-31.36 300.416-147.712 348.224-176.192 23.168-13.824 34.56-24.704 34.88-34.432zM462.656 81.84c55.36-22.72 74.56-23.488 121.664-3.776 47.168 19.776 293.376 131.648 339.968 151.104 24 10.048 35.84 19.2 35.456 29.632H960v101.952c0 10.176-10.816 21.44-35.072 35.904C877.056 425.072 629.376 541.44 576.64 572.8c-52.736 31.36-81.984 31.104-123.648 8.32-41.664-22.656-305.28-144.32-352.768-170.24C76.544 397.936 64 387.056 64 376.688V273.28c-0.32-10.304 11.072-19.968 34.368-30.464 46.656-20.8 308.8-138.24 364.288-160.896v-0.064z m129.792 238.4l-207.552 36.352 144.832 68.608 62.72-104.96z m128.704-113.6l-135.936 61.44 122.688 55.36 13.376-5.952 122.752-55.424-122.88-55.424z m-392.32 13.44c-61.248 0-110.912 22.016-110.912 49.152 0 27.072 49.664 49.088 110.976 49.088s110.912-21.952 110.912-49.088-49.6-49.088-110.912-49.088l-0.064-0.064z m134.656-101.888l20.096 42.304-66.88 27.52 89.6 9.216 28.032 53.248 17.408-47.744 77.632-9.216-60.16-25.728 16-43.712-59.136 22.08-62.592-27.968z"
fill="#D82A1F" p-id="3819"></path>
</svg>

+ 2
- 0
web/src/constants/setting.ts 파일 보기

@@ -4,6 +4,7 @@ export enum UserSettingRouteKey {
Profile = 'profile',
Password = 'password',
Model = 'model',
System = 'system',
Team = 'team',
Logout = 'logout',
}
@@ -12,6 +13,7 @@ export const UserSettingRouteMap = {
[UserSettingRouteKey.Profile]: 'Profile',
[UserSettingRouteKey.Password]: 'Password',
[UserSettingRouteKey.Model]: 'Model Providers',
[UserSettingRouteKey.System]: 'System Version',
[UserSettingRouteKey.Team]: 'Team',
[UserSettingRouteKey.Logout]: 'Log out',
};

+ 41
- 2
web/src/hooks/userSettingHook.ts 파일 보기

@@ -1,7 +1,8 @@
import { ITenantInfo } from '@/interfaces/database/knowledge';
import { IUserInfo } from '@/interfaces/database/userSetting';
import { ISystemStatus, IUserInfo } from '@/interfaces/database/userSetting';
import userService from '@/services/userService';
import authorizationUtil from '@/utils/authorizationUtil';
import { useCallback, useEffect, useMemo } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { history, useDispatch, useSelector } from 'umi';

export const useFetchUserInfo = () => {
@@ -92,3 +93,41 @@ export const useSaveSetting = () => {

return saveSetting;
};

export const useFetchSystemVersion = () => {
const [version, setVersion] = useState('');
const [loading, setLoading] = useState(false);

const fetchSystemVersion = useCallback(async () => {
setLoading(true);
const { data } = await userService.getSystemVersion();
if (data.retcode === 0) {
setVersion(data.data);
setLoading(false);
}
}, []);

return { fetchSystemVersion, version, loading };
};

export const useFetchSystemStatus = () => {
const [systemStatus, setSystemStatus] = useState<ISystemStatus>(
{} as ISystemStatus,
);
const [loading, setLoading] = useState(false);

const fetchSystemStatus = useCallback(async () => {
setLoading(true);
const { data } = await userService.getSystemStatus();
if (data.retcode === 0) {
setSystemStatus(data.data);
setLoading(false);
}
}, []);

return {
systemStatus,
fetchSystemStatus,
loading,
};
};

+ 28
- 0
web/src/interfaces/database/userSetting.ts 파일 보기

@@ -19,3 +19,31 @@ export interface IUserInfo {
update_date: string;
update_time: number;
}

export interface ISystemStatus {
es: Es;
minio: Minio;
mysql: Minio;
redis: Redis;
}

interface Redis {
status: string;
elapsed: number;
error: string;
pending: number;
}

export interface Minio {
status: string;
elapsed: number;
error: string;
}

interface Es {
status: string;
elapsed: number;
error: string;
number_of_nodes: number;
active_shards: number;
}

+ 1
- 0
web/src/locales/en.ts 파일 보기

@@ -393,6 +393,7 @@ export default {
model: 'Model Providers',
modelDescription: 'Set the model parameter and API Key here.',
team: 'Team',
system: 'System',
logout: 'Log out',
username: 'Username',
usernameMessage: 'Please input your username!',

+ 1
- 0
web/src/locales/zh-traditional.ts 파일 보기

@@ -364,6 +364,7 @@ export default {
modelDescription: '在此設置模型參數和 API Key。',
team: '團隊',
logout: '登出',
system: '系統',
username: '使用者名稱',
usernameMessage: '請輸入用戶名',
photo: '頭像',

+ 1
- 0
web/src/locales/zh.ts 파일 보기

@@ -380,6 +380,7 @@ export default {
model: '模型提供商',
modelDescription: '在此设置模型参数和 API Key。',
team: '团队',
system: '系统',
logout: '登出',
username: '用户名',
usernameMessage: '请输入用户名',

+ 2
- 0
web/src/pages/user-setting/constants.tsx 파일 보기

@@ -4,11 +4,13 @@ import { ReactComponent as PasswordIcon } from '@/assets/svg/password.svg';
import { ReactComponent as ProfileIcon } from '@/assets/svg/profile.svg';
import { ReactComponent as TeamIcon } from '@/assets/svg/team.svg';
import { UserSettingRouteKey } from '@/constants/setting';
import { MonitorOutlined } from '@ant-design/icons';

export const UserSettingIconMap = {
[UserSettingRouteKey.Profile]: <ProfileIcon />,
[UserSettingRouteKey.Password]: <PasswordIcon />,
[UserSettingRouteKey.Model]: <ModelIcon />,
[UserSettingRouteKey.System]: <MonitorOutlined style={{ fontSize: 24 }} />,
[UserSettingRouteKey.Team]: <TeamIcon />,
[UserSettingRouteKey.Logout]: <LogoutIcon />,
};

+ 2
- 0
web/src/pages/user-setting/index.less 파일 보기

@@ -3,6 +3,8 @@

.outletWrapper {
padding: 32px 32px 0;
height: 100%;
overflow-y: auto;
}

.itemDescription {

+ 20
- 0
web/src/pages/user-setting/setting-system/index.less 파일 보기

@@ -0,0 +1,20 @@
.systemInfo {
width: 100%;
.title {
font-size: 20px;
font-weight: 600;
}
.text {
height: 26px;
line-height: 26px;
}
.badge {
:global(.ant-badge-status-dot) {
width: 10px;
height: 10px;
}
}
.error {
color: red;
}
}

+ 94
- 0
web/src/pages/user-setting/setting-system/index.tsx 파일 보기

@@ -0,0 +1,94 @@
import SvgIcon from '@/components/svg-icon';
import { useFetchSystemStatus } from '@/hooks/userSettingHook';
import { ISystemStatus, Minio } from '@/interfaces/database/userSetting';
import { Badge, Card, Flex, Spin, Typography } from 'antd';
import classNames from 'classnames';
import lowerCase from 'lodash/lowerCase';
import upperFirst from 'lodash/upperFirst';
import { useEffect } from 'react';

import { toFixed } from '@/utils/commonUtil';
import styles from './index.less';

const { Text } = Typography;

enum Status {
'green' = 'success',
'red' = 'error',
'yellow' = 'warning',
}

const TitleMap = {
es: 'Elasticsearch',
minio: 'MinIO Object Storage',
redis: 'Redis',
mysql: 'Mysql',
};

const SystemInfo = () => {
const {
systemStatus,
fetchSystemStatus,
loading: statusLoading,
} = useFetchSystemStatus();

useEffect(() => {
fetchSystemStatus();
}, [fetchSystemStatus]);

return (
<section className={styles.systemInfo}>
<Spin spinning={statusLoading}>
<Flex gap={16} vertical>
{Object.keys(systemStatus).map((key) => {
const info = systemStatus[key as keyof ISystemStatus];

return (
<Card
type="inner"
title={
<Flex align="center" gap={10}>
<SvgIcon name={key} width={26}></SvgIcon>
<span className={styles.title}>
{TitleMap[key as keyof typeof TitleMap]}
</span>
<Badge
className={styles.badge}
status={Status[info.status as keyof typeof Status]}
/>
</Flex>
}
key={key}
>
{Object.keys(info)
.filter((x) => x !== 'status')
.map((x) => {
return (
<Flex
key={x}
align="center"
gap={16}
className={styles.text}
>
<b>{upperFirst(lowerCase(x))}:</b>
<Text
className={classNames({
[styles.error]: x === 'error',
})}
>
{toFixed(info[x as keyof Minio]) as any}
{x === 'elapsed' && ' ms'}
</Text>
</Flex>
);
})}
</Card>
);
})}
</Flex>
</Spin>
</section>
);
};

export default SystemInfo;

+ 3
- 0
web/src/pages/user-setting/sidebar/index.less 파일 보기

@@ -1,3 +1,6 @@
.sideBarWrapper {
padding-top: 32px;
.version {
color: rgb(17, 206, 17);
}
}

+ 16
- 4
web/src/pages/user-setting/sidebar/index.tsx 파일 보기

@@ -1,7 +1,7 @@
import { useSecondPathName } from '@/hooks/routeHook';
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import React, { useMemo } from 'react';
import { Flex, Menu } from 'antd';
import React, { useEffect, useMemo } from 'react';
import { useNavigate } from 'umi';
import {
UserSettingBaseKey,
@@ -10,7 +10,7 @@ import {
} from '../constants';

import { useTranslate } from '@/hooks/commonHooks';
import { useLogout } from '@/hooks/userSettingHook';
import { useFetchSystemVersion, useLogout } from '@/hooks/userSettingHook';
import styles from './index.less';

type MenuItem = Required<MenuProps>['items'][number];
@@ -20,6 +20,11 @@ const SideBar = () => {
const pathName = useSecondPathName();
const logout = useLogout();
const { t } = useTranslate('setting');
const { version, fetchSystemVersion } = useFetchSystemVersion();

useEffect(() => {
fetchSystemVersion();
}, [fetchSystemVersion]);

function getItem(
label: string,
@@ -32,7 +37,14 @@ const SideBar = () => {
key,
icon,
children,
label: t(label),
label: (
<Flex justify={'space-between'}>
{t(label)}
<span className={styles.version}>
{label === 'system' && version}
</span>
</Flex>
),
type,
} as MenuItem;
}

+ 4
- 0
web/src/routes.ts 파일 보기

@@ -78,6 +78,10 @@ const routes = [
path: '/user-setting/team',
component: '@/pages/user-setting/setting-team',
},
{
path: '/user-setting/system',
component: '@/pages/user-setting/setting-system',
},
],
},
{

+ 10
- 0
web/src/services/userService.ts 파일 보기

@@ -16,6 +16,8 @@ const {
set_tenant_info,
add_llm,
delete_llm,
getSystemStatus,
getSystemVersion,
} = api;
const methods = {
@@ -71,6 +73,14 @@ const methods = {
url: delete_llm,
method: 'post',
},
getSystemStatus: {
url: getSystemStatus,
method: 'get',
},
getSystemVersion: {
url: getSystemVersion,
method: 'get',
},
} as const;
const userService = registerServer<keyof typeof methods>(methods, request);

+ 4
- 0
web/src/utils/api.ts 파일 보기

@@ -77,4 +77,8 @@ export default {
createFolder: `${api_host}/file/create`,
connectFileToKnowledge: `${api_host}/file2document/convert`,
getFile: `${api_host}/file/get`,
// system
getSystemVersion: `${api_host}/system/version`,
getSystemStatus: `${api_host}/system/status`,
};

+ 7
- 0
web/src/utils/commonUtil.ts 파일 보기

@@ -65,3 +65,10 @@ export const filterOptionsByInput = (
input: string,
option: { label: string; value: string } | undefined,
) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase());

export const toFixed = (value: unknown, fixed = 2) => {
if (typeof value === 'number') {
return value.toFixed(fixed);
}
return value;
};

+ 1
- 1
web/src/utils/registerServer.ts 파일 보기

@@ -9,7 +9,7 @@ const registerServer = <T extends string>(
) => {
const server: Service<T> = {} as Service<T>;
for (let key in opt) {
server[key] = (params: any, urlAppendix?: string) => {
server[key] = (params?: any, urlAppendix?: string) => {
let url = opt[key].url;
const requestOptions = opt[key];
if (urlAppendix) {

Loading…
취소
저장