feat: i18n

This commit is contained in:
wangdan-fit2cloud 2025-01-20 14:21:30 +08:00
parent 765c24dd3f
commit eca33e463a
29 changed files with 135 additions and 78 deletions

View File

@ -68,7 +68,9 @@
<span class="color-secondary">{{ f.label }}:</span> {{ f.value }}
</div>
<div v-if="item.document_list?.length > 0">
<p class="mb-8 color-secondary">文档:</p>
<p class="mb-8 color-secondary">
{{ $t('common.fileUpload.document') }}:
</p>
<el-space wrap>
<template v-for="(f, i) in item.document_list" :key="i">
@ -88,7 +90,7 @@
</el-space>
</div>
<div v-if="item.image_list?.length > 0">
<p class="mb-8 color-secondary">图片:</p>
<p class="mb-8 color-secondary">{{ $t('common.fileUpload.image') }}:</p>
<el-space wrap>
<template v-for="(f, i) in item.image_list" :key="i">
@ -165,7 +167,10 @@
class="card-never border-r-4"
v-if="item.type !== WorkflowType.Application"
>
<h5 class="p-8-12">角色设定 (System)</h5>
<h5 class="p-8-12">
{{ $t('views.application.applicationForm.form.roleSettings.label') }}
(System)
</h5>
<div class="p-8-12 border-t-dashed lighter">
{{ item.system || '-' }}
</div>
@ -174,7 +179,7 @@
class="card-never border-r-4 mt-8"
v-if="item.type !== WorkflowType.Application"
>
<h5 class="p-8-12">历史记录</h5>
<h5 class="p-8-12">{{ $t('components.chat.history') }}</h5>
<div class="p-8-12 border-t-dashed lighter">
<template v-if="item.history_message?.length > 0">
<p
@ -278,7 +283,7 @@
</template>
<template v-if="item.type === WorkflowType.SpeechToTextNode">
<div class="card-never border-r-4">
<h5 class="p-8-12">参数输入</h5>
<h5 class="p-8-12"> {{ $t('components.chat.executionDetails.paramInput') }}</h5>
<div class="p-8-12 border-t-dashed lighter">
<div class="mb-8">
<div v-if="item.audio_list?.length > 0">
@ -325,7 +330,7 @@
<template v-if="item.type === WorkflowType.TextToSpeechNode">
<div class="card-never border-r-4">
<h5 class="p-8-12">参数输入</h5>
<h5 class="p-8-12"> {{ $t('components.chat.executionDetails.paramInput') }}</h5>
<div class="p-8-12 border-t-dashed lighter">
<div class="p-8-12 border-t-dashed lighter">
<p class="mb-8 color-secondary">文本内容:</p>
@ -467,7 +472,12 @@
class="card-never border-r-4"
v-if="item.type !== WorkflowType.Application"
>
<h5 class="p-8-12">角色设定 (System)</h5>
<h5 class="p-8-12">
{{
$t('views.application.applicationForm.form.roleSettings.label')
}}
(System)
</h5>
<div class="p-8-12 border-t-dashed lighter">
{{ item.system || '-' }}
</div>
@ -476,7 +486,7 @@
class="card-never border-r-4 mt-8"
v-if="item.type !== WorkflowType.Application"
>
<h5 class="p-8-12">历史记录</h5>
<h5 class="p-8-12">{{ $t('components.chat.history') }}</h5>
<div class="p-8-12 border-t-dashed lighter">
<template v-if="item.history_message?.length > 0">
<p

View File

@ -7,11 +7,12 @@
</el-card>
</template>
<script setup lang="ts">
import { t } from '@/locales'
defineOptions({ name: 'CardAdd' })
defineProps({
title: {
type: String,
default: '标题'
default: t('common.title')
}
})
</script>

View File

@ -39,7 +39,7 @@
</template>
<script setup lang="ts">
import { ref, useSlots } from 'vue'
import { t } from '@/locales'
defineOptions({ name: 'CardBox' })
const props = withDefaults(
defineProps<{
@ -56,7 +56,7 @@ const props = withDefaults(
*/
showIcon?: boolean
}>(),
{ title: '标题', description: '', showIcon: true, border: true }
{ title: t('common.title'), description: '', showIcon: true, border: true }
)
const show = ref(false)

View File

@ -35,6 +35,7 @@ import type { FormField } from '@/components/dynamics-form/type'
import FormItemLabel from './FormItemLabel.vue'
import type { Dict } from '@/api/type/common'
import bus from '@/bus'
import { t } from '@/locales'
const props = defineProps<{
//
modelValue: any
@ -104,8 +105,8 @@ const errMsg = computed(() => {
return props_info.value.err_msg
? props_info.value.err_msg
: isString(props.formfield.label)
? props.formfield.label + '不能为空'
: props.formfield.label.label + '不能为空'
? props.formfield.label + t('components.dynamicsForm.tip.requiredMessage')
: props.formfield.label.label + t('components.dynamicsForm.tip.requiredMessage')
})
/**
* 反序列化

View File

@ -43,6 +43,7 @@ import { oneDark } from '@codemirror/theme-one-dark'
import { Codemirror } from 'vue-codemirror'
import { linter } from '@codemirror/lint'
import { computed, ref } from 'vue'
import { t } from '@/locales'
const props = withDefaults(defineProps<{ modelValue?: any }>(), { modelValue: () => {} })
const emit = defineEmits(['update:modelValue'])
@ -107,7 +108,7 @@ const validate_rules = (rule: any, value: any, callback: any) => {
try {
JSON.parse(model_value.value)
} catch (e) {
callback(new Error('JSON格式不正确'))
callback(new Error(t('components.dynamicsForm.tip.requiredMessage')))
return false
}
}

View File

@ -6,7 +6,7 @@
<el-input
v-model="filterText"
:validate-event="false"
placeholder="请输入关键字搜索"
:placeholder="$t('components.dynamicsForm.searchBar.placeholder')"
class="input-with-select"
style="--el-color-danger: #c0c4cc"
clearable

View File

@ -6,7 +6,7 @@
<el-input
v-model="filterText"
:validate-event="false"
placeholder="请输入关键字搜索"
:placeholder="$t('components.dynamicsForm.searchBar.placeholder')"
class="input-with-select"
style="--el-color-danger: #c0c4cc"
clearable

View File

@ -1,6 +1,6 @@
<template>
<el-dialog
:title="$t('views.document.setting.generateQuestion')"
:title="$t('views.document.setting.generateQuestion.title')"
v-model="dialogVisible"
width="650"
:close-on-click-modal="false"
@ -19,23 +19,31 @@
<AppIcon iconName="app-warning-colorful" style="font-size: 16px"></AppIcon>
</div>
<div class="ml-12 lighter">
<p>提示词中的 {data} 为分段内容的占位符执行时替换为分段内容发送给 AI 模型</p>
<p>
AI
模型根据分段内容生成相关问题请将生成的问题放至&lt;question&gt;&lt;/question&gt;
</p>
<p>生成效果依赖于所选模型和提示词用户可自行调整至最佳效果</p>
<p>{{ $t('views.document.setting.generateQuestion.tip1', { data: '{data}' }) }}</p>
<p>{{ $t('views.document.setting.generateQuestion.tip2') }}</p>
<p>{{ $t('views.document.setting.generateQuestion.tip3') }}</p>
</div>
</div>
<el-form-item label="AI 模型" prop="model_id">
<el-form-item
:label="$t('views.application.applicationForm.form.aiModel.label')"
prop="model_id"
>
<ModelSelect
v-model="form.model_id"
:placeholder="$t('views.application.applicationForm.form.aiModel.placeholder')"
:options="modelOptions"
></ModelSelect>
</el-form-item>
<el-form-item label="提示词" prop="prompt">
<el-input v-model="form.prompt" placeholder="请输入提示词" :rows="7" type="textarea" />
<el-form-item
:label="$t('views.application.applicationForm.form.prompt.label')"
prop="prompt"
>
<el-input
v-model="form.prompt"
:placeholder="$t('views.application.applicationForm.form.prompt.placeholder')"
:rows="7"
type="textarea"
/>
</el-form-item>
</el-form>
</div>
@ -82,8 +90,20 @@ const userId = user.userInfo?.id as string
const form = ref(prompt.get(userId))
const rules = reactive({
model_id: [{ required: true, message: '请选择AI 模型', trigger: 'blur' }],
prompt: [{ required: true, message: '请输入提示词', trigger: 'blur' }]
model_id: [
{
required: true,
message: t('views.application.applicationForm.form.aiModel.placeholder'),
trigger: 'blur'
}
],
prompt: [
{
required: true,
message: t('views.application.applicationForm.form.prompt.placeholder'),
trigger: 'blur'
}
]
})
const open = (ids: string[], type: string) => {
@ -104,14 +124,14 @@ const submitHandle = async (formEl: FormInstance) => {
if (apiType.value === 'paragraph') {
const data = { ...form.value, paragraph_id_list: idList.value }
paragraphApi.batchGenerateRelated(id, documentId, data, loading).then(() => {
MsgSuccess('生成问题成功')
MsgSuccess(t('views.document.setting.generateQuestion.successMessage'))
emit('refresh')
dialogVisible.value = false
})
} else if (apiType.value === 'document') {
const data = { ...form.value, document_id_list: idList.value }
documentApi.batchGenerateRelated(id, data, loading).then(() => {
MsgSuccess('生成问题成功')
MsgSuccess(t('views.document.setting.generateQuestion.successMessage'))
emit('refresh')
dialogVisible.value = false
})

View File

@ -4,7 +4,6 @@
</el-tag>
</template>
<script setup lang="ts">
import { ref, computed, useSlots } from 'vue'
defineOptions({ name: 'TagEllipsis' })
</script>
<style lang="scss" scoped>

View File

@ -66,7 +66,7 @@ const querySearchAsync = (queryString: string, cb: (arg: any) => void) => {
UserApi.getUserList(queryString).then((res) => {
if (res.data.length === 0) {
noData.value = true
matchResults = [{ default: '无匹配数据' }]
matchResults = [{ default: t('components.noData') }]
} else {
noData.value = false
matchResults = res.data

View File

@ -50,5 +50,7 @@ export default {
enableSuccess: 'Enable Successful',
disableSuccess: 'Disable Successful'
},
inputPlaceholder: 'Please input'
inputPlaceholder: 'Please input',
title: 'Title',
content: 'Content'
}

View File

@ -9,7 +9,6 @@ export default {
},
setting: {
migration: 'Migration',
generateQuestion: 'Generate Questions',
cancelGenerateQuestion: 'Cancel Generating Questions',
cancelVectorization: 'Cancel Vectorization',
cancelGenerate: 'Cancel Generation'
@ -72,7 +71,8 @@ export default {
},
patterns: {
label: 'Segment Delimiters',
tooltip: 'Recursively split according to the selected symbols in order. If the split result exceeds the segment length, it will be truncated to the segment length.',
tooltip:
'Recursively split according to the selected symbols in order. If the split result exceeds the segment length, it will be truncated to the segment length.',
placeholder: 'Please select'
},
limit: {
@ -83,7 +83,8 @@ export default {
text: 'Remove duplicate extra symbols, spaces, blank lines, and tab characters.'
},
checkedConnect: {
label: 'Add Segment Titles as Associated Questions During Import (Applicable for QA Pairs where Titles are Questions)'
label:
'Add Segment Titles as Associated Questions During Import (Applicable for QA Pairs where Titles are Questions)'
}
},
buttons: {
@ -117,17 +118,20 @@ export default {
sync: {
label: 'Sync',
confirmTitle: 'Confirm Sync Document?',
confirmMessage1: 'Syncing will delete existing data and retrieve new data. Please proceed with caution.',
confirmMessage1:
'Syncing will delete existing data and retrieve new data. Please proceed with caution.',
confirmMessage2: 'Cannot sync, please set the document URL first.',
successMessage: 'Document synced successfully'
},
delete: {
confirmTitle1: 'Confirm Batch Deletion of',
confirmTitle2: 'Documents?',
confirmMessage: 'Segments within the selected documents will also be deleted. Please proceed with caution.',
confirmMessage:
'Segments within the selected documents will also be deleted. Please proceed with caution.',
successMessage: 'Batch deletion successful',
confirmTitle3: 'Confirm Deleting Document:',
confirmMessage1: 'All segments under this document will be deleted. Please proceed with caution.'
confirmMessage1:
'All segments under this document will be deleted. Please proceed with caution.'
},
form: {
source_url: {
@ -153,5 +157,16 @@ export default {
error: 'Segments that failed vectorization',
all: 'All Segments'
}
},
hitHandlingMethod: {
optimization: 'Model optimization',
directly_return: 'Direct answer'
},
generateQuestion: {
title: 'Generate Questions',
successMessage: 'Question generation successful',
tip1: 'The {data} in the prompt is a placeholder for segmented content, which is replaced by the segmented content when executed and sent to the AI model;',
tip2: 'The AI model generates relevant questions based on the segmented content. Please place the generated questions within the <question></question> tags, and the system will automatically associate the questions within these tags;',
tip3: 'The generation effect depends on the selected model and prompt. Users can adjust to achieve the best effect.'
}
}

View File

@ -31,11 +31,9 @@ export default {
editMark: 'Edit Label',
form: {
content: {
label: 'Content',
placeholder: 'Please enter the content'
},
title: {
label: 'Title',
placeholder: 'Please set a title for the current content for management and viewing'
},
}

View File

@ -8,11 +8,6 @@ export default {
batchSelected: 'Batch Select',
cancelSelected: 'Cancel Selection'
},
tip: {},
searchBar: {
title: 'Title',
content: 'Content'
},
delete: {
confirmTitle: 'Confirm Deletion of Paragraph:',
confirmMessage: 'Deletion cannot be undone. Please proceed with caution.'

View File

@ -51,5 +51,7 @@ export default {
enableSuccess: '启用成功',
disableSuccess: '禁用成功'
},
inputPlaceholder: '请输入'
inputPlaceholder: '请输入',
title: '标题',
content: '内容'
}

View File

@ -15,12 +15,19 @@ export default {
placeholder: '请输入默认值',
requiredMessage: '请输入默认值'
},
tip: {
requiredMessage: '不能为空',
jsonMessage: 'JSON格式不正确'
},
searchBar: {
placeholder: '请输入关键字搜索'
},
paramForm: {
field: {
label: '参数',
placeholder: '请输入参数',
requiredMessage: '参数 为必填属性',
requiredMessage2:'只能输入字母数字和下划线'
requiredMessage2: '只能输入字母数字和下划线'
},
name: {
label: '显示名称',

View File

@ -2,5 +2,6 @@ import dynamicsForm from './dynamics-form'
import chat from './ai-chat'
export default {
dynamicsForm,
chat
chat,
noData: '无匹配数据'
}

View File

@ -9,7 +9,6 @@ export default {
},
setting: {
migration: '迁移',
generateQuestion: '生成问题',
cancelGenerateQuestion: '取消生成问题',
cancelVectorization: '取消向量化',
cancelGenerate: '取消生成'
@ -158,5 +157,12 @@ export default {
hitHandlingMethod: {
optimization: '模型优化',
directly_return: '直接回答'
},
generateQuestion: {
title: '生成问题',
successMessage: '生成问题成功',
tip1: '提示词中的 {data} 为分段内容的占位符,执行时替换为分段内容发送给 AI 模型;',
tip2: 'AI 模型根据分段内容生成相关问题,请将生成的问题放至&lt;question&gt;&lt;/question&gt;标签中,系统会自动关联标签中的问题;',
tip3: '生成效果依赖于所选模型和提示词,用户可自行调整至最佳效果。'
}
}

View File

@ -31,11 +31,9 @@ export default {
editMark: '修改标注',
form: {
content: {
label: '内容',
placeholder: '请输入内容'
},
title: {
label: '标题',
placeholder: '请给当前内容设置一个标题,以便管理查看'
},
}

View File

@ -8,11 +8,6 @@ export default {
batchSelected: '批量选择',
cancelSelected: '取消选择'
},
tip: {},
searchBar: {
title: '标题',
content: '内容'
},
delete: {
confirmTitle: '是否删除段落:',
confirmMessage: '删除后无法恢复,请谨慎操作。'

View File

@ -50,5 +50,7 @@ export default {
enableSuccess: '啟用成功',
disableSuccess: '停用成功'
},
inputPlaceholder: '請輸入'
inputPlaceholder: '請輸入',
title: '標題',
content: '内容'
}

View File

@ -9,7 +9,7 @@ export default {
},
setting: {
migration: '遷移',
generateQuestion: '生成問題',
cancelGenerateQuestion: '取消生成問題',
cancelVectorization: '取消向量化',
cancelGenerate: '取消生成'
@ -154,5 +154,16 @@ export default {
error: '向量化未成功的分段',
all: '全部分段'
}
},
hitHandlingMethod: {
optimization: '模型優化',
directly_return: '直接回答'
},
generateQuestion: {
title: '生成問題',
successMessage: '生成問題成功',
tip1: '提示詞中的 {data} 為分段內容的佔位符,執行時替換為分段內容並發送給 AI 模型;',
tip2: 'AI 模型根據分段內容生成相關問題,請將生成的問題放置於 <question></question> 標籤中,系統會自動關聯標籤中的問題;',
tip3: '生成效果取決於所選模型和提示詞,用戶可自行調整至最佳效果。'
}
}

View File

@ -31,11 +31,9 @@ export default {
editMark: '修改標註',
form: {
content: {
label: '內容',
placeholder: '請輸入內容'
},
title: {
label: '標題',
placeholder: '請給當前內容設定一個標題,以便管理查看'
},
}

View File

@ -8,11 +8,6 @@ export default {
batchSelected: '批量選擇',
cancelSelected: '取消選擇'
},
tip: {},
searchBar: {
title: '標題',
content: '內容'
},
delete: {
confirmTitle: '是否刪除段落:',
confirmMessage: '刪除後無法恢復,請謹慎操作。'

View File

@ -72,7 +72,7 @@ const startedMap = {
}
const taskTypeMap = {
[TaskType.EMBEDDING]: t('views.dataset.setting.vectorization'),
[TaskType.GENERATE_PROBLEM]: t('views.document.setting.generateQuestion'),
[TaskType.GENERATE_PROBLEM]: t('views.document.setting.generateQuestion.title'),
[TaskType.SYNC]: t('views.dataset.setting.sync')
}
const stateMap: any = {

View File

@ -26,7 +26,7 @@
{{ $t('views.dataset.setting.vectorization') }}
</el-button>
<el-button @click="openGenerateDialog()" :disabled="multipleSelection.length === 0">
{{ $t('views.document.setting.generateQuestion') }}
{{ $t('views.document.setting.generateQuestion.title') }}
</el-button>
<el-button @click="openBatchEditDocument" :disabled="multipleSelection.length === 0">
{{ $t('common.setting') }}
@ -314,7 +314,7 @@
</el-dropdown-item>
<el-dropdown-item v-else @click="openGenerateDialog(row)">
<el-icon><Connection /></el-icon>
{{ $t('views.document.setting.generateQuestion') }}
{{ $t('views.document.setting.generateQuestion.title') }}
</el-dropdown-item>
<el-dropdown-item @click="openDatasetDialog(row)">
<AppIcon iconName="app-migrate"></AppIcon>
@ -403,7 +403,7 @@
</el-dropdown-item>
<el-dropdown-item v-else @click="openGenerateDialog(row)">
<el-icon><Connection /></el-icon>
{{ $t('views.document.setting.generateQuestion') }}
{{ $t('views.document.setting.generateQuestion.title') }}
</el-dropdown-item>
<el-dropdown-item @click="openDatasetDialog(row)">
<AppIcon iconName="app-migrate"></AppIcon>

View File

@ -23,7 +23,7 @@
>
</el-input>
</el-form-item>
<el-form-item :label="$t('views.log.form.content.label')" prop="content">
<el-form-item :label="$t('common.content')" prop="content">
<MdEditor
v-model="form.content"
:placeholder="$t('views.log.form.content.placeholder')"
@ -39,7 +39,7 @@
</template>
</MdEditor>
</el-form-item>
<el-form-item :label="$t('views.log.form.title.label')">
<el-form-item :label="$t('common.title')">
<el-input
show-word-limit
v-model="form.title"

View File

@ -45,8 +45,8 @@
>
<template #prepend>
<el-select v-model="searchType" placeholder="Select" style="width: 80px">
<el-option :label="$t('views.paragraph.searchBar.title')" value="title" />
<el-option :label="$t('views.paragraph.searchBar.content')" value="content" />
<el-option :label="$t('common.title')" value="title" />
<el-option :label="$t('common.content')" value="content" />
</el-select>
</template>
</el-input>
@ -134,7 +134,7 @@
<el-dropdown-item @click="openGenerateDialog(item)">
<el-icon><Connection /></el-icon>
{{
$t('views.document.setting.generateQuestion')
$t('views.document.setting.generateQuestion.title')
}}</el-dropdown-item
>
<el-dropdown-item @click="openSelectDocumentDialog(item)">
@ -159,7 +159,7 @@
<div class="mul-operation border-t w-full" v-if="isBatch === true">
<el-button :disabled="multipleSelection.length === 0" @click="openGenerateDialog()">
{{ $t('views.document.setting.generateQuestion') }}
{{ $t('views.document.setting.generateQuestion.title') }}
</el-button>
<el-button :disabled="multipleSelection.length === 0" @click="openSelectDocumentDialog()">
{{ $t('views.document.setting.migration') }}

View File

@ -66,8 +66,8 @@
>
<template #prepend>
<el-select v-model="searchType" placeholder="Select" style="width: 80px">
<el-option :label="$t('views.paragraph.searchBar.title')" value="title" />
<el-option :label="$t('views.paragraph.searchBar.content')" value="content" />
<el-option :label="$t('common.title')" value="title" />
<el-option :label="$t('common.content')" value="content" />
</el-select>
</template>
</el-input>