feat(i18n): add internationalization support across multiple components
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
@@ -31,27 +32,21 @@ import type { INextTestingResult } from '@/interfaces/database/knowledge';
|
||||
import KnowledgeBreadcrumbs from './components/KnowledgeBreadcrumbs';
|
||||
import TestChunkResult from './components/TestChunkResult';
|
||||
import { useSnackbar } from '@/components/Provider/SnackbarProvider';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { toLower } from 'lodash';
|
||||
import { t } from 'i18next';
|
||||
|
||||
// 语言选项常量
|
||||
const Languages = [
|
||||
'English',
|
||||
'Chinese',
|
||||
'Spanish',
|
||||
'French',
|
||||
'German',
|
||||
'Japanese',
|
||||
'Korean',
|
||||
'Vietnamese',
|
||||
const options = [
|
||||
{ value: 'en', label: t('knowledgeTesting.languages.english') },
|
||||
{ value: 'zh', label: t('knowledgeTesting.languages.chinese') },
|
||||
{ value: 'ja', label: t('knowledgeTesting.languages.japanese') },
|
||||
{ value: 'ko', label: t('knowledgeTesting.languages.korean') },
|
||||
{ value: 'fr', label: t('knowledgeTesting.languages.french') },
|
||||
{ value: 'de', label: t('knowledgeTesting.languages.german') },
|
||||
{ value: 'es', label: t('knowledgeTesting.languages.spanish') },
|
||||
{ value: 'vi', label: t('knowledgeTesting.languages.vietnamese') },
|
||||
];
|
||||
|
||||
const options = Languages.map((x) => ({
|
||||
label: t('language.' + toLower(x)),
|
||||
value: x,
|
||||
}));
|
||||
|
||||
// 表单数据接口
|
||||
interface TestFormData {
|
||||
question: string;
|
||||
@@ -65,9 +60,9 @@ interface TestFormData {
|
||||
}
|
||||
|
||||
function KnowledgeBaseTesting() {
|
||||
const { t } = useTranslation();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
// 状态管理
|
||||
const [testResult, setTestResult] = useState<INextTestingResult | null>(null);
|
||||
@@ -151,12 +146,12 @@ function KnowledgeBaseTesting() {
|
||||
if (response.data.code === 0) {
|
||||
setTestResult(response.data.data);
|
||||
setPage(1); // 重置到第一页
|
||||
showMessage.success('检索测试完成');
|
||||
showMessage.success(t('knowledgeTesting.retrievalTestComplete'));
|
||||
} else {
|
||||
throw new Error(response.data.message || '检索测试失败');
|
||||
throw new Error(response.data.message || t('knowledgeTesting.retrievalTestFailed'));
|
||||
}
|
||||
} catch (error: any) {
|
||||
showMessage.error(error.message || '检索测试失败');
|
||||
showMessage.error(error.message || t('knowledgeTesting.retrievalTestFailed'));
|
||||
} finally {
|
||||
setTesting(false);
|
||||
}
|
||||
@@ -203,10 +198,10 @@ function KnowledgeBaseTesting() {
|
||||
if (response.data.code === 0) {
|
||||
setTestResult(response.data.data);
|
||||
} else {
|
||||
throw new Error(response.data.message || '分页请求失败');
|
||||
throw new Error(response.data.message || t('knowledgeTesting.paginationRequestFailed'));
|
||||
}
|
||||
} catch (error: any) {
|
||||
showMessage.error(error.message || '分页请求失败');
|
||||
showMessage.error(error.message || t('knowledgeTesting.paginationRequestFailed'));
|
||||
} finally {
|
||||
setTesting(false);
|
||||
}
|
||||
@@ -227,7 +222,7 @@ function KnowledgeBaseTesting() {
|
||||
if (detailLoading) {
|
||||
return (
|
||||
<Container maxWidth="lg" sx={{ py: 4 }}>
|
||||
<Typography>加载中...</Typography>
|
||||
<Typography>{t('common.loading')}</Typography>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@@ -239,22 +234,22 @@ function KnowledgeBaseTesting() {
|
||||
<KnowledgeBreadcrumbs
|
||||
kbItems={[
|
||||
{
|
||||
label: '知识库',
|
||||
label: t('knowledgeTesting.knowledgeBase'),
|
||||
path: '/knowledge'
|
||||
},
|
||||
{
|
||||
label: knowledgeDetail?.name || '知识库详情',
|
||||
label: knowledgeDetail?.name || t('knowledgeTesting.knowledgeBaseDetail'),
|
||||
path: `/knowledge/${id}`
|
||||
},
|
||||
{
|
||||
label: '测试'
|
||||
label: t('knowledgeTesting.testing')
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
<Box sx={{ mb: 3 }}>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
知识库测试
|
||||
{t('knowledgeTesting.knowledgeBaseTesting')}
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" color="text.secondary">
|
||||
{knowledgeDetail?.name}
|
||||
@@ -266,25 +261,25 @@ function KnowledgeBaseTesting() {
|
||||
<Grid size={4}>
|
||||
<Paper sx={{ p: 3, position: 'sticky', top: 20 }}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
测试配置
|
||||
{t('knowledgeTesting.testConfiguration')}
|
||||
</Typography>
|
||||
|
||||
<Box component="form" onSubmit={handleSubmit(handleTestSubmit)} sx={{ mt: 2 }}>
|
||||
<TextField
|
||||
{...register('question', { required: '请输入测试问题' })}
|
||||
label="测试问题"
|
||||
{...register('question', { required: t('knowledgeTesting.pleaseEnterTestQuestion') })}
|
||||
label={t('knowledgeTesting.testQuestion')}
|
||||
multiline
|
||||
rows={3}
|
||||
fullWidth
|
||||
margin="normal"
|
||||
error={!!errors.question}
|
||||
helperText={errors.question?.message}
|
||||
placeholder="请输入您想要测试的问题..."
|
||||
placeholder={t('knowledgeTesting.testQuestionPlaceholder')}
|
||||
/>
|
||||
|
||||
<Box sx={{ mt: 3 }}>
|
||||
<Typography gutterBottom>
|
||||
相似度阈值: {watch('similarity_threshold')}
|
||||
{t('knowledgeTesting.similarityThreshold')}: {watch('similarity_threshold')}
|
||||
</Typography>
|
||||
<Slider
|
||||
{...register('similarity_threshold')}
|
||||
@@ -300,7 +295,7 @@ function KnowledgeBaseTesting() {
|
||||
|
||||
<Box sx={{ mt: 3 }}>
|
||||
<Typography gutterBottom>
|
||||
向量相似度权重: {watch('vector_similarity_weight')}
|
||||
{t('knowledgeTesting.vectorSimilarityWeight')}: {watch('vector_similarity_weight')}
|
||||
</Typography>
|
||||
<Slider
|
||||
{...register('vector_similarity_weight')}
|
||||
@@ -315,18 +310,18 @@ function KnowledgeBaseTesting() {
|
||||
</Box>
|
||||
|
||||
<FormControl fullWidth margin="normal">
|
||||
<InputLabel>重排序模型 (可选)</InputLabel>
|
||||
<InputLabel>{t('knowledgeTesting.rerankModel')}</InputLabel>
|
||||
<Controller
|
||||
name="rerank_id"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Select
|
||||
{...field}
|
||||
label="重排序模型 (可选)"
|
||||
label={t('knowledgeTesting.rerankModel')}
|
||||
disabled={rerankLoading}
|
||||
>
|
||||
<MenuItem value="">
|
||||
<em>不使用重排序</em>
|
||||
<em>{t('knowledgeTesting.noRerank')}</em>
|
||||
</MenuItem>
|
||||
{rerankOptions.map((group) => [
|
||||
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||
@@ -345,9 +340,9 @@ function KnowledgeBaseTesting() {
|
||||
{watch('rerank_id') && (
|
||||
<TextField
|
||||
{...register('top_k', {
|
||||
required: '请输入返回结果数量',
|
||||
min: { value: 1, message: '最小值为1' },
|
||||
max: { value: 2048, message: '最大值为2048' }
|
||||
required: t('knowledgeTesting.pleaseEnterResultCount'),
|
||||
min: { value: 1, message: t('knowledgeTesting.minValue1') },
|
||||
max: { value: 2048, message: t('knowledgeTesting.maxValue2048') }
|
||||
})}
|
||||
label="Top-K"
|
||||
type="number"
|
||||
@@ -355,12 +350,12 @@ function KnowledgeBaseTesting() {
|
||||
margin="normal"
|
||||
inputProps={{ min: 1, max: 2048 }}
|
||||
error={!!errors.top_k}
|
||||
helperText={errors.top_k?.message || '与Rerank模型配合使用'}
|
||||
helperText={errors.top_k?.message || t('knowledgeTesting.useWithRerankModel')}
|
||||
/>
|
||||
)}
|
||||
|
||||
<FormControl fullWidth margin="normal">
|
||||
<InputLabel>跨语言搜索</InputLabel>
|
||||
<InputLabel>{t('knowledgeTesting.crossLanguageSearch')}</InputLabel>
|
||||
<Controller
|
||||
name="cross_languages"
|
||||
control={control}
|
||||
@@ -368,8 +363,8 @@ function KnowledgeBaseTesting() {
|
||||
<Select
|
||||
{...field}
|
||||
multiple
|
||||
label="跨语言搜索"
|
||||
input={<OutlinedInput label="跨语言搜索" />}
|
||||
label={t('knowledgeTesting.crossLanguageSearch')}
|
||||
input={<OutlinedInput label={t('knowledgeTesting.crossLanguageSearch')} />}
|
||||
renderValue={(selected) => (
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
|
||||
{selected.map((value) => {
|
||||
@@ -399,7 +394,7 @@ function KnowledgeBaseTesting() {
|
||||
checked={watch('use_kg')}
|
||||
/>
|
||||
}
|
||||
label="使用知识图谱"
|
||||
label={t('knowledgeTesting.useKnowledgeGraph')}
|
||||
/>
|
||||
|
||||
<Button
|
||||
@@ -409,7 +404,7 @@ function KnowledgeBaseTesting() {
|
||||
disabled={testing}
|
||||
sx={{ mt: 2 }}
|
||||
>
|
||||
{testing ? '测试中...' : '开始测试'}
|
||||
{testing ? t('knowledgeTesting.testing') : t('knowledgeTesting.startTest')}
|
||||
</Button>
|
||||
</Box>
|
||||
</Paper>
|
||||
|
||||
Reference in New Issue
Block a user