feat: text internationalization

This commit is contained in:
wb-lh513319
2024-08-20 19:32:57 +08:00
parent 4139418654
commit 35a5c0a715
13 changed files with 197 additions and 92 deletions

View File

@@ -118,7 +118,7 @@ function ChatDefault() {
}}
/>
<span className="flex items-center text-gray-500 gap-1 dark:text-slate-300">
<span></span>
<span>{t('app_in_mind')}</span>
<span
className="flex items-center cursor-pointer"
onClick={() => {
@@ -126,15 +126,15 @@ function ChatDefault() {
}}
>
<Image key="image_explore" src={'/pictures/explore_active.png'} alt="construct_image" width={24} height={24} />
<span className="text-default">广</span>
<span className="text-default">{t('explore')}</span>
</span>
<span></span>
<span>{t('Discover_more')}</span>
</span>
</div>
<TabContent apps={apps?.app_list || []} loading={loading} refresh={refresh} type={activeKey as any} />
{helps && helps.length > 0 && (
<div>
<h2 className="font-medium text-xl my-4"></h2>
<h2 className="font-medium text-xl my-4">{t('help')}</h2>
<div className="flex justify-start gap-4">
{helps.map((help) => (
<span

View File

@@ -46,13 +46,14 @@ const { confirm } = Modal;
const SyncContent: React.FC<{ name: string; id: number }> = ({ name, id }) => {
const [syncLoading, setSyncLoading] = useState<boolean>(false);
const { t } = useTranslation();
const handleSync = async (spaceName: string, id: number) => {
setSyncLoading(true);
const res = await apiInterceptors(syncDocument(spaceName, { doc_ids: [id] }));
setSyncLoading(false);
if (res[2]?.success) {
message.success('同步已发起,请稍后');
message.success(t('Synchronization_initiated'));
}
};
@@ -66,7 +67,7 @@ const SyncContent: React.FC<{ name: string; id: number }> = ({ name, id }) => {
}}
>
<SyncOutlined />
<span></span>
<span>{t('Sync')}</span>
</Space>
);
};
@@ -258,7 +259,7 @@ export default function DocPanel(props: IProps) {
manual: true,
onSuccess: async (res) => {
if (res.data.success) {
message.success('编辑成功');
message.success(t('Edit_Success'));
await fetchDocuments();
setEditOpen(false);
} else {
@@ -289,7 +290,7 @@ export default function DocPanel(props: IProps) {
}}
loading={isLoading}
>
{t('Refresh_status')}
</Button>
</div>
</div>
@@ -309,11 +310,11 @@ export default function DocPanel(props: IProps) {
<Button
onClick={async () => {
await apiInterceptors(syncDocument(space.name, { doc_ids: [] }));
message.success('同步已发起,请稍后');
message.success(t('Synchronization_initiated'));
}}
className="border"
>
{t('synchronization')}
</Button>
</div>
<Spin spinning={searchLoading}>
@@ -346,12 +347,12 @@ export default function DocPanel(props: IProps) {
}}
>
<EyeOutlined />
<span></span>
<span>{t('detail')}</span>
</Space>
),
},
{
key: 'sync',
key: `${t('Sync')}`,
label: <SyncContent name={space.name} id={document.id} />,
},
{
@@ -364,7 +365,7 @@ export default function DocPanel(props: IProps) {
}}
>
<EditOutlined />
<span></span>
<span>{t('Edit')}</span>
</Space>
),
},
@@ -377,7 +378,7 @@ export default function DocPanel(props: IProps) {
}}
>
<DeleteOutlined />
<span></span>
<span>{t('Delete')}</span>
</Space>
),
},
@@ -453,7 +454,7 @@ export default function DocPanel(props: IProps) {
space.vector_type === 'KnowledgeGraph' && (<Button size="middle" className="flex items-center mx-2" icon={<DeploymentUnitOutlined />} onClick={openGraphVisualPage}>{t('View_Graph')}</Button>)
}
<Button icon={<ExperimentOutlined />} onClick={() => setRecallTestOpen(true)}>
{t('Recall_test')}
</Button>
</Space>
<Divider />
@@ -461,13 +462,13 @@ export default function DocPanel(props: IProps) {
<ArgumentsModal space={space} argumentsShow={argumentsShow} setArgumentsShow={setArgumentsShow} />
{/* 编辑弹窗 */}
<Modal
title="编辑文档"
title={t('Edit_document')}
open={editOpen}
onCancel={() => setEditOpen(false)}
destroyOnClose={true}
footer={[
<Button key="back" onClick={() => setEditOpen(false)}>
{t('cancel')}
</Button>,
<Button
key="submit"
@@ -478,7 +479,7 @@ export default function DocPanel(props: IProps) {
await editChunkRun(values);
}}
>
{t('verify')}
</Button>,
]}
>
@@ -493,10 +494,10 @@ export default function DocPanel(props: IProps) {
}),
}}
>
<Form.Item label="文档名" name="doc_name">
<Form.Item label={t('Document_name')} name="doc_name">
<Input />
</Form.Item>
<Form.Item label="关联问题">
<Form.Item label={t('Correlation_problem')}>
<Form.List name="questions">
{(fields, { add, remove }) => (
<>
@@ -523,7 +524,7 @@ export default function DocPanel(props: IProps) {
block
icon={<PlusOutlined />}
>
{t('Add_problem')}
</Button>
</Form.Item>
</>

View File

@@ -31,8 +31,8 @@ export default function DocTypeForm(props: IProps) {
},
{
type: 'YUQUEURL',
title: '语雀文档',
subTitle: '获取语雀文档的内容',
title: t('yuque'),
subTitle: t('Get_yuque_document'),
iconType: 'YUQUEURL',
},
];

View File

@@ -144,14 +144,14 @@ export default function DocUploadForm(props: IProps) {
<Form.Item<FieldType> label={`${t('Text')}:`} name="text" rules={[{ required: true, message: t('Please_input_the_description') }]}>
<TextArea rows={4} />
</Form.Item>
<Form.Item<FieldType> label="关联问题:">
<Form.Item<FieldType> label={`${t('Correlation_problem')}:`}>
<Form.List name="questions">
{(fields, { add, remove }) => (
<>
{fields.map(({ key, name }, index) => (
<div key={key} className={cls('flex flex-1 items-center gap-8 mb-6')}>
<Form.Item label="" name={[name, 'question']} className="grow">
<Input placeholder="请输入问题" />
<Input placeholder={t('input_question')} />
</Form.Item>
<Form.Item>
<MinusCircleOutlined
@@ -171,7 +171,7 @@ export default function DocUploadForm(props: IProps) {
block
icon={<PlusOutlined />}
>
{t('Add_problem')}
</Button>
</Form.Item>
</>
@@ -195,14 +195,14 @@ export default function DocUploadForm(props: IProps) {
>
<Input className="mb-5 h-12" placeholder={t('Please_input_the_Web_Page_URL')} />
</Form.Item>
<Form.Item<FieldType> label="关联问题:">
<Form.Item<FieldType> label={`${t('Correlation_problem')}:`}>
<Form.List name="questions">
{(fields, { add, remove }) => (
<>
{fields.map(({ key, name }, index) => (
<div key={key} className={cls('flex flex-1 items-center gap-8 mb-6')}>
<Form.Item label="" name={[name, 'question']} className="grow">
<Input placeholder="请输入问题" />
<Input placeholder={t('input_question')} />
</Form.Item>
<Form.Item>
<MinusCircleOutlined
@@ -222,7 +222,7 @@ export default function DocUploadForm(props: IProps) {
block
icon={<PlusOutlined />}
>
{t('Add_problem')}
</Button>
</Form.Item>
</>
@@ -239,31 +239,31 @@ export default function DocUploadForm(props: IProps) {
<Form.Item<FieldType> label={`${t('Name')}:`} name="docName" rules={[{ required: true, message: t('Please_input_the_name') }]}>
<Input className="mb-5 h-12" placeholder={t('Please_input_the_name')} />
</Form.Item>
<Form.Item<FieldType> label="文档地址" name="webPageUrl" rules={[{ required: true, message: '请输入文档地址' }]}>
<Input className="mb-5 h-12" placeholder="请输入文档地址" />
<Form.Item<FieldType> label={t('document_url')} name="webPageUrl" rules={[{ required: true, message: t('input_document_url') }]}>
<Input className="mb-5 h-12" placeholder={t('input_document_url')} />
</Form.Item>
<Form.Item<FieldType>
label="文档token"
label={t('document_token')}
name="doc_token"
tooltip={
<>
tokentoken获取
{t('Get_token')}
<Typography.Link href="https://yuque.antfin-inc.com/lark/openapi/dh8zp4" target="_blank">
{t('Reference_link')}
</Typography.Link>
</>
}
>
<Input className="mb-5 h-12" placeholder="请输入文档token" />
<Input className="mb-5 h-12" placeholder={t('input_document_token')} />
</Form.Item>
<Form.Item<FieldType> label="关联问题:">
<Form.Item<FieldType> label={`${t('Correlation_problem')}:`}>
<Form.List name="questions">
{(fields, { add, remove }) => (
<>
{fields.map(({ key, name }, index) => (
<div key={key} className={cls('flex flex-1 items-center gap-8 mb-6')}>
<Form.Item label="" name={[name, 'question']} className="grow">
<Input placeholder="请输入问题" />
<Input placeholder={t('input_question')} />
</Form.Item>
<Form.Item>
<MinusCircleOutlined
@@ -283,7 +283,7 @@ export default function DocUploadForm(props: IProps) {
block
icon={<PlusOutlined />}
>
{t('Add_problem')}
</Button>
</Form.Item>
</>
@@ -341,7 +341,7 @@ export default function DocUploadForm(props: IProps) {
block
icon={<PlusOutlined />}
>
{t('Add_problem')}
</Button>
</Form.Item>
</>

View File

@@ -24,7 +24,7 @@ import 'moment/locale/zh-cn';
import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { ReactNode, useCallback, useContext, useMemo, useState } from 'react';
import { ReactNode, useCallback, useContext, useMemo, useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
type SettingItem = {
@@ -406,6 +406,12 @@ function SideBar() {
// queryDialogueList();
// }, [queryDialogueList]);
useEffect(() => {
const language = i18n.language;
if (language === 'zh') moment.locale('zh-cn');
if (language === 'en') moment.locale('en');
}, [])
// useEffect(() => {
// setLogo(mode === 'dark' ? '/WHITE_LOGO.png' : '/logo_zh_latest.png');
// }, [mode]);

View File

@@ -108,6 +108,7 @@ export const CommonEn = {
try_again: 'Try again',
no_data: 'No data',
Open_Sidebar: 'Unfold',
verify: 'Verify',
cancel: 'Cancel',
Edit_Success: 'Edit Success',
Add: 'Add',
@@ -181,7 +182,9 @@ export const CommonEn = {
no_context_tip: 'Please enter your question',
Terminal: 'Terminal',
used_apps: 'Used Apps',
app_in_mind: "Don't have an app in mind? to",
explore: 'Explore',
Discover_more: 'Discove more',
sdk_insert: 'SDK Insert',
my_apps: 'My Apps',
awel_flow: 'AWEL Flow',
@@ -214,6 +217,7 @@ export const CommonEn = {
edit_application: 'edit application',
add_application: 'add application',
app_name: 'App Name',
input_app_name: 'Please enter the application name',
LLM_strategy: 'LLM Strategy',
LLM_strategy_value: 'LLM Strategy Value',
resource: 'Resource',
@@ -225,6 +229,8 @@ export const CommonEn = {
please_enter_the_keywords: 'Please enter the keywords',
input_tip: 'Please select the model and enter the description to start quickly',
create_app: 'Create App',
copy_url: 'Click the Copy Share link',
double_click_open: 'Double click on Nail nail to open',
construct: ' Construct App',
chat_online: 'Chat',
recommend_apps: 'Recommend',
@@ -242,5 +248,46 @@ export const CommonEn = {
update: 'Update',
native_type: 'App type',
refreshSuccess: 'Refresh Success',
Download: 'Download'
Download: 'Download',
success: 'Success',
input_parameter: 'Input parameter',
output_structure: 'Output structure',
User_input: 'User input',
LLM_test: 'LLM test',
Output_verification: 'Output verification',
select_scene: 'Please select a scene',
select_type: 'Please select a type',
Please_complete_the_input_parameters: 'Please complete the input parameters',
Please_fill_in_the_user_input: 'Please fill in the user input',
help: 'I can help you:',
Refresh_status: 'Refresh status',
Recall_test: 'Recall test',
synchronization: 'One-key synchronization',
Synchronization_initiated: 'Synchronization has been initiated, please wait',
Edit_document: 'Edit document',
Document_name: 'Document name',
Correlation_problem: 'Correlation problem',
Add_problem: 'Add problem',
New_knowledge_base: 'New knowledge base',
yuque: 'yuque document',
Get_yuque_document: 'Get the contents of the Sparrow document',
document_url: 'Document address',
input_document_url: 'Please enter the document address',
Get_token: 'Please obtain the team knowledge base token first',
Reference_link: 'Reference link',
document_token: 'Document token',
input_document_token: 'Please enter document token',
input_question: 'Please enter a question',
detail: 'Detail',
Manual_entry: 'Manual entry',
Data_content: 'Data content',
Main_content: 'Main content',
Auxiliary_data: 'Auxiliary data',
enter_question_first: 'Please enter the question first',
unpublish: 'Unpublish',
publish: 'Publish',
Update_successfully: 'Update successfully',
Create_successfully: 'Create successfully',
Update_failure: 'Update failure',
Create_failure: 'Create failure',
} as const;

View File

@@ -115,6 +115,7 @@ export const CommonZh: Resources['translation'] = {
no_data: '暂无数据',
Prompt: '提示语',
Open_Sidebar: '展开',
verify: '确认',
cancel: '取消',
Edit_Success: '编辑成功',
Add: '新增',
@@ -188,7 +189,9 @@ export const CommonZh: Resources['translation'] = {
no_context_tip: '请输入你的问题',
Terminal: '终端',
used_apps: '最近使用',
app_in_mind: '没有心仪的应用?去',
explore: '探索广场',
Discover_more: '发现更多',
sdk_insert: 'SDK接入',
my_apps: '我的应用',
awel_flow: 'AWEL 工作流',
@@ -223,6 +226,7 @@ export const CommonZh: Resources['translation'] = {
edit_application: '编辑应用',
add_application: '添加应用',
app_name: '应用名称',
input_app_name: '请输入应用名称',
LLM_strategy: '模型策略',
LLM_strategy_value: '模型策略参数',
operators: '算子',
@@ -233,10 +237,12 @@ export const CommonZh: Resources['translation'] = {
please_enter_the_keywords: '请输入关键词',
input_tip: '请选择模型,输入描述快速开始',
create_app: '创建应用',
copy_url: '单击复制分享链接',
double_click_open: '双击钉钉打开',
construct: '应用管理',
chat_online: '在线对话',
recommend_apps: '热门推荐',
all_apps: '热门推荐',
all_apps: '全部应用',
latest_apps: '最新应用',
my_collected_apps: '我的收藏',
collect_success: '收藏成功',
@@ -250,4 +256,45 @@ export const CommonZh: Resources['translation'] = {
update: '更新',
refreshSuccess: '刷新成功',
Download: '下载',
success: '成功',
input_parameter: '输入参数',
output_structure: '输出结构',
User_input: '用户输入',
LLM_test: 'LLM测试',
Output_verification: '输出验证',
select_scene: '请选择场景',
select_type: '请选择类型',
Please_complete_the_input_parameters: '请填写完整的输入参数',
Please_fill_in_the_user_input: '请填写用户输入内容',
help: '我可以帮您:',
Refresh_status: '刷新状态',
Recall_test: '召回测试',
synchronization: '一键同步',
Synchronization_initiated: '同步已发起,请稍后',
Edit_document: '编辑文档',
Document_name: '文档名',
Correlation_problem: '关联问题',
Add_problem: '添加问题',
New_knowledge_base: '新增知识库',
yuque: '语雀文档',
Get_yuque_document: '获取语雀文档的内容',
document_url: '文档地址',
input_document_url: '请输入文档地址',
Get_token: '请先获取团队知识库tokentoken获取',
Reference_link: '参考链接',
document_token: '文档token',
input_document_token: '请输入文档token',
input_question: '请输入问题',
detail: '详情',
Manual_entry: '手动录入',
Data_content: '数据内容',
Main_content: '主要内容',
Auxiliary_data: '辅助数据',
enter_question_first: '请先输入问题',
unpublish: '取消发布',
publish: '发布应用',
Update_successfully: '更新成功',
Create_successfully: '创建成功',
Update_failure: '更新失败',
Create_failure: '创建失败',
} as const;

View File

@@ -6,6 +6,7 @@ import classNames from 'classnames';
import Image from 'next/image';
import { useRouter } from 'next/router';
import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import styles from './styles.module.css';
@@ -73,6 +74,7 @@ const CreateAppModal: React.FC<{
refresh?: any;
type?: 'add' | 'edit';
}> = ({ open, onCancel, type = 'add', refresh }) => {
const { t } = useTranslation();
const appInfo = JSON.parse(localStorage.getItem('new_app_info') || '{}');
const { message } = App.useApp();
const [form] = Form.useForm();
@@ -115,14 +117,14 @@ const CreateAppModal: React.FC<{
const [, res] = await apiInterceptors(getAppList({}));
const curApp = res?.app_list?.find((item) => item.app_code === appInfo?.app_code);
localStorage.setItem('new_app_info', JSON.stringify({ ...curApp, isEdit: true }));
message.success('更新成功');
message.success(t('Update_successfully'));
} else {
message.success('创建成功');
message.success(t('Create_successfully'));
localStorage.setItem('new_app_info', JSON.stringify(data));
router.push(`/construct/app/extra`);
}
} else {
message.error(type === 'edit' ? '更新失败' : '创建失败');
message.error(type === 'edit' ? t('Update_failure') : t('Create_failure'));
}
await refresh?.();
onCancel();
@@ -150,7 +152,7 @@ const CreateAppModal: React.FC<{
>
<Modal
className={styles['create-app-modal-container']}
title="创建应用"
title={t('create_app')}
width={900}
open={open}
onOk={async () => {
@@ -177,14 +179,14 @@ const CreateAppModal: React.FC<{
app_describe: appInfo?.app_describe,
}}
>
<Form.Item label="工作模式" name="team_mode" required rules={[{ required: true, message: '请选择工作模式' }]}>
<Form.Item label={t('team_modal')} name="team_mode" required rules={[{ required: true, message: t('Please_input_the_work_modal') }]}>
<WorkModeSelect disable={type === 'edit'} options={data || []} />
</Form.Item>
<Form.Item label="应用名称:" name="app_name" required rules={[{ required: true, message: '请输入应用名称' }]}>
<Input placeholder="请输入应用名称" autoComplete="off" className="h-8" />
<Form.Item label={`${t('app_name')}`} name="app_name" required rules={[{ required: true, message: t('input_app_name') }]}>
<Input placeholder={t('input_app_name')} autoComplete="off" className="h-8" />
</Form.Item>
<Form.Item label="描述:" name="app_describe" required rules={[{ required: true, message: '请输入应用描述' }]}>
<Input.TextArea autoComplete="off" placeholder="请输入应用描述" autoSize={{ minRows: 2.5 }} />
<Form.Item label={`${t('Description')}`} name="app_describe" required rules={[{ required: true, message: t('Please_input_the_description') }]}>
<Input.TextArea autoComplete="off" placeholder={t('Please_input_the_description')} autoSize={{ minRows: 2.5 }} />
</Form.Item>
{/* <Form.Item label="应用图标:" name="app_icon" valuePropName="fileList">
<Upload listType="picture-card">

View File

@@ -317,7 +317,7 @@ export default function AppContent() {
fontSize: 12,
}}
/>
<span className="text-sm text-gray-500"></span>
<span className="text-sm text-gray-500">{t('copy_url')}</span>
</div>
<div className="flex items-center gap-2">
<BulbOutlined
@@ -326,7 +326,7 @@ export default function AppContent() {
fontSize: 12,
}}
/>
<span className="text-sm text-gray-500"></span>
<span className="text-sm text-gray-500">{t('double_click_open')}</span>
</div>
</div>
}
@@ -349,7 +349,7 @@ export default function AppContent() {
operate(item);
}}
>
{item.published === 'true' ? '取消发布' : '发布应用'}
{item.published === 'true' ? t('unpublish') : t('publish')}
</span>
),
},
@@ -363,7 +363,7 @@ export default function AppContent() {
showDeleteConfirm(item);
}}
>
{t('Delete')}
</span>
),
},

View File

@@ -176,7 +176,7 @@ function ChunkList() {
/>
<MenuModal
modal={{
title: '手动录入',
title: t('Manual_entry'),
width: '70%',
open: isModalOpen,
footer: false,
@@ -193,13 +193,13 @@ function ChunkList() {
items={[
{
key: 'edit',
label: '数据内容',
label: t('Data_content'),
children: (
<div className="flex gap-4">
<Card size="small" title="主要内容" className="w-2/3 flex-wrap overflow-y-auto">
<Card size="small" title={t('Main_content')} className="w-2/3 flex-wrap overflow-y-auto">
<MarkDownContext>{currentChunkInfo?.content}</MarkDownContext>
</Card>
<Card size="small" title="辅助数据" className="w-1/3">
<Card size="small" title={t('Auxiliary_data')} className="w-1/3">
<MarkDownContext>{currentChunkInfo?.meta_info}</MarkDownContext>
</Card>
</div>
@@ -207,7 +207,7 @@ function ChunkList() {
},
{
key: 'delete',
label: '添加问题',
label: t('Add_problem'),
children: (
<Card
size="small"
@@ -218,11 +218,11 @@ function ChunkList() {
onClick={async () => {
const formVal = form.getFieldsValue();
if (!formVal.questions) {
message.warning('请先输入问题');
message.warning(t('enter_question_first'));
return;
}
if (formVal.questions?.filter(Boolean).length === 0) {
message.warning('请先输入问题');
message.warning(t('enter_question_first'));
return;
}
const questions = formVal.questions?.filter(Boolean).map((item: any) => item.question);
@@ -230,7 +230,7 @@ function ChunkList() {
}}
loading={addLoading}
>
{t('save')}
</Button>
}
>
@@ -241,7 +241,7 @@ function ChunkList() {
{fields.map(({ key, name }) => (
<div key={key} className={cls('flex flex-1 items-center gap-8')}>
<Form.Item label="" name={[name, 'question']} className="grow">
<Input placeholder="请输入" />
<Input placeholder={t('Please_Input')} />
</Form.Item>
<Form.Item>
<MinusCircleOutlined
@@ -261,7 +261,7 @@ function ChunkList() {
block
icon={<PlusOutlined />}
>
{t('Add_problem')}
</Button>
</Form.Item>
</>

View File

@@ -191,7 +191,7 @@ const Knowledge = () => {
key: 'del',
label: (
<span className="text-red-400" onClick={() => showDeleteConfirm(space)}>
{t('Delete')}
</span>
),
},
@@ -254,7 +254,7 @@ const Knowledge = () => {
<DocPanel space={currentSpace!} onAddDoc={onAddDoc} onDeleteDoc={getSpaces} addStatus={addStatus} />
</Modal>
<Modal
title="新增知识库"
title={t('New_knowledge_base')}
centered
open={isAddShow}
destroyOnClose={true}

View File

@@ -17,6 +17,7 @@ import MarkdownIt from 'markdown-it';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import 'react-markdown-editor-lite/lib/index.css';
import styles from '../styles.module.css';
@@ -78,6 +79,7 @@ const TemperatureItem: React.FC<{ value?: any; onChange?: (value: any) => void }
const AddOrEditPrompt: React.FC = () => {
const router = useRouter();
const { type = '' } = router.query;
const { t } = useTranslation();
const { modelList, model, mode } = useContext(ChatContext);
const theme = mode === 'dark' ? githubDarkTheme : githubLightTheme;
@@ -172,7 +174,7 @@ const AddOrEditPrompt: React.FC = () => {
{
manual: true,
onSuccess: () => {
message.success(`${type === 'add' ? '新增' : '更新'}成功`);
message.success(`${type === 'add' ? t('Add') : t('update')}${t('success')}`);
router.replace('/construct/prompt');
},
},
@@ -205,11 +207,11 @@ const AddOrEditPrompt: React.FC = () => {
}
const midVals = midForm.getFieldsValue();
if (!Object.values(midVals).every((value) => !!value)) {
message.warning('请填写完整的输入参数');
message.warning(t('Please_complete_the_input_parameters'));
return;
}
if (!bottomForm.getFieldValue('user_input')) {
message.warning('请填写用户输入内容');
message.warning(t('Please_fill_in_the_user_input'));
return;
}
topForm.validateFields().then(async (values) => {
@@ -358,11 +360,11 @@ const AddOrEditPrompt: React.FC = () => {
router.replace('/construct/prompt');
}}
/>
<span className="font-medium text-sm">{type === 'add' ? '新增' : '编辑'} Prompt</span>
<span className="font-medium text-sm">{type === 'add' ? t('Add') : t('Edit')} Prompt</span>
</Space>
<Space>
<Button type="primary" onClick={operateFn} loading={operateLoading}>
{type === 'add' ? '保存' : '更新'}
{type === 'add' ? t('save') : t('update')}
</Button>
</Space>
</header>
@@ -397,13 +399,13 @@ const AddOrEditPrompt: React.FC = () => {
<Card className="mb-4">
<Form form={topForm}>
<div className="flex w-full gap-1 justify-between">
<Form.Item label="Type" name="prompt_type" className="w-2/5" rules={[{ required: true, message: '请选择类型' }]}>
<Select options={TypeOptions} placeholder="请选择类型" allowClear />
<Form.Item label="Type" name="prompt_type" className="w-2/5" rules={[{ required: true, message: t('select_type') }]}>
<Select options={TypeOptions} placeholder={t('select_type')} allowClear />
</Form.Item>
<Form.Item name="target" className="w-3/5" rules={[{ required: true, message: '请选择场景' }]}>
<Form.Item name="target" className="w-3/5" rules={[{ required: true, message: t('select_scene') }]}>
<Select
loading={loading}
placeholder="请选择场景"
placeholder={t('select_scene')}
allowClear
showSearch
onChange={async (value) => {
@@ -423,24 +425,24 @@ const AddOrEditPrompt: React.FC = () => {
<Input disabled />
</Form.Item>
)}
<Form.Item label="Name" name="prompt_name" className="m-0" rules={[{ required: true, message: '请输入prompt名称' }]}>
<Input placeholder="请输入prompt名称" />
<Form.Item label="Name" name="prompt_name" className="m-0" rules={[{ required: true, message: `${t('Please_Input')}prompt${t('Prompt_Info_Name')}` }]}>
<Input placeholder={`${t('Please_Input')}prompt${t('Prompt_Info_Name')}`} />
</Form.Item>
</Form>
</Card>
<Card title="输入参数" className="mb-4">
<Card title={t('input_parameter')} className="mb-4">
<Form form={midForm}>
{variables.length > 0 &&
variables
.filter((item) => item !== 'out_schema')
.map((item) => (
<Form.Item key={item} label={item} name={item} rules={[{ message: `请输入${item}` }]}>
<Input placeholder="请输入" />
<Form.Item key={item} label={item} name={item} rules={[{ message: `${t('Please_Input')}${item}` }]}>
<Input placeholder={t('Please_Input')} />
</Form.Item>
))}
</Form>
</Card>
<Card title="输出结构" className="flex flex-col flex-1">
<Card title={t('output_structure')} className="flex flex-col flex-1">
<JsonView
style={{ ...theme, width: '100%', padding: 4 }}
className={classNames({
@@ -453,34 +455,34 @@ const AddOrEditPrompt: React.FC = () => {
/>
<div className="flex flex-col mt-4">
<Form form={bottomForm} initialValues={{ model: model, temperature: 0.5, prompt_language: 'en' }}>
<Form.Item label="模型" name="model">
<Form.Item label={t('model')} name="model">
<Select className="h-8 rounded-3xl" options={modelOptions} allowClear showSearch />
</Form.Item>
<Form.Item label="温度" name="temperature">
<Form.Item label={t('temperature')} name="temperature">
<TemperatureItem />
</Form.Item>
<Form.Item label="语言" name="prompt_language">
<Form.Item label={t('language')} name="prompt_language">
<Select
options={[
{
label: '英文',
label: t('English'),
value: 'en',
},
{
label: '中文',
label: t('Chinese'),
value: 'zh',
},
]}
/>
</Form.Item>
<Form.Item label="用户输入" name="user_input">
<Input placeholder="请输入" />
<Form.Item label={t('User_input')} name="user_input">
<Input placeholder={t('Please_Input')} />
</Form.Item>
</Form>
</div>
<Space className="flex justify-between">
<Button type="primary" onClick={onLLMTest} loading={llmLoading}>
LLM测试
{t('LLM_test')}
</Button>
<Button
type="primary"
@@ -491,7 +493,7 @@ const AddOrEditPrompt: React.FC = () => {
await run();
}}
>
{t('Output_verification')}
</Button>
</Space>
</Card>

View File

@@ -99,7 +99,7 @@ const Prompt = () => {
width: '10%',
},
{
title: '语言',
title: t('language'),
dataIndex: 'prompt_language',
key: 'prompt_language',
render: (lang) => (lang ? LangMap[lang as keyof typeof LangMap] : '-'),