feat(i18n): add internationalization support across multiple components

This commit is contained in:
2025-10-29 16:40:20 +08:00
parent 184c232cc8
commit 9199ed7c29
34 changed files with 1455 additions and 761 deletions

View File

@@ -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>