commit
276e036e12
|
@ -39,64 +39,30 @@ export const fileIconMap = {
|
||||||
xml: 'xml.svg',
|
xml: 'xml.svg',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LanguageList = [
|
export const LanguageList = ['Chinese', 'Traditional Chinese', 'English'];
|
||||||
'English',
|
|
||||||
'Chinese',
|
|
||||||
'Traditional Chinese',
|
|
||||||
'Indonesia',
|
|
||||||
'Spanish',
|
|
||||||
'Vietnamese',
|
|
||||||
'Japanese',
|
|
||||||
'Portuguese BR',
|
|
||||||
'German',
|
|
||||||
];
|
|
||||||
|
|
||||||
export const LanguageMap = {
|
export const LanguageMap = {
|
||||||
English: 'English',
|
|
||||||
Chinese: '简体中文',
|
Chinese: '简体中文',
|
||||||
'Traditional Chinese': '繁體中文',
|
'Traditional Chinese': '繁體中文',
|
||||||
Indonesia: 'Indonesia',
|
English: 'English',
|
||||||
Spanish: 'Español',
|
|
||||||
Vietnamese: 'Tiếng việt',
|
|
||||||
Japanese: '日本語',
|
|
||||||
'Portuguese BR': 'Português BR',
|
|
||||||
German: 'German',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum LanguageAbbreviation {
|
export enum LanguageAbbreviation {
|
||||||
En = 'en',
|
|
||||||
Zh = 'zh',
|
Zh = 'zh',
|
||||||
ZhTraditional = 'zh-TRADITIONAL',
|
ZhTraditional = 'zh-TRADITIONAL',
|
||||||
Id = 'id',
|
En = 'en',
|
||||||
Ja = 'ja',
|
|
||||||
Es = 'es',
|
|
||||||
Vi = 'vi',
|
|
||||||
PtBr = 'pt-BR',
|
|
||||||
De = 'de',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LanguageAbbreviationMap = {
|
export const LanguageAbbreviationMap = {
|
||||||
[LanguageAbbreviation.En]: 'English',
|
|
||||||
[LanguageAbbreviation.Zh]: '简体中文',
|
[LanguageAbbreviation.Zh]: '简体中文',
|
||||||
[LanguageAbbreviation.ZhTraditional]: '繁體中文',
|
[LanguageAbbreviation.ZhTraditional]: '繁體中文',
|
||||||
[LanguageAbbreviation.Id]: 'Indonesia',
|
[LanguageAbbreviation.En]: 'English',
|
||||||
[LanguageAbbreviation.Es]: 'Español',
|
|
||||||
[LanguageAbbreviation.Vi]: 'Tiếng việt',
|
|
||||||
[LanguageAbbreviation.Ja]: '日本語',
|
|
||||||
[LanguageAbbreviation.PtBr]: 'Português BR',
|
|
||||||
[LanguageAbbreviation.De]: 'Deutsch',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LanguageTranslationMap = {
|
export const LanguageTranslationMap = {
|
||||||
English: 'en',
|
|
||||||
Chinese: 'zh',
|
Chinese: 'zh',
|
||||||
'Traditional Chinese': 'zh-TRADITIONAL',
|
'Traditional Chinese': 'zh-TRADITIONAL',
|
||||||
Indonesia: 'id',
|
English: 'en',
|
||||||
Spanish: 'es',
|
|
||||||
Vietnamese: 'vi',
|
|
||||||
Japanese: 'ja',
|
|
||||||
'Portuguese BR': 'pt-br',
|
|
||||||
German: 'de',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum FileMimeType {
|
export enum FileMimeType {
|
||||||
|
|
|
@ -38,7 +38,7 @@ export interface ISystemStatus {
|
||||||
storage: Storage;
|
storage: Storage;
|
||||||
database: Database;
|
database: Database;
|
||||||
redis: Redis;
|
redis: Redis;
|
||||||
task_executor_heartbeat: Record<string, TaskExecutorHeartbeatItem[]>;
|
// task_executor_heartbeat: Record<string, TaskExecutorHeartbeatItem[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Redis {
|
interface Redis {
|
||||||
|
|
|
@ -27,7 +27,7 @@ interface IProps {
|
||||||
fontSize: number;
|
fontSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChatContainer = ({ controller, fontSize = 16 }: IProps) => {
|
const ChatContainer = ({ controller, fontSize = 18 }: IProps) => {
|
||||||
const { conversationId } = useGetChatSearchParams();
|
const { conversationId } = useGetChatSearchParams();
|
||||||
const { data: conversation } = useFetchNextConversation();
|
const { data: conversation } = useFetchNextConversation();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,20 @@
|
||||||
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
|
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
|
||||||
|
import EmbedModal from '@/components/api-service/embed-modal';
|
||||||
|
import { useShowEmbedModal } from '@/components/api-service/hooks';
|
||||||
import RenameModal from '@/components/rename-modal';
|
import RenameModal from '@/components/rename-modal';
|
||||||
|
import SvgIcon from '@/components/svg-icon';
|
||||||
|
import { useTheme } from '@/components/theme-provider';
|
||||||
|
import { SharedFrom } from '@/constants/chat';
|
||||||
|
import {
|
||||||
|
useClickConversationCard,
|
||||||
|
useClickDialogCard,
|
||||||
|
useFetchNextDialogList,
|
||||||
|
useGetChatSearchParams,
|
||||||
|
} from '@/hooks/chat-hooks';
|
||||||
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
|
import { useSetSelectedRecord } from '@/hooks/logic-hooks';
|
||||||
|
import { IDialog } from '@/interfaces/database/chat';
|
||||||
|
import { FontStorageUtil } from '@/utils/font-storage';
|
||||||
import {
|
import {
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
|
@ -13,6 +28,8 @@ import {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Flex,
|
Flex,
|
||||||
MenuProps,
|
MenuProps,
|
||||||
|
Modal,
|
||||||
|
Slider,
|
||||||
Space,
|
Space,
|
||||||
Spin,
|
Spin,
|
||||||
Tag,
|
Tag,
|
||||||
|
@ -21,6 +38,7 @@ import {
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { MenuItemProps } from 'antd/lib/menu/MenuItem';
|
import { MenuItemProps } from 'antd/lib/menu/MenuItem';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { PictureInPicture2 } from 'lucide-react';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import ChatConfigurationModal from './chat-configuration-modal';
|
import ChatConfigurationModal from './chat-configuration-modal';
|
||||||
import ChatContainer from './chat-container';
|
import ChatContainer from './chat-container';
|
||||||
|
@ -32,23 +50,6 @@ import {
|
||||||
useRenameConversation,
|
useRenameConversation,
|
||||||
useSelectDerivedConversationList,
|
useSelectDerivedConversationList,
|
||||||
} from './hooks';
|
} from './hooks';
|
||||||
|
|
||||||
import EmbedModal from '@/components/api-service/embed-modal';
|
|
||||||
import { useShowEmbedModal } from '@/components/api-service/hooks';
|
|
||||||
import SvgIcon from '@/components/svg-icon';
|
|
||||||
import { useTheme } from '@/components/theme-provider';
|
|
||||||
import { SharedFrom } from '@/constants/chat';
|
|
||||||
import {
|
|
||||||
useClickConversationCard,
|
|
||||||
useClickDialogCard,
|
|
||||||
useFetchNextDialogList,
|
|
||||||
useGetChatSearchParams,
|
|
||||||
} from '@/hooks/chat-hooks';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
|
||||||
import { useSetSelectedRecord } from '@/hooks/logic-hooks';
|
|
||||||
import { IDialog } from '@/interfaces/database/chat';
|
|
||||||
import { Modal, Slider } from 'antd';
|
|
||||||
import { PictureInPicture2 } from 'lucide-react';
|
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
@ -166,16 +167,20 @@ const Chat = () => {
|
||||||
}, [addTemporaryConversation]);
|
}, [addTemporaryConversation]);
|
||||||
|
|
||||||
const [fontSizeModalVisible, setFontSizeModalVisible] = useState(false);
|
const [fontSizeModalVisible, setFontSizeModalVisible] = useState(false);
|
||||||
const [fontSize, setFontSize] = useState(16); // 默认字体大小
|
const [fontSize, setFontSize] = useState(18); // 默认字体大小
|
||||||
|
|
||||||
// 从localStorage加载字体大小设置
|
// 从存储加载字体大小设置
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const savedFontSize = localStorage.getItem('chatFontSize');
|
const savedFontSize = FontStorageUtil.getFontSize();
|
||||||
if (savedFontSize) {
|
setFontSize(savedFontSize);
|
||||||
setFontSize(parseInt(savedFontSize));
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 字体大小变化处理
|
||||||
|
const handleFontSizeChange = (value: number) => {
|
||||||
|
setFontSize(value);
|
||||||
|
FontStorageUtil.setFontSize(value);
|
||||||
|
};
|
||||||
|
|
||||||
const buildAppItems = (dialog: IDialog) => {
|
const buildAppItems = (dialog: IDialog) => {
|
||||||
const dialogId = dialog.id;
|
const dialogId = dialog.id;
|
||||||
|
|
||||||
|
@ -429,10 +434,7 @@ const Chat = () => {
|
||||||
step={1}
|
step={1}
|
||||||
defaultValue={fontSize}
|
defaultValue={fontSize}
|
||||||
style={{ width: '80%' }}
|
style={{ width: '80%' }}
|
||||||
onChange={(value) => {
|
onChange={handleFontSizeChange}
|
||||||
setFontSize(value);
|
|
||||||
localStorage.setItem('chatFontSize', value.toString());
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
@ -1,19 +1,13 @@
|
||||||
import SvgIcon from '@/components/svg-icon';
|
import SvgIcon from '@/components/svg-icon';
|
||||||
import { useFetchSystemStatus } from '@/hooks/user-setting-hooks';
|
import { useFetchSystemStatus } from '@/hooks/user-setting-hooks';
|
||||||
import {
|
import { ISystemStatus } from '@/interfaces/database/user-setting';
|
||||||
ISystemStatus,
|
import { toFixed } from '@/utils/common-util';
|
||||||
TaskExecutorHeartbeatItem,
|
|
||||||
} from '@/interfaces/database/user-setting';
|
|
||||||
import { Badge, Card, Flex, Spin, Typography } from 'antd';
|
import { Badge, Card, Flex, Spin, Typography } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import lowerCase from 'lodash/lowerCase';
|
import lowerCase from 'lodash/lowerCase';
|
||||||
import upperFirst from 'lodash/upperFirst';
|
import upperFirst from 'lodash/upperFirst';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { toFixed } from '@/utils/common-util';
|
|
||||||
import { isObject } from 'lodash';
|
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
import TaskBarChat from './task-bar-chat';
|
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
@ -28,11 +22,9 @@ const TitleMap = {
|
||||||
storage: 'Object Storage',
|
storage: 'Object Storage',
|
||||||
redis: 'Redis',
|
redis: 'Redis',
|
||||||
database: 'Database',
|
database: 'Database',
|
||||||
task_executor_heartbeats: 'Task Executor',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const IconMap = {
|
const IconMap = {
|
||||||
es: 'es',
|
|
||||||
doc_engine: 'storage',
|
doc_engine: 'storage',
|
||||||
redis: 'redis',
|
redis: 'redis',
|
||||||
storage: 'minio',
|
storage: 'minio',
|
||||||
|
@ -56,15 +48,16 @@ const SystemInfo = () => {
|
||||||
<Flex gap={16} vertical>
|
<Flex gap={16} vertical>
|
||||||
{Object.keys(systemStatus).map((key) => {
|
{Object.keys(systemStatus).map((key) => {
|
||||||
const info = systemStatus[key as keyof ISystemStatus];
|
const info = systemStatus[key as keyof ISystemStatus];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
type="inner"
|
type="inner"
|
||||||
title={
|
title={
|
||||||
<Flex align="center" gap={10}>
|
<Flex align="center" gap={10}>
|
||||||
{key === 'task_executor_heartbeats' ? (
|
{key === 'task_executor_heartbeats' ? (
|
||||||
<img src="/logo.svg" alt="" width={26} />
|
<div></div>
|
||||||
) : (
|
) : (
|
||||||
|
// <img src="/logo.svg" alt="" width={26} />
|
||||||
|
// 各组件Icon
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
name={IconMap[key as keyof typeof IconMap]}
|
name={IconMap[key as keyof typeof IconMap]}
|
||||||
width={26}
|
width={26}
|
||||||
|
@ -82,15 +75,7 @@ const SystemInfo = () => {
|
||||||
key={key}
|
key={key}
|
||||||
>
|
>
|
||||||
{key === 'task_executor_heartbeats' ? (
|
{key === 'task_executor_heartbeats' ? (
|
||||||
isObject(info) ? (
|
<div> </div>
|
||||||
<TaskBarChat
|
|
||||||
data={info as Record<string, TaskExecutorHeartbeatItem[]>}
|
|
||||||
></TaskBarChat>
|
|
||||||
) : (
|
|
||||||
<Text className={styles.error}>
|
|
||||||
{typeof info.error === 'string' ? info.error : ''}
|
|
||||||
</Text>
|
|
||||||
)
|
|
||||||
) : (
|
) : (
|
||||||
Object.keys(info)
|
Object.keys(info)
|
||||||
.filter((x) => x !== 'status')
|
.filter((x) => x !== 'status')
|
||||||
|
@ -103,6 +88,7 @@ const SystemInfo = () => {
|
||||||
className={styles.text}
|
className={styles.text}
|
||||||
>
|
>
|
||||||
<b>{upperFirst(lowerCase(x))}:</b>
|
<b>{upperFirst(lowerCase(x))}:</b>
|
||||||
|
{/* 卡片具体文字数值 */}
|
||||||
<Text
|
<Text
|
||||||
className={classNames({
|
className={classNames({
|
||||||
[styles.error]: x === 'error',
|
[styles.error]: x === 'error',
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import { Domain } from '@/constants/common';
|
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
import { useLogout } from '@/hooks/login-hooks';
|
import { useLogout } from '@/hooks/login-hooks';
|
||||||
import { useSecondPathName } from '@/hooks/route-hook';
|
import { useSecondPathName } from '@/hooks/route-hook';
|
||||||
import { useFetchSystemVersion } from '@/hooks/user-setting-hooks';
|
|
||||||
import type { MenuProps } from 'antd';
|
import type { MenuProps } from 'antd';
|
||||||
import { Flex, Menu } from 'antd';
|
import { Flex, Menu } from 'antd';
|
||||||
import React, { useEffect, useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useNavigate } from 'umi';
|
import { useNavigate } from 'umi';
|
||||||
import {
|
import {
|
||||||
UserSettingBaseKey,
|
UserSettingBaseKey,
|
||||||
|
@ -21,13 +19,6 @@ const SideBar = () => {
|
||||||
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(() => {
|
|
||||||
if (location.host !== Domain) {
|
|
||||||
fetchSystemVersion();
|
|
||||||
}
|
|
||||||
}, [fetchSystemVersion]);
|
|
||||||
|
|
||||||
function getItem(
|
function getItem(
|
||||||
label: string,
|
label: string,
|
||||||
|
@ -43,9 +34,7 @@ const SideBar = () => {
|
||||||
label: (
|
label: (
|
||||||
<Flex justify={'space-between'}>
|
<Flex justify={'space-between'}>
|
||||||
{t(label)}
|
{t(label)}
|
||||||
<span className={styles.version}>
|
<span className={styles.version}>{label === 'system'}</span>
|
||||||
{label === 'system' && version}
|
|
||||||
</span>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
),
|
),
|
||||||
type,
|
type,
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// 字体大小存储工具
|
||||||
|
export const FontStorageUtil = {
|
||||||
|
// 获取字体大小
|
||||||
|
getFontSize: (): number => {
|
||||||
|
try {
|
||||||
|
// 优先从localStorage获取
|
||||||
|
const localStorageValue = localStorage.getItem('chatFontSize');
|
||||||
|
if (localStorageValue && !isNaN(parseInt(localStorageValue))) {
|
||||||
|
return parseInt(localStorageValue);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('localStorage不可用,尝试从cookie获取');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 从cookie获取
|
||||||
|
const cookieValue = document.cookie
|
||||||
|
.split('; ')
|
||||||
|
.find((row) => row.startsWith('chatFontSize='))
|
||||||
|
?.split('=')[1];
|
||||||
|
|
||||||
|
if (cookieValue && !isNaN(parseInt(cookieValue))) {
|
||||||
|
return parseInt(cookieValue);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('cookie也不可用');
|
||||||
|
}
|
||||||
|
|
||||||
|
return 18; // 默认字体大小
|
||||||
|
},
|
||||||
|
|
||||||
|
// 保存字体大小
|
||||||
|
setFontSize: (size: number): void => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem('chatFontSize', size.toString());
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('localStorage保存失败,尝试使用cookie');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 设置cookie,有效期30天
|
||||||
|
const expires = new Date();
|
||||||
|
expires.setDate(expires.getDate() + 30);
|
||||||
|
document.cookie = `chatFontSize=${size}; expires=${expires.toUTCString()}; path=/`;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('cookie保存也失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in New Issue