feat: i18n

This commit is contained in:
王丹 2025-01-20 11:02:55 +08:00
parent 0e7f466723
commit 96f467fa21
50 changed files with 752 additions and 376 deletions

View File

@ -1,10 +1,11 @@
<template>
<div class="flex align-center mt-16" v-if="!isWorkFlow(props.type)">
<span class="mr-4 color-secondary">知识来源</span>
<span class="mr-4 color-secondary">{{ $t('components.chat.KnowledgeSource.title') }}</span>
<el-divider direction="vertical" />
<el-button type="primary" class="mr-8" link @click="openParagraph(data)">
<AppIcon iconName="app-reference-outlined" class="mr-4"></AppIcon>
引用分段 {{ data.paragraph_list?.length || 0 }}</el-button
{{ $t('components.chat.KnowledgeSource.referenceParagraph') }}
{{ data.paragraph_list?.length || 0 }}</el-button
>
</div>
<div class="mt-8" v-if="!isWorkFlow(props.type)">
@ -42,8 +43,8 @@
<div class="border-t color-secondary flex-between mt-12" style="padding-top: 12px">
<div>
<span class="mr-8"> 消耗 tokens: {{ data?.message_tokens + data?.answer_tokens }} </span>
<span> 耗时: {{ data?.run_time?.toFixed(2) }} s</span>
<span class="mr-8"> {{ $t('components.chat.KnowledgeSource.consume') }} tokens: {{ data?.message_tokens + data?.answer_tokens }} </span>
<span> {{ $t('components.chat.KnowledgeSource.consumeTime') }}: {{ data?.run_time?.toFixed(2) }} s</span>
</div>
<el-button
v-if="isWorkFlow(props.type)"
@ -52,7 +53,7 @@
@click="openExecutionDetail(data.execution_details)"
>
<el-icon class="mr-4"><Document /></el-icon>
执行详情</el-button
{{ $t('components.chat.executionDetails.title') }}</el-button
>
</div>
<!-- 知识库引用 dialog -->

View File

@ -19,7 +19,7 @@
<el-form-item label="优化后问题">
<el-input v-model="detail.padding_problem_text" disabled />
</el-form-item>
<el-form-item label="引用分段">
<el-form-item :label="$t('components.chat.KnowledgeSource.referenceParagraph')">
<div v-if="detail.paragraph_list.length > 0" class="w-full">
<template v-for="(item, index) in detail.paragraph_list" :key="index">
<ParagraphCard :data="item" :index="index" />

View File

@ -6,7 +6,7 @@
<el-input
ref="quickInputRef"
v-model="inputValue"
:placeholder="`请输入${quickCreateName}`"
:placeholder="`${$t('common.inputPlaceholder')}${quickCreateName}`"
class="w-500 mr-12"
autofocus
:maxlength="quickCreateMaxlength || '-'"

View File

@ -7,7 +7,7 @@
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{ $t('common.add') }}
</el-button>
</div>
</template>

View File

@ -7,7 +7,7 @@
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{ $t('common.add') }}
</el-button>
</div>
</template>

View File

@ -7,7 +7,7 @@
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{ $t('common.add') }}
</el-button>
</div>
</template>

View File

@ -7,7 +7,7 @@
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{ $t('common.add') }}
</el-button>
</div>
</template>

View File

@ -20,7 +20,7 @@
</el-button>
</div>
<!-- Codemirror 弹出层 -->
<el-dialog v-model="dialogVisible" title="Python 代码" append-to-body fullscreen>
<el-dialog v-model="dialogVisible" :title="'Python ' + $t('views.functionLib.functionForm.form.param.code')" append-to-body fullscreen>
<Codemirror
v-model="cloneContent"
:extensions="extensions"

View File

@ -22,7 +22,7 @@
<el-input
ref="inputRef"
v-model="writeValue"
placeholder="请输入"
:placeholder="$t('common.inputPlaceholder')"
autofocus
:maxlength="maxlength || '-'"
:show-word-limit="maxlength ? true : false"

View File

@ -33,6 +33,7 @@
<script setup lang="ts">
import { ref, watch } from 'vue'
import UserApi from '@/api/user'
import { t } from '@/locales'
defineOptions({ name: 'TagsInput' })
const props = defineProps({
tags: {
@ -42,7 +43,7 @@ const props = defineProps({
},
placeholder: {
type: String,
default: '请输入'
default: t('common.inputPlaceholder')
},
limit: {
/* 最多生成标签数 */

View File

@ -27,7 +27,6 @@ export default {
createDate: 'Create date',
createTime: 'Create time',
operation: 'Operation',
document: 'Documentation',
character: 'characters',
export: 'Export',
exportSuccess: 'Export successful',
@ -40,9 +39,16 @@ export default {
required: 'Required',
noData: 'No data',
result: 'Result',
fileUpload: {
document: 'Documentation',
image: 'Image',
audio: 'Audio',
video: 'Video'
},
status: {
label: 'Status',
enableSuccess: 'Enable Successful',
disableSuccess: 'Disable Successful'
}
},
inputPlaceholder: 'Please input'
}

View File

@ -27,7 +27,7 @@ export default {
createDate: '创建日期',
createTime: '创建时间',
operation: '操作',
document: '文档',
character: '字符',
export: '导出',
exportSuccess: '导出成功',
@ -40,9 +40,16 @@ export default {
required: '必填',
noData: '暂无数据',
result: '结果',
fileUpload: {
document: '文档',
image: '图片',
audio: '音频',
video: '视频'
},
status: {
label: '状态',
enableSuccess: '启用成功',
disableSuccess: '禁用成功'
}
},
inputPlaceholder: '请输入'
}

View File

@ -5,19 +5,27 @@ export default {
only20history: '仅显示最近 20 条对话',
question_count: '条提问',
exportReords: '导出聊天记录',
chatId: '对话id',
userInput: '用户输入',
passwordValidator: {
title: '请输入密码打开链接',
errorMessage1: '密码不能为空',
errorMessage2: '密码错误'
},
executionDetails: {
title: '执行详情',
paramInput: '参数输入',
paramOutput: '参数输出',
},
tip: {
error500Message: '抱歉,当前正在维护,无法提供服务,请稍后再试!',
errorIdentifyMessage: '无法识别用户身份',
errorLimitMessage:'抱歉,您的提问已达到最大限制,请明天再来吧!'
errorLimitMessage: '抱歉,您的提问已达到最大限制,请明天再来吧!'
},
executionDetails: {
title: '执行详情',
paramInput: '参数输入',
paramOutput: '参数输出'
},
KnowledgeSource: {
title: '知识来源',
referenceParagraph: '引用分段',
consume: '消耗',
consumeTime: '耗时'
}
}

View File

@ -19,7 +19,8 @@ export default {
field: {
label: '参数',
placeholder: '请输入参数',
requiredMessage: '参数 为必填属性'
requiredMessage: '参数 为必填属性',
requiredMessage2:'只能输入字母数字和下划线'
},
name: {
label: '显示名称',

View File

@ -1,8 +1,8 @@
import type { result } from 'lodash'
export default {
node: '节点',
baseComponent: '基础组件',
nodeSetting: '节点设置',
workflow: '工作流',
searchBar: {
placeholder: '按名称搜索'
},
@ -31,7 +31,8 @@ export default {
functionNodeError: '该函数不可用',
repeatedNodeError: '节点名称已存在!',
cannotCopy: '不能被复制',
copyError: '已复制节点'
copyError: '已复制节点',
paramErrorMessage: '参数已存在: '
},
delete: {
confirmTitle: '确定删除该节点?',
@ -50,7 +51,8 @@ export default {
Referencing: '引用变量',
ReferencingRequired: '引用变量必填',
ReferencingError: '引用变量错误',
NoReferencing: '不存在的引用变量'
NoReferencing: '不存在的引用变量',
fieldMessage: '请选择变量'
},
condition: {
title: '执行条件',
@ -78,12 +80,36 @@ export default {
currentTime: '当前时间'
},
baseNode: {
label: '基本信息'
label: '基本信息',
fileUpload: {
label: '文件上传',
tooltip: '开启后,问答页面会显示上传文件的按钮。'
},
FileUploadSetting: {
title: '文件上传设置',
maxFiles: '单次上传最多文件数',
fileLimit: '每个文件最大MB',
fileUploadType: {
label: '上传的文件类型',
documentText: '需要使用“文档内容提取”节点解析文档内容',
imageText: '需要使用“图片理解”节点解析图片内容',
audioText: '需要使用“语音转文本”节点解析音频内容'
}
}
},
aiChatNode: {
label: 'AI 对话',
text: '与 AI 大模型进行对话',
answer: 'AI 回答内容'
answer: 'AI 回答内容',
returnContent: {
label: '返回内容',
tooltip: `关闭后该节点的内容则不输出给用户。
`
},
defaultPrompt: `已知信息:
{{.data}}
{{.question}}`
},
searchDatasetNode: {
label: '知识库检索',
@ -91,28 +117,62 @@ export default {
paragraph_list: '检索结果的分段列表',
is_hit_handling_method_list: '满足直接回答的分段列表',
result: '检索结果',
directly_return: '满足直接回答的分段内容'
directly_return: '满足直接回答的分段内容',
selectDatasetText: '关联的知识库展示在这里',
searchParam: '检索参数',
searchQuestion: {
label: '检索问题',
placeholder: '请选择检索问题',
requiredMessage: '请选择检索问题'
}
},
questionNode: {
label: '问题优化',
text: '根据历史聊天记录优化完善当前问题,更利于匹配知识库分段',
result: '问题优化结果'
result: '问题优化结果',
defaultPrompt: `根据上下文优化和完善用户问题:{{开始.question}}
`,
systemDefault: '你是一个问题优化大师'
},
conditionNode: {
label: '判断器',
text: '根据不同条件执行不同的节点',
branch_name: '分支名称'
branch_name: '分支名称',
conditions: {
label: '条件',
info: '符合以下',
requiredMessage: '请选择条件'
},
valueMessage: '请输入值',
addCondition: '添加条件',
addBranch: '添加分支'
},
replyNode: {
label: '指定回复',
text: '指定回复内容,引用变量会转换为字符串进行输出',
content: '内容'
content: '内容',
replyContent: {
label: '回复内容',
custom: '自定义',
reference: '引用变量'
}
},
rerankerNode: {
label: '多路召回',
text: '使用重排模型对多个知识库的检索结果进行二次召回',
result_list: '重排结果列表',
result: '重排结果'
result: '重排结果',
rerankerContent: {
label: '重排内容',
requiredMessage: '请选择重排内容'
},
higher: '高于',
ScoreTooltip: 'Score越高相关性越强。',
max_paragraph_char_number: '最大引用字符数',
reranker_model: {
label: '重排模型',
placeholder: '请选择重排模型'
}
},
formNode: {
label: '表单收集',
@ -120,7 +180,14 @@ export default {
form_content_format: `你好,请先填写下面表单内容:
{{form}}
`,
form_data: '表单全部内容'
form_data: '表单全部内容',
formContent: {
label: '表单输出内容',
requiredMessage: '请表单输出内容',
tooltip: '设置执行该节点输出的内容,{ form } 为表单的占位符。'
},
formAllContent: '表单全部内容',
formSetting: '表单配置'
},
documentExtractNode: {
label: '文档内容提取',
@ -130,21 +197,54 @@ export default {
imageUnderstandNode: {
label: '图片理解',
text: '识别出图片中的对象、场景等信息回答用户问题',
answer: 'AI 回答内容'
answer: 'AI 回答内容',
model: {
label: '图片理解模型',
requiredMessage: '请选择图片理解模型'
},
image: {
label: '选择图片',
requiredMessage: '请选择图片'
}
},
imageGenerateNode: {
label: '图片生成',
text: '根据提供的文本内容生成图片',
answer: 'AI 回答内容',
image: '图片'
model: {
label: '图片生成模型',
requiredMessage: '请选择图片生成模型'
},
prompt: {
label: '提示词(正向)',
tooltip: '正向提示词,用来描述生成图像中期望包含的元素和视觉特点'
},
negative_prompt: {
label: '提示词(负向)',
tooltip: '反向提示词,用来描述不希望在画面中看到的内容,可以对画面进行限制。',
placeholder: '请描述不想生成的图片内容,比如:颜色、血腥内容'
}
},
speechToTextNode: {
label: '语音转文本',
text: '将音频通过语音识别模型转换为文本'
text: '将音频通过语音识别模型转换为文本',
stt_model: {
label: '语音识别模型'
},
audio: {
label: '选择语音文件',
placeholder: '请选择语音文件'
}
},
textToSpeechNode: {
label: '文本转语音',
text: '将文本通过语音合成模型转换为音频'
text: '将文本通过语音合成模型转换为音频',
tts_model: {
label: '语音识别模型'
},
content: {
label: '选择文本内容'
}
},
functionNode: {
label: '自定义函数',
@ -169,5 +269,6 @@ export default {
len_gt: '长度大于',
len_le: '长度小于等于',
len_lt: '长度小于'
}
},
FileUploadSetting: {}
}

View File

@ -1,6 +1,3 @@
import Password from '@/views/chat/auth/component/password.vue'
import { create } from 'lodash'
export default {
title: '应用',
createApplication: '创建应用',
@ -59,6 +56,7 @@ export default {
references: ' (引用知识库)',
placeholder: '请输入提示词',
requiredMessage: '请输入提示词',
tooltip:'通过调整提示词内容,可以引导大模型聊天方向,该提示词会被固定在上下文的开头,可以使用变量。',
noReferencesTooltip:
'通过调整提示词内容,可以引导大模型聊天方向,该提示词会被固定在上下文的开头。可以使用变量:{question} 是用户提出问题的占位符。',
referencesTooltip:

View File

@ -41,7 +41,7 @@ export default {
},
inputParam: {
label: '输入参数',
placeholder: '请输入参数值',
placeholder: '请选择参数',
requiredMessage: '请输入参数值'
},
paramName: {

View File

@ -40,7 +40,8 @@ export default {
modelParams: '模型参数',
editParam: '编辑参数',
addParam: '添加参数',
paramSetting: '模型参数设置'
paramSetting: '模型参数设置',
apiParamPassing: '接口传参'
},
form: {
templateName: {

View File

@ -27,7 +27,6 @@ export default {
createDate: '創建日期',
createTime: '創建時間',
operation: '操作',
document: '文檔',
character: '字符',
export: '匯出',
exportSuccess: '匯出成功',
@ -40,9 +39,16 @@ export default {
required: '必填',
noData: '暂无数据',
result: '結果',
fileUpload: {
document: '文檔',
image: '圖片',
audio: '音頻',
video: '視頻'
},
status: {
label: '狀態',
enableSuccess: '啟用成功',
disableSuccess: '停用成功'
}
},
inputPlaceholder: '請輸入'
}

View File

@ -103,7 +103,7 @@
</div>
<div class="mt-4 mb-16 url-height">
<div>
<el-text>API {{ $t('common.document') }}</el-text
<el-text>API {{ $t('common.fileUpload.document') }}</el-text
><el-button
type="primary"
link

View File

@ -4,7 +4,7 @@
<template #sub-title>
<div class="mt-8">
<span class="bold">{{ data?.document_list.length || 0 }}</span>
<el-text type="info" class="ml-4">{{ $t('common.document') }}</el-text>
<el-text type="info" class="ml-4">{{ $t('common.fileUpload.document') }}</el-text>
<el-divider direction="vertical" />
<span class="bold">{{ paragraph_count || 0 }}</span>
<el-text type="info" class="ml-4">{{

View File

@ -85,7 +85,7 @@
<div class="footer-content flex-between">
<div>
<span class="bold">{{ item?.document_count || 0 }}</span>
{{ $t('common.document') }}<el-divider direction="vertical" />
{{ $t('common.fileUpload.document') }}<el-divider direction="vertical" />
<span class="bold">{{ numberFormat(item?.char_length) || 0 }}</span>
{{ $t('common.character') }}<el-divider direction="vertical" />
<span class="bold">{{ item?.application_mapping_count || 0 }}</span>

View File

@ -1,5 +1,5 @@
<template>
<LayoutContainer :header="$t('common.document')" class="document-main">
<LayoutContainer :header="$t('common.fileUpload.document')" class="document-main">
<div class="main-calc-height">
<div class="p-24">
<div class="flex-between">

View File

@ -44,7 +44,7 @@
</template>
<el-input
v-model="item.value"
:placeholder="$t('views.functionLib.functionForm.form.inputParam.placeholder')"
:placeholder="$t('views.functionLib.functionForm.form.inputParam.requiredMessage')"
/>
</el-form-item>
</template>

View File

@ -190,7 +190,7 @@
ref="quickInputRef"
v-model="inputValue"
type="textarea"
placeholder="请输入"
:placeholder="$t('common.inputPlaceholder')"
:autosize="{ minRows: 1, maxRows: 8 }"
@keydown.enter="sendChatHandle($event)"
/>

View File

@ -1,6 +1,6 @@
<template>
<el-dialog
:title="`${$t('views.log.selectDataset')}/${$t('common.document')}`"
:title="`${$t('views.log.selectDataset')}/${$t('common.fileUpload.document')}`"
v-model="dialogVisible"
width="500"
:close-on-click-modal="false"

View File

@ -186,7 +186,9 @@ export const formNode = {
node_data: {
is_result: true,
form_field_list: [],
form_content_format: t('views.applicationWorkflow.nodes.formNode.form_content_format')
form_content_format: t('views.applicationWorkflow.nodes.formNode.form_content_format', {
form: '{{form}}'
})
},
config: {
fields: [

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never" style="--el-card-padding: 12px">
<el-form
@submit.prevent
@ -13,18 +13,21 @@
hide-required-asterisk
>
<el-form-item
label="AI 模型"
:label="$t('views.application.applicationForm.form.aiModel.label')"
prop="model_id"
:rules="{
required: true,
message: '请选择 AI 模型',
message: $t('views.application.applicationForm.form.aiModel.placeholder'),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between w-full">
<div>
<span>AI 模型<span class="danger">*</span></span>
<span
>{{ $t('views.application.applicationForm.form.aiModel.label')
}}<span class="danger">*</span></span
>
</div>
<el-button
:disabled="!chat_data.model_id"
@ -49,32 +52,35 @@
></ModelSelect>
</el-form-item>
<el-form-item label="角色设定">
<el-form-item :label="$t('views.application.applicationForm.form.roleSettings.label')">
<MdEditorMagnify
title="角色设定"
:title="$t('views.application.applicationForm.form.roleSettings.label')"
v-model="chat_data.system"
style="height: 100px"
@submitDialog="submitSystemDialog"
placeholder="角色设定"
:placeholder="$t('views.application.applicationForm.form.roleSettings.label')"
/>
</el-form-item>
<el-form-item
label="提示词"
:label="$t('views.application.applicationForm.form.prompt.label')"
prop="prompt"
:rules="{
required: true,
message: '请输入提示词',
message: $t('views.application.applicationForm.form.prompt.requiredMessage'),
trigger: 'blur'
}"
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>提示词<span class="danger">*</span></span>
<span
>{{ $t('views.application.applicationForm.form.prompt.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content
>通过调整提示词内容可以引导大模型聊天方向该提示词会被固定在上下文的开头可以使用变量
>{{ $t('views.application.applicationForm.form.prompt.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -82,19 +88,19 @@
</template>
<MdEditorMagnify
@wheel="wheel"
title="提示词"
:title="$t('views.application.applicationForm.form.prompt.label')"
v-model="chat_data.prompt"
style="height: 150px"
@submitDialog="submitDialog"
/>
</el-form-item>
<el-form-item label="历史聊天记录">
<el-form-item :label="$t('views.application.applicationForm.form.historyRecord.label')">
<template #label>
<div class="flex-between">
<div>历史聊天记录</div>
<div>{{ $t('views.application.applicationForm.form.historyRecord.label') }}</div>
<el-select v-model="chat_data.dialogue_type" type="small" style="width: 100px">
<el-option :label="$t('views.applicationWorkflow.node')" value="NODE" />
<el-option label="工作流" value="WORKFLOW" />
<el-option :label="$t('views.applicationWorkflow.workflow')" value="WORKFLOW" />
</el-select>
</div>
</template>
@ -108,16 +114,21 @@
:step-strictly="true"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -141,7 +152,7 @@ import applicationApi from '@/api/application'
import useStore from '@/stores'
import { isLastNode } from '@/workflow/common/data'
import AIModeParamSettingDialog from '@/views/application/component/AIModeParamSettingDialog.vue'
import { t } from '@/locales'
const { model } = useStore()
const wheel = (e: any) => {
@ -174,10 +185,7 @@ const {
} = app.config.globalProperties.$route as any
// @ts-ignore
const defaultPrompt = `已知信息:
{{知识库检索.data}}
问题
{{开始.question}}`
const defaultPrompt = t('views.applicationWorkflow.nodes.aiChatNode.defaultPrompt')
const form = {
model_id: '',
system: '',

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -11,10 +11,12 @@
ref="applicationNodeFormRef"
>
<el-form-item
label="用户问题"
:label="$t('views.applicationWorkflow.nodes.startNode.question')"
prop="question_reference_address"
:rules="{
message: '请选择检索问题',
message: $t(
'views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.requiredMessage'
),
trigger: 'blur',
required: true
}"
@ -23,17 +25,19 @@
ref="applicationNodeFormRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
:placeholder="
$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.placeholder')
"
v-model="form_data.question_reference_address"
/>
</el-form-item>
<el-form-item
v-if="form_data.hasOwnProperty('document_list') || 'document_list' in form_data"
label="选择文档"
:label="$t('views.problem.relateParagraph.selectDocument')"
prop="document_list"
:rules="{
message: '请选择文档',
message: $t('views.log.documentPlaceholder'),
trigger: 'blur',
required: false
}"
@ -42,17 +46,19 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择文档"
:placeholder="$t('views.log.documentPlaceholder')"
v-model="form_data.document_list"
/>
</el-form-item>
<el-form-item
v-if="form_data.hasOwnProperty('image_list') || 'image_list' in form_data"
label="选择图片"
:label="$t('views.applicationWorkflow.nodes.imageUnderstandNode.image.label')"
prop="image_list"
:rules="{
message: '请选择图片',
message: $t(
'views.applicationWorkflow.nodes.imageUnderstandNode.image.requiredMessage'
),
trigger: 'blur',
required: false
}"
@ -61,17 +67,19 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择图片"
:placeholder="
$t('views.applicationWorkflow.nodes.imageUnderstandNode.image.requiredMessage')
"
v-model="form_data.image_list"
/>
</el-form-item>
<el-form-item
v-if="form_data.hasOwnProperty('audio_list') || 'audio_list' in form_data"
label="选择语音文件"
:label="$t('views.applicationWorkflow.nodes.speechToTextNode.audio.label')"
prop="audio_list"
:rules="{
message: '请选择语音文件',
message: $t('views.applicationWorkflow.nodes.speechToTextNode.audio.placeholder'),
trigger: 'blur',
required: false
}"
@ -80,7 +88,7 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择语音文件"
:placeholder="$t('views.applicationWorkflow.nodes.speechToTextNode.audio.placeholder'),"
v-model="form_data.audio_list"
/>
</el-form-item>
@ -89,14 +97,20 @@
:label="field.variable"
:prop="'api_input_field_list.' + index + '.value'"
:rules="[
{ required: field.is_required, message: `请输入${field.variable}`, trigger: 'blur' }
{
required: field.is_required,
message: `${$t('common.inputPlaceholder')}${field.variable}`,
trigger: 'blur'
}
]"
>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
:placeholder="
$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.placeholder')
"
v-model="form_data.api_input_field_list[index].value"
/>
</el-form-item>
@ -107,28 +121,39 @@
:label="field.label"
:prop="'user_input_field_list.' + index + '.value'"
:rules="[
{ required: field.required, message: `请输入${field.label}`, trigger: 'blur' }
{
required: field.required,
message: `${$t('common.inputPlaceholder')}${field.label}`,
trigger: 'blur'
}
]"
>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
:placeholder="
$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.placeholder')
"
v-model="form_data.user_input_field_list[index].value"
/>
</el-form-item>
</div>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>

View File

@ -19,17 +19,17 @@
:model="form"
require-asterisk-position="right"
>
<el-form-item label="参数" prop="variable">
<el-form-item :label="$t('components.dynamicsForm.paramForm.field.label')" prop="variable">
<el-input
v-model="form.variable"
placeholder="请输入参数"
:placeholder="$t('components.dynamicsForm.paramForm.field.placeholder')"
maxlength="64"
show-word-limit
@blur="form.variable = form.variable.trim()"
/>
</el-form-item>
<el-form-item label="是否必填" @click.prevent>
<el-form-item :label="$t('components.dynamicsForm.paramForm.required.label')" @click.prevent>
<el-switch size="small" v-model="form.is_required"></el-switch>
</el-form-item>
<el-form-item
@ -62,7 +62,7 @@
import { reactive, ref, watch } from 'vue'
import type { FormInstance } from 'element-plus'
import { cloneDeep } from 'lodash'
import { t } from '@/locales'
const emit = defineEmits(['refresh'])
const fieldFormRef = ref()
@ -80,10 +80,10 @@ const form = ref<any>({
})
const rules = reactive({
name: [{ required: true, message: '请输入显示名称', trigger: 'blur' }],
name: [{ required: true, message: t('components.dynamicsForm.paramForm.name.requiredMessage'), trigger: 'blur' }],
variable: [
{ required: true, message: '请输入参数', trigger: 'blur' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: '只能输入字母数字和下划线', trigger: 'blur' }
{ required: true, message: t('components.dynamicsForm.paramForm.field.requiredMessage'), trigger: 'blur' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: t('components.dynamicsForm.paramForm.field.requiredMessage2'), trigger: 'blur' }
]
})

View File

@ -1,11 +1,11 @@
<template>
<div class="flex-between mb-16">
<h5 class="lighter">{{ '接口传参' }}</h5>
<h5 class="lighter">{{ $t('views.applicationWorkflow.templateForm.title.apiParamPassing') }}</h5>
<el-button link type="primary" @click="openAddDialog()">
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{$t('common.add')}}
</el-button>
</div>
<el-table
@ -13,7 +13,7 @@
:data="props.nodeModel.properties.api_input_field_list"
class="mb-16"
>
<el-table-column prop="variable" label="参数" />
<el-table-column prop="variable" :label="$t('components.dynamicsForm.paramForm.field.label')" />
<el-table-column prop="default_value" :label="$t('components.dynamicsForm.default.label')" />
<el-table-column :label="$t('common.required')">
<template #default="{ row }">
@ -50,7 +50,7 @@ import { onMounted, ref } from 'vue'
import { set } from 'lodash'
import ApiFieldFormDialog from './ApiFieldFormDialog.vue'
import { MsgError } from '@/utils/message'
import { t } from '@/locales'
const props = defineProps<{ nodeModel: any }>()
const currentIndex = ref(null)
@ -72,7 +72,7 @@ function deleteField(index: any) {
function refreshFieldList(data: any) {
for (let i = 0; i < inputFieldList.value.length; i++) {
if (inputFieldList.value[i].variable === data.variable && currentIndex.value !== i) {
MsgError('参数已存在: ' + data.variable)
MsgError(t('views.applicationWorkflow.tip.paramErrorMessage') + data.variable)
return
}
}
@ -80,7 +80,7 @@ function refreshFieldList(data: any) {
let arr = props.nodeModel.properties.user_input_field_list
for (let i = 0; i < arr.length; i++) {
if (arr[i].field === data.variable) {
MsgError('参数已存在: ' + data.variable)
MsgError(t('views.applicationWorkflow.tip.paramErrorMessage') + data.variable)
return
}
}

View File

@ -1,6 +1,6 @@
<template>
<el-dialog
title="文件上传设置"
:title="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.title')"
v-model="dialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
@ -15,7 +15,7 @@
:model="form_data"
require-asterisk-position="right"
>
<el-form-item label="单次上传最多文件数">
<el-form-item :label="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.maxFiles')">
<el-slider
v-model="form_data.maxFiles"
show-input
@ -24,7 +24,7 @@
:max="10"
/>
</el-form-item>
<el-form-item label="每个文件最大MB">
<el-form-item :label="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileLimit')">
<el-slider
v-model="form_data.fileLimit"
show-input
@ -33,7 +33,7 @@
:max="100"
/>
</el-form-item>
<el-form-item label="上传的文件类型">
<el-form-item :label="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.label')">
<el-card
shadow="hover"
class="card-checkbox cursor w-full mb-8"
@ -45,8 +45,10 @@
<div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-doc.svg" alt="" />
<div>
<p class="line-height-22 mt-4">文档TXTMDDOCXHTMLCSVXLSXXLSPDF</p>
<el-text class="color-secondary">需要使用文档内容提取节点解析文档内容</el-text>
<p class="line-height-22 mt-4">
{{ $t('common.fileUpload.document') }}TXTMDDOCXHTMLCSVXLSXXLSPDF
</p>
<el-text class="color-secondary">{{$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.documentText')}}</el-text>
</div>
</div>
<el-checkbox
@ -66,8 +68,10 @@
<div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-image.svg" alt="" />
<div>
<p class="line-height-22 mt-4">图片JPGJPEGPNGGIF</p>
<el-text class="color-secondary">需要使用图片理解节点解析图片内容</el-text>
<p class="line-height-22 mt-4">
{{ $t('common.fileUpload.image') }}JPGJPEGPNGGIF
</p>
<el-text class="color-secondary">{{$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.imageText')}}</el-text>
</div>
</div>
<el-checkbox v-model="form_data.image" @change="form_data.image = !form_data.image" />
@ -85,8 +89,8 @@
<div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-audio.svg" alt="" />
<div>
<p class="line-height-22 mt-4">音频MP3WAVOGGACC</p>
<el-text class="color-secondary">需要使用语音转文本节点解析音频内容</el-text>
<p class="line-height-22 mt-4">{{ $t('common.fileUpload.audio') }}MP3WAVOGGACC</p>
<el-text class="color-secondary">{{$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.audioText')}}</el-text>
</div>
</div>
<el-checkbox v-model="form_data.audio" @change="form_data.audio = !form_data.audio" />

View File

@ -35,6 +35,7 @@ import { cloneDeep } from 'lodash'
import DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue'
import type { FormField } from '@/components/dynamics-form/type'
import _ from 'lodash'
import { t } from '@/locales'
const emit = defineEmits(['refresh'])
const DynamicsFormConstructorRef = ref()
@ -121,11 +122,11 @@ const currentRow = computed(() => {
})
const currentIndex = ref(null)
const inputTypeList = ref([
{ label: '文本框', value: 'TextInputConstructor' },
{ label: '单选框', value: 'SingleSelectConstructor' },
{ label: '多选框', value: 'MultiSelectConstructor' },
{ label: '选项卡', value: 'RadioCardConstructor' },
{ label: '日期', value: 'DatePickerConstructor' }
{ label: t('components.dynamicsForm.input_type_list.TextInput'), value: 'TextInputConstructor' },
{ label: t('components.dynamicsForm.input_type_list.SingleSelect'), value: 'SingleSelectConstructor' },
{ label: t('components.dynamicsForm.input_type_list.MultiSelect'), value: 'MultiSelectConstructor' },
{ label: t('components.dynamicsForm.input_type_list.RadioCard'), value: 'RadioCardConstructor' },
{ label: t('components.dynamicsForm.input_type_list.DatePicker'), value: 'DatePickerConstructor' }
])
const dialogVisible = ref<boolean>(false)

View File

@ -1,11 +1,11 @@
<template>
<div class="flex-between mb-16">
<h5 class="lighter">{{ '用户输入' }}</h5>
<h5 class="lighter">{{ $t('components.chat.userInput') }}</h5>
<el-button link type="primary" @click="openAddDialog()">
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{ $t('common.add') }}
</el-button>
</div>
<el-table
@ -13,13 +13,13 @@
:data="props.nodeModel.properties.user_input_field_list"
class="mb-16"
>
<el-table-column prop="field" label="参数">
<el-table-column prop="field" :label="$t('components.dynamicsForm.paramForm.field.label')">
<template #default="{ row }">
<span :title="row.field" class="ellipsis-1">{{ row.field }}</span>
</template>
</el-table-column>
<el-table-column prop="label" label="显示名称">
<el-table-column prop="label" :label="$t('components.dynamicsForm.paramForm.name.label')">
<template #default="{ row }">
<span v-if="row.label && row.label.input_type === 'TooltipLabel'">
<span :title="row.label.label" class="ellipsis-1">
@ -33,24 +33,33 @@
>
</template>
</el-table-column>
<el-table-column label="组件类型">
<el-table-column :label="$t('components.dynamicsForm.paramForm.input_type.label')">
<template #default="{ row }">
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">文本框</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">滑块</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SwitchInput'">开关</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SingleSelect'"
>单选框</el-tag
>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'MultiSelect'">多选框</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'RadioCard'">选项卡</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'DatePicker'">日期</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">{{
$t('components.dynamicsForm.input_type_list.TextInput')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">{{
$t('components.dynamicsForm.input_type_list.Slider')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SwitchInput'">{{
$t('components.dynamicsForm.input_type_list.SwitchInput')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SingleSelect'">{{
$t('components.dynamicsForm.input_type_list.SingleSelect')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'MultiSelect'">{{
$t('components.dynamicsForm.input_type_list.MultiSelect')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'RadioCard'">{{
$t('components.dynamicsForm.input_type_list.RadioCard')
}}</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'DatePicker'">{{
$t('components.dynamicsForm.input_type_list.DatePicker')
}}</el-tag>
</template>
</el-table-column>
<el-table-column
prop="default_value"
:label="$t('components.dynamicsForm.default.label')"
>
<el-table-column prop="default_value" :label="$t('components.dynamicsForm.default.label')">
<template #default="{ row }">
<span :title="row.default_value" class="ellipsis-1">{{ getDefaultValue(row) }}</span>
</template>
@ -90,7 +99,7 @@ import { onMounted, ref } from 'vue'
import { set } from 'lodash'
import UserFieldFormDialog from './UserFieldFormDialog.vue'
import { MsgError } from '@/utils/message'
import { t } from '@/locales'
const props = defineProps<{ nodeModel: any }>()
const UserFieldFormDialogRef = ref()
@ -108,7 +117,7 @@ function deleteField(index: any) {
function refreshFieldList(data: any, index: any) {
for (let i = 0; i < inputFieldList.value.length; i++) {
if (inputFieldList.value[i].field === data.field && index !== i) {
MsgError('参数已存在: ' + data.field)
MsgError(t('views.applicationWorkflow.tip.paramErrorMessage') + data.field)
return
}
}
@ -116,7 +125,7 @@ function refreshFieldList(data: any, index: any) {
let arr = props.nodeModel.properties.api_input_field_list
for (let i = 0; i < arr.length; i++) {
if (arr[i].variable === data.field) {
MsgError('参数已存在: ' + data.field)
MsgError(t('views.applicationWorkflow.tip.paramErrorMessage') + data.field)
return
}
}

View File

@ -10,10 +10,10 @@
ref="baseNodeFormRef"
>
<el-form-item
label="应用名称"
:label="$t('views.application.applicationForm.form.appName.label')"
prop="name"
:rules="{
message: '应用名称不能为空',
message: t('views.application.applicationForm.form.appName.requiredMessage'),
trigger: 'blur',
required: true
}"
@ -21,25 +21,25 @@
<el-input
v-model="form_data.name"
maxlength="64"
placeholder="请输入应用名称"
:placeholder="t('views.application.applicationForm.form.appName.placeholder')"
show-word-limit
@blur="form_data.name = form_data.name?.trim()"
/>
</el-form-item>
<el-form-item label="应用描述">
<el-form-item :label="$t('views.application.applicationForm.form.appDescription.label')">
<el-input
v-model="form_data.desc"
placeholder="请输入应用描述"
:placeholder="$t('views.application.applicationForm.form.appDescription.placeholder')"
:rows="3"
type="textarea"
maxlength="256"
show-word-limit
/>
</el-form-item>
<el-form-item label="开场白">
<el-form-item :label="$t('views.application.applicationForm.form.prologue')">
<MdEditorMagnify
@wheel="wheel"
title="开场白"
:title="$t('views.application.applicationForm.form.prologue')"
v-model="form_data.prologue"
style="height: 150px"
@submitDialog="submitDialog"
@ -49,10 +49,12 @@
<template #label>
<div class="flex-between">
<div class="flex align-center">
<span class="mr-4">文件上传</span>
<span class="mr-4">{{
$t('views.applicationWorkflow.nodes.baseNode.fileUpload.label')
}}</span>
<el-tooltip
effect="dark"
content="开启后,问答页面会显示上传文件的按钮。"
:content="$t('views.applicationWorkflow.nodes.baseNode.fileUpload.tooltip')"
placement="right"
>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
@ -84,9 +86,13 @@
<el-form-item>
<template #label>
<div class="flex-between">
<span class="mr-4">语音输入</span>
<span class="mr-4">{{
$t('views.application.applicationForm.form.voiceInput.label')
}}</span>
<div class="flex">
<el-checkbox v-model="form_data.stt_autosend">自动发送</el-checkbox>
<el-checkbox v-model="form_data.stt_autosend">{{
$t('views.application.applicationForm.form.voiceInput.autoSend')
}}</el-checkbox>
<el-switch
class="ml-8"
size="small"
@ -107,9 +113,13 @@
<el-form-item>
<template #label>
<div class="flex-between">
<span class="mr-4">语音播放</span>
<span class="mr-4">{{
$t('views.application.applicationForm.form.voicePlay.label')
}}</span>
<div class="flex">
<el-checkbox v-model="form_data.tts_autoplay">自动播放</el-checkbox>
<el-checkbox v-model="form_data.tts_autoplay">{{
$t('views.application.applicationForm.form.voicePlay.autoPlay')
}}</el-checkbox>
<el-switch
class="ml-8"
size="small"
@ -121,8 +131,14 @@
</template>
<div class="w-full">
<el-radio-group v-model="form_data.tts_type" v-show="form_data.tts_model_enable">
<el-radio label="浏览器播放(免费)" value="BROWSER" />
<el-radio label="TTS模型" value="TTS" />
<el-radio
:label="$t('views.application.applicationForm.form.voicePlay.browser')"
value="BROWSER"
/>
<el-radio
:label="$t('views.application.applicationForm.form.voicePlay.tts')"
value="TTS"
/>
</el-radio-group>
</div>
<div class="flex-between w-full">
@ -170,7 +186,6 @@ import ApiInputFieldTable from './component/ApiInputFieldTable.vue'
import UserInputFieldTable from './component/UserInputFieldTable.vue'
import FileUploadSettingDialog from '@/workflow/nodes/base-node/component/FileUploadSettingDialog.vue'
const {
params: { id }
} = app.config.globalProperties.$route as any
@ -226,10 +241,16 @@ const validate = () => {
!form_data.value.tts_model_id &&
form_data.value.tts_type === 'TTS'
) {
return Promise.reject({ node: props.nodeModel, errMessage: '请选择语音播放模型' })
return Promise.reject({
node: props.nodeModel,
errMessage: t('views.application.applicationForm.form.voicePlay.requiredMessage')
})
}
if (form_data.value.stt_model_enable && !form_data.value.stt_model_id) {
return Promise.reject({ node: props.nodeModel, errMessage: '请选择语音输入模型' })
return Promise.reject({
node: props.nodeModel,
errMessage: t('views.application.applicationForm.form.voiceInput.requiredMessage')
})
}
return baseNodeFormRef.value?.validate().catch((err) => {
return Promise.reject({ node: props.nodeModel, errMessage: err })
@ -272,7 +293,7 @@ function sttModelEnableChange() {
const openTTSParamSettingDialog = () => {
const model_id = form_data.value.tts_model_id
if (!model_id) {
MsgSuccess(t('请选择语音播放模型'))
MsgSuccess(t('views.application.applicationForm.form.voicePlay.requiredMessage'))
return
}
TTSModeParamSettingDialogRef.value?.open(model_id, id, form_data.value.tts_model_params_setting)

View File

@ -18,17 +18,25 @@
<div class="flex-between lighter">
{{ item.type }}
<div class="info" v-if="item.conditions.length > 1">
<span>符合以下</span>
<span>{{ $t('views.applicationWorkflow.nodes.conditionNode.conditions.info') }}</span>
<el-select
:teleported="false"
v-model="item.condition"
size="small"
style="width: 60px; margin: 0 8px"
>
<el-option label="所有" value="and" />
<el-option label="任一" value="or" />
<el-option
:label="$t('views.applicationWorkflow.nodes.condition.AND')"
value="and"
/>
<el-option
:label="$t('views.applicationWorkflow.nodes.condition.OR')"
value="or"
/>
</el-select>
<span>条件</span>
<span>{{
$t('views.applicationWorkflow.nodes.conditionNode.conditions.label')
}}</span>
</div>
</div>
<div v-if="index !== form_data.branch.length - 1" class="mt-8">
@ -40,7 +48,7 @@
:rules="{
type: 'array',
required: true,
message: '请选择变量',
message: $t('views.applicationWorkflow.variable.fieldMessage'),
trigger: 'change'
}"
>
@ -48,7 +56,9 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择变量"
:placeholder="
$t('views.applicationWorkflow.variable.fieldMessage')
"
v-model="condition.field"
/>
</el-form-item>
@ -58,7 +68,9 @@
:prop="'branch.' + index + '.conditions.' + cIndex + '.compare'"
:rules="{
required: true,
message: '请选择条件',
message: $t(
'views.applicationWorkflow.nodes.conditionNode.conditions.requiredMessage'
),
trigger: 'change'
}"
>
@ -66,7 +78,11 @@
@wheel="wheel"
:teleported="false"
v-model="condition.compare"
placeholder="请选择条件"
:placeholder="
$t(
'views.applicationWorkflow.nodes.conditionNode.conditions.requiredMessage'
)
"
clearable
@change="changeCondition($event, index, cIndex)"
>
@ -82,11 +98,16 @@
:prop="'branch.' + index + '.conditions.' + cIndex + '.value'"
:rules="{
required: true,
message: '请输入值',
message: $t('views.applicationWorkflow.nodes.conditionNode.valueMessage'),
trigger: 'blur'
}"
>
<el-input v-model="condition.value" placeholder="请输入值" />
<el-input
v-model="condition.value"
:placeholder="
$t('views.applicationWorkflow.nodes.conditionNode.valueMessage')
"
/>
</el-form-item>
</el-col>
<el-col :span="1">
@ -110,12 +131,13 @@
@click="addCondition(index)"
v-if="index !== form_data.branch.length - 1"
>
<el-icon class="mr-4"><Plus /></el-icon>
<el-icon class="mr-4"><Plus /></el-icon>
{{ $t('views.applicationWorkflow.nodes.conditionNode.addCondition') }}
</el-button>
</el-card>
</template>
<el-button link type="primary" @click="addBranch">
<el-icon class="mr-4"><Plus /></el-icon>
<el-icon class="mr-4"><Plus /></el-icon> {{ $t('views.applicationWorkflow.nodes.conditionNode.addBranch') }}
</el-button>
</el-form>
</NodeContainer>

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -10,10 +10,10 @@
label-width="auto"
ref="DatasetNodeFormRef"
>
<el-form-item label="选择文档" :rules="{
<el-form-item :label="$t('views.problem.relateParagraph.selectDocument')" :rules="{
type: 'array',
required: true,
message: '请选择文件',
message: $t('views.log.documentPlaceholder'),
trigger: 'change'
}"
>
@ -21,7 +21,7 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择文档"
:placeholder="$t('views.log.documentPlaceholder')"
v-model="form_data.document_list"
/>
</el-form-item>

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never" style="--el-card-padding: 12px">
<el-form
@submit.prevent
@ -12,43 +12,55 @@
hide-required-asterisk
>
<el-form-item
label="表单输出内容"
:label="$t('views.applicationWorkflow.nodes.formNode.formContent.label')"
prop="form_content_format"
:rules="{
required: true,
message: '请表单输出内容',
message: $t('views.applicationWorkflow.nodes.formNode.formContent.requiredMessage'),
trigger: 'blur'
}"
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>表单输出内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.formNode.formContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
设置执行该节点输出的内容{{ '{ form }' }}为表单的占位符
{{
$t('views.applicationWorkflow.nodes.formNode.formContent.tooltip', {
form: '{ form }'
})
}}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
</div>
</template>
<MdEditorMagnify
title="表单输出内容"
:title="$t('views.applicationWorkflow.nodes.formNode.formContent.label')"
v-model="form_data.form_content_format"
style="height: 150px"
@submitDialog="submitDialog"
/>
</el-form-item>
<el-form-item label="表单配置" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.formNode.formSetting')"
@click.prevent
>
<template #label>
<div class="flex-between">
<h5 class="lighter">{{ '表单配置' }}</h5>
<h5 class="lighter">
{{ $t('views.applicationWorkflow.nodes.formNode.formSetting') }}
</h5>
<el-button link type="primary" @click="openAddFormCollect()">
<el-icon class="mr-4">
<Plus />
</el-icon>
添加
{{ $t('common.add') }}
</el-button>
</div></template
>
@ -58,12 +70,18 @@
v-if="form_data.form_field_list.length > 0"
:data="form_data.form_field_list"
>
<el-table-column prop="field" label="参数">
<el-table-column
prop="field"
:label="$t('components.dynamicsForm.paramForm.field.label')"
>
<template #default="{ row }">
<span :title="row.field" class="ellipsis-1">{{ row.field }}</span>
</template>
</el-table-column>
<el-table-column prop="label" label="显示名称">
<el-table-column
prop="label"
:label="$t('components.dynamicsForm.paramForm.name.label')"
>
<template #default="{ row }">
<span v-if="row.label && row.label.input_type === 'TooltipLabel'">
<span :title="row.label.label" class="ellipsis-1">
@ -78,7 +96,10 @@
</template>
</el-table-column>
<el-table-column label="组件类型" width="110px">
<el-table-column
:label="$t('components.dynamicsForm.paramForm.input_type.label')"
width="110px"
>
<template #default="{ row }">
<el-tag type="info" class="info-tag">{{
input_type_list.find((item) => item.value === row.input_type)?.label
@ -138,6 +159,7 @@ import { ref, onMounted, computed } from 'vue'
import { input_type_list } from '@/components/dynamics-form/constructor/data'
import { MsgError } from '@/utils/message'
import { set, cloneDeep } from 'lodash'
import { t } from '@/locales'
const props = defineProps<{ nodeModel: any }>()
const formNodeFormRef = ref<FormInstance>()
const editFormField = (form_field_data: any, field_index: number) => {
@ -152,7 +174,7 @@ const editFormField = (form_field_data: any, field_index: number) => {
}
const addFormField = (form_field_data: any) => {
if (form_data.value.form_field_list.some((field: any) => field.field === form_field_data.field)) {
MsgError('参数已存在:' + form_field_data.field)
MsgError(t('views.applicationWorkflow.tip.paramErrorMessage') + form_field_data.field)
return
}
form_data.value.form_field_list = cloneDeep([...form_data.value.form_field_list, form_field_data])
@ -161,7 +183,7 @@ const addFormField = (form_field_data: any) => {
const sync_form_field_list = () => {
const fields = [
{
label: '表单全部内容',
label: t('views.applicationWorkflow.nodes.formNode.formAllContent'),
value: 'form_data'
},
...form_data.value.form_field_list.map((item: any) => ({
@ -187,9 +209,9 @@ const deleteField = (form_field_data: any) => {
}
const form = ref<any>({
is_result: true,
form_content_format: `你好,请先填写下面表单内容:
{{form}}
填写后请点击提交按钮进行提交`,
form_content_format: t('views.applicationWorkflow.nodes.formNode.form_content_format', {
form: '{{form}}'
}),
form_field_list: []
})
const form_data = computed({

View File

@ -1,7 +1,7 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-16">节点设置</h5>
<h5 class="lighter mb-8">输入参数</h5>
<h5 class="title-decoration-1 mb-16">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<h5 class="lighter mb-8">{{ $t('views.functionLib.functionForm.form.inputParam.label') }}</h5>
<el-form
@submit.prevent
ref="FunctionNodeFormRef"
@ -18,7 +18,7 @@
:prop="'input_field_list.' + index + '.value'"
:rules="{
required: item.is_required,
message: '请输入参数值',
message: $t('views.functionLib.functionForm.form.inputParam.requiredMessage'),
trigger: 'blur'
}"
>
@ -40,25 +40,31 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择参数"
:placeholder="$t('views.functionLib.functionForm.form.inputParam.placeholder')"
v-model="item.value"
/>
<el-input v-else v-model="item.value" placeholder="请输入参数值" />
<el-input v-else v-model="item.value" :placeholder="$t('views.functionLib.functionForm.form.inputParam.requiredMessage')" />
</el-form-item>
</template>
</div>
<el-text type="info" v-else> {{ $t('common.noData') }} </el-text>
</el-card>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户 如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>

View File

@ -1,10 +1,10 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-16">节点设置</h5>
<h5 class="title-decoration-1 mb-16">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<div class="flex-between">
<h5 class="lighter mb-8">输入参数</h5>
<h5 class="lighter mb-8">{{ $t('views.functionLib.functionForm.form.inputParam.label') }}</h5>
<el-button link type="primary" @click="openAddDialog()">
<el-icon class="mr-4"><Plus /></el-icon>
<el-icon class="mr-4"><Plus /></el-icon> {{ $t('common.add') }}
</el-button>
</div>
<el-form
@ -23,7 +23,7 @@
:prop="'input_field_list.' + index + '.value'"
:rules="{
required: item.is_required,
message: '请输入参数值',
message: $t('views.functionLib.functionForm.form.inputParam.requiredMessage'),
trigger: 'blur'
}"
>
@ -55,11 +55,15 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择参数"
:placeholder="$t('views.functionLib.functionForm.form.inputParam.placeholder')"
v-model="item.value"
:width="100"
/>
<el-input v-else v-model="item.value" placeholder="请输入参数值" />
<el-input
v-else
v-model="item.value"
:placeholder="$t('views.functionLib.functionForm.form.inputParam.requiredMessage')"
/>
</el-form-item>
</template>
</div>
@ -67,7 +71,9 @@
<el-text type="info" v-else> {{ $t('common.noData') }} </el-text>
</el-card>
<h5 class="lighter mb-8">Python 代码</h5>
<h5 class="lighter mb-8">
Python {{ $t('views.functionLib.functionForm.form.param.code') }}
</h5>
<div class="function-CodemirrorEditor mb-8" v-if="showEditor">
<CodemirrorEditor
v-model="chat_data.code"
@ -81,15 +87,21 @@
</div>
</div>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户 如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -100,7 +112,7 @@
</el-form>
<FieldFormDialog ref="FieldFormDialogRef" @refresh="refreshFieldList" />
<!-- Codemirror 弹出层 -->
<el-dialog v-model="dialogVisible" title="Python 代码" append-to-body fullscreen>
<el-dialog v-model="dialogVisible" :title="'Python ' + $t('views.functionLib.functionForm.form.param.code')" append-to-body fullscreen>
<CodemirrorEditor
v-model="cloneContent"
style="

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :node-model="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -12,18 +12,21 @@
hide-required-asterisk
>
<el-form-item
label="图片生成模型"
:label="$t('views.applicationWorkflow.nodes.imageGenerateNode.model.label')"
prop="model_id"
:rules="{
required: true,
message: '请选择图片生成模型',
message: $t('views.applicationWorkflow.nodes.imageGenerateNode.model.requiredMessage'),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between w-full">
<div>
<span>图片生成模型<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.imageGenerateNode.model.label')
}}<span class="danger">*</span></span
>
</div>
<el-button
:disabled="!form_data.model_id"
@ -42,28 +45,33 @@
@wheel="wheel"
:teleported="false"
v-model="form_data.model_id"
placeholder="请选择图片生成模型"
:placeholder="
$t('views.applicationWorkflow.nodes.imageGenerateNode.model.requiredMessage')
"
:options="modelOptions"
></ModelSelect>
</el-form-item>
<el-form-item
label="提示词(正向)"
:label="$t('views.applicationWorkflow.nodes.imageGenerateNode.prompt.label')"
prop="prompt"
:rules="{
required: true,
message: '请输入提示词',
message: $t('views.application.applicationForm.form.prompt.requiredMessage'),
trigger: 'blur'
}"
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>提示词(正向)<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.imageGenerateNode.prompt.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content
>正向提示词用来描述生成图像中期望包含的元素和视觉特点
>{{ $t('views.applicationWorkflow.nodes.imageGenerateNode.prompt.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -71,29 +79,31 @@
</template>
<MdEditorMagnify
@wheel="wheel"
title="提示词(正向)"
:title="$t('views.applicationWorkflow.nodes.imageGenerateNode.prompt.label')"
v-model="form_data.prompt"
style="height: 150px"
@submitDialog="submitDialog"
/>
</el-form-item>
<el-form-item
label="提示词(负向)"
:label="$t('views.applicationWorkflow.nodes.imageGenerateNode.negative_prompt.label')"
prop="prompt"
:rules="{
required: false,
message: '请输入提示词',
message: $t('views.application.applicationForm.form.prompt.requiredMessage'),
trigger: 'blur'
}"
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>提示词(负向)</span>
<span>{{
$t('views.applicationWorkflow.nodes.imageGenerateNode.negative_prompt.label')
}}</span>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content
>反向提示词用来描述不希望在画面中看到的内容可以对画面进行限制
>{{ $t('views.applicationWorkflow.nodes.imageGenerateNode.negative_prompt.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -101,23 +111,28 @@
</template>
<MdEditorMagnify
@wheel="wheel"
title="提示词(负向)"
:title=" $t('views.applicationWorkflow.nodes.imageGenerateNode.negative_prompt.label')"
v-model="form_data.negative_prompt"
placeholder="请描述不想生成的图片内容,比如:颜色、血腥内容"
:placeholder="$t('views.applicationWorkflow.nodes.imageGenerateNode.negative_prompt.placeholder')"
style="height: 150px"
@submitDialog="submitNegativeDialog"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -140,7 +155,7 @@ import { app } from '@/main'
import useStore from '@/stores'
import type { FormInstance } from 'element-plus'
import AIModeParamSettingDialog from '@/views/application/component/AIModeParamSettingDialog.vue'
import { t } from '@/locales'
const { model } = useStore()
const {
@ -168,7 +183,7 @@ const wheel = (e: any) => {
}
}
const defaultPrompt = `{{开始.question}}`
const defaultPrompt = `{{${t('views.applicationWorkflow.nodes.startNode.label')}.question}}`
const form = {
model_id: '',

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :node-model="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -12,18 +12,23 @@
hide-required-asterisk
>
<el-form-item
label="图片理解模型"
:label="$t('views.applicationWorkflow.nodes.imageUnderstandNode.model.label')"
prop="model_id"
:rules="{
required: true,
message: '请选择图片理解模型',
message: $t(
'views.applicationWorkflow.nodes.imageUnderstandNode.model.requiredMessage'
),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between w-full">
<div>
<span>图片理解模型<span class="danger">*</span></span>
<span
>{{ t('views.applicationWorkflow.nodes.imageUnderstandNode.model.label')
}}<span class="danger">*</span></span
>
</div>
<el-button
:disabled="!form_data.model_id"
@ -41,37 +46,42 @@
@wheel="wheel"
:teleported="false"
v-model="form_data.model_id"
placeholder="请选择图片理解模型"
:placeholder="
$t('views.applicationWorkflow.nodes.imageUnderstandNode.model.requiredMessage')
"
:options="modelOptions"
></ModelSelect>
</el-form-item>
<el-form-item label="角色设定">
<el-form-item :label="$t('views.application.applicationForm.form.roleSettings.label')">
<MdEditorMagnify
title="角色设定"
:title="$t('views.application.applicationForm.form.roleSettings.label')"
v-model="form_data.system"
style="height: 100px"
@submitDialog="submitSystemDialog"
placeholder="角色设定"
:placeholder="$t('views.application.applicationForm.form.roleSettings.label')"
/>
</el-form-item>
<el-form-item
label="提示词"
:label="$t('views.application.applicationForm.form.prompt.label')"
prop="prompt"
:rules="{
required: true,
message: '请输入提示词',
message: $t('views.application.applicationForm.form.prompt.requiredMessage'),
trigger: 'blur'
}"
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>提示词<span class="danger">*</span></span>
<span
>{{ $t('views.application.applicationForm.form.prompt.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content
>通过调整提示词内容可以引导大模型聊天方向该提示词会被固定在上下文的开头可以使用变量
>{{ $t('views.application.applicationForm.form.prompt.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -79,7 +89,7 @@
</template>
<MdEditorMagnify
@wheel="wheel"
title="提示词"
:title="$t('views.application.applicationForm.form.prompt.label')"
v-model="form_data.prompt"
style="height: 150px"
@submitDialog="submitDialog"
@ -88,10 +98,10 @@
<el-form-item>
<template #label>
<div class="flex-between">
<div>历史聊天记录</div>
<div>{{ $t('views.application.applicationForm.form.historyRecord.label') }}</div>
<el-select v-model="form_data.dialogue_type" type="small" style="width: 100px">
<el-option label="节点" value="NODE" />
<el-option label="工作流" value="WORKFLOW" />
<el-option :label="$t('views.applicationWorkflow.node')" value="NODE" />
<el-option :label="$t('views.applicationWorkflow.workflow')" value="WORKFLOW" />
</el-select>
</div>
</template>
@ -106,33 +116,47 @@
/>
</el-form-item>
<el-form-item
label="选择图片"
:label="$t(
'views.applicationWorkflow.nodes.imageUnderstandNode.image.label'
),"
:rules="{
type: 'array',
required: true,
message: '请选择图片',
message: $t(
'views.applicationWorkflow.nodes.imageUnderstandNode.image.requiredMessage'
),
trigger: 'change'
}"
>
<template #label>选择图片<span class="danger">*</span></template>
<template #label
>{{ $t('views.applicationWorkflow.nodes.imageUnderstandNode.image.label')
}}<span class="danger">*</span></template
>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择图片"
:placeholder="$t(
'views.applicationWorkflow.nodes.imageUnderstandNode.image.requiredMessage'
)"
v-model="form_data.image_list"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -156,7 +180,7 @@ import useStore from '@/stores'
import NodeCascader from '@/workflow/common/NodeCascader.vue'
import type { FormInstance } from 'element-plus'
import AIModeParamSettingDialog from '@/views/application/component/AIModeParamSettingDialog.vue'
import { t } from '@/locales'
const { model } = useStore()
const {
@ -188,7 +212,7 @@ const wheel = (e: any) => {
}
}
const defaultPrompt = `{{开始.question}}`
const defaultPrompt = `{{${t('views.applicationWorkflow.nodes.startNode.label')}.question}}`
const form = {
model_id: '',

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never" style="--el-card-padding: 12px">
<el-form
@submit.prevent
@ -13,18 +13,21 @@
hide-required-asterisk
>
<el-form-item
label="AI 模型"
:label="$t('views.application.applicationForm.form.aiModel.label')"
prop="model_id"
:rules="{
required: true,
message: '请选择 AI 模型',
message: $t('views.application.applicationForm.form.aiModel.placeholder'),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between">
<div>
<span>AI 模型<span class="danger">*</span></span>
<span
>{{ $t('views.application.applicationForm.form.aiModel.label')
}}<span class="danger">*</span></span
>
</div>
<el-button
type="primary"
@ -48,33 +51,36 @@
showFooter
></ModelSelect>
</el-form-item>
<el-form-item label="角色设定">
<el-form-item :label="$t('views.application.applicationForm.form.roleSettings.label')">
<MdEditorMagnify
title="角色设定"
:title="$t('views.application.applicationForm.form.roleSettings.label')"
v-model="form_data.system"
style="height: 100px"
@submitDialog="submitSystemDialog"
placeholder="角色设定"
:placeholder="$t('views.application.applicationForm.form.roleSettings.label')"
/>
</el-form-item>
<el-form-item
label="提示词"
:label="$t('views.application.applicationForm.form.prompt.label')"
prop="prompt"
:rules="{
required: true,
message: '请输入提示词',
message: $t('views.application.applicationForm.form.prompt.tooltip'),
trigger: 'blur'
}"
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>提示词<span class="danger">*</span></span>
<span
>{{ $t('views.application.applicationForm.form.prompt.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content
>通过调整提示词内容可以引导大模型聊天方向该提示词会被固定在上下文的开头可以使用变量</template
>
<template #content>{{
$t('views.application.applicationForm.form.prompt.tooltip')
}}</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
<el-icon><EditPen /></el-icon>
</el-tooltip>
@ -82,13 +88,13 @@
</template>
<MdEditorMagnify
@wheel="wheel"
title="提示词"
:title="$t('views.application.applicationForm.form.prompt.label')"
v-model="form_data.prompt"
style="height: 150px"
@submitDialog="submitDialog"
/>
</el-form-item>
<el-form-item label="历史聊天记录">
<el-form-item :label="$t('views.application.applicationForm.form.historyRecord.label')">
<el-input-number
v-model="form_data.dialogue_number"
:min="0"
@ -99,16 +105,21 @@
:step-strictly="true"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -132,6 +143,7 @@ import { ref, computed, onMounted } from 'vue'
import applicationApi from '@/api/application'
import useStore from '@/stores'
import { isLastNode } from '@/workflow/common/data'
import { t } from '@/locales'
const { model } = useStore()
const AIModeParamSettingDialogRef = ref<InstanceType<typeof AIModeParamSettingDialog>>()
@ -164,11 +176,10 @@ const {
} = app.config.globalProperties.$route as any
// @ts-ignore
const defaultPrompt = `根据上下文优化和完善用户问题:{{开始.question}}
请输出一个优化后的问题`
const defaultPrompt = t('views.applicationWorkflow.nodes.questionNode.defaultPrompt')
const form = {
model_id: '',
system: '你是一个问题优化大师',
system: t('views.applicationWorkflow.nodes.questionNode.systemDefault'),
prompt: defaultPrompt,
dialogue_number: 1,
is_result: false

View File

@ -9,18 +9,18 @@
label-width="auto"
ref="replyNodeFormRef"
>
<el-form-item label="回复内容">
<el-form-item :label="$t('views.applicationWorkflow.nodes.replyNode.replyContent.label')">
<template #label>
<div class="flex-between">
<span>回复内容</span>
<span>{{ $t('views.applicationWorkflow.nodes.replyNode.replyContent.label') }}</span>
<el-select
:teleported="false"
v-model="form_data.reply_type"
size="small"
style="width: 85px"
>
<el-option label="引用变量" value="referencing" />
<el-option label="自定义" value="content" />
<el-option :label="$t('views.applicationWorkflow.nodes.replyNode.replyContent.reference')" value="referencing" />
<el-option :label="$t('views.applicationWorkflow.nodes.replyNode.replyContent.custom')" value="content" />
</el-select>
</div>
</template>
@ -28,7 +28,7 @@
<MdEditorMagnify
v-if="form_data.reply_type === 'content'"
@wheel="wheel"
title="回复内容"
:title="$t('views.applicationWorkflow.nodes.replyNode.replyContent.label')"
v-model="form_data.content"
style="height: 150px"
@submitDialog="submitDialog"
@ -38,20 +38,27 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
:placeholder="
$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.placeholder')
"
v-model="form_data.fields"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>

View File

@ -18,8 +18,14 @@
<el-form-item>
<template #label>
<div class="flex align-center">
<span class="mr-4">Score 高于</span>
<el-tooltip effect="dark" content="Score越高相关性越强。" placement="right">
<span class="mr-4"
>Score {{ $t('views.applicationWorkflow.nodes.rerankerNode.higher') }}</span
>
<el-tooltip
effect="dark"
:content="$t('views.applicationWorkflow.nodes.rerankerNode.ScoreTooltip')"
placement="right"
>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
</div>

View File

@ -11,18 +11,23 @@
hide-required-asterisk
>
<el-form-item
label="重排内容"
:label="$t('views.applicationWorkflow.nodes.rerankerNode.rerankerContent.label')"
prop="reranker_reference_list"
:rules="{
type: 'array',
message: '请选择重排内容',
message: $t(
'views.applicationWorkflow.nodes.rerankerNode.rerankerContent.requiredMessage'
),
trigger: 'change',
required: true
}"
>
<template #label>
<div class="flex-between">
<span>重排内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.rerankerNode.rerankerContent.label')
}}<span class="danger">*</span></span
>
<el-button @click="add_reranker_reference" link type="primary">
<el-icon class="mr-4"><Plus /></el-icon>
</el-button>
@ -40,7 +45,7 @@
:rules="{
type: 'array',
required: true,
message: '请选择变量',
message: $t('views.applicationWorkflow.variable.fieldMessage'),
trigger: 'change'
}"
>
@ -48,7 +53,11 @@
:key="index"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择重排内容"
:placeholder="
$t(
'views.applicationWorkflow.nodes.rerankerNode.rerankerContent.requiredMessage'
)
"
v-model="form_data.reranker_reference_list[index]"
/>
</el-form-item>
@ -60,10 +69,10 @@
</el-col>
</el-row>
</el-form-item>
<el-form-item label="检索参数">
<el-form-item :label="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchParam')">
<template #label>
<div class="flex-between">
<span>检索参数</span>
<span>{{ $t('views.applicationWorkflow.nodes.searchDatasetNode.searchParam') }}</span>
<el-button type="primary" link @click="openParamSettingDialog">
<el-icon><Setting /></el-icon>
</el-button>
@ -71,13 +80,22 @@
</template>
<div class="w-full">
<el-row>
<el-col :span="12" class="color-secondary lighter"> Score 高于</el-col>
<el-col :span="12" class="color-secondary lighter">
Score
{{ $t('views.applicationWorkflow.nodes.rerankerNode.higher') }}</el-col
>
<el-col :span="12" class="lighter">
{{ form_data.reranker_setting.similarity?.toFixed(3) }}</el-col
>
<el-col :span="12" class="color-secondary lighter"> 引用分段 Top</el-col>
<el-col :span="12" class="color-secondary lighter">
{{ $t('components.chat.KnowledgeSource.referenceParagraph') }} Top</el-col
>
<el-col :span="12" class="lighter"> {{ form_data.reranker_setting.top_n }}</el-col>
<el-col :span="12" class="color-secondary lighter"> 最大引用字符数</el-col>
<el-col :span="12" class="color-secondary lighter">
{{
$t('views.applicationWorkflow.nodes.rerankerNode.max_paragraph_char_number')
}}</el-col
>
<el-col :span="12" class="lighter">
{{ form_data.reranker_setting.max_paragraph_char_number }}</el-col
>
@ -85,46 +103,56 @@
</div>
</el-form-item>
<el-form-item
label="检索问题"
:label="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.label')"
prop="question_reference_address"
:rules="{
message: '请选择检索问题',
message: $t(
'views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.requiredMessage'
),
trigger: 'blur',
required: true
}"
>
<template #label>
<div class="flex-between">
<span>检索问题<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.label')
}}<span class="danger">*</span></span
>
</div>
</template>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="检索问题"
:placeholder="
$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.label')
"
v-model="form_data.question_reference_address"
/>
</el-form-item>
<el-form-item
label="重排模型"
:label="$t('views.applicationWorkflow.nodes.reranker_model.label')"
prop="reranker_model_id"
:rules="{
required: true,
message: '请选择重排模型',
message: $t('views.applicationWorkflow.nodes.reranker_model.placeholder'),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between">
<span>重排模型<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.reranker_model.label')
}}<span class="danger">*</span></span
>
</div>
</template>
<ModelSelect
@wheel="wheel"
:teleported="false"
v-model="form_data.reranker_model_id"
placeholder="请选择重排模型"
:placeholder="$t('views.applicationWorkflow.nodes.reranker_model.placeholder')"
:options="modelOptions"
@submitModel="getModel"
showFooter
@ -227,7 +255,6 @@ const validate = () => {
}
onMounted(() => {
getModel()
set(props.nodeModel, 'validate', validate)
})

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :nodeModel="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -10,10 +10,10 @@
label-width="auto"
ref="DatasetNodeFormRef"
>
<el-form-item label="选择知识库">
<el-form-item :label="$t('views.log.selectDataset')">
<template #label>
<div class="flex-between">
<span>选择知识库</span>
<span>{{ $t('views.log.selectDataset') }}</span>
<el-button type="primary" link @click="openDatasetDialog">
<el-icon><Plus /></el-icon>
</el-button>
@ -21,7 +21,7 @@
</template>
<div class="w-full">
<el-text type="info" v-if="form_data.dataset_id_list?.length === 0">
关联的知识库展示在这里
{{ $t('views.applicationWorkflow.nodes.searchDatasetNode.selectDatasetText') }}
</el-text>
<template v-for="(item, index) in form_data.dataset_id_list" :key="index" v-else>
<div class="flex-between border border-r-4 white-bg mb-4" style="padding: 5px 8px">
@ -50,10 +50,10 @@
</template>
</div>
</el-form-item>
<el-form-item label="检索参数">
<el-form-item :label="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchParam')">
<template #label>
<div class="flex-between">
<span>检索参数</span>
<span>{{ $t('views.applicationWorkflow.nodes.searchDatasetNode.searchParam') }}</span>
<el-button type="primary" link @click="openParamSettingDialog">
<el-icon><Setting /></el-icon>
</el-button>
@ -61,19 +61,27 @@
</template>
<div class="w-full">
<el-row>
<el-col :span="12" class="color-secondary lighter">检索模式</el-col>
<el-col :span="12" class="color-secondary lighter">{{
$t('views.application.applicationForm.dialog.selectSearchMode')
}}</el-col>
<el-col :span="12" class="lighter">
{{
SearchMode[form_data.dataset_setting.search_mode as keyof typeof SearchMode]
}}</el-col
>
<el-col :span="12" class="color-secondary lighter"> 相似度高于</el-col>
<el-col :span="12" class="color-secondary lighter">
{{ $t('views.application.applicationForm.dialog.similarityThreshold') }}</el-col
>
<el-col :span="12" class="lighter">
{{ form_data.dataset_setting.similarity?.toFixed(3) }}</el-col
>
<el-col :span="12" class="color-secondary lighter"> 引用分段 Top</el-col>
<el-col :span="12" class="color-secondary lighter">{{
$t('views.application.applicationForm.dialog.topReferences')
}}</el-col>
<el-col :span="12" class="lighter"> {{ form_data.dataset_setting.top_n }}</el-col>
<el-col :span="12" class="color-secondary lighter"> 最大引用字符数</el-col>
<el-col :span="12" class="color-secondary lighter">
{{ $t('views.application.applicationForm.dialog.maxCharacters') }}</el-col
>
<el-col :span="12" class="lighter">
{{ form_data.dataset_setting.max_paragraph_char_number }}</el-col
>
@ -81,10 +89,10 @@
</div>
</el-form-item>
<el-form-item
label="检索问题"
:label="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.label')"
prop="question_reference_address"
:rules="{
message: '请选择检索问题',
message: $t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.requiredMessage'),
trigger: 'blur',
required: true
}"
@ -93,7 +101,7 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择检索问题"
:placeholder="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.placeholder')"
v-model="form_data.question_reference_address"
/>
</el-form-item>

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :node-model="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -12,18 +12,21 @@
hide-required-asterisk
>
<el-form-item
label="语音识别模型"
:label="$t('views.applicationWorkflow.nodes.speechToTextNode.stt_model.label')"
prop="stt_model_id"
:rules="{
required: true,
message: '请选择语音识别模型',
message: $t('views.application.applicationForm.form.voiceInput.placeholder'),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between w-full">
<div>
<span>语音识别模型<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.speechToTextNode.stt_model.label')
}}<span class="danger">*</span></span
>
</div>
</div>
</template>
@ -36,10 +39,10 @@
></ModelSelect>
</el-form-item>
<el-form-item
label="选择语音文件"
:label="$t('views.applicationWorkflow.nodes.speechToTextNode.audio.label')"
prop="audio_list"
:rules="{
message: '选择语音文件',
message: $t('views.applicationWorkflow.nodes.speechToTextNode.audio.label'),
trigger: 'change',
required: true
}"
@ -47,7 +50,10 @@
<template #label>
<div class="flex-between w-full">
<div>
<span>选择语音文件<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.speechToTextNode.audio.label')
}}<span class="danger">*</span></span
>
</div>
</div>
</template>
@ -55,21 +61,26 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="请选择语音文件"
:placeholder="$t('views.applicationWorkflow.nodes.speechToTextNode.audio.placeholder')"
v-model="form_data.audio_list"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -154,8 +165,6 @@ function getModel() {
}
}
onMounted(() => {
getModel()

View File

@ -17,11 +17,7 @@
>
<el-button
link
@click="
copyClick(
`{{${$t('views.applicationWorkflow.variable.global')}.${item.value}}}`
)
"
@click="copyClick(`{{${$t('views.applicationWorkflow.variable.global')}.${item.value}}}`)"
style="padding: 0"
>
<AppIcon iconName="app-copy"></AppIcon>
@ -35,14 +31,14 @@ import { cloneDeep, set } from 'lodash'
import NodeContainer from '@/workflow/common/NodeContainer.vue'
import { copyClick } from '@/utils/clipboard'
import { ref, computed, onMounted } from 'vue'
import { t } from '@/locales'
const props = defineProps<{ nodeModel: any }>()
const showicon = ref(false)
const globalFields = [
{ label: '当前时间', value: 'time' },
{ label: '历史聊天记录', value: 'history_context' },
{ label: '对话id', value: 'chat_id' }
{ label: t('views.applicationWorkflow.nodes.startNode.currentTime'), value: 'time' },
{ label: t('views.application.applicationForm.form.historyRecord.label'), value: 'history_context' },
{ label: t('components.chat.chatId'), value: 'chat_id' }
]
const getRefreshFieldList = () => {
@ -92,16 +88,16 @@ const refreshFileUploadConfig = () => {
}
let fileUploadFields = []
if (form_data[0].document) {
fileUploadFields.push({ label: '文档', value: 'document' })
fileUploadFields.push({ label: t('common.fileUpload.document'), value: 'document' })
}
if (form_data[0].image) {
fileUploadFields.push({ label: '图片', value: 'image' })
fileUploadFields.push({ label: t('common.fileUpload.image'), value: 'image' })
}
if (form_data[0].audio) {
fileUploadFields.push({ label: '音频', value: 'audio' })
fileUploadFields.push({ label: t('common.fileUpload.audio'), value: 'audio' })
}
if (form_data[0].video) {
fileUploadFields.push({ label: '视频', value: 'video' })
fileUploadFields.push({ label: t('common.fileUpload.video'), value: 'video' })
}
set(props.nodeModel.properties.config, 'fields', [...fields, ...fileUploadFields])

View File

@ -1,6 +1,6 @@
<template>
<NodeContainer :node-model="nodeModel">
<h5 class="title-decoration-1 mb-8">节点设置</h5>
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
<el-card shadow="never" class="card-never">
<el-form
@submit.prevent
@ -12,18 +12,21 @@
hide-required-asterisk
>
<el-form-item
label="语音合成模型"
:label="$t('views.applicationWorkflow.nodes.textToSpeechNode.tts_model.label')"
prop="tts_model_id"
:rules="{
required: true,
message: '请选择语音合成模型',
message: $t('views.application.applicationForm.form.voicePlay.placeholder'),
trigger: 'change'
}"
>
<template #label>
<div class="flex-between w-full">
<div>
<span>语音合成模型<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.textToSpeechNode.tts_model.label')
}}<span class="danger">*</span></span
>
</div>
<el-button
type="primary"
@ -46,9 +49,9 @@
</el-form-item>
<el-form-item
prop="content_list"
label="选择文本内容"
:label="$t('views.applicationWorkflow.nodes.textToSpeechNode.content.label')"
:rules="{
message: '选择文本内容',
message: $t('views.applicationWorkflow.nodes.textToSpeechNode.content.label'),
trigger: 'blur',
required: true
}"
@ -56,7 +59,10 @@
<template #label>
<div class="flex-between w-full">
<div>
<span>选择文本内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.textToSpeechNode.content.label')
}}<span class="danger">*</span></span
>
</div>
</div>
</template>
@ -64,21 +70,26 @@
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
placeholder="选择文本内容"
:placeholder="$t('views.applicationWorkflow.nodes.textToSpeechNode.content.label')"
v-model="form_data.content_list"
/>
</el-form-item>
<el-form-item label="返回内容" @click.prevent>
<el-form-item
:label="$t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')"
@click.prevent
>
<template #label>
<div class="flex align-center">
<div class="mr-4">
<span>返回内容<span class="danger">*</span></span>
<span
>{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label')
}}<span class="danger">*</span></span
>
</div>
<el-tooltip effect="dark" placement="right" popper-class="max-w-200">
<template #content>
关闭后该节点的内容则不输出给用户
如果你想让用户看到该节点的输出内容请打开开关
{{ $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.tooltip') }}
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
@ -172,7 +183,7 @@ function getModel() {
const openTTSParamSettingDialog = () => {
const model_id = form_data.value.tts_model_id
if (!model_id) {
MsgSuccess(t('请选择语音播放模型'))
MsgSuccess(t('views.application.applicationForm.form.voicePlay.requiredMessage'))
return
}
TTSModeParamSettingDialogRef.value?.open(model_id, id, form_data.value.model_params_setting)