### 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
| <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> |
| <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> |
| <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> |
| <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> |
| Profile = 'profile', | Profile = 'profile', | ||||
| Password = 'password', | Password = 'password', | ||||
| Model = 'model', | Model = 'model', | ||||
| System = 'system', | |||||
| Team = 'team', | Team = 'team', | ||||
| Logout = 'logout', | Logout = 'logout', | ||||
| } | } | ||||
| [UserSettingRouteKey.Profile]: 'Profile', | [UserSettingRouteKey.Profile]: 'Profile', | ||||
| [UserSettingRouteKey.Password]: 'Password', | [UserSettingRouteKey.Password]: 'Password', | ||||
| [UserSettingRouteKey.Model]: 'Model Providers', | [UserSettingRouteKey.Model]: 'Model Providers', | ||||
| [UserSettingRouteKey.System]: 'System Version', | |||||
| [UserSettingRouteKey.Team]: 'Team', | [UserSettingRouteKey.Team]: 'Team', | ||||
| [UserSettingRouteKey.Logout]: 'Log out', | [UserSettingRouteKey.Logout]: 'Log out', | ||||
| }; | }; |
| import { ITenantInfo } from '@/interfaces/database/knowledge'; | 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 authorizationUtil from '@/utils/authorizationUtil'; | ||||
| import { useCallback, useEffect, useMemo } from 'react'; | |||||
| import { useCallback, useEffect, useMemo, useState } from 'react'; | |||||
| import { history, useDispatch, useSelector } from 'umi'; | import { history, useDispatch, useSelector } from 'umi'; | ||||
| export const useFetchUserInfo = () => { | export const useFetchUserInfo = () => { | ||||
| return saveSetting; | 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, | |||||
| }; | |||||
| }; |
| update_date: string; | update_date: string; | ||||
| update_time: number; | 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; | |||||
| } |
| model: 'Model Providers', | model: 'Model Providers', | ||||
| modelDescription: 'Set the model parameter and API Key here.', | modelDescription: 'Set the model parameter and API Key here.', | ||||
| team: 'Team', | team: 'Team', | ||||
| system: 'System', | |||||
| logout: 'Log out', | logout: 'Log out', | ||||
| username: 'Username', | username: 'Username', | ||||
| usernameMessage: 'Please input your username!', | usernameMessage: 'Please input your username!', |
| modelDescription: '在此設置模型參數和 API Key。', | modelDescription: '在此設置模型參數和 API Key。', | ||||
| team: '團隊', | team: '團隊', | ||||
| logout: '登出', | logout: '登出', | ||||
| system: '系統', | |||||
| username: '使用者名稱', | username: '使用者名稱', | ||||
| usernameMessage: '請輸入用戶名', | usernameMessage: '請輸入用戶名', | ||||
| photo: '頭像', | photo: '頭像', |
| model: '模型提供商', | model: '模型提供商', | ||||
| modelDescription: '在此设置模型参数和 API Key。', | modelDescription: '在此设置模型参数和 API Key。', | ||||
| team: '团队', | team: '团队', | ||||
| system: '系统', | |||||
| logout: '登出', | logout: '登出', | ||||
| username: '用户名', | username: '用户名', | ||||
| usernameMessage: '请输入用户名', | usernameMessage: '请输入用户名', |
| import { ReactComponent as ProfileIcon } from '@/assets/svg/profile.svg'; | import { ReactComponent as ProfileIcon } from '@/assets/svg/profile.svg'; | ||||
| import { ReactComponent as TeamIcon } from '@/assets/svg/team.svg'; | import { ReactComponent as TeamIcon } from '@/assets/svg/team.svg'; | ||||
| import { UserSettingRouteKey } from '@/constants/setting'; | import { UserSettingRouteKey } from '@/constants/setting'; | ||||
| import { MonitorOutlined } from '@ant-design/icons'; | |||||
| export const UserSettingIconMap = { | export const UserSettingIconMap = { | ||||
| [UserSettingRouteKey.Profile]: <ProfileIcon />, | [UserSettingRouteKey.Profile]: <ProfileIcon />, | ||||
| [UserSettingRouteKey.Password]: <PasswordIcon />, | [UserSettingRouteKey.Password]: <PasswordIcon />, | ||||
| [UserSettingRouteKey.Model]: <ModelIcon />, | [UserSettingRouteKey.Model]: <ModelIcon />, | ||||
| [UserSettingRouteKey.System]: <MonitorOutlined style={{ fontSize: 24 }} />, | |||||
| [UserSettingRouteKey.Team]: <TeamIcon />, | [UserSettingRouteKey.Team]: <TeamIcon />, | ||||
| [UserSettingRouteKey.Logout]: <LogoutIcon />, | [UserSettingRouteKey.Logout]: <LogoutIcon />, | ||||
| }; | }; |
| .outletWrapper { | .outletWrapper { | ||||
| padding: 32px 32px 0; | padding: 32px 32px 0; | ||||
| height: 100%; | |||||
| overflow-y: auto; | |||||
| } | } | ||||
| .itemDescription { | .itemDescription { |
| .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; | |||||
| } | |||||
| } |
| 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; |
| .sideBarWrapper { | .sideBarWrapper { | ||||
| padding-top: 32px; | padding-top: 32px; | ||||
| .version { | |||||
| color: rgb(17, 206, 17); | |||||
| } | |||||
| } | } |
| import { useSecondPathName } from '@/hooks/routeHook'; | import { useSecondPathName } from '@/hooks/routeHook'; | ||||
| import type { MenuProps } from 'antd'; | 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 { useNavigate } from 'umi'; | ||||
| import { | import { | ||||
| UserSettingBaseKey, | UserSettingBaseKey, | ||||
| } from '../constants'; | } from '../constants'; | ||||
| import { useTranslate } from '@/hooks/commonHooks'; | import { useTranslate } from '@/hooks/commonHooks'; | ||||
| import { useLogout } from '@/hooks/userSettingHook'; | |||||
| import { useFetchSystemVersion, useLogout } from '@/hooks/userSettingHook'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| type MenuItem = Required<MenuProps>['items'][number]; | type MenuItem = Required<MenuProps>['items'][number]; | ||||
| const pathName = useSecondPathName(); | const pathName = useSecondPathName(); | ||||
| const logout = useLogout(); | const logout = useLogout(); | ||||
| const { t } = useTranslate('setting'); | const { t } = useTranslate('setting'); | ||||
| const { version, fetchSystemVersion } = useFetchSystemVersion(); | |||||
| useEffect(() => { | |||||
| fetchSystemVersion(); | |||||
| }, [fetchSystemVersion]); | |||||
| function getItem( | function getItem( | ||||
| label: string, | label: string, | ||||
| key, | key, | ||||
| icon, | icon, | ||||
| children, | children, | ||||
| label: t(label), | |||||
| label: ( | |||||
| <Flex justify={'space-between'}> | |||||
| {t(label)} | |||||
| <span className={styles.version}> | |||||
| {label === 'system' && version} | |||||
| </span> | |||||
| </Flex> | |||||
| ), | |||||
| type, | type, | ||||
| } as MenuItem; | } as MenuItem; | ||||
| } | } |
| path: '/user-setting/team', | path: '/user-setting/team', | ||||
| component: '@/pages/user-setting/setting-team', | component: '@/pages/user-setting/setting-team', | ||||
| }, | }, | ||||
| { | |||||
| path: '/user-setting/system', | |||||
| component: '@/pages/user-setting/setting-system', | |||||
| }, | |||||
| ], | ], | ||||
| }, | }, | ||||
| { | { |
| set_tenant_info, | set_tenant_info, | ||||
| add_llm, | add_llm, | ||||
| delete_llm, | delete_llm, | ||||
| getSystemStatus, | |||||
| getSystemVersion, | |||||
| } = api; | } = api; | ||||
| const methods = { | const methods = { | ||||
| url: delete_llm, | url: delete_llm, | ||||
| method: 'post', | method: 'post', | ||||
| }, | }, | ||||
| getSystemStatus: { | |||||
| url: getSystemStatus, | |||||
| method: 'get', | |||||
| }, | |||||
| getSystemVersion: { | |||||
| url: getSystemVersion, | |||||
| method: 'get', | |||||
| }, | |||||
| } as const; | } as const; | ||||
| const userService = registerServer<keyof typeof methods>(methods, request); | const userService = registerServer<keyof typeof methods>(methods, request); |
| createFolder: `${api_host}/file/create`, | createFolder: `${api_host}/file/create`, | ||||
| connectFileToKnowledge: `${api_host}/file2document/convert`, | connectFileToKnowledge: `${api_host}/file2document/convert`, | ||||
| getFile: `${api_host}/file/get`, | getFile: `${api_host}/file/get`, | ||||
| // system | |||||
| getSystemVersion: `${api_host}/system/version`, | |||||
| getSystemStatus: `${api_host}/system/status`, | |||||
| }; | }; |
| input: string, | input: string, | ||||
| option: { label: string; value: string } | undefined, | option: { label: string; value: string } | undefined, | ||||
| ) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase()); | ) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase()); | ||||
| export const toFixed = (value: unknown, fixed = 2) => { | |||||
| if (typeof value === 'number') { | |||||
| return value.toFixed(fixed); | |||||
| } | |||||
| return value; | |||||
| }; |
| ) => { | ) => { | ||||
| const server: Service<T> = {} as Service<T>; | const server: Service<T> = {} as Service<T>; | ||||
| for (let key in opt) { | for (let key in opt) { | ||||
| server[key] = (params: any, urlAppendix?: string) => { | |||||
| server[key] = (params?: any, urlAppendix?: string) => { | |||||
| let url = opt[key].url; | let url = opt[key].url; | ||||
| const requestOptions = opt[key]; | const requestOptions = opt[key]; | ||||
| if (urlAppendix) { | if (urlAppendix) { |