balibabu commited on
Commit
74ade83
·
1 Parent(s): 886ae57

feat: Support Traditional Chinese (#336)

Browse files

### What problem does this PR solve?

Support Traditional Chinese

Issue link: #335
### Type of change

- [x] New Feature (non-breaking change which adds functionality)

web/src/app.tsx CHANGED
@@ -1,18 +1,26 @@
1
- import { default as i18n, default as i18next } from '@/locales/config';
2
  import { App, ConfigProvider, ConfigProviderProps } from 'antd';
3
  import enUS from 'antd/locale/en_US';
4
  import zhCN from 'antd/locale/zh_CN';
 
5
  import React, { ReactNode, useEffect, useState } from 'react';
6
  import storage from './utils/authorizationUtil';
7
 
 
 
 
 
 
 
8
  type Locale = ConfigProviderProps['locale'];
9
 
10
  const RootProvider = ({ children }: React.PropsWithChildren) => {
11
- const getLocale = (lng: string) => (lng === 'zh' ? zhCN : enUS);
 
12
 
13
  const [locale, setLocal] = useState<Locale>(getLocale(storage.getLanguage()));
14
 
15
- i18next.on('languageChanged', function (lng: string) {
16
  storage.setLanguage(lng);
17
  setLocal(getLocale(lng));
18
  });
 
1
+ import i18n from '@/locales/config';
2
  import { App, ConfigProvider, ConfigProviderProps } from 'antd';
3
  import enUS from 'antd/locale/en_US';
4
  import zhCN from 'antd/locale/zh_CN';
5
+ import zh_HK from 'antd/locale/zh_HK';
6
  import React, { ReactNode, useEffect, useState } from 'react';
7
  import storage from './utils/authorizationUtil';
8
 
9
+ const AntLanguageMap = {
10
+ en: enUS,
11
+ zh: zhCN,
12
+ 'zh-TRADITIONAL': zh_HK,
13
+ };
14
+
15
  type Locale = ConfigProviderProps['locale'];
16
 
17
  const RootProvider = ({ children }: React.PropsWithChildren) => {
18
+ const getLocale = (lng: string) =>
19
+ AntLanguageMap[lng as keyof typeof AntLanguageMap] ?? enUS;
20
 
21
  const [locale, setLocal] = useState<Locale>(getLocale(storage.getLanguage()));
22
 
23
+ i18n.on('languageChanged', function (lng: string) {
24
  storage.setLanguage(lng);
25
  setLocal(getLocale(lng));
26
  });
web/src/constants/common.ts CHANGED
@@ -38,3 +38,11 @@ export const fileIconMap = {
38
  xlsx: 'xlsx.svg',
39
  xml: 'xml.svg',
40
  };
 
 
 
 
 
 
 
 
 
38
  xlsx: 'xlsx.svg',
39
  xml: 'xml.svg',
40
  };
41
+
42
+ export const LanguageList = ['English', 'Chinese', 'Traditional Chinese'];
43
+
44
+ export const LanguageTranslationMap = {
45
+ English: 'en',
46
+ Chinese: 'zh',
47
+ 'Traditional Chinese': 'zh-TRADITIONAL',
48
+ };
web/src/hooks/logicHooks.ts CHANGED
@@ -1,3 +1,4 @@
 
1
  import { IKnowledgeFile } from '@/interfaces/database/knowledge';
2
  import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
3
  import { useCallback, useState } from 'react';
@@ -53,7 +54,9 @@ export const useChangeLanguage = () => {
53
  const saveSetting = useSaveSetting();
54
 
55
  const changeLanguage = (lng: string) => {
56
- i18n.changeLanguage(lng === 'Chinese' ? 'zh' : 'en');
 
 
57
  saveSetting({ language: lng });
58
  };
59
 
 
1
+ import { LanguageTranslationMap } from '@/constants/common';
2
  import { IKnowledgeFile } from '@/interfaces/database/knowledge';
3
  import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
4
  import { useCallback, useState } from 'react';
 
54
  const saveSetting = useSaveSetting();
55
 
56
  const changeLanguage = (lng: string) => {
57
+ i18n.changeLanguage(
58
+ LanguageTranslationMap[lng as keyof typeof LanguageTranslationMap],
59
+ );
60
  saveSetting({ language: lng });
61
  };
62
 
web/src/layouts/components/right-toolbar/index.tsx CHANGED
@@ -2,9 +2,11 @@ import { ReactComponent as TranslationIcon } from '@/assets/svg/translation.svg'
2
  import { useTranslate } from '@/hooks/commonHooks';
3
  import { GithubOutlined } from '@ant-design/icons';
4
  import { Dropdown, MenuProps, Space } from 'antd';
 
5
  import React from 'react';
6
  import User from '../user';
7
 
 
8
  import { useChangeLanguage } from '@/hooks/logicHooks';
9
  import styled from './index.less';
10
 
@@ -28,17 +30,12 @@ const RightToolBar = () => {
28
  changeLanguage(key);
29
  };
30
 
31
- const items: MenuProps['items'] = [
32
- {
33
- key: 'English',
34
- label: <span>{t('english')}</span>,
35
- },
36
- { type: 'divider' },
37
- {
38
- key: 'Chinese',
39
- label: <span>{t('chinese')}</span>,
40
- },
41
- ];
42
 
43
  return (
44
  <div className={styled.toolbarWrapper}>
 
2
  import { useTranslate } from '@/hooks/commonHooks';
3
  import { GithubOutlined } from '@ant-design/icons';
4
  import { Dropdown, MenuProps, Space } from 'antd';
5
+ import camelCase from 'lodash/camelCase';
6
  import React from 'react';
7
  import User from '../user';
8
 
9
+ import { LanguageList } from '@/constants/common';
10
  import { useChangeLanguage } from '@/hooks/logicHooks';
11
  import styled from './index.less';
12
 
 
30
  changeLanguage(key);
31
  };
32
 
33
+ const items: MenuProps['items'] = LanguageList.map((x) => ({
34
+ key: x,
35
+ label: <span>{t(camelCase(x))}</span>,
36
+ })).reduce<MenuProps['items']>((pre, cur) => {
37
+ return [...pre!, { type: 'divider' }, cur];
38
+ }, []);
 
 
 
 
 
39
 
40
  return (
41
  <div className={styled.toolbarWrapper}>
web/src/locales/config.ts CHANGED
@@ -3,15 +3,18 @@ import { initReactI18next } from 'react-i18next';
3
 
4
  import translation_en from './en';
5
  import translation_zh from './zh';
 
6
 
7
  const resources = {
8
  en: translation_en,
9
  zh: translation_zh,
 
10
  };
11
 
12
  i18n.use(initReactI18next).init({
13
  resources,
14
  lng: 'en',
 
15
  interpolation: {
16
  escapeValue: false,
17
  },
 
3
 
4
  import translation_en from './en';
5
  import translation_zh from './zh';
6
+ import translation_zh_traditional from './zh-traditional';
7
 
8
  const resources = {
9
  en: translation_en,
10
  zh: translation_zh,
11
+ 'zh-TRADITIONAL': translation_zh_traditional,
12
  };
13
 
14
  i18n.use(initReactI18next).init({
15
  resources,
16
  lng: 'en',
17
+ fallbackLng: 'en',
18
  interpolation: {
19
  escapeValue: false,
20
  },
web/src/locales/en.ts CHANGED
@@ -15,7 +15,8 @@ export default {
15
  edit: 'Edit',
16
  upload: 'Upload',
17
  english: 'English',
18
- chinese: 'Chinese',
 
19
  language: 'Language',
20
  languageMessage: 'Please input your language!',
21
  languagePlaceholder: 'select your language',
 
15
  edit: 'Edit',
16
  upload: 'Upload',
17
  english: 'English',
18
+ chinese: 'Simplified Chinese',
19
+ traditionalChinese: 'Traditional Chinese',
20
  language: 'Language',
21
  languageMessage: 'Please input your language!',
22
  languagePlaceholder: 'select your language',
web/src/locales/zh-traditional.ts ADDED
@@ -0,0 +1,419 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export default {
2
+ translation: {
3
+ common: {
4
+ delete: '刪除',
5
+ deleteModalTitle: '確定刪除嗎?',
6
+ ok: '是',
7
+ cancel: '否',
8
+ total: '總共',
9
+ rename: '重命名',
10
+ name: '名稱',
11
+ save: '保持',
12
+ namePlaceholder: '請輸入名稱',
13
+ next: '下一步',
14
+ create: '創建',
15
+ edit: '編輯',
16
+ upload: '上傳',
17
+ english: '英語',
18
+ chinese: '中文簡體',
19
+ traditionalChinese: '中文繁體',
20
+ language: '語言',
21
+ languageMessage: '請輸入語言',
22
+ languagePlaceholder: '請選擇語言',
23
+ },
24
+ login: {
25
+ login: '登入',
26
+ signUp: '註冊',
27
+ loginDescription: '很高興再次見到您!',
28
+ registerDescription: '很高興您加入!',
29
+ emailLabel: '郵箱',
30
+ emailPlaceholder: '請輸入郵箱地址',
31
+ passwordLabel: '密碼',
32
+ passwordPlaceholder: '請輸入密碼',
33
+ rememberMe: '記住我',
34
+ signInTip: '沒有帳戶?',
35
+ signUpTip: '已經有帳戶?',
36
+ nicknameLabel: '名稱',
37
+ nicknamePlaceholder: '請輸入名稱',
38
+ register: '創建賬戶',
39
+ continue: '繼續',
40
+ title: '開始構建您的智能助手',
41
+ description:
42
+ '免費註冊以探索頂級 RAG 技術。創建知識庫和人工智能來增強您的業務',
43
+ review: '來自 500 多條評論',
44
+ },
45
+ header: {
46
+ knowledgeBase: '知識庫',
47
+ chat: '聊天',
48
+ register: '註冊',
49
+ signin: '登入',
50
+ home: '首頁',
51
+ setting: '用戶設置',
52
+ logout: '登出',
53
+ },
54
+ knowledgeList: {
55
+ welcome: '歡迎回來',
56
+ description: '今天我們要使用哪個知識庫?',
57
+ createKnowledgeBase: '創建知識庫',
58
+ name: '名稱',
59
+ namePlaceholder: '請輸入名稱',
60
+ doc: '文件',
61
+ },
62
+ knowledgeDetails: {
63
+ dataset: '數據集',
64
+ testing: '檢索測試',
65
+ configuration: '配置',
66
+ files: '文件',
67
+ name: '名稱',
68
+ namePlaceholder: '請輸入名稱',
69
+ doc: '文件',
70
+ datasetDescription: '嘿,添加數據集後別忘了調整解析塊!😉',
71
+ addFile: '新增文件',
72
+ searchFiles: '搜索文件',
73
+ localFiles: '本地文件',
74
+ emptyFiles: '新建空文件',
75
+ chunkNumber: '分塊數',
76
+ uploadDate: '上傳日期',
77
+ chunkMethod: '解析方法',
78
+ enabled: '啟用',
79
+ disabled: '禁用',
80
+ action: '動作',
81
+ parsingStatus: '解析狀態',
82
+ processBeginAt: '流程開始於',
83
+ processDuration: '過程持續時間',
84
+ progressMsg: '進度消息',
85
+ testingDescription: '最後一步!成功後,剩下的就交給Infiniflow AI吧。',
86
+ topK: 'top k',
87
+ topKTip:
88
+ '對於計算成本,並非所有檢索到的塊都會計算與查詢的向量餘弦相似度。Top K越大,召回率越高,檢索速度越慢。',
89
+ similarityThreshold: '相似度閾值',
90
+ similarityThresholdTip:
91
+ '我們使用混合相似度得分來評估兩行文本之間的距離。它是加權關鍵詞相似度和向量餘弦相似度。如果查詢和塊之間的相似度小於此閾值,則該塊將被過濾掉。',
92
+ vectorSimilarityWeight: '向量相似度權重',
93
+ vectorSimilarityWeightTip:
94
+ '我們使用混合相似度得分來評估兩行文本之間的距離。它是加權關鍵詞相似度和向量餘弦相似度。兩個權重之和為 1.0。',
95
+ testText: '測試文本',
96
+ testTextPlaceholder: '請輸入您的問題!',
97
+ testingLabel: '測試',
98
+ similarity: '混合相似度',
99
+ termSimilarity: '關鍵詞相似度',
100
+ vectorSimilarity: '向量相似度',
101
+ hits: '命中次數',
102
+ view: '看法',
103
+ filesSelected: '選定的文件',
104
+ upload: '上傳',
105
+ run: '啟動',
106
+ runningStatus0: '未啟動',
107
+ runningStatus1: '解析中',
108
+ runningStatus2: '取消',
109
+ runningStatus3: '成功',
110
+ runningStatus4: '失敗',
111
+ pageRanges: '頁碼範圍',
112
+ pageRangesTip:
113
+ '頁碼範圍:定義需要解析的頁面範圍。不包含在這些範圍內的頁面將被忽略。',
114
+ fromPlaceholder: '從',
115
+ fromMessage: '缺少起始頁碼',
116
+ toPlaceholder: '到',
117
+ toMessage: '缺少結束頁碼(不包含)',
118
+ layoutRecognize: '佈局識別',
119
+ layoutRecognizeTip:
120
+ '使用視覺模型進行佈局分析,以更好地識別文檔結構,找到標題、文本塊、圖像和表格的位置。如果沒有此功能,則只能獲取 PDF 的純文本。',
121
+ taskPageSize: '任務頁面大小',
122
+ taskPageSizeMessage: '請輸入您的任務頁面大小!',
123
+ taskPageSizeTip: `如果使用佈局識別,PDF 文件將被分成連續的組。佈局分析將在組之間並行執行,以提高處理速度。“任務頁面大小”決定組的大小。頁面大小越大,將頁面之間的連續文本分割成不同塊的機會就越低。`,
124
+ addPage: '新增頁面',
125
+ greaterThan: '當前值必須大於起始值!',
126
+ greaterThanPrevious: '當前值必須大於之前的值!',
127
+ selectFiles: '選擇文件',
128
+ changeSpecificCategory: '更改特定類別',
129
+ uploadTitle: '點擊或拖拽文件至此區域即可上傳',
130
+ uploadDescription: '支持單次或批量上傳。嚴禁上傳公司數據或其他違禁文件。',
131
+ chunk: '解析塊',
132
+ bulk: '批量',
133
+ cancel: '取消',
134
+ },
135
+ knowledgeConfiguration: {
136
+ titleDescription: '在這裡更新您的知識庫詳細信息,尤其是解析方法。',
137
+ name: '知識庫名稱',
138
+ photo: '知識庫圖片',
139
+ description: '描述',
140
+ language: '語言',
141
+ languageMessage: '請輸入語言',
142
+ languagePlaceholder: '請輸入語言',
143
+ permissions: '權限',
144
+ embeddingModel: '嵌入模型',
145
+ chunkTokenNumber: '塊令牌數',
146
+ chunkTokenNumberMessage: '塊令牌數是必填項',
147
+ embeddingModelTip:
148
+ '用於嵌入塊的嵌入模型。一旦知識庫有了塊,它就無法更改。如果你想改變它,你需要刪除所有的塊。',
149
+ permissionsTip: '如果權限是“團隊”,則所有團隊成員都可以操作知識庫。',
150
+ chunkTokenNumberTip: '它大致確定了一個塊的令牌數量。',
151
+ chunkMethod: '解析方法',
152
+ chunkMethodTip: '說明位於右側。',
153
+ upload: '上傳',
154
+ english: '英語',
155
+ chinese: '中文',
156
+ embeddingModelPlaceholder: '請選擇嵌入模型',
157
+ chunkMethodPlaceholder: '請選擇分塊方法',
158
+ save: '保持',
159
+ me: '只有我',
160
+ team: '團隊',
161
+ cancel: '取消',
162
+ methodTitle: '分塊方法說明',
163
+ methodExamples: '示例',
164
+ methodExamplesDescription: '這個視覺指南是為了讓您更容易理解。',
165
+ dialogueExamplesTitle: '對話示例',
166
+ methodEmpty: '這將顯示知識庫類別的可視化解釋',
167
+ book: `<p>支持的文件格式為<b>DOCX</b>、<b>PDF</b>、<b>TXT</b>。</p><p>
168
+ 由於一本書很長,並不是所有部分都有用,如果是 PDF,
169
+ 請為每本書設置<i>頁面範圍</i>,以消除負面影響並節省分析計算時間。</p>`,
170
+ laws: `<p>支持的文件格式為<b>DOCX</b>、<b>PDF</b>、<b>TXT</b>。</p><p>
171
+ 法律文件有非常嚴格的書寫格式。我們使用文本特徵來檢測分割點。
172
+ </p><p>
173
+ chunk的粒度與'文章'一致,所有上層文本都會包含在chunk中。
174
+ </p>`,
175
+ manual: `<p>僅支持<b>PDF</b>。</p><p>
176
+ 我們假設手冊具有分層部分結構。我們使用最低的部分標題作為對文檔進行切片的樞軸。
177
+ 因此,同一部分中的圖和表不會被分割,並且塊大小可能會很大。
178
+ </p>`,
179
+ naive: `<p>支持的文件格式為<b>DOCX、EXCEL、PPT、IMAGE、PDF、TXT</b>。</p>
180
+ <p>此方法將簡單的方法應用於塊文件:</p>
181
+ <p>
182
+ <li>系統將使用視覺檢測模型將連續文本分割成多個片段。</li>
183
+ <li>接下來,這些連續的片段被合併成令牌數不超過“令牌數”的塊。</li></p>`,
184
+ paper: `<p>僅支持<b>PDF</b>文件。</p><p>
185
+ 如果我們的模型運行良好,論文將按其部分進行切片,例如<i>摘要、1.1、1.2</i>等。</p><p>
186
+ 這樣做的好處是LLM可以更好的概括論文中相關章節的內容,
187
+ 產生更全面的答案,幫助讀者更好地理解論文。
188
+ 缺點是它增加了 LLM 對話的背景並增加了計算成本,
189
+ 所以在對話過程中,你可以考慮減少‘<b>topN</b>’的設置。</p>`,
190
+ presentation: `<p>支持的文件格式為<b>PDF</b>、<b>PPTX</b>。</p><p>
191
+ 每個頁面都將被視為一個塊。並且每個頁面的縮略圖都會被存儲。</p><p>
192
+ <i>您上傳的所有PPT文件都會使用此方法自動分塊,無需為每個PPT文件進行設置。</i></p>`,
193
+ qa: `支持<p><b>EXCEL</b>和<b>CSV/TXT</b>文件。</p><p>
194
+ 如果文件是Excel格式,應該有2列問題和答案,沒有標題。
195
+ 問題欄位於答案欄之前。
196
+ 如果有多個工作表也沒關係,只要列的組合正確即可。</p><p>
197
+
198
+ 如果是 csv 格式,則應採用 UTF-8 編碼。使用 TAB 作為分隔符來分隔問題和答案。</p><p>
199
+
200
+ <i>所有變形的線都將被忽略。
201
+ 每對問答都將被視為一個塊。</i></p>`,
202
+ resume: `<p>支持的文件格式為<b>DOCX</b>、<b>PDF</b>、<b>TXT</b>。
203
+ </p><p>
204
+ 簡歷有多種格式,就像一個人的個性一樣,但我們經常必須將它們組織成結構化數據,以便於搜索。
205
+ </p><p>
206
+ 我們不是將簡歷分塊,而是將簡歷解析為結構化數據。作為HR,你可以扔掉所有的簡歷,
207
+ 您只需與<i>'ragflow'</i>交談即可列出所有符合資格的候選人。
208
+ </p>
209
+ `,
210
+ table: `支持<p><b>excel</b>和<b>csv/txt</b>格式文件。</p><p>以下是一些提示: <ul> <li>对于Csv或Txt文件,列之间的分隔符为 <em><b>tab</b></em>。</li> <li>第一行必须是列标题。</li> <li>列标题必须是有意义的术语,以便我们的法学硕士能够理解。列举一些同义词时最好使用斜杠<i>'/'</i>来分隔,甚至更好使用方括号枚举值,例如 <i>“性別/性別(男性,女性)”</i>.<p>以下是标题的一些示例:<ol> <li>供应商/供货商<b>'tab'</b>顏色(黃色、紅色、棕色)<b>'tab'</b>性別(男、女)<b>'tab'</B>尺码(m、l、xl、xxl)</li> <li>姓名/名字<b>'tab'</b>電話/手機/微信<b>'tab'</b>最高学历(高中,职高,硕士,本科,博士,初中,中技,中专,专科,专升本,mpa,mba,emba)</li> </ol> </p> </li> <li>表中的每一行都将被视为一个块。</li> </ul>`,
211
+ picture: `
212
+ <p>支持圖像文件。視頻即將推出。</p><p>
213
+ 如果圖片中有文字,則應用 OCR 提取文字作為其文字描述。
214
+ </p><p>
215
+ 如果OCR提取的文本不夠,可以使用視覺LLM來獲取描述。
216
+ </p>`,
217
+ one: `
218
+ <p>支持的文件格式為<b>DOCX、EXCEL、PDF、TXT</b>。
219
+ </p><p>
220
+ 對於一個文檔,它將被視為一個完整的塊,根本不會被分割。
221
+ </p><p>
222
+ 如果你要總結的東西需要一篇文章的全部上下文,並且所選LLM的上下文長度覆蓋了文檔長度,你可以嘗試這種方法。
223
+ </p>`,
224
+ },
225
+ chunk: {
226
+ chunk: '解析塊',
227
+ bulk: '批量',
228
+ selectAll: '選擇所有',
229
+ enabledSelected: '啟用選定的',
230
+ disabledSelected: '禁用選定的',
231
+ deleteSelected: '刪除選定的',
232
+ search: '搜尋',
233
+ all: '所有',
234
+ enabled: '啟用',
235
+ disabled: '禁用的',
236
+ keyword: '關鍵詞',
237
+ function: '函數',
238
+ chunkMessage: '請輸入值!',
239
+ },
240
+ chat: {
241
+ createAssistant: '新建助理',
242
+ assistantSetting: '助理設置',
243
+ promptEngine: '提示引擎',
244
+ modelSetting: '模型設置',
245
+ chat: '聊天',
246
+ newChat: '新建聊天',
247
+ send: '發送',
248
+ sendPlaceholder: '消息概要助手...',
249
+ chatConfiguration: '聊天配置',
250
+ chatConfigurationDescription: '在這裡,為你的專業知識庫裝扮專屬助手!💕',
251
+ assistantName: '助理姓名',
252
+ assistantNameMessage: '助理姓名是必填項',
253
+ namePlaceholder: '例如 賈維斯簡歷',
254
+ assistantAvatar: '助理頭像',
255
+ language: '語言',
256
+ emptyResponse: '空回复',
257
+ emptyResponseTip: `如果在知識庫中沒有檢索到用戶的問題,它將使用它作為答案。如果您希望 LLM 在未檢索到任何內容時提出自己的意見,請將此留空。`,
258
+ setAnOpener: '設置開場白',
259
+ setAnOpenerInitial: `你好!我是你的助理,有什麼可以幫到你的嗎?`,
260
+ setAnOpenerTip: '您想如何歡迎您的客戶?',
261
+ knowledgeBases: '知識庫',
262
+ knowledgeBasesMessage: '請選擇',
263
+ knowledgeBasesTip: '選擇關聯的知識庫。',
264
+ system: '系統',
265
+ systemInitialValue: `你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。回答需要考虑聊天历史。
266
+ 以下是知识库:
267
+ {knowledge}
268
+ 以上是知识库。`,
269
+ systemMessage: '請輸入',
270
+ systemTip:
271
+ '當LLM回答問題時,你需要LLM遵循的說明,比如角色設計、答案長度和答案語言等。',
272
+ topN: 'top n',
273
+ topNTip: `並非所有相似度得分高於“相似度閾值”的塊都會被提供給法學碩士。LLM 只能看到這些“Top N”塊。`,
274
+ variable: '變量',
275
+ variableTip: `如果您使用对话 API,变量可能会帮助您使用不同的策略与客户聊天。
276
+ 这些变量用于填写提示中的“系统”部分,以便给LLM一个提示。
277
+ “知识”是一个非常特殊的变量,它将用检索到的块填充。
278
+ “System”中的所有变量都应该用大括号括起来。`,
279
+ add: '新增',
280
+ key: '關鍵字',
281
+ optional: '可選的',
282
+ operation: '操作',
283
+ model: '模型',
284
+ modelTip: '大語言聊天模型',
285
+ modelMessage: '請選擇',
286
+ freedom: '自由',
287
+ improvise: '即興創作',
288
+ precise: '精確',
289
+ balance: '平衡',
290
+ freedomTip: `“精確”意味著法學碩士會保守並謹慎地回答你的問題。“即興發揮”意味著你希望法學碩士能夠自由地暢所欲言。“平衡”是謹慎與自由之間的平衡。`,
291
+ temperature: '溫度',
292
+ temperatureMessage: '溫度是必填項',
293
+ temperatureTip:
294
+ '該參���控制模型預測的隨機性。較低的溫度使模型對其響應更有信心,而較高的溫度則使其更具創造性和多樣性。',
295
+ topP: '頂級P',
296
+ topPMessage: 'Top P 是必填項',
297
+ topPTip:
298
+ '該參數也稱為“核心採樣”,它設置一個閾值來選擇較小的單詞集進行採樣。它專注於最可能的單詞,剔除不太可能的單詞。',
299
+ presencePenalty: '出席處罰',
300
+ presencePenaltyMessage: '出席處罰是必填項',
301
+ presencePenaltyTip:
302
+ '這會通過懲罰對話中已經出現的單詞來阻止模型重複相同的信息。',
303
+ frequencyPenalty: '頻率懲罰',
304
+ frequencyPenaltyMessage: '頻率懲罰是必填項',
305
+ frequencyPenaltyTip:
306
+ '與存在懲罰類似,這減少了模型頻繁重複相同單詞的傾向。',
307
+ maxTokens: '最大token數',
308
+ maxTokensMessage: '最大token數是必填項',
309
+ maxTokensTip:
310
+ '這設置了模型輸出的最大長度,以標記(單詞或單詞片段)的數量來衡量。',
311
+ },
312
+ setting: {
313
+ profile: '概述',
314
+ profileDescription: '在此更新您的照片和個人詳細信息。',
315
+ password: '密碼',
316
+ passwordDescription: '請輸入您當前的密碼以更改您的密碼。',
317
+ model: '模型提供商',
318
+ modelDescription: '在此管理您的帳戶設置和首選項。',
319
+ team: '團隊',
320
+ logout: '登出',
321
+ username: '使用者名稱',
322
+ usernameMessage: '請輸入用戶名',
323
+ photo: '頭像',
324
+ photoDescription: '這將顯示在您的個人資料上。',
325
+ colorSchema: '主題',
326
+ colorSchemaMessage: '請選擇您的主題!',
327
+ colorSchemaPlaceholder: '請選擇您的主題!',
328
+ bright: '明亮',
329
+ dark: '暗色',
330
+ timezone: '時區',
331
+ timezoneMessage: '請選擇時區',
332
+ timezonePlaceholder: '請選擇時區',
333
+ email: '郵箱地址',
334
+ emailDescription: '一旦註冊,電子郵件將無法更改。',
335
+ currentPassword: '當前密碼',
336
+ currentPasswordMessage: '請輸入當前密碼',
337
+ newPassword: '新密碼',
338
+ newPasswordMessage: '請輸入新密碼',
339
+ newPasswordDescription: '您的新密碼必須超過 8 個字符。',
340
+ confirmPassword: '確認新密碼',
341
+ confirmPasswordMessage: '請確認新密碼',
342
+ confirmPasswordNonMatchMessage: '您輸入的新密碼不匹配!',
343
+ cancel: '取消',
344
+ addedModels: '添加了的模型',
345
+ modelsToBeAdded: '待添加的模型',
346
+ addTheModel: '添加模型',
347
+ apiKey: 'api-key',
348
+ apiKeyMessage: '請輸入 api key!',
349
+ apiKeyTip: 'API key可以通過註冊相應的LLM供應商來獲取。',
350
+ showMoreModels: '展示更多模型',
351
+ baseUrl: 'base-url',
352
+ baseUrlTip:
353
+ '如果您的 API 密鑰來自 OpenAI,請忽略它。任何其他中間提供商都會提供帶有 API 密鑰的基本 URL。',
354
+ modify: '修改',
355
+ systemModelSettings: '系統模型設置',
356
+ chatModel: '聊天模型',
357
+ chatModelTip: '所有新創建的知識庫都會使用默認的聊天LLM。',
358
+ embeddingModel: '嵌入模型',
359
+ embeddingModelTip: '所有新創建的知識庫都將使用的默認嵌入模型。',
360
+ img2txtModel: 'img2Txt模型',
361
+ img2txtModelTip:
362
+ '所有新創建的知識庫都將使用默認的多模塊模型。它可以描述圖片或視頻。',
363
+ sequence2txtModel: 'sequence2Txt模型',
364
+ sequence2txtModelTip:
365
+ '所有新創建的知識庫都將使用默認的 ASR 模型。使用此模型將語音翻譯為相應的文本。',
366
+ workspace: '工作空間',
367
+ upgrade: '升級',
368
+ addLlmTitle: '添加Llm',
369
+ modelName: '模型名稱',
370
+ modelUid: '模型uid',
371
+ modelType: '模型類型',
372
+ addLlmBaseUrl: '基礎 Url',
373
+ vision: '是否支持Vision',
374
+ modelNameMessage: '請輸入模型名稱!',
375
+ modelTypeMessage: '請輸入模型類型!',
376
+ baseUrlNameMessage: '請輸入基礎 Url!',
377
+ ollamaLink: '如何集成Ollama',
378
+ },
379
+ message: {
380
+ registered: '註冊成功',
381
+ logout: '登出成功',
382
+ logged: '登錄成功',
383
+ pleaseSelectChunk: '請選擇解析塊',
384
+ modified: '更新成功',
385
+ created: '創建成功',
386
+ deleted: '刪除成功',
387
+ renamed: '重命名成功',
388
+ operated: '操作成功',
389
+ updated: '更新成功',
390
+ 200: '服務器成功返回請求的數據。',
391
+ 201: '新建或修改數據成功。',
392
+ 202: '一個請求已經進入後台排隊(異步任務)。',
393
+ 204: '刪除數據成功。',
394
+ 400: '發出的請求有錯誤,服務器沒有進行新建或修改數據的操作。',
395
+ 401: '用戶沒有權限(令牌、用戶名、密碼錯誤)。',
396
+ 403: '用戶得到授權,但是訪問是被禁止的。',
397
+ 404: '發出的請求針對的是不存在的記錄,服務器沒有進行操作。',
398
+ 406: '請求的格式不可得。',
399
+ 410: '請求的資源被永久刪除,且不會再得到的。',
400
+ 422: '當創建一個對象時,發生一個驗證錯誤。',
401
+ 500: '服務器發生錯誤,請檢查服務器。',
402
+ 502: '網關錯誤。',
403
+ 503: '服務不可用,服務器暫時過載或維護。',
404
+ 504: '網關超時。',
405
+ requestError: '請求錯誤',
406
+ networkAnomalyDescription: '您的網絡發生異常,無法連接服務器',
407
+ networkAnomaly: '網絡異常',
408
+ hint: '提示',
409
+ },
410
+ footer: {
411
+ profile: '“保留所有權利 @ react”',
412
+ },
413
+ layout: {
414
+ file: '文件',
415
+ knowledge: '知識',
416
+ chat: '聊天',
417
+ },
418
+ },
419
+ };
web/src/locales/zh.ts CHANGED
@@ -15,7 +15,8 @@ export default {
15
  edit: '编辑',
16
  upload: '上传',
17
  english: '英文',
18
- chinese: '中文',
 
19
  language: '语言',
20
  languageMessage: '请输入语言',
21
  languagePlaceholder: '请选择语言',
 
15
  edit: '编辑',
16
  upload: '上传',
17
  english: '英文',
18
+ chinese: '中文简体',
19
+ traditionalChinese: '中文繁体',
20
  language: '语言',
21
  languageMessage: '请输入语言',
22
  languagePlaceholder: '请选择语言',
web/src/pages/user-setting/model.ts CHANGED
@@ -1,3 +1,4 @@
 
1
  import { ITenantInfo } from '@/interfaces/database/knowledge';
2
  import {
3
  IFactory,
@@ -66,7 +67,11 @@ const model: DvaModel<SettingModelState> = {
66
  // };
67
  // authorizationUtil.setUserInfo(userInfo);
68
  if (retcode === 0) {
69
- i18n.changeLanguage(res.language === 'Chinese' ? 'zh' : 'en');
 
 
 
 
70
  yield put({ type: 'setUserInfo', payload: res });
71
  // localStorage.setItem('userInfo',res.)
72
  }
 
1
+ import { LanguageTranslationMap } from '@/constants/common';
2
  import { ITenantInfo } from '@/interfaces/database/knowledge';
3
  import {
4
  IFactory,
 
67
  // };
68
  // authorizationUtil.setUserInfo(userInfo);
69
  if (retcode === 0) {
70
+ i18n.changeLanguage(
71
+ LanguageTranslationMap[
72
+ res.language as keyof typeof LanguageTranslationMap
73
+ ],
74
+ );
75
  yield put({ type: 'setUserInfo', payload: res });
76
  // localStorage.setItem('userInfo',res.)
77
  }
web/src/pages/user-setting/setting-profile/index.tsx CHANGED
@@ -20,6 +20,7 @@ import {
20
  Upload,
21
  UploadFile,
22
  } from 'antd';
 
23
  import { useEffect } from 'react';
24
  import SettingTitle from '../components/setting-title';
25
  import { TimezoneList } from '../constants';
@@ -29,6 +30,7 @@ import {
29
  useValidateSubmittable,
30
  } from '../hooks';
31
 
 
32
  import { useTranslate } from '@/hooks/commonHooks';
33
  import { useChangeLanguage } from '@/hooks/logicHooks';
34
  import parentStyles from '../index.less';
@@ -162,12 +164,11 @@ const UserSettingProfile = () => {
162
  placeholder={t('languagePlaceholder', { keyPrefix: 'common' })}
163
  onChange={changeLanguage}
164
  >
165
- <Option value="English">
166
- {t('english', { keyPrefix: 'common' })}
167
- </Option>
168
- <Option value="Chinese">
169
- {t('chinese', { keyPrefix: 'common' })}
170
- </Option>
171
  </Select>
172
  </Form.Item>
173
  <Divider />
 
20
  Upload,
21
  UploadFile,
22
  } from 'antd';
23
+ import camelCase from 'lodash/camelCase';
24
  import { useEffect } from 'react';
25
  import SettingTitle from '../components/setting-title';
26
  import { TimezoneList } from '../constants';
 
30
  useValidateSubmittable,
31
  } from '../hooks';
32
 
33
+ import { LanguageList } from '@/constants/common';
34
  import { useTranslate } from '@/hooks/commonHooks';
35
  import { useChangeLanguage } from '@/hooks/logicHooks';
36
  import parentStyles from '../index.less';
 
164
  placeholder={t('languagePlaceholder', { keyPrefix: 'common' })}
165
  onChange={changeLanguage}
166
  >
167
+ {LanguageList.map((x) => (
168
+ <Option value={x} key={x}>
169
+ {t(camelCase(x), { keyPrefix: 'common' })}
170
+ </Option>
171
+ ))}
 
172
  </Select>
173
  </Form.Item>
174
  <Divider />