feat: Internationalization

This commit is contained in:
dataeaseShu
2025-07-04 15:07:38 +08:00
parent ad6074d80f
commit 3c2c12443b
13 changed files with 198 additions and 106 deletions
+31 -1
View File
@@ -6,6 +6,7 @@
"AI Model Configuration": "AI Model Configuration"
},
"common": {
"empty": " ",
"back": "Back",
"confirm": "Confirm",
"cancel": "Cancel",
@@ -157,7 +158,7 @@
"table_notes": "Table notes",
"field_notes": "Field notes",
"select_all": "Select all",
"mysql_data_source": "Modify MySQL data source",
"mysql_data_source": "Modify {msg} data source",
"configuration_information": "Configuration information",
"data_source": "Do you want to delete the data source: {msg}?",
"operate_with_caution": "After being deleted, the data source cannot be intelligently counted. Please operate with caution.",
@@ -165,6 +166,35 @@
"cannot_be_deleted": "The chart of the dashboard uses this data source and cannot be deleted.",
"got_it": "Got it"
},
"model": {
"default_model": "Default model",
"model_type": "Model type",
"basic_model": "Basic model",
"set_successfully": "Set successfully",
"operate_with_caution": "After the system default model is replaced, the result of intelligent question will be affected, please operate with caution.",
"system_default_model": "Do you want to set {msg} as the system default model?",
"ai_model_configuration": "AI model configuration",
"system_default_model_de": "System default model",
"relevant_results_found": "No relevant results found",
"add_model": "Add model",
"select_supplier": "Select supplier",
"the_basic_model": "Please set a name for the basic model",
"the_basic_model_de": "Please select the basic model",
"model_name": "Model name",
"custom_model_name": "Custom model name",
"enter_to_add": "For models not listed in the list, just enter the model name and press Enter to add",
"api_domain_name": "API domain name",
"advanced_settings": "Advanced settings",
"model_parameters": "Model parameters",
"add": "Add",
"parameters": "Parameters",
"display_name": "Display name",
"parameter_value": "Parameter value",
"text": "Text",
"number": "Number",
"parameter_type": "Parameter type",
"verification_successful": "Verification successful"
},
"chat": {
"chart_type": {
"table": "Table",
+31 -1
View File
@@ -6,6 +6,7 @@
"AI Model Configuration": "模型配置"
},
"common": {
"empty": "",
"back": "返回",
"confirm": "确认",
"cancel": "取消",
@@ -157,7 +158,7 @@
"table_notes": "表备注",
"field_notes": "字段备注",
"select_all": "全选",
"mysql_data_source": "修改 MySQL 数据源",
"mysql_data_source": "修改 {msg} 数据源",
"configuration_information": "配置信息",
"data_source": "是否删除数据源:{msg}?",
"operate_with_caution": "被删除后,将无法对该数据源进行智能问数,请谨慎操作。",
@@ -165,6 +166,35 @@
"cannot_be_deleted": "仪表板的图表使用了该数据源,不可删除。",
"got_it": "知道了"
},
"model": {
"default_model": "默认模型",
"model_type": "模型类型",
"basic_model": "基础模型",
"set_successfully": "设置成功",
"operate_with_caution": "系统默认模型被替换后,智能问数的结果将会受到影响,请谨慎操作。",
"system_default_model": "是否设置 {msg} 为系统默认模型?",
"ai_model_configuration": "AI 模型配置",
"system_default_model_de": "系统默认模型",
"relevant_results_found": "没有找到相关结果",
"add_model": "添加模型",
"select_supplier": "选择供应商",
"the_basic_model": "请给基础模型设置一个名称",
"the_basic_model_de": "请选择基础模型",
"model_name": "模型名称",
"custom_model_name": "自定义的模型名称",
"enter_to_add": "列表中未列出的模型,直接输入模型名称,回车即可添加",
"api_domain_name": "API 域名",
"advanced_settings": "高级设置",
"model_parameters": "模型参数",
"add": "添加",
"parameters": "参数",
"display_name": "显示名称",
"parameter_value": "参数值",
"text": "文本",
"number": "数值",
"parameter_type": "参数类型",
"verification_successful": "校验成功"
},
"chat": {
"chart_type": {
"table": "明细表",
+7 -6
View File
@@ -1,12 +1,11 @@
<script lang="ts" setup>
import azure from '@/assets/model/icon_Azure_OpenAI_colorful.png'
import delIcon from '@/assets/svg/icon_delete.svg'
import icon_more_outlined from '@/assets/svg/icon_more_outlined.svg'
import icon_form_outlined from '@/assets/svg/icon_form_outlined.svg'
import icon_chat_outlined from '@/assets/svg/icon_chat_outlined.svg'
import { ref, unref } from 'vue'
import { ref, unref, computed } from 'vue'
import { ClickOutside as vClickOutside } from 'element-plus-secondary'
import { dsTypeWithImg } from './js/ds-type'
import edit from '@/assets/svg/icon_edit_outlined.svg'
const props = withDefaults(
@@ -27,7 +26,9 @@ const props = withDefaults(
)
const emits = defineEmits(['edit', 'del', 'question', 'dataTableDetail'])
const icon = computed(() => {
return (dsTypeWithImg.find((ele) => props.type === ele.type) || {}).img
})
const handleEdit = () => {
emits('edit')
}
@@ -53,7 +54,7 @@ const onClickOutside = () => {
<template>
<div class="card" @click="dataTableDetail">
<div class="name-icon">
<img :src="azure" width="32px" height="32px" />
<img :src="icon" width="32px" height="32px" />
<div class="info">
<div class="name">{{ name }}</div>
<div class="type">{{ type }}</div>
@@ -80,9 +81,9 @@ const onClickOutside = () => {
<el-icon
ref="buttonRef"
v-click-outside="onClickOutside"
@click.stop
class="more"
size="16"
@click.stop
>
<icon_more_outlined></icon_more_outlined>
</el-icon>
+2 -2
View File
@@ -304,8 +304,8 @@ const changeStatus = (row: any) => {
@closed="closeTable"
>
<el-input
:placeholder="$t('datasource.please_enter')"
v-model="tableComment"
:placeholder="$t('datasource.please_enter')"
:rows="3"
type="textarea"
/>
@@ -324,8 +324,8 @@ const changeStatus = (row: any) => {
@closed="closeField"
>
<el-input
:placeholder="$t('datasource.please_enter')"
v-model="fieldComment"
:placeholder="$t('datasource.please_enter')"
:rows="3"
type="textarea"
/>
+13 -13
View File
@@ -64,11 +64,12 @@ const formatKeywords = (item: string) => {
`<span class="isSearch">${defaultDatasourceKeywords.value}</span>`
)
}
const currentType = ref('')
const handleEditDatasource = (res: any) => {
activeStep.value = 1
datasourceConfigvVisible.value = true
editDatasource.value = true
currentType.value = res.type_name
nextTick(() => {
datasourceFormRef.value.initForm(res)
})
@@ -80,14 +81,6 @@ const handleAddDatasource = () => {
}
const deleteHandler = (item: any) => {
ElMessageBox.confirm(t('datasource.data_source_de', { msg: item.name }), {
tip: t('datasource.cannot_be_deleted'),
cancelButtonText: t('datasource.got_it'),
showConfirmButton: false,
customClass: 'confirm-no_icon',
autofocus: false,
})
return
ElMessageBox.confirm(t('datasource.data_source', { msg: item.name }), {
confirmButtonType: 'danger',
tip: t('datasource.operate_with_caution'),
@@ -106,9 +99,12 @@ const deleteHandler = (item: any) => {
})
})
.catch(() => {
ElMessage({
type: 'info',
message: 'Delete canceled',
ElMessageBox.confirm(t('datasource.data_source_de', { msg: item.name }), {
tip: t('datasource.cannot_be_deleted'),
cancelButtonText: t('datasource.got_it'),
showConfirmButton: false,
customClass: 'confirm-no_icon',
autofocus: false,
})
})
}
@@ -255,7 +251,11 @@ const dataTableDetail = (ele: any) => {
:show-close="false"
>
<template #header="{ close }">
<span style="white-space: nowrap">{{ $t('datasource.new_data_source') }}</span>
<span style="white-space: nowrap">{{
editDatasource
? t('datasource.mysql_data_source', { msg: currentType })
: $t('datasource.new_data_source')
}}</span>
<div v-if="!editDatasource" class="flex-center" style="width: 100%">
<el-steps custom style="max-width: 500px; flex: 1" :active="activeStep" align-center>
<el-step>
+2 -6
View File
@@ -88,8 +88,6 @@ const close = () => {
const initForm = (item: any, editTable: boolean = false) => {
isEditTable.value = false
dsFormRef.value!.clearValidate()
console.log('item', item)
if (item) {
dialogTitle.value = editTable ? t('ds.form.title.choose_tables') : t('ds.form.title.edit')
isCreate.value = false
@@ -198,8 +196,7 @@ const save = async (formEl: FormInstance | undefined) => {
if (form.value.id) {
if (!isEditTable.value) {
// only update datasource config info
datasourceApi.update(requestObj).then((res) => {
console.log(res)
datasourceApi.update(requestObj).then(() => {
close()
emit('refresh')
})
@@ -212,8 +209,7 @@ const save = async (formEl: FormInstance | undefined) => {
}
} else {
requestObj.tables = list
datasourceApi.add(requestObj).then((res: any) => {
console.log(res)
datasourceApi.add(requestObj).then(() => {
close()
emit('refresh')
})
+1 -1
View File
@@ -53,7 +53,7 @@ defineExpose({
<DatasourceForm
ref="datasourceFormRef"
:active-step="2"
activeName=""
active-name=""
@change-active-step="changeActiveStep"
@refresh="refresh"
></DatasourceForm>
+2 -4
View File
@@ -332,8 +332,7 @@ const save = async (formEl: FormInstance | undefined) => {
if (form.value.id) {
if (!isEditTable.value) {
// only update datasource config info
datasourceApi.update(requestObj).then((res) => {
console.log(res)
datasourceApi.update(requestObj).then(() => {
close()
emit('refresh')
})
@@ -346,8 +345,7 @@ const save = async (formEl: FormInstance | undefined) => {
}
} else {
requestObj.tables = list
datasourceApi.add(requestObj).then((res: any) => {
console.log(res)
datasourceApi.add(requestObj).then(() => {
close()
emit('refresh')
})
+3 -3
View File
@@ -36,14 +36,14 @@ const handleDel = () => {
<div class="name-icon">
<img :src="azure" width="32px" height="32px" />
<span class="name">{{ name }}</span>
<span class="default">默认模型</span>
<span class="default">{{ $t('model.default_model') }}</span>
</div>
<div class="type-value">
<span class="type">模型类型</span>
<span class="type">{{ $t('model.model_type') }}</span>
<span class="value"> {{ modleType }}</span>
</div>
<div class="type-value">
<span class="type">基础模型</span>
<span class="type">{{ $t('model.basic_model') }}</span>
<span class="value"> {{ baseModle }}</span>
</div>
<div class="methods">
+23 -23
View File
@@ -68,22 +68,22 @@ const modelListWithSearch = computed(() => {
})
const beforeClose = () => {
modelConfigvVisible.value = false
ElMessage.success('设置成功')
ElMessageBox.confirm('是否设置 Azure OpenAI 123 为系统默认模型?', {
confirmButtonType: 'primary',
tip: '系统默认模型被替换后,智能问数的结果将会受到影响,请谨慎操作。',
confirmButtonText: t('datasource.confirm'),
cancelButtonText: t('common.cancel'),
customClass: 'confirm-no_icon',
autofocus: false,
})
ElMessageBox.confirm('是否设置 Azure OpenAI 123 为系统默认模型?', {
confirmButtonType: 'danger',
confirmButtonText: t('dashboard.delete'),
cancelButtonText: t('common.cancel'),
customClass: 'confirm-no_icon',
autofocus: false,
})
ElMessage.success(t('model.set_successfully'))
// ElMessageBox.confirm(t('model.system_default_model', { msg: msg}), {
// confirmButtonType: 'primary',
// tip: t('model.operate_with_caution'),
// confirmButtonText: t('datasource.confirm'),
// cancelButtonText: t('common.cancel'),
// customClass: 'confirm-no_icon',
// autofocus: false,
// })
// ElMessageBox.confirm(t('model.system_default_model', { msg: msg}), {
// confirmButtonType: 'danger',
// confirmButtonText: t('dashboard.delete'),
// cancelButtonText: t('common.cancel'),
// customClass: 'confirm-no_icon',
// autofocus: false,
// })
}
const defaultModelListWithSearch = computed(() => {
if (!defaultModelKeywords.value) return defaultModelList.value
@@ -192,7 +192,7 @@ const submit = (item: any) => {
<template>
<div class="model-config">
<div class="model-methods">
<span class="title">AI 模型配置</span>
<span class="title">{{ t('model.ai_model_configuration') }}</span>
<div class="button-input">
<el-input
v-model="keywords"
@@ -213,7 +213,7 @@ const submit = (item: any) => {
<template #icon>
<icon_admin_outlined></icon_admin_outlined>
</template>
系统默认模型
{{ t('model.system_default_model_de') }}
</el-button></template
>
<div class="popover">
@@ -244,7 +244,7 @@ const submit = (item: any) => {
</el-icon>
</div>
<div v-if="!defaultModelListWithSearch.length" class="popover-item empty">
没有找到相关结果
{{ t('model.relevant_results_found') }}
</div>
</div>
</div>
@@ -254,7 +254,7 @@ const submit = (item: any) => {
<template #icon>
<icon_add_outlined></icon_add_outlined>
</template>
添加模型
{{ t('model.add_model') }}
</el-button>
</div>
</div>
@@ -286,14 +286,14 @@ const submit = (item: any) => {
:show-close="false"
>
<template #header="{ close }">
<span style="white-space: nowrap">添加模型</span>
<span style="white-space: nowrap">{{ t('model.add_model') }}</span>
<div v-if="!editModel" class="flex-center" style="width: 100%">
<el-steps custom style="max-width: 500px; flex: 1" :active="activeStep" align-center>
<el-step>
<template #title> 选择供应商 </template>
<template #title> {{ t('model.select_supplier') }} </template>
</el-step>
<el-step>
<template #title> 添加模型 </template>
<template #title> {{ t('model.add_model') }} </template>
</el-step>
</el-steps>
</div>
+40 -19
View File
@@ -7,6 +7,7 @@ import icon_delete from '@/assets/svg/icon_delete.svg'
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
import ParamsForm from './ParamsForm.vue'
import { modelTypeOptions } from '@/entity/CommonEntity.ts'
import { useI18n } from 'vue-i18n'
withDefaults(
defineProps<{
@@ -26,6 +27,7 @@ interface Form {
name: string
id: string
}
const { t } = useI18n()
const modelForm = reactive({
id: '',
@@ -75,8 +77,8 @@ const rules = {
},
],
endpoint: [{ required: true, message: 'endpoint', trigger: 'blur' }],
modelName: [{ required: true, message: '请选择基础模型', trigger: 'blur' }],
name: [{ required: true, message: '请给基础模型设置一个名称', trigger: 'blur' }],
modelName: [{ required: true, message: t('model.the_basic_model_de'), trigger: 'blur' }],
name: [{ required: true, message: t('model.the_basic_model'), trigger: 'blur' }],
api_key: [{ required: true, message: 'api_key', trigger: 'blur' }],
}
@@ -148,8 +150,8 @@ defineExpose({
>
<el-form-item class="custom-require flex-inline" prop="name">
<template #label
><span class="custom-require_danger">模型名称</span>
<el-tooltip effect="dark" content="自定义的模型名称" placement="right">
><span class="custom-require_danger">{{ t('model.model_name') }}</span>
<el-tooltip effect="dark" :content="t('model.custom_model_name')" placement="right">
<el-icon style="margin-left: 4px" size="16">
<dashboard_info></dashboard_info>
</el-icon>
@@ -157,7 +159,7 @@ defineExpose({
</template>
<el-input v-model="modelForm.name" />
</el-form-item>
<el-form-item prop="type" label="模型类型">
<el-form-item prop="type" :label="t('model.model_type')">
<el-select v-model="modelForm.type" style="width: 100%">
<el-option
v-for="item in modelTypeOptions"
@@ -169,8 +171,8 @@ defineExpose({
</el-form-item>
<el-form-item class="custom-require" prop="modelName">
<template #label
><span class="custom-require_danger">基础模型</span>
<span class="enter">列表中未列出的模型,直接输入模型名称,回车即可添加</span>
><span class="custom-require_danger">{{ t('model.basic_model') }}</span>
<span class="enter">{{ t('model.enter_to_add') }}</span>
</template>
<el-select v-model="modelForm.type" style="width: 100%">
<el-option
@@ -181,11 +183,21 @@ defineExpose({
/>
</el-select>
</el-form-item>
<el-form-item prop="endpoint" label="API 域名">
<el-input v-model="modelForm.endpoint" />
<el-form-item prop="endpoint" :label="t('model.api_domain_name')">
<el-input
v-model="modelForm.endpoint"
:placeholder="
$t('datasource.please_enter') + $t('common.empty') + $t('model.api_domain_name')
"
/>
</el-form-item>
<el-form-item prop="api_key" label="API Key">
<el-input v-model="modelForm.api_key" type="password" show-password />
<el-input
v-model="modelForm.api_key"
:placeholder="$t('datasource.please_enter') + $t('common.empty') + 'API Key'"
type="password"
show-password
/>
</el-form-item>
</el-form>
<div
@@ -193,27 +205,32 @@ defineExpose({
:class="advancedSettingExpand && 'expand'"
@click="advancedSettingExpand = !advancedSettingExpand"
>
高级设置
{{ t('model.advanced_settings') }}
<el-icon size="16">
<arrow_down></arrow_down>
</el-icon>
</div>
<div v-if="advancedSettingExpand" class="model-params">
模型参数
{{ t('model.model_parameters') }}
<span class="add" @click="handleParamsCreate">
<el-icon size="16">
<icon_add_outlined></icon_add_outlined>
</el-icon>
添加
{{ t('model.add') }}
</span>
</div>
<div v-if="advancedSettingExpand" class="params-table">
<el-table :data="advancedSetting" style="width: 100%">
<el-table-column prop="params" label="参数" width="280" />
<el-table-column prop="name" label="显示名称" width="280" />
<el-table-column prop="value" label="参数值" />
<el-table-column fixed="right" width="80" class-name="operation-column_text" label="操作">
<el-table-column prop="params" :label="t('model.parameters')" width="280" />
<el-table-column prop="name" :label="t('model.display_name')" width="280" />
<el-table-column prop="value" :label="t('model.parameter_value')" />
<el-table-column
fixed="right"
width="80"
class-name="operation-column_text"
:label="$t('ds.actions')"
>
<template #default="scope">
<el-button text type="primary" @click="handleParamsEdite(scope.row)">
<el-icon size="16">
@@ -230,11 +247,15 @@ defineExpose({
</el-table>
</div>
</div>
<el-drawer v-model="paramsFormDrawer" :size="600" title="添加参数">
<el-drawer
v-model="paramsFormDrawer"
:size="600"
:title="$t('model.add') + $t('common.empty') + $t('model.parameters')"
>
<ParamsForm ref="paramsFormRef" @submit="submit"></ParamsForm>
<template #footer>
<el-button secondary @click="cancel"> {{ $t('common.cancel') }} </el-button>
<el-button type="primary" @click="addParams"> 添加 </el-button>
<el-button type="primary" @click="addParams"> {{ t('model.add') }} </el-button>
</template>
</el-drawer>
</div>
@@ -34,7 +34,7 @@ const handleModelClick = (item: any) => {
<template>
<div class="model-list">
<div class="title">选择供应商</div>
<div class="title">{{ $t('model.select_supplier') }}</div>
<el-input
v-model="keywords"
clearable
+42 -26
View File
@@ -1,5 +1,8 @@
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const paramsRef = ref()
const paramsForm = reactive({
name: '',
@@ -9,10 +12,27 @@ const paramsForm = reactive({
})
const rules = {
name: [{ required: true, message: '请给基础模型设置一个名称', trigger: 'blur' }],
params: [{ required: true, message: '请给基础模型设置一个名称', trigger: 'blur' }],
value: [{ required: true, message: '请给基础模型设置一个名称', trigger: 'blur' }],
type: [{ required: true, message: '请给基础模型设置一个名称', trigger: 'blur' }],
name: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('model.display_name'),
trigger: 'blur',
},
],
params: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('model.parameters'),
trigger: 'blur',
},
],
value: [
{
required: true,
message: t('datasource.please_enter') + t('common.empty') + t('model.parameter_value'),
trigger: 'blur',
},
],
}
const initForm = (item: any) => {
@@ -22,8 +42,6 @@ const initForm = (item: any) => {
paramsRef.value.clearValidate()
}
const typeList = ['文本', '数值', 'Json']
const emits = defineEmits(['submit'])
const submit = () => {
@@ -48,29 +66,27 @@ defineExpose({
:model="paramsForm"
style="width: 100%"
>
<el-form-item prop="params" label="参数">
<el-input v-model="paramsForm.params" />
</el-form-item>
<el-form-item prop="name" label="显示名称">
<el-input v-model="paramsForm.name" />
</el-form-item>
<el-form-item prop="type" label="参数类型">
<el-radio-group v-model="paramsForm.type">
<el-radio v-for="(ele, index) in typeList" :key="ele" :value="index">{{ ele }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="value" :label="typeList[paramsForm.type]">
<el-input-number
v-if="paramsForm.type === 1"
v-model="paramsForm.value"
controls-position="right"
/>
<el-form-item prop="params" :label="$t('model.parameters')">
<el-input
v-if="paramsForm.type === 0"
v-model="paramsForm.params"
:placeholder="$t('datasource.please_enter') + $t('common.empty') + $t('model.parameters')"
/>
</el-form-item>
<el-form-item prop="name" :label="$t('model.display_name')">
<el-input
v-model="paramsForm.name"
:placeholder="
$t('datasource.please_enter') + $t('common.empty') + $t('model.display_name')
"
/>
</el-form-item>
<el-form-item prop="value" :label="$t('model.parameter_value')">
<el-input
v-model="paramsForm.value"
placeholder="请输入 1-50 个字符"
:placeholder="
$t('datasource.please_enter') + $t('common.empty') + $t('model.parameter_value')
"
/>
<el-input v-if="paramsForm.type === 2" v-model="paramsForm.value" type="textarea" />
</el-form-item>
</el-form>
</div>