### What problem does this PR solve? Fixed an issue where refreshing the login page caused the language settings to become invalid. Issue link: #249 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)tags/v0.1.0
| import i18next from '@/locales/config'; | |||||
| import { default as i18n, default as i18next } from '@/locales/config'; | |||||
| import { App, ConfigProvider, ConfigProviderProps } from 'antd'; | import { App, ConfigProvider, ConfigProviderProps } from 'antd'; | ||||
| import enUS from 'antd/locale/en_US'; | import enUS from 'antd/locale/en_US'; | ||||
| import zhCN from 'antd/locale/zh_CN'; | import zhCN from 'antd/locale/zh_CN'; | ||||
| }); | }); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| i18next.changeLanguage(storage.getLanguage()); | |||||
| }, [locale]); | |||||
| // Because the language is saved in the backend, a token is required to obtain the api. However, the login page cannot obtain the language through the getUserInfo api, so the language needs to be saved in localstorage. | |||||
| const lng = storage.getLanguage(); | |||||
| if (lng) { | |||||
| i18n.changeLanguage(lng); | |||||
| } | |||||
| }, []); | |||||
| return ( | return ( | ||||
| <ConfigProvider | <ConfigProvider | 
| import { ReactComponent as StarIon } from '@/assets/svg/chat-star.svg'; | import { ReactComponent as StarIon } from '@/assets/svg/chat-star.svg'; | ||||
| import { ReactComponent as KnowledgeBaseIcon } from '@/assets/svg/knowledge-base.svg'; | import { ReactComponent as KnowledgeBaseIcon } from '@/assets/svg/knowledge-base.svg'; | ||||
| import { ReactComponent as Logo } from '@/assets/svg/logo.svg'; | import { ReactComponent as Logo } from '@/assets/svg/logo.svg'; | ||||
| import { useTranslate } from '@/hooks/commonHooks'; | |||||
| import { useNavigateWithFromState } from '@/hooks/routeHook'; | |||||
| import { Layout, Radio, Space, theme } from 'antd'; | import { Layout, Radio, Space, theme } from 'antd'; | ||||
| import { useCallback, useMemo } from 'react'; | |||||
| import { useLocation } from 'umi'; | |||||
| import Toolbar from '../right-toolbar'; | import Toolbar from '../right-toolbar'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| import { useNavigateWithFromState } from '@/hooks/routeHook'; | |||||
| import { useCallback, useMemo } from 'react'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import { useLocation } from 'umi'; | |||||
| const { Header } = Layout; | const { Header } = Layout; | ||||
| const RagHeader = () => { | const RagHeader = () => { | ||||
| } = theme.useToken(); | } = theme.useToken(); | ||||
| const navigate = useNavigateWithFromState(); | const navigate = useNavigateWithFromState(); | ||||
| const { pathname } = useLocation(); | const { pathname } = useLocation(); | ||||
| const { t } = useTranslation('translation', { keyPrefix: 'header' }); | |||||
| const { t } = useTranslate('header'); | |||||
| const tagsData = useMemo( | const tagsData = useMemo( | ||||
| () => [ | () => [ | 
| uploadTitle: 'Click or drag file to this area to upload', | uploadTitle: 'Click or drag file to this area to upload', | ||||
| uploadDescription: | uploadDescription: | ||||
| 'Support for a single or bulk upload. Strictly prohibited from uploading company data or other banned files.', | 'Support for a single or bulk upload. Strictly prohibited from uploading company data or other banned files.', | ||||
| chunk: 'Chunk', | |||||
| }, | }, | ||||
| knowledgeConfiguration: { | knowledgeConfiguration: { | ||||
| titleDescription: | titleDescription: | ||||
| chunkMessage: 'Please input value!', | chunkMessage: 'Please input value!', | ||||
| }, | }, | ||||
| chat: { | chat: { | ||||
| createAssistant: 'Create an Assistant', | |||||
| assistantSetting: 'Assistant Setting', | assistantSetting: 'Assistant Setting', | ||||
| promptEngine: 'Prompt Engine', | promptEngine: 'Prompt Engine', | ||||
| modelSetting: 'Model Setting', | modelSetting: 'Model Setting', | ||||
| img2txtModel: 'Img2txt model', | img2txtModel: 'Img2txt model', | ||||
| img2txtModelTip: | img2txtModelTip: | ||||
| 'The default multi-module model all the newly created knowledgebase will use. It can describe a picture or video.', | 'The default multi-module model all the newly created knowledgebase will use. It can describe a picture or video.', | ||||
| sequence2txtModel: 'Img2txt model', | |||||
| sequence2txtModel: 'Sequence2txt model', | |||||
| sequence2txtModelTip: | sequence2txtModelTip: | ||||
| 'The default ASR model all the newly created knowledgebase will use. Use this model to translate voices to corresponding text.', | 'The default ASR model all the newly created knowledgebase will use. Use this model to translate voices to corresponding text.', | ||||
| workspace: 'Workspace', | workspace: 'Workspace', | 
| searchFiles: '搜索文件', | searchFiles: '搜索文件', | ||||
| localFiles: '本地文件', | localFiles: '本地文件', | ||||
| emptyFiles: '新建空文件', | emptyFiles: '新建空文件', | ||||
| chunkNumber: '模块数', | |||||
| chunkNumber: '分块数', | |||||
| uploadDate: '上传日期', | uploadDate: '上传日期', | ||||
| chunkMethod: '解析方法', | chunkMethod: '解析方法', | ||||
| enabled: '启用', | enabled: '启用', | ||||
| testTextPlaceholder: '请输入您的问题!', | testTextPlaceholder: '请输入您的问题!', | ||||
| testingLabel: '测试', | testingLabel: '测试', | ||||
| similarity: '混合相似度', | similarity: '混合相似度', | ||||
| termSimilarity: '术语相似度', | |||||
| termSimilarity: '关键词相似度', | |||||
| vectorSimilarity: '向量相似度', | vectorSimilarity: '向量相似度', | ||||
| hits: '命中数', | hits: '命中数', | ||||
| view: '看法', | view: '看法', | ||||
| uploadTitle: '点击或拖拽文件至此区域即可上传', | uploadTitle: '点击或拖拽文件至此区域即可上传', | ||||
| uploadDescription: | uploadDescription: | ||||
| '支持单次或批量上传。 严禁上传公司数据或其他违禁文件。', | '支持单次或批量上传。 严禁上传公司数据或其他违禁文件。', | ||||
| chunk: '解析块', | |||||
| }, | }, | ||||
| knowledgeConfiguration: { | knowledgeConfiguration: { | ||||
| titleDescription: '在这里更新您的知识库详细信息,尤其是解析方法。', | titleDescription: '在这里更新您的知识库详细信息,尤其是解析方法。', | ||||
| chunkMessage: '请输入值!', | chunkMessage: '请输入值!', | ||||
| }, | }, | ||||
| chat: { | chat: { | ||||
| createAssistant: '新建助理', | |||||
| assistantSetting: '助理设置', | assistantSetting: '助理设置', | ||||
| promptEngine: '提示引擎', | promptEngine: '提示引擎', | ||||
| modelSetting: '模型设置', | modelSetting: '模型设置', | ||||
| img2txtModel: 'Img2txt模型', | img2txtModel: 'Img2txt模型', | ||||
| img2txtModelTip: | img2txtModelTip: | ||||
| '所有新创建的知识库都将使用默认的多模块模型。 它可以描述图片或视频。', | '所有新创建的知识库都将使用默认的多模块模型。 它可以描述图片或视频。', | ||||
| sequence2txtModel: 'Img2txt模型', | |||||
| sequence2txtModel: 'Sequence2txt模型', | |||||
| sequence2txtModelTip: | sequence2txtModelTip: | ||||
| '所有新创建的知识库都将使用默认的 ASR 模型。 使用此模型将语音翻译为相应的文本。', | '所有新创建的知识库都将使用默认的 ASR 模型。 使用此模型将语音翻译为相应的文本。', | ||||
| workspace: '工作空间', | workspace: '工作空间', | 
| import { useDeleteChunkByIds } from '@/hooks/knowledgeHook'; | import { useDeleteChunkByIds } from '@/hooks/knowledgeHook'; | ||||
| import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; | import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; | ||||
| import { DeleteOutlined } from '@ant-design/icons'; | import { DeleteOutlined } from '@ant-design/icons'; | ||||
| import { Checkbox, Form, Input, Modal, Space } from 'antd'; | |||||
| import { Checkbox, Divider, Form, Input, Modal, Space } from 'antd'; | |||||
| import React, { useCallback, useEffect, useState } from 'react'; | import React, { useCallback, useEffect, useState } from 'react'; | ||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||
| import { useDispatch, useSelector } from 'umi'; | import { useDispatch, useSelector } from 'umi'; | ||||
| </section> | </section> | ||||
| {chunkId && ( | {chunkId && ( | ||||
| <section> | <section> | ||||
| <p>{t('chunk.function')} *</p> | |||||
| <Divider></Divider> | |||||
| <Space size={'large'}> | <Space size={'large'}> | ||||
| <Checkbox onChange={handleCheck} checked={checked}> | <Checkbox onChange={handleCheck} checked={checked}> | ||||
| {t('chunk.enabled')} | {t('chunk.enabled')} | 
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||
| import { Link, Outlet, useDispatch, useLocation } from 'umi'; | import { Link, Outlet, useDispatch, useLocation } from 'umi'; | ||||
| import Siderbar from './components/knowledge-sidebar'; | import Siderbar from './components/knowledge-sidebar'; | ||||
| import { | |||||
| KnowledgeDatasetRouteKey, | |||||
| KnowledgeRouteKey, | |||||
| datasetRouteMap, | |||||
| } from './constant'; | |||||
| import { KnowledgeDatasetRouteKey, KnowledgeRouteKey } from './constant'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| const KnowledgeAdding = () => { | const KnowledgeAdding = () => { | ||||
| if (datasetActiveKey) { | if (datasetActiveKey) { | ||||
| items.push({ | items.push({ | ||||
| title: datasetRouteMap[datasetActiveKey], | |||||
| title: t(`knowledgeDetails.${datasetActiveKey}`), | |||||
| }); | }); | ||||
| } | } | ||||
| <Flex className={styles.chatAppWrapper}> | <Flex className={styles.chatAppWrapper}> | ||||
| <Flex flex={1} vertical> | <Flex flex={1} vertical> | ||||
| <Button type="primary" onClick={handleShowChatConfigurationModal()}> | <Button type="primary" onClick={handleShowChatConfigurationModal()}> | ||||
| Create an Assistant | |||||
| {t('createAssistant')} | |||||
| </Button> | </Button> | ||||
| <Divider></Divider> | <Divider></Divider> | ||||
| <Flex className={styles.chatAppContent} vertical gap={10}> | <Flex className={styles.chatAppContent} vertical gap={10}> | 
| // }; | // }; | ||||
| // authorizationUtil.setUserInfo(userInfo); | // authorizationUtil.setUserInfo(userInfo); | ||||
| if (retcode === 0) { | if (retcode === 0) { | ||||
| i18n.changeLanguage(res.language === 'Chinese' ? 'zh' : 'en'); | |||||
| yield put({ type: 'setUserInfo', payload: res }); | yield put({ type: 'setUserInfo', payload: res }); | ||||
| // localStorage.setItem('userInfo',res.) | // localStorage.setItem('userInfo',res.) | ||||
| } | } |